Răsfoiți Sursa

Load RTTI symbols indirectly for targets that support packages.

nutils.pas: 
  + add a new function load_typeinfo_pointer_node which generates a node that results in a pointer node of the corresponding RTTI data; this data is loaded indirectly if the target supports packages, otherwise it's loaded directly
nld.pas:
  - remove trttidatatype (moved to symconst.pas)
  + extend trttinode by the possiblity to specify whether the RTTI symbols should be loaded directly or indirectly
  * the resultdef of a trttinode is ^Pointer if the symbols are loaded indirectly
symconst.pas:
  + add trttidatatype (from nld.pas)
* change all caddrnode.create_internal(crttinode.create(a,b,c)) to load_typeinfo_pointer_node(a,b.c)

git-svn-id: branches/svenbarth/packages@28338 -
svenbarth 11 ani în urmă
părinte
comite
5bf3813d6d

+ 1 - 3
compiler/ncal.pas

@@ -2774,9 +2774,7 @@ implementation
                   begin
                     if not assigned(pt) or (i=0) then
                       internalerror(200304082);
-                    hiddentree:=caddrnode.create_internal(
-                      crttinode.create(Tstoreddef(pt.resultdef),fullrtti,rdt_normal)
-                    );
+                    hiddentree:=load_typeinfo_pointer_node(pt.resultdef,fullrtti,rdt_normal);
                   end
               else
                 hiddentree:=cnothingnode.create;

+ 3 - 3
compiler/ncgld.pas

@@ -1355,11 +1355,11 @@ implementation
         location_reset_ref(location,LOC_CREFERENCE,OS_NO,sizeof(pint));
         case rttidatatype of
           rdt_normal:
-            location.reference.symbol:=RTTIWriter.get_rtti_label(rttidef,rttitype,false);
+            location.reference.symbol:=RTTIWriter.get_rtti_label(rttidef,rttitype,rttiindirect);
           rdt_ord2str:
-            location.reference.symbol:=RTTIWriter.get_rtti_label_ord2str(rttidef,rttitype,false);
+            location.reference.symbol:=RTTIWriter.get_rtti_label_ord2str(rttidef,rttitype,rttiindirect);
           rdt_str2ord:
-            location.reference.symbol:=RTTIWriter.get_rtti_label_str2ord(rttidef,rttitype,false);
+            location.reference.symbol:=RTTIWriter.get_rtti_label_str2ord(rttidef,rttitype,rttiindirect);
         end;
       end;
 

+ 3 - 4
compiler/ncnv.pas

