소스 검색

* support var/out managed types on the callee side in location_get_data_ref()

git-svn-id: branches/jvmbackend@18604 -
Jonas Maebe 14 년 전
부모
커밋
887248af2d
1개의 변경된 파일17개의 추가작업 그리고 6개의 파일을 삭제
  1. 17 6
      compiler/jvm/hlcgcpu.pas

+ 17 - 6
compiler/jvm/hlcgcpu.pas

@@ -1452,7 +1452,7 @@ implementation
       { This routine is a combination of a generalised a_loadaddr_ref_reg()
       { This routine is a combination of a generalised a_loadaddr_ref_reg()
         that also works for addresses in registers (in case loadref is false)
         that also works for addresses in registers (in case loadref is false)
         and of a_load_ref_reg (in case loadref is true). It is used for
         and of a_load_ref_reg (in case loadref is true). It is used for
-        a) getting the address of managed types
+        a) getting the address of managed var/out parameters
         b) getting to the actual data of value types that are passed by
         b) getting to the actual data of value types that are passed by
            reference by the compiler (and then get a local copy at the caller
            reference by the compiler (and then get a local copy at the caller
            side). Normally, depending on whether this reference is passed in a
            side). Normally, depending on whether this reference is passed in a
@@ -1470,32 +1470,43 @@ implementation
 
 
         However, managed types are also implicit pointers in Pascal, so in that
         However, managed types are also implicit pointers in Pascal, so in that
         case "taking the address" again consists of simply returning the
         case "taking the address" again consists of simply returning the
-        implicit pointer/current value.
+        implicit pointer/current value (in case of a var/out parameter, this
+        value is stored inside an array).
       }
       }
       if not loadref then
       if not loadref then
         begin
         begin
           if not is_managed_type(def) then
           if not is_managed_type(def) then
             internalerror(2011020601);
             internalerror(2011020601);
+          tmploc:=l;
         end
         end
       else
       else
         begin
         begin
           if not jvmimplicitpointertype(def) then
           if not jvmimplicitpointertype(def) then
-            internalerror(2011020602);
+            begin
+              { passed by reference in array of single element; l contains the
+                base address of the array }
+              location_reset_ref(tmploc,LOC_REFERENCE,OS_ADDR,4);
+              reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,4);
+              tmploc.reference.arrayreftype:=art_indexconst;
+              tmploc.reference.indexoffset:=0;
+              a_load_loc_reg(list,java_jlobject,java_jlobject,l,tmploc.reference.base);
+            end
+          else
+            tmploc:=l;
         end;
         end;
-      case l.loc of
+      case tmploc.loc of
         LOC_REGISTER,
         LOC_REGISTER,
         LOC_CREGISTER :
         LOC_CREGISTER :
           begin
           begin
             { the implicit pointer is in a register and has to be in a
             { the implicit pointer is in a register and has to be in a
               reference -> create a reference and put it there }
               reference -> create a reference and put it there }
-            tmploc:=l;
             location_force_mem(list,tmploc,java_jlobject);
             location_force_mem(list,tmploc,java_jlobject);
             ref:=tmploc.reference;
             ref:=tmploc.reference;
           end;
           end;
         LOC_REFERENCE,
         LOC_REFERENCE,
         LOC_CREFERENCE :
         LOC_CREFERENCE :
           begin
           begin
-            ref:=l.reference;
+            ref:=tmploc.reference;
           end;
           end;
         else
         else
           internalerror(2011020603);
           internalerror(2011020603);