Jelajahi Sumber

* fixed accessing var-parameters from nested routines
o support for JVM arrays in JVM addrnodes and derefnodes (so we
can take the address of var parameters to store them in the
parentfpstruct and later dereference them)
o process loadnode.left also in tjvmloadnode.pass_generate_code() when
handling var-parameters

git-svn-id: branches/jvmbackend@18593 -

Jonas Maebe 14 tahun lalu
induk
melakukan
7cf06b9aa6
2 mengubah file dengan 49 tambahan dan 12 penghapusan
  1. 10 3
      compiler/jvm/njvmld.pas
  2. 39 9
      compiler/jvm/njvmmem.pas

+ 10 - 3
compiler/jvm/njvmld.pas

@@ -141,13 +141,20 @@ procedure tjvmloadnode.pass_generate_code;
   begin
   begin
     if is_copyout_addr_param_load then
     if is_copyout_addr_param_load then
       begin
       begin
-        { the parameter is passed as an array of one element containing the
-          parameter value }
+        { in case of nested access, load address of field in nestedfpstruct }
+        if assigned(left) then
+          generate_nested_access(tabstractnormalvarsym(symtableentry));
         location_reset_ref(location,LOC_REFERENCE,def_cgsize(resultdef),4);
         location_reset_ref(location,LOC_REFERENCE,def_cgsize(resultdef),4);
         location.reference.arrayreftype:=art_indexconst;
         location.reference.arrayreftype:=art_indexconst;
         location.reference.base:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
         location.reference.base:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
-        hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,tparavarsym(symtableentry).localloc,location.reference.base);
         location.reference.indexoffset:=0;
         location.reference.indexoffset:=0;
+        { load the field from the nestedfpstruct, or the parameter location.
+          In both cases, the result is an array of one element containing the
+          parameter value }
+        if assigned(left) then
+          hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,left.location,location.reference.base)
+        else
+          hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,tparavarsym(symtableentry).localloc,location.reference.base);
       end
       end
     else
     else
       inherited pass_generate_code;
       inherited pass_generate_code;

+ 39 - 9
compiler/jvm/njvmmem.pas

@@ -78,15 +78,28 @@ implementation
       end;
       end;
 
 
     procedure tjvmderefnode.pass_generate_code;
     procedure tjvmderefnode.pass_generate_code;
+      var
+        implicitptr: boolean;
       begin
       begin
         secondpass(left);
         secondpass(left);
+        implicitptr:=jvmimplicitpointertype(tpointerdef(left.resultdef).pointeddef);
         if (left.resultdef.typ=pointerdef) and
         if (left.resultdef.typ=pointerdef) and
             ((left.resultdef=voidpointertype) or
             ((left.resultdef=voidpointertype) or
-             jvmimplicitpointertype(tpointerdef(left.resultdef).pointeddef)) then
+             implicitptr) then
           begin
           begin
-            { this is basically a typecast: the left node is a regular
-              'pointer', and we typecast it to an implicit pointer }
-            location_copy(location,left.location);
+            if implicitptr then
+              { this is basically a typecast: the left node is a regular
+                'pointer', and we typecast it to an implicit pointer }
+              location_copy(location,left.location)
+            else
+              begin
+                { these are always arrays (used internally for pointers to var
+                  parameters stored in nestedfpstructs) }
+                hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+                location_reset_ref(location,LOC_REFERENCE,OS_ADDR,4);
+                reference_reset_base(location.reference,left.location.register,0,4);
+                location.reference.arrayreftype:=art_indexconst;
+              end;
           end
           end
         else
         else
           internalerror(2011052901);
           internalerror(2011052901);
@@ -129,15 +142,32 @@ implementation
 
 
 
 
     procedure tjvmaddrnode.pass_generate_code;
     procedure tjvmaddrnode.pass_generate_code;
+      var
+        implicitptr: boolean;
       begin
       begin
         secondpass(left);
         secondpass(left);
-        if jvmimplicitpointertype(left.resultdef) or
+        implicitptr:=jvmimplicitpointertype(left.resultdef);
+        if implicitptr or
            (nf_internal in flags) then
            (nf_internal in flags) then
           begin
           begin
-            { this is basically a typecast: the left node is an implicit
-              pointer, and we typecast it to a regular 'pointer'
-              (java.lang.Object) }
-            location_copy(location,left.location);
+            if implicitptr then
+              { this is basically a typecast: the left node is an implicit
+                pointer, and we typecast it to a regular 'pointer'
+                (java.lang.Object) }
+              location_copy(location,left.location)
+            else
+              begin
+                { these are always arrays (used internally for pointers to var
+                  parameters stored in nestedfpstructs) -> get base pointer to
+                  array }
+                if (left.location.loc<>LOC_REFERENCE) or
+                   (left.location.reference.arrayreftype<>art_indexconst) or
+                   (left.location.reference.base=NR_NO) or
+                   assigned(left.location.reference.symbol) then
+                  internalerror(2011060701);
+                location_reset(location,LOC_REGISTER,OS_ADDR);
+                location.register:=left.location.reference.base;
+              end;
           end
           end
         else
         else
           begin
           begin