@@ -1661,7 +1661,7 @@ implementation
       begin
         result := ccallnode.createinternres(
           'fpc_variant_to_dynarray',
-          ccallparanode.create(caddrnode.create_internal(crttinode.create(tstoreddef(resultdef),initrtti,rdt_normal)),
+          ccallparanode.create(load_typeinfo_pointer_node(resultdef,initrtti,rdt_normal),
             ccallparanode.create(left,nil)
           ),resultdef);
         typecheckpass(result);
@@ -1673,7 +1673,7 @@ implementation
       begin
         result := ccallnode.createinternres(
           'fpc_dynarray_to_variant',
-          ccallparanode.create(caddrnode.create_internal(crttinode.create(tstoreddef(left.resultdef),initrtti,rdt_normal)),
+          ccallparanode.create(load_typeinfo_pointer_node(left.resultdef,initrtti,rdt_normal),
             ccallparanode.create(ctypeconvnode.create_explicit(left,voidpointertype),nil)
           ),resultdef);
         typecheckpass(result);
@@ -1765,8 +1765,7 @@ implementation
                   (ctemprefnode.create(temp2)),
                ccallparanode.create(cordconstnode.create
                   (1,s32inttype,true),
-               ccallparanode.create(caddrnode.create_internal
-                  (crttinode.create(tstoreddef(resultdef),initrtti,rdt_normal)),
+               ccallparanode.create(load_typeinfo_pointer_node(resultdef,initrtti,rdt_normal),
                ccallparanode.create(
                  ctypeconvnode.create_internal(
                    ctemprefnode.create(temp),voidpointertype),

+ 2 - 6
compiler/ngenutil.pas

@@ -199,9 +199,7 @@ implementation
         begin
           result:=ccallnode.createintern('fpc_initialize',
                 ccallparanode.create(
-                    caddrnode.create_internal(
-                        crttinode.create(
-                            tstoreddef(p.resultdef),initrtti,rdt_normal)),
+                    load_typeinfo_pointer_node(p.resultdef,initrtti,rdt_normal),
                 ccallparanode.create(
                     caddrnode.create_internal(p),
                 nil)));
@@ -242,9 +240,7 @@ implementation
       else
         result:=ccallnode.createintern('fpc_finalize',
               ccallparanode.create(
-                  caddrnode.create_internal(
-                      crttinode.create(
-                          tstoreddef(p.resultdef),initrtti,rdt_normal)),
+                  load_typeinfo_pointer_node(p.resultdef,initrtti,rdt_normal),
               ccallparanode.create(
                   caddrnode.create_internal(p),
               nil)));

+ 15 - 27
compiler/ninl.pas

@@ -316,15 +316,11 @@ implementation
           begin
             {Insert a reference to the ord2string index.}
             newparas.right:=Ccallparanode.create(
-              Caddrnode.create_internal(
-                Crttinode.create(Tenumdef(source.left.resultdef),fullrtti,rdt_normal)
-              ),
+              load_typeinfo_pointer_node(source.left.resultdef,fullrtti,rdt_normal),
               newparas.right);
             {Insert a reference to the typinfo.}
             newparas.right:=Ccallparanode.create(
-              Caddrnode.create_internal(
-                Crttinode.create(Tenumdef(source.left.resultdef),fullrtti,rdt_ord2str)
-              ),
+              load_typeinfo_pointer_node(source.left.resultdef,fullrtti,rdt_ord2str),
               newparas.right);
             {Insert a type conversion from the enumeration to longint.}
             source.left:=Ctypeconvnode.create_internal(source.left,s32inttype);
@@ -899,15 +895,11 @@ implementation
                       {To write(ln) an enum we need a some extra parameters.}
                       {Insert a reference to the ord2string index.}
                       indexpara:=Ccallparanode.create(
-                        Caddrnode.create_internal(
-                          Crttinode.create(Tenumdef(para.left.resultdef),fullrtti,rdt_normal)
-                        ),
+                        load_typeinfo_pointer_node(para.left.resultdef,fullrtti,rdt_normal),
                         nil);
                       {Insert a reference to the typinfo.}
                       indexpara:=Ccallparanode.create(
-                        Caddrnode.create_internal(
-                         Crttinode.create(Tenumdef(para.left.resultdef),fullrtti,rdt_ord2str)
-                        ),
+                        load_typeinfo_pointer_node(para.left.resultdef,fullrtti,rdt_ord2str),
                         indexpara);
                       {Insert a type conversion to to convert the enum to longint.}
                       para.left:=Ctypeconvnode.create_internal(para.left,s32inttype);
@@ -920,9 +912,9 @@ implementation
                   if para.left.resultdef.typ=enumdef then
                     begin
                       {Insert a reference to the string2ord index.}
-                      indexpara:=Ccallparanode.create(Caddrnode.create_internal(
-                        Crttinode.create(Tenumdef(para.left.resultdef),fullrtti,rdt_str2ord)
-                      ),nil);
+                      indexpara:=Ccallparanode.create(
+                        load_typeinfo_pointer_node(para.left.resultdef,fullrtti,rdt_str2ord),
+                        nil);
                       {Insert a type conversion to to convert the enum to longint.}
                       para.left:=Ctypeconvnode.create_internal(para.left,s32inttype);
                       typecheckpass(para.left);
@@ -1567,9 +1559,9 @@ implementation
           enumdef:
             begin
               suffix:='enum_';
-              sizepara:=Ccallparanode.create(Caddrnode.create_internal(
-                Crttinode.create(Tenumdef(destpara.resultdef),fullrtti,rdt_str2ord)
-              ),nil);
+              sizepara:=Ccallparanode.create(
+                load_typeinfo_pointer_node(destpara.resultdef,fullrtti,rdt_str2ord),
+                nil);
             end;
         end;
 
@@ -3343,9 +3335,7 @@ implementation
 
           in_typeinfo_x:
             begin
-              result:=caddrnode.create_internal(
-                crttinode.create(tstoreddef(left.resultdef),fullrtti,rdt_normal)
-              );
+              result:=load_typeinfo_pointer_node(left.resultdef,fullrtti,rdt_normal);
             end;
 
           in_assigned_x:
@@ -3923,8 +3913,7 @@ implementation
                      (ctemprefnode.create(temp)),
                   ccallparanode.create(cordconstnode.create
                      (dims,sinttype,true),
-                  ccallparanode.create(caddrnode.create_internal
-                     (crttinode.create(tstoreddef(destppn.resultdef),initrtti,rdt_normal)),
+                  ccallparanode.create(load_typeinfo_pointer_node(destppn.resultdef,initrtti,rdt_normal),
                   ccallparanode.create(ctypeconvnode.create_internal(destppn,voidpointertype),nil))));
            addstatement(newstatement,ccallnode.createintern('fpc_dynarray_setlength',npara));
            addstatement(newstatement,ctempdeletenode.create(temp));
@@ -4014,8 +4003,7 @@ implementation
             { create call to fpc_dynarray_copy }
             npara:=ccallparanode.create(highppn,
                    ccallparanode.create(lowppn,
-                   ccallparanode.create(caddrnode.create_internal
-                      (crttinode.create(tstoreddef(paradef),initrtti,rdt_normal)),
+                   ccallparanode.create(load_typeinfo_pointer_node(paradef,initrtti,rdt_normal),
                    ccallparanode.create
                       (ctypeconvnode.create_internal(ppn.left,voidpointertype),nil))));
             result:=ccallnode.createinternres('fpc_dynarray_copy',npara,paradef);
@@ -4054,8 +4042,8 @@ implementation
          { create call to fpc_initialize }
          if is_managed_type(tpointerdef(left.resultdef).pointeddef) then
           begin
-            para := ccallparanode.create(caddrnode.create_internal(crttinode.create
-                       (tstoreddef(tpointerdef(left.resultdef).pointeddef),initrtti,rdt_normal)),
+            para := ccallparanode.create(
+                       load_typeinfo_pointer_node(tpointerdef(left.resultdef).pointeddef,initrtti,rdt_normal),
                     ccallparanode.create(ctemprefnode.create
                        (temp),nil));
             addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));

+ 15 - 10
compiler/nld.pas

@@ -33,8 +33,6 @@ interface
        symconst,symbase,symtype,symsym,symdef;
 
     type
-       Trttidatatype = (rdt_normal,rdt_ord2str,rdt_str2ord);
-
        tloadnodeflags = (
          loadnf_is_self,
          loadnf_load_self_pointer,
@@ -146,7 +144,8 @@ interface
           rttidef : tstoreddef;
           rttidefderef : tderef;
           rttidatatype : Trttidatatype;
-          constructor create(def:tstoreddef;rt:trttitype;dt:Trttidatatype);virtual;
+          rttiindirect : boolean;
+          constructor create(def:tstoreddef;rt:trttitype;dt:Trttidatatype;indirect:boolean);virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderefimpl;override;
@@ -819,8 +818,7 @@ implementation
             not is_dynamic_array(left.resultdef) and
             not(target_info.system in systems_garbage_collected_managed_types) then
          begin
-           hp:=ccallparanode.create(caddrnode.create_internal(
-                  crttinode.create(tstoreddef(left.resultdef),initrtti,rdt_normal)),
+           hp:=ccallparanode.create(load_typeinfo_pointer_node(left.resultdef,initrtti,rdt_normal),
                ccallparanode.create(ctypeconvnode.create_internal(
                  caddrnode.create_internal(left),voidpointertype),
                ccallparanode.create(ctypeconvnode.create_internal(
@@ -896,8 +894,7 @@ implementation
             nil));
         if needrtti then
           hp:=ccallparanode.create(
-            caddrnode.create_internal(
-              crttinode.create(tstoreddef(left.resultdef),initrtti,rdt_normal)),
+            load_typeinfo_pointer_node(left.resultdef,initrtti,rdt_normal),
             hp);
         result:=ccallnode.createintern(hs,hp);
         firstpass(result);
@@ -1267,12 +1264,13 @@ implementation
 *****************************************************************************}
 
 
-    constructor trttinode.create(def:tstoreddef;rt:trttitype;dt:Trttidatatype);
+    constructor trttinode.create(def:tstoreddef;rt:trttitype;dt:Trttidatatype;indirect:boolean);
       begin
          inherited create(rttin);
          rttidef:=def;
          rttitype:=rt;
          rttidatatype:=dt;
+         rttiindirect:=indirect;
       end;
 
 
@@ -1282,6 +1280,7 @@ implementation
         ppufile.getderef(rttidefderef);
         rttitype:=trttitype(ppufile.getbyte);
         rttidatatype:=trttidatatype(ppufile.getbyte);
+        rttiindirect:=boolean(ppufile.getbyte);
       end;
 
 
@@ -1291,6 +1290,7 @@ implementation
         ppufile.putderef(rttidefderef);
         ppufile.putbyte(byte(rttitype));
         ppufile.putbyte(byte(rttidatatype));
+        ppufile.putbyte(ord(rttiindirect));
       end;
 
 
@@ -1316,6 +1316,7 @@ implementation
          n.rttidef:=rttidef;
          n.rttitype:=rttitype;
          n.rttidatatype:=rttidatatype;
+         n.rttiindirect:=rttiindirect;
          result:=n;
       end;
 
@@ -1324,7 +1325,10 @@ implementation
       begin
         { rtti information will be returned as a void pointer }
         result:=nil;
-        resultdef:=voidpointertype;
+        if rttiindirect then
+          resultdef:=getpointerdef(voidpointertype)
+        else
+          resultdef:=voidpointertype;
       end;
 
 
@@ -1344,7 +1348,8 @@ implementation
           inherited docompare(p) and
           (rttidef = trttinode(p).rttidef) and
           (rttitype = trttinode(p).rttitype) and
-          (rttidatatype = trttinode(p).rttidatatype);
+          (rttidatatype = trttinode(p).rttidatatype) and
+          (rttiindirect=trttinode(p).rttiindirect);
       end;
 
 end.

+ 23 - 3
compiler/nutils.pas

@@ -27,7 +27,7 @@ interface
 
   uses
     globtype,constexp,
-    symtype,symsym,symbase,symtable,
+    symtype,symsym,symbase,symtable,symconst,
     node;
 
   const
@@ -75,6 +75,7 @@ interface
     function load_self_pointer_node:tnode;
     function load_vmt_pointer_node:tnode;
     function is_self_node(p:tnode):boolean;
+    function load_typeinfo_pointer_node(def:tdef;rt:trttitype;dt:trttidatatype):tnode;
 
     function node_complexity(p: tnode): cardinal;
     function node_resources_fpu(p: tnode): cardinal;
@@ -144,8 +145,8 @@ interface
 implementation
 
     uses
-      cutils,verbose,globals,
-      symconst,symdef,
+      cutils,verbose,globals,systems,
+      symdef,
       defutil,defcmp,
       nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
       cpubase,cgbase,procinfo,
@@ -550,6 +551,25 @@ implementation
       end;
 
 
+    function load_typeinfo_pointer_node(def:tdef;rt:trttitype;dt:trttidatatype):tnode;
+      begin
+        { further potential for optimizations:
+          - if the node resides in the same unit as the def (and thus the RTTI symbol) we can use
+            the direct approach (pay attention to inlining though!)
+          - if this unit is compiled as part of a library or program (in contrast to a package)
+            then we could use the indirect approach as well (the code won't "migrate" back into any
+            used package so this would be a "safe" optimization) }
+        result:=caddrnode.create_internal(
+                    crttinode.create(tstoreddef(def),rt,dt,tf_supports_packages in target_info.flags)
+                  );
+        include(result.flags,nf_typedaddr);
+        if tf_supports_packages in target_info.flags then
+          begin
+            result:=cderefnode.create(result);
+            include(result.flags,nf_no_checkpointer);
+          end;
+      end;
+
     { this function must return a very high value ("infinity") for   }
     { trees containing a call, the rest can be balanced more or less }
     { at will, probably best mainly in terms of required memory      }

+ 1 - 2
compiler/pexpr.pas

@@ -1681,8 +1681,7 @@ implementation
                     (ctemprefnode.create(temp2)),
                  ccallparanode.create(cordconstnode.create
                     (1,s32inttype,true),
-                 ccallparanode.create(caddrnode.create_internal
-                    (crttinode.create(tstoreddef(arrdef),initrtti,rdt_normal)),
+                 ccallparanode.create(load_typeinfo_pointer_node(arrdef,initrtti,rdt_normal),
                  ccallparanode.create(
                    ctypeconvnode.create_internal(
                      ctemprefnode.create(arrnode),voidpointertype),

+ 1 - 2
compiler/pinline.pas

@@ -546,8 +546,7 @@ implementation
            { create call to fpc_initialize/finalize_array }
            npara:=ccallparanode.create(ctypeconvnode.create
                      (ppn.left,s32inttype),
-                  ccallparanode.create(caddrnode.create_internal
-                     (crttinode.create(tstoreddef(destppn.left.resultdef),initrtti,rdt_normal)),
+                  ccallparanode.create(load_typeinfo_pointer_node(destppn.left.resultdef,initrtti,rdt_normal),
                   ccallparanode.create(caddrnode.create_internal
                      (destppn.left),nil)));
            if isinit then

+ 6 - 0
compiler/symconst.pas

@@ -619,6 +619,12 @@ type
     objcclassrtti,objcclassrortti
   );
 
+  trttidatatype = (
+    rdt_normal,
+    rdt_ord2str,
+    rdt_str2ord
+  );
+
   { The order is from low priority to high priority,
     Note: the operators > and < are used on this list }
   tequaltype = (