Browse Source

* write full/init rtti and VMTs separately instead of at the same time
o this allows us to write the VMTs earlier (before the synthetic method
implementations are generated), which means we can create new synthetic
methods while generating the VMTs (for interface trampolines)

git-svn-id: trunk@31635 -

Jonas Maebe 10 years ago
parent
commit
be2ec5be59
3 changed files with 79 additions and 29 deletions
  1. 58 0
      compiler/ncgrtti.pas
  2. 9 28
      compiler/ncgvmt.pas
  3. 12 1
      compiler/pmodules.pas

+ 58 - 0
compiler/ncgrtti.pas

@@ -64,6 +64,9 @@ interface
         function  get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
         function  get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
       end;
       end;
 
 
+    { generate RTTI and init tables }
+    procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
+
     var
     var
       RTTIWriter : TRTTIWriter;
       RTTIWriter : TRTTIWriter;
 
 
@@ -95,6 +98,61 @@ implementation
        end;
        end;
 
 
 
 
+    procedure write_persistent_type_info(st: tsymtable; is_global: boolean);
+      var
+        i : longint;
+        def : tdef;
+      begin
+        { no Delphi-style RTTI for managed platforms }
+        if target_info.system in systems_managed_vm then
+          exit;
+        for i:=0 to st.DefList.Count-1 do
+          begin
+            def:=tdef(st.DefList[i]);
+            case def.typ of
+              recorddef:
+                write_persistent_type_info(trecorddef(def).symtable,is_global);
+              objectdef :
+                begin
+                  { Skip generics and forward defs }
+                  if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
+                     (oo_is_forward in tobjectdef(def).objectoptions) then
+                    continue;
+                  write_persistent_type_info(tobjectdef(def).symtable,is_global);
+                end;
+              procdef :
+                begin
+                  if assigned(tprocdef(def).localst) and
+                     (tprocdef(def).localst.symtabletype=localsymtable) then
+                    write_persistent_type_info(tprocdef(def).localst,false);
+                  if assigned(tprocdef(def).parast) then
+                    write_persistent_type_info(tprocdef(def).parast,false);
+                end;
+            end;
+            { always generate persistent tables for types in the interface so
+              they can be reused in other units and give always the same pointer
+              location. }
+            { Init }
+            if (
+                assigned(def.typesym) and
+                is_global and
+                not is_objc_class_or_protocol(def)
+               ) or
+               is_managed_type(def) or
+               (ds_init_table_used in def.defstates) then
+              RTTIWriter.write_rtti(def,initrtti);
+            { RTTI }
+            if (
+                assigned(def.typesym) and
+                is_global and
+                not is_objc_class_or_protocol(def)
+               ) or
+               (ds_rtti_table_used in def.defstates) then
+              RTTIWriter.write_rtti(def,fullrtti);
+          end;
+      end;
+
+
 {***************************************************************************
 {***************************************************************************
                               TRTTIWriter
                               TRTTIWriter
 ***************************************************************************}
 ***************************************************************************}

+ 9 - 28
compiler/ncgvmt.pas

@@ -98,8 +98,8 @@ interface
       end;
       end;
       TVMTWriterClass = class of TVMTWriter;
       TVMTWriterClass = class of TVMTWriter;
 
 
-    { generate persistent type information like VMT, RTTI and inittables }
-    procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
+    { generate VMTs }
+    procedure write_vmts(st:tsymtable;is_global:boolean);
 
 
   var
   var
     CVMTWriter: TVMTWriterClass = TVMTWriter;
     CVMTWriter: TVMTWriterClass = TVMTWriter;
@@ -1268,7 +1268,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure do_write_persistent_type_info(st:tsymtable;is_global:boolean);
+    procedure do_write_vmts(st:tsymtable;is_global:boolean);
       var
       var
         i : longint;
         i : longint;
         def : tdef;
         def : tdef;
@@ -1281,14 +1281,14 @@ implementation
             def:=tdef(st.DefList[i]);
             def:=tdef(st.DefList[i]);
             case def.typ of
             case def.typ of
               recorddef :
               recorddef :
