Browse Source

+ support for (non-variant) arrayconstructornodes for the JVM target
o when allocating array temps for the JVM target, use the specified
"forcesize" for the first dimension, since the arraydef size may
be invalid (e.g., in case it's an array constructor)

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

Jonas Maebe 14 years ago
parent
commit
bf21cd7a15
3 changed files with 72 additions and 15 deletions
  1. 35 2
      compiler/jvm/njvmld.pas
  2. 5 1
      compiler/jvm/tgcpu.pas
  3. 32 12
      compiler/ncgld.pas

+ 35 - 2
compiler/jvm/njvmld.pas

@@ -26,6 +26,9 @@ unit njvmld;
 interface
 interface
 
 
 uses
 uses
+  globtype,
+  symtype,
+  cgutils,
   node, ncgld;
   node, ncgld;
 
 
 type
 type
@@ -33,12 +36,20 @@ type
     function is_addr_param_load: boolean; override;
     function is_addr_param_load: boolean; override;
   end;
   end;
 
 
+  tjvmarrayconstructornode = class(tcgarrayconstructornode)
+   protected
+    procedure makearrayref(var ref: treference; eledef: tdef); override;
+    procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
+  end;
+
 implementation
 implementation
 
 
 uses
 uses
+  verbose,
+  aasmdata,
   nld,
   nld,
-  symsym,
-  jvmdef;
+  symsym,symdef,jvmdef,
+  cgbase,hlcgobj;
 
 
 function tjvmloadnode.is_addr_param_load: boolean;
 function tjvmloadnode.is_addr_param_load: boolean;
   begin
   begin
@@ -48,7 +59,29 @@ function tjvmloadnode.is_addr_param_load: boolean;
   end;
   end;
 
 
 
 
+{ tjvmarrayconstructornode }
+
+procedure tjvmarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
+  var
+    basereg: tregister;
+  begin
+    { arrays are implicitly dereferenced }
+    basereg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
+    hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,ref,basereg);
+    reference_reset_base(ref,basereg,0,1);
+    ref.arrayreftype:=art_indexconst;
+    ref.indexoffset:=0;
+  end;
+
+
+procedure tjvmarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
+  begin
+    inc(ref.indexoffset);
+  end;
+
+
 begin
 begin
   cloadnode:=tjvmloadnode;
   cloadnode:=tjvmloadnode;
+  carrayconstructornode:=tjvmarrayconstructornode;
 end.
 end.
 
 

+ 5 - 1
compiler/jvm/tgcpu.pas

@@ -78,9 +78,13 @@ unit tgcpu;
                   ndim:=0;
                   ndim:=0;
                   eledef:=def;
                   eledef:=def;
                   repeat
                   repeat
-                    thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,tarraydef(eledef).elecount,R_INTREGISTER);
+                    if forcesize<>-1 then
+                      thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,forcesize div tarraydef(eledef).elesize,R_INTREGISTER)
+                    else
+                      thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,tarraydef(eledef).elecount,R_INTREGISTER);
                     eledef:=tarraydef(eledef).elementdef;
                     eledef:=tarraydef(eledef).elementdef;
                     inc(ndim);
                     inc(ndim);
+                    forcesize:=-1;
                   until (eledef.typ<>arraydef) or
                   until (eledef.typ<>arraydef) or
                         is_dynamic_array(eledef);
                         is_dynamic_array(eledef);
                   eledef:=tarraydef(def).elementdef;
                   eledef:=tarraydef(def).elementdef;

+ 32 - 12
compiler/ncgld.pas

@@ -27,6 +27,8 @@ unit ncgld;
 interface
 interface
 
 
     uses
     uses
+      globtype,
+      symtype,
       node,nld,cgutils;
       node,nld,cgutils;
 
 
     type
     type
@@ -41,6 +43,10 @@ interface
        end;
        end;
 
 
        tcgarrayconstructornode = class(tarrayconstructornode)
        tcgarrayconstructornode = class(tarrayconstructornode)
+         protected
+          procedure makearrayref(var ref: treference; eledef: tdef);virtual;
+          procedure advancearrayoffset(var ref: treference; elesize: asizeint);virtual;
+         public
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
        end;
        end;
 
 
@@ -54,9 +60,9 @@ implementation
     uses
     uses
       cutils,
       cutils,
       systems,
       systems,
-      verbose,globtype,globals,constexp,
+      verbose,globals,constexp,
       nutils,
       nutils,
-      symtable,symconst,symtype,symdef,symsym,defutil,paramgr,
+      symtable,symconst,symdef,symsym,defutil,paramgr,
       ncnv,ncon,nmem,nbas,ncgrtti,
       ncnv,ncon,nmem,nbas,ncgrtti,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       cgbase,pass_2,
       cgbase,pass_2,
