Browse Source

* store the vmt field rather than only its offset in tobjectdef, so we can
easily find it again later (since it's hidden and doesn't have a fixed
name, it's hard otherwise). Needed for the typed constant builder.

git-svn-id: branches/hlcgllvm@28760 -

Jonas Maebe 11 years ago
parent
commit
854fe2230a
2 changed files with 24 additions and 17 deletions
  1. 1 1
      compiler/ppu.pas
  2. 23 16
      compiler/symdef.pas

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 171;
+  CurrentPPUVersion = 172;
 
 { buffer sizes }
   maxentrysize = 1024;

+ 23 - 16
compiler/symdef.pas

@@ -381,7 +381,8 @@ interface
           { and no vmt field for objects without virtuals }
           vmtentries     : TFPList;
           vmcallstaticinfo : pmvcallstaticinfo;
-          vmt_offset     : longint;
+          vmt_field       : tsym;
+          vmt_fieldderef  : tderef;
           iidguid        : pguid;
           iidstr         : pshortstring;
           { store implemented interfaces defs and name mappings }
@@ -431,6 +432,7 @@ interface
           function  vmt_mangledname : TSymStr;
           procedure check_forwards; override;
           procedure insertvmt;
+          function  vmt_offset: asizeint;
           procedure set_parent(c : tobjectdef);
           function find_destructor: tprocdef;
           function implements_any_interfaces: boolean;
@@ -5877,7 +5879,6 @@ implementation
         symtable:=tObjectSymtable.create(self,n,current_settings.packrecords);
         { create space for vmt !! }
         vmtentries:=TFPList.Create;
-        vmt_offset:=0;
         set_parent(c);
         if objecttype in [odt_interfacecorba,odt_interfacecom,odt_dispinterface] then
           prepareguid;
@@ -5909,7 +5910,7 @@ implementation
          tObjectSymtable(symtable).paddingsize:=ppufile.getword;
          tObjectSymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
          tObjectSymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
-         vmt_offset:=ppufile.getlongint;
+         ppufile.getderef(vmt_fieldderef);
          ppufile.getderef(childofderef);
 
          { load guid }
@@ -6063,7 +6064,7 @@ implementation
         tobjectdef(result).extendeddef:=extendeddef;
         if assigned(tcinitcode) then
           tobjectdef(result).tcinitcode:=tcinitcode.getcopy;
-        tobjectdef(result).vmt_offset:=vmt_offset;
+        tobjectdef(result).vmt_field:=vmt_field;
         if assigned(iidguid) then
           begin
             new(tobjectdef(result).iidguid);
@@ -6111,7 +6112,7 @@ implementation
          ppufile.putword(tObjectSymtable(symtable).paddingsize);
          ppufile.putbyte(byte(tObjectSymtable(symtable).fieldalignment));
          ppufile.putbyte(byte(tObjectSymtable(symtable).recordalignment));
-         ppufile.putlongint(vmt_offset);
+         ppufile.putderef(vmt_fieldderef);
          ppufile.putderef(childofderef);
          if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
            begin
@@ -6175,6 +6176,7 @@ implementation
          vmtentry : pvmtentry;
       begin
          inherited buildderef;
+         vmt_fieldderef.build(vmt_field);
          childofderef.build(childof);
          if df_copied_def in defoptions then
            cloneddefderef.build(symtable.defowner)
@@ -6204,6 +6206,7 @@ implementation
          vmtentry : pvmtentry;
       begin
          inherited deref;
+         vmt_field:=tsym(vmt_fieldderef.resolve);
          childof:=tobjectdef(childofderef.resolve);
          if df_copied_def in defoptions then
            begin
@@ -6363,7 +6366,7 @@ implementation
             { if parent has a vmt field then the offset is the same for the child PM }
             if (oo_has_vmt in c.objectoptions) or is_class(self) then
               begin
-                vmt_offset:=c.vmt_offset;
+                vmt_field:=c.vmt_field;
                 include(objectoptions,oo_has_vmt);
               end;
           end;
@@ -6371,8 +6374,6 @@ implementation
 
 
    procedure tobjectdef.insertvmt;
-     var
-       vs: tfieldvarsym;
      begin
         if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
           exit;
@@ -6389,19 +6390,25 @@ implementation
                  tObjectSymtable(symtable).datasize:=align(tObjectSymtable(symtable).datasize,sizeof(pint));
                  tObjectSymtable(symtable).alignrecord(tObjectSymtable(symtable).datasize,sizeof(pint));
                end;
-             vs:=cfieldvarsym.create('_vptr$'+objname^,vs_value,voidpointertype,[]);
-             hidesym(vs);
-             tObjectSymtable(symtable).insert(vs);
-             tObjectSymtable(symtable).addfield(vs,vis_hidden);
-             if (tObjectSymtable(symtable).usefieldalignment<>bit_alignment) then
-               vmt_offset:=vs.fieldoffset
-             else
-               vmt_offset:=vs.fieldoffset div 8;
+             vmt_field:=cfieldvarsym.create('_vptr$'+objname^,vs_value,voidpointertype,[]);
+             hidesym(vmt_field);
+             tObjectSymtable(symtable).insert(vmt_field);
+             tObjectSymtable(symtable).addfield(tfieldvarsym(vmt_field),vis_hidden);
              include(objectoptions,oo_has_vmt);
           end;
      end;
 
 
+   function tobjectdef.vmt_offset: asizeint;
+     begin
+        if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
+          result:=0
+        else if (tObjectSymtable(symtable).usefieldalignment<>bit_alignment) then
+          result:=tfieldvarsym(vmt_field).fieldoffset
+        else
+          result:=tfieldvarsym(vmt_field).fieldoffset div 8;
+     end;
+
 
    procedure tobjectdef.check_forwards;
      begin