-                do_write_persistent_type_info(trecorddef(def).symtable,is_global);
+                do_write_vmts(trecorddef(def).symtable,is_global);
               objectdef :
               objectdef :
                 begin
                 begin
                   { Skip generics and forward defs }
                   { Skip generics and forward defs }
                   if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
                   if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
                      (oo_is_forward in tobjectdef(def).objectoptions) then
                      (oo_is_forward in tobjectdef(def).objectoptions) then
                     continue;
                     continue;
-                  do_write_persistent_type_info(tobjectdef(def).symtable,is_global);
+                  do_write_vmts(tobjectdef(def).symtable,is_global);
                   { Write also VMT if not done yet }
                   { Write also VMT if not done yet }
                   if not(ds_vmt_written in def.defstates) then
                   if not(ds_vmt_written in def.defstates) then
                     begin
                     begin
@@ -1307,37 +1307,18 @@ implementation
                 begin
                 begin
                   if assigned(tprocdef(def).localst) and
                   if assigned(tprocdef(def).localst) and
                      (tprocdef(def).localst.symtabletype=localsymtable) then
                      (tprocdef(def).localst.symtabletype=localsymtable) then
-                    do_write_persistent_type_info(tprocdef(def).localst,false);
+                    do_write_vmts(tprocdef(def).localst,false);
                   if assigned(tprocdef(def).parast) then
                   if assigned(tprocdef(def).parast) then
-                    do_write_persistent_type_info(tprocdef(def).parast,false);
+                    do_write_vmts(tprocdef(def).parast,false);
                 end;
                 end;
             end;
             end;
-            { generate always persistent tables for types in the interface so it can
-              be reused in other units and give always the same pointer location. }
-            { Init }
-            if (
-                assigned(def.typesym) and
-                is_global and
-                not is_objc_class_or_protocol(def)
-               ) or
-               is_managed_type(def) or
-               (ds_init_table_used in def.defstates) then
-              RTTIWriter.write_rtti(def,initrtti);
-            { RTTI }
-            if (
-                assigned(def.typesym) and
-                is_global and
-                not is_objc_class_or_protocol(def)
-               ) or
-               (ds_rtti_table_used in def.defstates) then
-              RTTIWriter.write_rtti(def,fullrtti);
           end;
           end;
       end;
       end;
 
 
-    procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
+    procedure write_vmts(st:tsymtable;is_global:boolean);
       begin
       begin
         create_hlcodegen;
         create_hlcodegen;
-        do_write_persistent_type_info(st,is_global);
+        do_write_vmts(st,is_global);
         destroy_hlcodegen;
         destroy_hlcodegen;
       end;
       end;
 
 

+ 12 - 1
compiler/pmodules.pas

@@ -46,7 +46,7 @@ implementation
        pexports,
        pexports,
        objcgutl,
        objcgutl,
        wpobase,
        wpobase,
-       scanner,pbase,pexpr,psystem,psub,pdecsub,ncgvmt,
+       scanner,pbase,pexpr,psystem,psub,pdecsub,ncgvmt,ncgrtti,
        cpuinfo;
        cpuinfo;
 
 
 
 
@@ -1070,6 +1070,13 @@ type
          { Generate specializations of objectdefs methods }
          { Generate specializations of objectdefs methods }
          generate_specialization_procs;
          generate_specialization_procs;
 
 
+         { Generate VMTs }
+         if Errorcount=0 then
+           begin
+             write_vmts(current_module.globalsymtable,true);
+             write_vmts(current_module.localsymtable,false);
+           end;
+
          { add implementations for synthetic method declarations added by
          { add implementations for synthetic method declarations added by
            the compiler }
            the compiler }
          add_synthetic_method_implementations(current_module.globalsymtable);
          add_synthetic_method_implementations(current_module.globalsymtable);
@@ -2144,6 +2151,10 @@ type
          { Generate specializations of objectdefs methods }
          { Generate specializations of objectdefs methods }
          generate_specialization_procs;
          generate_specialization_procs;
 
 
+         { Generate VMTs }
+         if Errorcount=0 then
+           write_vmts(current_module.localsymtable,false);
+
          { add implementations for synthetic method declarations added by
          { add implementations for synthetic method declarations added by
            the compiler }
            the compiler }
          add_synthetic_method_implementations(current_module.localsymtable);
          add_synthetic_method_implementations(current_module.localsymtable);