@@ -1007,6 +1013,19 @@ implementation
         vtAnsiString16  = 19;
         vtAnsiString16  = 19;
         vtAnsiString64  = 20;
         vtAnsiString64  = 20;
 
 
+
+    procedure tcgarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
+      begin
+        { do nothing by default }
+      end;
+
+
+    procedure tcgarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
+      begin
+        inc(ref.offset,elesize);
+      end;
+
+
     procedure tcgarrayconstructornode.pass_generate_code;
     procedure tcgarrayconstructornode.pass_generate_code;
       var
       var
         hp    : tarrayconstructornode;
         hp    : tarrayconstructornode;
@@ -1042,10 +1061,11 @@ implementation
         { Allocate always a temp, also if no elements are required, to
         { Allocate always a temp, also if no elements are required, to
           be sure that location is valid (PFV) }
           be sure that location is valid (PFV) }
          if tarraydef(resultdef).highrange=-1 then
          if tarraydef(resultdef).highrange=-1 then
-           tg.gethltemp(current_asmdata.CurrAsmList,eledef,elesize,tt_normal,location.reference)
+           tg.gethltemp(current_asmdata.CurrAsmList,resultdef,elesize,tt_normal,location.reference)
          else
          else
-           tg.gethltemp(current_asmdata.CurrAsmList,eledef,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference);
+           tg.gethltemp(current_asmdata.CurrAsmList,resultdef,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference);
          href:=location.reference;
          href:=location.reference;
+         makearrayref(href,eledef);
         { Process nodes in array constructor }
         { Process nodes in array constructor }
         hp:=self;
         hp:=self;
         while assigned(hp) do
         while assigned(hp) do
@@ -1063,7 +1083,7 @@ implementation
               secondpass(hp.left);
               secondpass(hp.left);
               { Move flags and jump in register }
               { Move flags and jump in register }
               if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
               if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
-                location_force_reg(current_asmdata.CurrAsmList,hp.left.location,def_cgsize(hp.left.resultdef),false);
+                hlcg.location_force_reg(current_asmdata.CurrAsmList,hp.left.location,hp.left.resultdef,hp.left.resultdef,false);
 
 
               if (hp.left.location.loc=LOC_JUMP) then
               if (hp.left.location.loc=LOC_JUMP) then
                 begin
                 begin
@@ -1193,7 +1213,7 @@ implementation
                  dec(href.offset,sizeof(pint));
                  dec(href.offset,sizeof(pint));
                  cg.a_load_const_ref(current_asmdata.CurrAsmList, OS_INT,vtype,href);
                  cg.a_load_const_ref(current_asmdata.CurrAsmList, OS_INT,vtype,href);
                  { goto next array element }
                  { goto next array element }
-                 inc(href.offset,sizeof(pint)*2);
+                 advancearrayoffset(href,sizeof(pint)*2);
                end
                end
               else
               else
               { normal array constructor of the same type }
               { normal array constructor of the same type }
@@ -1207,15 +1227,15 @@ implementation
                        hp.left.location.register,href,mms_movescalar);
                        hp.left.location.register,href,mms_movescalar);
                    LOC_FPUREGISTER,
                    LOC_FPUREGISTER,
                    LOC_CFPUREGISTER :
                    LOC_CFPUREGISTER :
-                     cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location.size,hp.left.location.register,href);
+                     hlcg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.resultdef,hp.left.resultdef,hp.left.location.register,href);
                    LOC_REFERENCE,
                    LOC_REFERENCE,
                    LOC_CREFERENCE :
                    LOC_CREFERENCE :
                      begin
                      begin
                        if is_shortstring(hp.left.resultdef) then
                        if is_shortstring(hp.left.resultdef) then
-                         cg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
-                             Tstringdef(hp.left.resultdef).len)
+                         hlcg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
+                             Tstringdef(hp.left.resultdef))
                        else
                        else
-                         cg.g_concatcopy(current_asmdata.CurrAsmList,hp.left.location.reference,href,elesize);
+                         hlcg.g_concatcopy(current_asmdata.CurrAsmList,eledef,hp.left.location.reference,href);
                      end;
                      end;
                    else
                    else
                      begin
                      begin
@@ -1224,10 +1244,10 @@ implementation
                          cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
                          cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
                        else
                        else
 {$endif not cpu64bitalu}
 {$endif not cpu64bitalu}
-                         cg.a_load_loc_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location,href);
+                         hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,eledef,eledef,hp.left.location,href);
                      end;
                      end;
                  end;
                  end;
-                 inc(href.offset,elesize);
+                 advancearrayoffset(href,elesize);
                end;
                end;
               if freetemp then
               if freetemp then
                 location_freetemp(current_asmdata.CurrAsmList,hp.left.location);
                 location_freetemp(current_asmdata.CurrAsmList,hp.left.location);