Browse Source

* when the user calls initialize(), force initialization to happen on the
JVM platform (normally it's not necessary because all types are
automatically initialized)

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

Jonas Maebe 14 years ago
parent
commit
40cf2cefa0
5 changed files with 68 additions and 9 deletions
  1. 1 1
      compiler/hlcgobj.pas
  2. 62 4
      compiler/jvm/njvmutil.pas
  3. 2 2
      compiler/ngenutil.pas
  4. 2 2
      compiler/pinline.pas
  5. 1 0
      rtl/java/compproc.inc

+ 1 - 1
compiler/hlcgobj.pas

@@ -2103,7 +2103,7 @@ implementation
         begin
           OldAsmList:=current_asmdata.CurrAsmList;
           current_asmdata.CurrAsmList:=TAsmList(arg);
-          hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner));
+          hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner),false);
           firstpass(hp);
           secondpass(hp);
           hp.free;

+ 62 - 4
compiler/jvm/njvmutil.pas

@@ -33,7 +33,7 @@ interface
 
   type
     tjvmnodeutils = class(tnodeutils)
-      class function initialize_data_node(p:tnode):tnode; override;
+      class function initialize_data_node(p:tnode; force: boolean):tnode; override;
       class function finalize_data_node(p:tnode):tnode; override;
       class function force_init: boolean; override;
       class procedure insertbssdata(sym: tstaticvarsym); override;
@@ -54,14 +54,21 @@ interface
 implementation
 
     uses
-      verbose,cutils,globals,constexp,fmodule,
+      verbose,cutils,globtype,globals,constexp,fmodule,
       aasmdata,aasmtai,cpubase,aasmcpu,
       symdef,symbase,symtable,defutil,jvmdef,
-      nbas,ncnv,ncon,ninl,ncal,
+      nbas,ncnv,ncon,ninl,ncal,nld,nmem,
       ppu,
       pass_1;
 
-  class function tjvmnodeutils.initialize_data_node(p:tnode):tnode;
+  class function tjvmnodeutils.initialize_data_node(p:tnode; force: boolean):tnode;
+    var
+      normaldim: longint;
+      temp: ttempcreatenode;
+      stat: tstatementnode;
+      def: tdef;
+      paras: tcallparanode;
+      proc: string;
     begin
       if not assigned(p.resultdef) then
         typecheckpass(p);
@@ -85,6 +92,57 @@ implementation
             ccallparanode.create(genintconstnode(0),
               ccallparanode.create(p,nil)));
         end
+      else if force then
+        begin
+          { an explicit call to initialize() }
+          if p.resultdef.typ=recorddef then
+            result:=ccallnode.createinternmethod(p,'FPCINITIALIZEREC',nil)
+          else if p.resultdef.typ=arraydef then
+            begin
+              stat:=nil;
+              { in case it's an open array whose elements are regular arrays, put the
+                dimension of the regular arrays on the stack (otherwise pass 0) }
+              normaldim:=0;
+              def:=tarraydef(p.resultdef).elementdef;
+              while (def.typ=arraydef) and
+                    not is_dynamic_array(def) do
+                begin
+                  inc(normaldim);
+                  def:=tarraydef(def).elementdef;
+                end;
+              if jvmimplicitpointertype(p.resultdef) then
+                begin
+                  p:=caddrnode.create(p);
+                  include(p.flags,nf_typedaddr);
+                end;
+              paras:=ccallparanode.create(ctypeconvnode.create_explicit(p,
+                search_system_type('TJOBJECTARRAY').typedef),nil);
+              paras:=ccallparanode.create(genintconstnode(normaldim),paras);
+              if is_wide_or_unicode_string(def) then
+                proc:='fpc_initialize_array_unicodestring'
+              else if is_ansistring(def) then
+                proc:='fpc_initialize_array_ansistring'
+              else if is_dynamic_array(def) then
+                proc:='fpc_initialize_array_dynarr'
+              else if is_record(def) then
+                begin
+                  result:=internalstatements(stat);
+                  temp:=ctempcreatenode.create(def,def.size,tt_persistent,true);
+                  addstatement(stat,temp);
+                  paras:=ccallparanode.create(ctemprefnode.create(temp),paras);
+                  proc:='fpc_initialize_array_record'
+                end;
+              if assigned(stat) then
+                begin
+                  addstatement(stat,ccallnode.createintern(proc,paras));
+                  addstatement(stat,ctempdeletenode.create(temp));
+                end
+              else
+                result:=ccallnode.createintern(proc,paras);
+            end
+          else
+            result:=cassignmentnode.create(p,cnilnode.create);
+        end
       else
         begin
           p.free;

+ 2 - 2
compiler/ngenutil.pas

@@ -33,7 +33,7 @@ interface
   type
     tnodeutils = class
       class function call_fail_node:tnode; virtual;
-      class function initialize_data_node(p:tnode):tnode; virtual;
+      class function initialize_data_node(p:tnode; force: boolean):tnode; virtual;
       class function finalize_data_node(p:tnode):tnode; virtual;
       { returns true if the unit requires an initialisation section (e.g.,
         to force class constructors for the JVM target to initialise global
@@ -143,7 +143,7 @@ implementation
     end;
 
 
-  class function tnodeutils.initialize_data_node(p:tnode):tnode;
+  class function tnodeutils.initialize_data_node(p:tnode; force: boolean):tnode;
     begin
       if not assigned(p.resultdef) then
         typecheckpass(p);

+ 2 - 2
compiler/pinline.pas

@@ -314,7 +314,7 @@ implementation
                      { create call to fpc_initialize }
                      if is_managed_type(tpointerdef(p.resultdef).pointeddef) or
                        ((m_iso in current_settings.modeswitches) and (tpointerdef(p.resultdef).pointeddef.typ=filedef)) then
-                       addstatement(newstatement,cnodeutils.initialize_data_node(cderefnode.create(ctemprefnode.create(temp))));
+                       addstatement(newstatement,cnodeutils.initialize_data_node(cderefnode.create(ctemprefnode.create(temp)),false));
 
                      { copy the temp to the destination }
                      addstatement(newstatement,cassignmentnode.create(
@@ -518,7 +518,7 @@ implementation
         else
          begin
            if isinit then
-             newblock:=cnodeutils.initialize_data_node(ppn.left)
+             newblock:=cnodeutils.initialize_data_node(ppn.left,true)
            else
              newblock:=cnodeutils.finalize_data_node(ppn.left);
          end;

+ 1 - 0
rtl/java/compproc.inc

@@ -607,6 +607,7 @@ Procedure fpc_Copy_proc (Src, Dest, TypeInfo : Pointer); compilerproc; inline;
     -> normalarrdim will be 2
 }
 procedure fpc_initialize_array_unicodestring(arr: TJObjectArray; normalarrdim: longint);compilerproc;
+procedure fpc_initialize_array_ansistring(arr: TJObjectArray; normalarrdim: longint);compilerproc;
 { normalarrdim contains the number of dimensions
   a regular array, if any, that contains these unicodestrings. E.g.:
    type