浏览代码

* generate init_final table from actual uses clauses

Michaël Van Canneyt 1 年之前
父节点
当前提交
2ba04dbd13
共有 3 个文件被更改,包括 61 次插入41 次删除
  1. 13 10
      compiler/jvm/njvmutil.pas
  2. 45 26
      compiler/ngenutil.pas
  3. 3 5
      compiler/pmodules.pas

+ 13 - 10
compiler/jvm/njvmutil.pas

@@ -55,7 +55,7 @@ interface
       class procedure InsertResStrInits; override;
       class procedure InsertResStrInits; override;
       class procedure InsertMemorySizes; override;
       class procedure InsertMemorySizes; override;
      protected
      protected
-       class procedure insert_init_final_table(entries:tfplist); override;
+       class procedure insert_init_final_table(main: tmodule; entries:tfplist); override;
      strict protected
      strict protected
        class procedure add_main_procdef_paras(pd: tdef); override;
        class procedure add_main_procdef_paras(pd: tdef); override;
     end;
     end;
@@ -387,24 +387,27 @@ implementation
         inherited;
         inherited;
     end;
     end;
 
 
-  class procedure tjvmnodeutils.insert_init_final_table(entries:tfplist);
+  class procedure tjvmnodeutils.insert_init_final_table(main: tmodule; entries:tfplist);
+
     var
     var
       hp : tused_unit;
       hp : tused_unit;
       unitinits : TAsmList;
       unitinits : TAsmList;
       unitclassname: string;
       unitclassname: string;
       mainpsym: tsym;
       mainpsym: tsym;
       mainpd: tprocdef;
       mainpd: tprocdef;
-    begin
-      { JVM does not use the entries list }
+      m : tmodule;
+      i : integer;
 
 
+    begin
       unitinits:=TAsmList.Create;
       unitinits:=TAsmList.Create;
-      hp:=tused_unit(usedunits.first);
-      while assigned(hp) do
+      for I:=0 to entries.Count-1 do
         begin
         begin
+          hp:=tused_unit(entries[i]);
+          m:=hp.u;
           { class constructors are automatically handled by the JVM }
           { class constructors are automatically handled by the JVM }
 
 
-          { call the unit init code and make it external }
-          if (hp.u.moduleflags*[mf_init,mf_finalize])<>[] then
+          { for non-main module, call the unit init code and make it external }
+          if (m<>main) and ((m.moduleflags*[mf_init,mf_finalize])<>[]) then
             begin
             begin
               { trigger init code by referencing the class representing the
               { trigger init code by referencing the class representing the
                 unit; if necessary, it will register the fini code to run on
                 unit; if necessary, it will register the fini code to run on
@@ -419,10 +422,10 @@ implementation
               unitinits.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(unitclassname,AT_METADATA)));
               unitinits.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(unitclassname,AT_METADATA)));
               unitinits.concat(taicpu.op_none(a_pop));
               unitinits.concat(taicpu.op_none(a_pop));
             end;
             end;
-          hp:=tused_unit(hp.next);
         end;
         end;
+
       { insert in main program routine }
       { insert in main program routine }
-      mainpsym:=tsym(current_module.localsymtable.find(mainaliasname));
+      mainpsym:=tsym(main.localsymtable.find(mainaliasname));
       if not assigned(mainpsym) or
       if not assigned(mainpsym) or
          (mainpsym.typ<>procsym) then
          (mainpsym.typ<>procsym) then
         internalerror(2011041901);
         internalerror(2011041901);

+ 45 - 26
compiler/ngenutil.pas

@@ -113,14 +113,14 @@ interface
       class procedure insertbssdata(sym : tstaticvarsym); virtual;
       class procedure insertbssdata(sym : tstaticvarsym); virtual;
 
 
       class function create_main_procdef(const name: string; potype:tproctypeoption; ps: tprocsym):tdef; virtual;
       class function create_main_procdef(const name: string; potype:tproctypeoption; ps: tprocsym):tdef; virtual;
-      class procedure InsertInitFinalTable;
+      class procedure InsertInitFinalTable(main : tmodule);
      protected
      protected
       class procedure InsertRuntimeInits(const prefix:string;list:TLinkedList;unitflag:tmoduleflag); virtual;
       class procedure InsertRuntimeInits(const prefix:string;list:TLinkedList;unitflag:tmoduleflag); virtual;
       class procedure InsertRuntimeInitsTablesTable(const prefix,tablename:string;unitflag:tmoduleflag); virtual;
       class procedure InsertRuntimeInitsTablesTable(const prefix,tablename:string;unitflag:tmoduleflag); virtual;
 
 
-      class procedure insert_init_final_table(entries:tfplist); virtual;
+      class procedure insert_init_final_table(main: tmodule; entries:tfplist); virtual;
 
 
-      class function get_init_final_list: tfplist;
+      class function get_init_final_list(main : tmodule): tfplist;
       class procedure release_init_final_list(list:tfplist);
       class procedure release_init_final_list(list:tfplist);
      public
      public
       class procedure InsertThreadvarTablesTable; virtual;
       class procedure InsertThreadvarTablesTable; virtual;
@@ -1020,37 +1020,56 @@ implementation
     end;
     end;
 
 
 
 
