@@ -397,18 +397,6 @@ TManagedInterfaceField = class(TManagedObjectField)
397397 procedure FinalizeValue (instance: Pointer); override;
398398 end ;
399399
400- const
401- { $IF SizeOf(Pointer) = 4}
402- PROPSLOT_MASK = $FF000000;
403- PROPSLOT_FIELD = $FF000000;
404- PROPSLOT_VIRTUAL = $FE000000;
405- { $ELSEIF SizeOf(Pointer) = 8}
406- PROPSLOT_MASK = $FF00000000000000;
407- PROPSLOT_FIELD = $FF00000000000000;
408- PROPSLOT_VIRTUAL = $FE00000000000000;
409- { $ELSE OTHER_PTR_SIZE}
410- { $MESSAGE Fatal 'Unrecognized pointer size'}
411- { $IFEND OTHER_PTR_SIZE}
412400 strict private
413401 DefaultFields: TArray<TInitializableField>;
414402 ManagedFields: TArray<TFinalizableField>;
@@ -1303,6 +1291,7 @@ TRefCountedObject = class abstract
13031291 function QueryInterface (const IID: TGUID; out obj): HResult; stdcall;
13041292 function _AddRef : Integer; stdcall;
13051293 function _Release : Integer; stdcall;
1294+ function GetInterface (const IID: TGUID; out Obj): Boolean;
13061295{ $IFNDEF AUTOREFCOUNT}
13071296 procedure AfterConstruction ; override;
13081297 procedure BeforeDestruction ; override;
@@ -2027,7 +2016,7 @@ THandleFinalizer<T> = class(TInterfacedObject, IShared<T>)
20272016
20282017{ $IFDEF DELPHIXE6_UP}{ $RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS(DefaultFieldRttiVisibility)}{ $ENDIF}
20292018
2030- TWeakReference = class abstract (TInterfacedObject )
2019+ TWeakReference = class abstract (TRefCountedObject )
20312020 private
20322021 fTarget: Pointer;
20332022 class procedure RegisterWeakRef (address: Pointer; instance: Pointer); static;
@@ -2986,6 +2975,22 @@ procedure UnregisterWeakRef(address: Pointer; const instance: TObject);
29862975 EmptyValue: TValue = ();
29872976 caReseted = caReset deprecated ' Use caReset' ;
29882977
2978+ ObjCastGUID: TGUID = ' {CEDF24DE-80A4-447D-8C75-EB871DC121FD}' ;
2979+
2980+ { $IFNDEF DELPHIXE3_UP}
2981+ { $IF SizeOf(Pointer) = 4}
2982+ PROPSLOT_MASK = $FF000000;
2983+ PROPSLOT_FIELD = $FF000000;
2984+ PROPSLOT_VIRTUAL = $FE000000;
2985+ { $ELSEIF SizeOf(Pointer) = 8}
2986+ PROPSLOT_MASK = $FF00000000000000;
2987+ PROPSLOT_FIELD = $FF00000000000000;
2988+ PROPSLOT_VIRTUAL = $FE00000000000000;
2989+ { $ELSE OTHER_PTR_SIZE}
2990+ { $MESSAGE Fatal 'Unrecognized pointer size'}
2991+ { $IFEND OTHER_PTR_SIZE}
2992+ { $ENDIF}
2993+
29892994implementation
29902995
29912996uses
@@ -4710,39 +4715,57 @@ procedure TInitTable.TManagedObjectField.InitializeValue(instance: Pointer);
47104715
47114716{ $REGION 'TInitTable.TManagedInterfaceField'}
47124717
4713- function InvokeImplGetter (const Self: TObject; implGetter: NativeUInt): IInterface;
4718+ procedure InvokeImplGetter (const self: TObject; implGetter: NativeUInt; var result: IInterface);
4719+ { $IFDEF PUREPASCAL}
4720+ type
4721+ { $IF defined(MSWINDOWS) or defined(OSX32)}
4722+ TGetProc = procedure (const self: TObject; var result: IInterface);
4723+ { $ELSE}
4724+ TGetProc = procedure (var result: IInterface; const self: TObject);
4725+ { $IFEND}
47144726var
4715- method: function: IInterface of object ;
4727+ getProc: TGetProc ;
47164728begin
4717- TMethod(method).Data := Self;
4718- { $IF SizeOf(NativeUInt) = 4}
4719- case implGetter of
4720- $FF000000..$FFFFFFFF:
4721- Result := IInterface(PPointer(PByte(Self) + (implGetter and $00FFFFFF))^);
4722- $FE000000..$FEFFFFFF:
4723- begin
4724- TMethod(method).Code := PPointer(PNativeInt(Self)^ + SmallInt(implGetter))^;
4725- Result := method;
4726- end ;
4727- else
4728- TMethod(method).Code := Pointer(implGetter);
4729- Result := method;
4730- end ;
4731- { $ELSE}
4732- if (implGetter and $FF00000000000000) = $FF00000000000000 then
4733- Result := IInterface(PPointer(PByte(Self) + (implGetter and $00FFFFFFFFFFFFFF))^)
4734- else if (implGetter and $FF00000000000000) = $FE00000000000000 then
4735- begin
4736- TMethod(method).Code := PPointer(PNativeInt(Self)^ + SmallInt(implGetter))^;
4737- Result := method;
4738- end
4729+ if (implGetter and PROPSLOT_MASK) = PROPSLOT_FIELD then
4730+ Result := IInterface(PPointer(PByte(self) + (implGetter and not PROPSLOT_MASK))^)
47394731 else
47404732 begin
4741- TMethod(method).Code := Pointer(implGetter);
4742- Result := method;
4733+ if (implGetter and PROPSLOT_MASK) = PROPSLOT_VIRTUAL then
4734+ getProc := PPointer(PNativeInt(self)^ + SmallInt(implGetter))^
4735+ else
4736+ getProc := Pointer(implGetter);
4737+ { $IF defined(MSWINDOWS) or defined(OSX32)}
4738+ GetProc(self, result);
4739+ { $ELSE}
4740+ GetProc(result, self);
4741+ { $IFEND}
47434742 end ;
4744- { $IFEND}
47454743end ;
4744+ { $ELSE}
4745+ { $IFDEF CPUX86}
4746+ asm
4747+ xchg edx,ecx
4748+ cmp ecx,PROPSLOT_FIELD
4749+ jae @@isField
4750+ cmp ecx,PROPSLOT_VIRTUAL
4751+ jb @@isStaticMethod
4752+
4753+ movsx ecx,cx
4754+ add ecx,[eax]
4755+ jmp dword ptr [ecx]
4756+
4757+ @@isStaticMethod:
4758+ jmp ecx
4759+
4760+ @@isField:
4761+ and ecx,not PROPSLOT_MASK
4762+ add ecx,eax
4763+ mov eax,edx
4764+ mov edx,[ecx]
4765+ jmp System.@IntfCopy
4766+ end ;
4767+ { $ENDIF}
4768+ { $ENDIF}
47464769
47474770constructor TInitTable.TManagedInterfaceField.Create(offset: Integer;
47484771 fieldType: PTypeInfo; cls: TClass; const factory: TFunc<PTypeInfo,Pointer>;
@@ -4766,7 +4789,7 @@ function TInitTable.TManagedInterfaceField.CreateInstance: Pointer;
47664789 else
47674790 begin
47684791 Result := nil ;
4769- IInterface(Result) := InvokeImplGetter(obj, fEntry.ImplGetter);
4792+ InvokeImplGetter(obj, fEntry.ImplGetter, IInterface(Result) );
47704793 end ;
47714794end ;
47724795
@@ -7139,6 +7162,26 @@ function TRefCountedObject.AsObject: TObject;
71397162 Result := Self;
71407163end ;
71417164
7165+ function TRefCountedObject.GetInterface (const IID: TGUID; out Obj): Boolean;
7166+ var
7167+ interfaceEntry: PInterfaceEntry;
7168+ begin
7169+ Pointer(Obj) := nil ;
7170+ interfaceEntry := GetInterfaceEntry(IID);
7171+ if interfaceEntry <> nil then
7172+ begin
7173+ if interfaceEntry.IOffset <> 0 then
7174+ begin
7175+ Pointer(Obj) := Pointer(PByte(Self) + interfaceEntry.IOffset);
7176+ if Pointer(Obj) <> nil then IInterface(Obj)._AddRef;
7177+ end
7178+ else
7179+ InvokeImplGetter(Self, interfaceEntry.ImplGetter, IInterface(Obj));
7180+ end else if IID = ObjCastGUID then
7181+ Pointer(Obj) := Pointer(Self);
7182+ Result := Pointer(Obj) <> nil ;
7183+ end ;
7184+
71427185{ $IFNDEF AUTOREFCOUNT}
71437186function TRefCountedObject.GetRefCount : Integer;
71447187begin
0 commit comments