فهرست منبع

* 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 سال پیش
والد
کامیت
be2ec5be59
3فایلهای تغییر یافته به همراه79 افزوده شده و 29 حذف شده
  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;
       end;
 
+    { generate RTTI and init tables }
+    procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
+
     var
       RTTIWriter : TRTTIWriter;
 
@@ -95,6 +98,61 @@ implementation
        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
 ***************************************************************************}

+ 9 - 28
compiler/ncgvmt.pas

@@ -98,8 +98,8 @@ interface
       end;
       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
     CVMTWriter: TVMTWriterClass = TVMTWriter;
@@ -1268,7 +1268,7 @@ implementation
       end;
 
 
-    procedure do_write_persistent_type_info(st:tsymtable;is_global:boolean);
+    procedure do_write_vmts(st:tsymtable;is_global:boolean);
       var
         i : longint;
         def : tdef;
@@ -1281,14 +1281,14 @@ implementation
             def:=tdef(st.DefList[i]);
             case def.typ of
               recorddef :
-                do_write_persistent_type_info(trecorddef(def).symtable,is_global);
+                do_write_vmts(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;
-                  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 }
                   if not(ds_vmt_written in def.defstates) then
                     begin
@@ -1307,37 +1307,18 @@ implementation
                 begin
                   if assigned(tprocdef(def).localst) and
                      (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
-                    do_write_persistent_type_info(tprocdef(def).parast,false);
+                    do_write_vmts(tprocdef(def).parast,false);
                 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;
 
-    procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
+    procedure write_vmts(st:tsymtable;is_global:boolean);
       begin
         create_hlcodegen;
-        do_write_persistent_type_info(st,is_global);
+        do_write_vmts(st,is_global);
         destroy_hlcodegen;
       end;
 

+ 12 - 1
compiler/pmodules.pas

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