-  class function tnodeutils.get_init_final_list:tfplist;
+  class function tnodeutils.get_init_final_list(main : tmodule):tfplist;
+
+    procedure addusedunits(m : tmodule);
+
     var
     var
       hp : tused_unit;
       hp : tused_unit;
       entry : pinitfinalentry;
       entry : pinitfinalentry;
     begin
     begin
-      result:=tfplist.create;
-      { Insert initialization/finalization of the used units }
-      hp:=tused_unit(usedunits.first);
+      hp:=tused_unit(m.used_units.first);
       while assigned(hp) do
       while assigned(hp) do
        begin
        begin
-         if (hp.u.moduleflags * [mf_init,mf_finalize])<>[] then
+         if (not hp.u.initfinalchecked) then
            begin
            begin
-             new(entry);
-             entry^.module:=hp.u;
-             entry^.initpd:=nil;
-             entry^.finipd:=nil;
-             if mf_init in hp.u.moduleflags then
-               entry^.initfunc:=make_mangledname('INIT$',hp.u.globalsymtable,'')
-             else
-               entry^.initfunc:='';
-             if mf_finalize in hp.u.moduleflags then
-               entry^.finifunc:=make_mangledname('FINALIZE$',hp.u.globalsymtable,'')
-             else
-               entry^.finifunc:='';
-             result.add(entry);
+           hp.u.initfinalchecked:=True;
+           addusedunits(hp.u);
+           if ((hp.u.moduleflags * [mf_init,mf_finalize])<>[]) then
+             begin
+               new(entry);
+               entry^.module:=hp.u;
+               entry^.initpd:=nil;
+               entry^.finipd:=nil;
+               if mf_init in hp.u.moduleflags then
+                 entry^.initfunc:=make_mangledname('INIT$',hp.u.globalsymtable,'')
+               else
+                 entry^.initfunc:='';
+               if mf_finalize in hp.u.moduleflags then
+                 entry^.finifunc:=make_mangledname('FINALIZE$',hp.u.globalsymtable,'')
+               else
+                 entry^.finifunc:='';
+               { Writeln('Adding Init/final for: ',hp.u.modulename^); }
+               result.add(entry);
+             end
+           {else
+              Writeln('NOT Adding Init/final for: ',hp.u.modulename^);}
            end;
            end;
          hp:=tused_unit(hp.next);
          hp:=tused_unit(hp.next);
        end;
        end;
 
 
+    end;
+
+    var
+      entry : pinitfinalentry;
+    begin
+      result:=tfplist.create;
+
+      { Insert initialization/finalization of the used units }
+      addusedunits(main);
+
       { Insert initialization/finalization of the program }
       { Insert initialization/finalization of the program }
-      if (current_module.moduleflags * [mf_init,mf_finalize])<>[] then
+      if (main.moduleflags * [mf_init,mf_finalize])<>[] then
         begin
         begin
           new(entry);
           new(entry);
           entry^.module:=current_module;
           entry^.module:=current_module;
@@ -1081,19 +1100,19 @@ implementation
     end;
     end;
 
 
 
 
-  class procedure tnodeutils.InsertInitFinalTable;
+  class procedure tnodeutils.InsertInitFinalTable(main : tmodule);
     var
     var
       entries : tfplist;
       entries : tfplist;
     begin
     begin
-      entries := get_init_final_list;
+      entries := get_init_final_list(main);
 
 
-      insert_init_final_table(entries);
+      insert_init_final_table(main,entries);
 
 
       release_init_final_list(entries);
       release_init_final_list(entries);
     end;
     end;
 
 
 
 
-  class procedure tnodeutils.insert_init_final_table(entries:tfplist);
+  class procedure tnodeutils.insert_init_final_table(main : tmodule; entries:tfplist);
     var
     var
       i : longint;
       i : longint;
       unitinits : ttai_typedconstbuilder;
       unitinits : ttai_typedconstbuilder;

+ 3 - 5
compiler/pmodules.pas

@@ -1028,7 +1028,7 @@ implementation
 
 
 
 
 {$ifdef jvm}
 {$ifdef jvm}
-      procedure addmoduleclass;
+      procedure addmoduleclass(curr : tmodule);
         var
         var
           def: tobjectdef;
           def: tobjectdef;
           typesym: ttypesym;
           typesym: ttypesym;
@@ -1065,8 +1065,6 @@ type
 
 
 
 
       begin
       begin
-        if (curr.modulename^='OGBASE') then
-          Writeln('Here');
         result:=true;
         result:=true;
         init_procinfo:=nil;
         init_procinfo:=nil;
         finalize_procinfo:=nil;
         finalize_procinfo:=nil;
@@ -1160,7 +1158,7 @@ type
 
 
 {$ifdef jvm}
 {$ifdef jvm}
          { fake classdef to represent the class corresponding to the unit }
          { fake classdef to represent the class corresponding to the unit }
-         addmoduleclass;
+         addmoduleclass(curr);
 {$endif}
 {$endif}
         read_interface_declarations;
         read_interface_declarations;
 
 
@@ -2476,7 +2474,7 @@ type
 
 
   {$ifdef jvm}
   {$ifdef jvm}
         { fake classdef to represent the class corresponding to the unit }
         { fake classdef to represent the class corresponding to the unit }
-        addmoduleclass;
+        addmoduleclass(curr);
   {$endif}
   {$endif}
 
 
         { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }
         { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }