Ver Fonte

* IID and IIDStr references of the VMT's interface table need to be indirect

git-svn-id: trunk@34338 -
svenbarth há 9 anos atrás
pai
commit
fb6546972b
3 ficheiros alterados com 59 adições e 6 exclusões
  1. 19 4
      compiler/ncgvmt.pas
  2. 31 0
      rtl/inc/objpas.inc
  3. 9 2
      rtl/inc/objpash.inc

+ 19 - 4
compiler/ncgvmt.pas

@@ -742,12 +742,18 @@ implementation
     procedure TVMTWriter.intf_gen_intf_ref(tcb: ttai_typedconstbuilder; AImplIntf: TImplementedInterface; intfindex: longint; interfaceentrydef, interfaceentrytypedef: tdef);
       var
         pd: tprocdef;
+        siid,
+        siidstr: tsymstr;
       begin
         tcb.maybe_begin_aggregate(interfaceentrydef);
         { GUID (or nil for Corba interfaces) }
+        siid:='';
         if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then
-          tcb.emit_tai(Tai_const.CreateName(
-            make_mangledname('IID',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),AT_DATA,0),cpointerdef.getreusable(rec_tguid))
+          begin
+            siid:=make_mangledname('IID',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^);
+            tcb.emit_tai(Tai_const.Create_sym_offset(
+              current_asmdata.RefAsmSymbol(siid,AT_DATA,true),0),cpointerdef.getreusable(rec_tguid));
+          end
         else
           tcb.emit_tai(Tai_const.Create_nil_dataptr,cpointerdef.getreusable(rec_tguid));
 
@@ -775,15 +781,24 @@ implementation
         end;
 
         { IIDStr }
+        siidstr:=make_mangledname('IIDSTR',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^);
         tcb.queue_init(cpointerdef.getreusable(cshortstringtype));
         tcb.queue_emit_asmsym(
           current_asmdata.RefAsmSymbol(
-            make_mangledname('IIDSTR',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),
-            AT_DATA),
+            siidstr,
+            AT_DATA,
+            true),
           cpointerdef.getreusable(carraydef.getreusable(cansichartype,length(AImplIntf.IntfDef.iidstr^)+1)));
         { IType }
         tcb.emit_ord_const(aint(AImplIntf.VtblImplIntf.IType),interfaceentrytypedef);
         tcb.maybe_end_aggregate(interfaceentrydef);
+
+        if findunitsymtable(AImplIntf.IntfDef.owner).moduleid<>findunitsymtable(_Class.owner).moduleid then
+          begin
+            if siid<>'' then
+              current_module.add_extern_asmsym(siid,AB_EXTERNAL,AT_DATA);
+            current_module.add_extern_asmsym(siidstr,AB_EXTERNAL,AT_DATA);
+          end;
       end;
 
 

+ 31 - 0
rtl/inc/objpas.inc

@@ -285,6 +285,37 @@
       end;
 
 
+{****************************************************************************
+                           TINTERFACEENTRY
+****************************************************************************}
+
+
+    function tinterfaceentry.GetIID: pguid;
+      begin
+        {$ifdef VER3_0}
+        GetIID:=IIDRef;
+        {$else VER3_0}
+        if Assigned(IIDRef) then
+          GetIID:=IIDRef^
+        else
+          GetIID:=Nil;
+        {$endif VER3_0}
+      end;
+
+
+    function tinterfaceentry.GetIIDStr: pshortstring;
+      begin
+        {$ifdef VER3_0}
+        GetIIDStr:=IIDStrRef;
+        {$else VER3_0}
+        if Assigned(IIDStrRef) then
+          GetIIDStr:=IIDStrRef^
+        else
+          GetIIDStr:=Nil;
+        {$endif VER3_0}
+      end;
+
+
 {****************************************************************************
                                TOBJECT
 ****************************************************************************}

+ 9 - 2
rtl/inc/objpash.inc

@@ -167,10 +167,17 @@
 
        pinterfaceentry = ^tinterfaceentry;
        tinterfaceentry = record
-         IID         : pguid; { if assigned(IID) then Com else Corba}
+       private
+         function GetIID: pguid; inline;
+         function GetIIDStr: pshortstring; inline;
+       public
+         property IID: pguid read GetIID;
+         property IIDStr: pshortstring read GetIIDStr;
+       public
+         IIDRef      : {$IFNDEF VER3_0}^{$ENDIF}pguid; { if assigned(IID) then Com else Corba}
          VTable      : Pointer;
          IOffset     : sizeuint;
-         IIDStr      : pshortstring; { never nil. Com: upper(GuidToString(IID^)) }
+         IIDStrRef   : {$IFNDEF VER3_0}^{$ENDIF}pshortstring; { never nil. Com: upper(GuidToString(IID^)) }
 {$ifdef VER2_6}
          case boolean of
 {$ifdef ENDIAN_BIG}