Просмотр исходного кода

* allocate/initialize implicit pointer type fields (arrays, records) in
JVM classes after calling the inherited constructor (before doing
so, self is not yet valid)

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

Jonas Maebe 14 лет назад
Родитель
Сommit
cc6a303ee2
2 измененных файлов с 65 добавлено и 3 удалено
  1. 58 3
      compiler/jvm/hlcgcpu.pas
  2. 7 0
      compiler/jvm/njvmcal.pas

+ 58 - 3
compiler/jvm/hlcgcpu.pas

@@ -29,7 +29,7 @@ interface
 uses
   globtype,
   aasmbase,aasmdata,
-  symtype,symdef,
+  symbase,symconst,symtype,symdef,
   cpubase, hlcgobj, cgbase, cgutils, parabase;
 
   type
@@ -147,7 +147,9 @@ uses
 
       property maxevalstackheight: longint read fmaxevalstackheight;
 
+      procedure gen_initialize_fields_code(list:TAsmList);
      protected
+      procedure allocate_implicit_structs_for_st_with_base_ref(list: TAsmList; st: tsymtable; ref: treference; allocvartyp: tsymtyp);
       procedure gen_load_uninitialized_function_result(list: TAsmList; pd: tprocdef; resdef: tdef; const resloc: tcgpara); override;
 
       procedure inittempvariables(list:TAsmList);override;
@@ -197,7 +199,7 @@ implementation
     verbose,cutils,globals,
     defutil,
     aasmtai,aasmcpu,
-    symconst,symtable,symsym,jvmdef,
+    symtable,symsym,jvmdef,
     procinfo,cgcpu,tgobj;
 
   const
@@ -1133,7 +1135,7 @@ implementation
         { self }
         a_load_ref_stack(list,size,source,prepare_stack_for_ref(list,source,false));
         { result }
-        a_load_ref_stack(list,size,dest,prepare_stack_for_ref(list,source,false));
+        a_load_ref_stack(list,size,dest,prepare_stack_for_ref(list,dest,false));
         { call fpcDeepCopy helper }
         srsym:=search_struct_member(tabstractrecorddef(size),'FPCDEEPCOPY');
         if not assigned(srsym) or
@@ -1675,6 +1677,59 @@ implementation
         end;
     end;
 
+  procedure thlcgjvm.allocate_implicit_structs_for_st_with_base_ref(list: TAsmList; st: tsymtable; ref: treference; allocvartyp: tsymtyp);
+    var
+      tmpref: treference;
+      vs: tabstractvarsym;
+      i: longint;
+    begin
+      for i:=0 to st.symlist.count-1 do
+        begin
+          if (tsym(st.symlist[i]).typ<>allocvartyp) then
+            continue;
+          vs:=tabstractvarsym(st.symlist[i]);
+          if not jvmimplicitpointertype(vs.vardef) then
+            continue;
+          ref.symbol:=current_asmdata.RefAsmSymbol(vs.mangledname);
+          tg.gethltemp(list,vs.vardef,vs.vardef.size,tt_persistent,tmpref);
+          { only copy the reference, not the actual data }
+          a_load_ref_ref(list,java_jlobject,java_jlobject,tmpref,ref);
+          { remains live since there's still a reference to the created
+            entity }
+          tg.ungettemp(list,tmpref);
+        end;
+    end;
+
+  procedure thlcgjvm.gen_initialize_fields_code(list: TAsmList);
+    var
+      selfpara: tparavarsym;
+      selfreg: tregister;
+      ref: treference;
+      obj: tabstractrecorddef;
+      i: longint;
+      needinit: boolean;
+    begin
+      obj:=tabstractrecorddef(current_procinfo.procdef.owner.defowner);
+      { check whether there are any fields that need initialisation }
+      needinit:=false;
+      for i:=0 to obj.symtable.symlist.count-1 do
+        if (tsym(obj.symtable.symlist[i]).typ=fieldvarsym) and
+           jvmimplicitpointertype(tfieldvarsym(obj.symtable.symlist[i]).vardef) then
+          begin
+            needinit:=true;
+            break;
+          end;
+      if not needinit then
+        exit;
+      selfpara:=tparavarsym(current_procinfo.procdef.parast.find('self'));
+      if not assigned(selfpara) then
+        internalerror(2011033001);
+      selfreg:=getaddressregister(list,selfpara.vardef);
+      a_load_loc_reg(list,obj,obj,selfpara.localloc,selfreg);
+      reference_reset_base(ref,selfreg,0,1);
+      allocate_implicit_structs_for_st_with_base_ref(list,obj.symtable,ref,fieldvarsym);
+    end;
+
   procedure thlcgjvm.resizestackfpuval(list: TAsmList; fromsize, tosize: tcgsize);
     begin
       if (fromsize=OS_F32) and

+ 7 - 0
compiler/jvm/njvmcal.pas

@@ -50,6 +50,7 @@ implementation
       cgbase,cgutils,tgobj,procinfo,
       cpubase,aasmdata,aasmcpu,
       hlcgobj,hlcgcpu,
+      node,
       jvmdef;
 
 
@@ -134,6 +135,12 @@ implementation
           thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,totalremovesize)
         else if totalremovesize<0 then
           thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,-totalremovesize);
+
+        { if this was an inherited constructor call, initialise all fields that
+          are wrapped types following it }
+        if (tprocdef(procdefinition).proctypeoption=potype_constructor) and
+           (cnf_inherited in callnodeflags) then
+          thlcgjvm(hlcg).gen_initialize_fields_code(current_asmdata.CurrAsmList);
       end;