浏览代码

* switch class'/object's parent reference in the VMT to an indirect reference
(this also requires the adjustment of a test)

git-svn-id: trunk@34172 -

svenbarth 9 年之前
父节点
当前提交
685f820622
共有 4 个文件被更改,包括 28 次插入4 次删除
  1. 1 1
      compiler/ncgvmt.pas
  2. 17 0
      rtl/inc/objpas.inc
  3. 7 1
      rtl/inc/objpash.inc
  4. 3 2
      tests/webtbs/tw16034.pp

+ 1 - 1
compiler/ncgvmt.pas

@@ -1129,7 +1129,7 @@ implementation
            begin
            begin
              tcb.queue_init(parentvmtdef);
              tcb.queue_init(parentvmtdef);
              tcb.queue_emit_asmsym(
              tcb.queue_emit_asmsym(
-               current_asmdata.RefAsmSymbol(_class.childof.vmt_mangledname,AT_DATA),
+               current_asmdata.RefAsmSymbol(_class.childof.vmt_mangledname,AT_DATA,true),
                tfieldvarsym(_class.childof.vmt_field).vardef);
                tfieldvarsym(_class.childof.vmt_field).vardef);
            end
            end
          else
          else

+ 17 - 0
rtl/inc/objpas.inc

@@ -267,6 +267,23 @@
           fpc_class_as_corbaintf:=nil;
           fpc_class_as_corbaintf:=nil;
       end;
       end;
 
 
+{****************************************************************************
+                               TVMT
+****************************************************************************}
+
+
+    function TVmt.GetvParent: PVmt;
+      begin
+        {$ifdef VER3_0}
+        GetvParent:=vParentRef;
+        {$else VER3_0}
+        if Assigned(vParentRef) then
+          GetvParent:=vParentRef^
+        else
+          GetvParent:=Nil;
+        {$endif VER3_0}
+      end;
+
 
 
 {****************************************************************************
 {****************************************************************************
                                TOBJECT
                                TOBJECT

+ 7 - 1
rtl/inc/objpash.inc

@@ -97,10 +97,16 @@
        pinterfacetable = ^tinterfacetable;
        pinterfacetable = ^tinterfacetable;
 
 
        PVmt = ^TVmt;
        PVmt = ^TVmt;
+       PPVmt = ^PVmt;
        TVmt = record
        TVmt = record
+       private
+         function GetvParent: PVmt; inline;
+       public
+         property vParent: PVmt read GetvParent;
+       public
          vInstanceSize: SizeInt;
          vInstanceSize: SizeInt;
          vInstanceSize2: SizeInt;
          vInstanceSize2: SizeInt;
-         vParent: PVmt;
+         vParentRef: {$ifdef VER3_0}PVmt{$else}PPVmt{$endif};
          vClassName: PShortString;
          vClassName: PShortString;
          vDynamicTable: Pointer;
          vDynamicTable: Pointer;
          vMethodTable: Pointer;
          vMethodTable: Pointer;

+ 3 - 2
tests/webtbs/tw16034.pp

@@ -77,11 +77,12 @@ enD;
 
 
 type
 type
   pObjVMT = ^TObjVMT;
   pObjVMT = ^TObjVMT;
+  ppObjVMT = ^pObjVMT;
   TObjVMT =
   TObjVMT =
     record
     record
       fInstanceSize: UInt;
       fInstanceSize: UInt;
       fInstanceSize2: Int;
       fInstanceSize2: Int;
-      fParent: pObjVMT;
+      fParent: ppObjVMT;
     enD;
     enD;
 
 
 Function GetInstanceSize(AVMT: pObjVMT): UInt;
 Function GetInstanceSize(AVMT: pObjVMT): UInt;
@@ -93,7 +94,7 @@ Function GetVMTPtrOffset(AVMT: pObjVMT): UInt;
 begin
 begin
   if (AVMT.fParent = nil) then
   if (AVMT.fParent = nil) then
     Result := GetInstanceSize(AVMT) - SizeOf(ptr) else
     Result := GetInstanceSize(AVMT) - SizeOf(ptr) else
-    Result := GetVMTPtrOffset(AVMT.fParent);
+    Result := GetVMTPtrOffset(AVMT.fParent^);
 enD;
 enD;
 
 
 Function SetVMT(Obj: ptr; AVMT: ptr): Bool;
 Function SetVMT(Obj: ptr; AVMT: ptr): Bool;