diff options
Diffstat (limited to 'rtl')
-rw-r--r-- | rtl/inc/objpas.inc | 204 | ||||
-rw-r--r-- | rtl/inc/objpash.inc | 26 |
2 files changed, 124 insertions, 106 deletions
diff --git a/rtl/inc/objpas.inc b/rtl/inc/objpas.inc index 9956edcc4c..85a2e32ec6 100644 --- a/rtl/inc/objpas.inc +++ b/rtl/inc/objpas.inc @@ -133,14 +133,11 @@ {**************************************************************************** TOBJECT ****************************************************************************} - constructor TObject.Create; - begin end; destructor TObject.Destroy; - begin end; @@ -155,19 +152,24 @@ class function TObject.InstanceSize : SizeInt; begin - InstanceSize:=pSizeInt(pointer(self)+vmtInstanceSize)^; + InstanceSize := PVmt(Self)^.vInstanceSize; end; + var + emptyintf: ptruint; public name 'FPC_EMPTYINTF'; + procedure InitInterfacePointers(objclass: tclass;instance : pointer); var - i: integer; + ovmt: PVmt; + i: longint; intftable: pinterfacetable; Res: pinterfaceentry; begin - while assigned(objclass) do + ovmt := PVmt(objclass); + while assigned(ovmt) and (ovmt^.vIntfTable <> @emptyintf) do begin - intftable:=pinterfacetable((pointer(objclass)+vmtIntfTable)^); + intftable:=ovmt^.vIntfTable; if assigned(intftable) then begin i:=intftable^.EntryCount; @@ -180,7 +182,7 @@ dec(i); end; end; - objclass:=pclass(pointer(objclass)+vmtParent)^; + ovmt:=ovmt^.vParent; end; end; @@ -192,7 +194,8 @@ { insert VMT pointer into the new created memory area } { (in class methods self contains the VMT!) } ppointer(instance)^:=pointer(self); - InitInterfacePointers(self,instance); + if PVmt(self)^.vIntfTable <> @emptyintf then + InitInterfacePointers(self,instance); InitInstance:=TObject(Instance); end; @@ -201,7 +204,7 @@ begin { type of self is class of tobject => it points to the vmt } { the parent vmt is saved at offset vmtParent } - classparent:=pclass(pointer(self)+vmtParent)^; + classparent:=tclass(PVmt(Self)^.vParent); end; class function TObject.NewInstance : tobject; @@ -247,13 +250,13 @@ var methodtable : pmethodnametable; i : dword; - vmt : tclass; + ovmt : PVmt; begin - vmt:=self; - while assigned(vmt) do + ovmt:=PVmt(self); + while assigned(ovmt) do begin - methodtable:=pmethodnametable((Pointer(vmt)+vmtMethodTable)^); + methodtable:=pmethodnametable(ovmt^.vMethodTable); if assigned(methodtable) then begin for i:=0 to methodtable^.count-1 do @@ -263,7 +266,7 @@ exit; end; end; - vmt:=pclass(pointer(vmt)+vmtParent)^; + ovmt := ovmt^.vParent; end; MethodAddress:=nil; end; @@ -273,12 +276,12 @@ var methodtable : pmethodnametable; i : dword; - vmt : tclass; + ovmt : PVmt; begin - vmt:=self; - while assigned(vmt) do + ovmt:=PVmt(self); + while assigned(ovmt) do begin - methodtable:=pmethodnametable((Pointer(vmt)+vmtMethodTable)^); + methodtable:=pmethodnametable(ovmt^.vMethodTable); if assigned(methodtable) then begin for i:=0 to methodtable^.count-1 do @@ -288,7 +291,7 @@ exit; end; end; - vmt:=pclass(pointer(vmt)+vmtParent)^; + ovmt := ovmt^.vParent; end; MethodName:=''; end; @@ -321,18 +324,18 @@ end; var - CurClassType: TClass; + ovmt: PVmt; FieldTable: PFieldTable; FieldInfo: PFieldInfo; - i: Integer; + i: longint; begin if Length(name) > 0 then begin - CurClassType := ClassType; - while CurClassType <> nil do + ovmt := PVmt(ClassType); + while ovmt <> nil do begin - FieldTable := PFieldTable((Pointer(CurClassType) + vmtFieldTable)^); + FieldTable := PFieldTable(ovmt^.vFieldTable); if FieldTable <> nil then begin FieldInfo := @FieldTable^.Fields[0]; @@ -351,7 +354,7 @@ end; end; { Try again with the parent class type } - CurClassType:=pclass(pointer(CurClassType)+vmtParent)^; + ovmt:=ovmt^.vParent; end; end; @@ -368,52 +371,42 @@ class function TObject.ClassInfo : pointer; begin - ClassInfo:=ppointer(Pointer(self)+vmtTypeInfo)^; + ClassInfo := PVmt(Self)^.vTypeInfo; end; class function TObject.ClassName : ShortString; begin - ClassName:=PShortString((Pointer(Self)+vmtClassName)^)^; + ClassName := PVmt(Self)^.vClassName^; end; class function TObject.ClassNameIs(const name : string) : boolean; begin - ClassNameIs:=ShortCompareText(ClassName, name) = 0; + // call to ClassName inlined here, this eliminates stack and string copying. + ClassNameIs:=ShortCompareText(PVmt(Self)^.vClassName^, name) = 0; end; class function TObject.InheritsFrom(aclass : TClass) : Boolean; var - vmt : tclass; + vmt: PVmt; begin - vmt:=self; - while assigned(vmt) do - begin - if vmt=aclass then - begin - InheritsFrom:=true; - exit; - end; - vmt:=pclass(pointer(vmt)+vmtParent)^; - end; - InheritsFrom:=false; + vmt:=PVmt(self); + while assigned(vmt) and (vmt <> PVmt(aclass)) do + vmt := vmt^.vParent; + InheritsFrom := (vmt = PVmt(aclass)); end; class function TObject.stringmessagetable : pstringmessagetable; begin - stringmessagetable:=pstringmessagetable((pointer(Self)+vmtMsgStrPtr)^); + stringmessagetable:=PVmt(Self)^.vMsgStrPtr; end; type tmessagehandler = procedure(var msg) of object; - tmessagehandlerrec = packed record - proc : pointer; - obj : pointer; - end; procedure TObject.Dispatch(var message); @@ -431,20 +424,20 @@ count,i : longint; msgtable : pmsgtable; p : pointer; - vmt : tclass; + ovmt : PVmt; msghandler : tmessagehandler; begin index:=dword(message); - vmt:=ClassType; - while assigned(vmt) do + ovmt := PVmt(ClassType); + while assigned(ovmt) do begin // See if we have messages at all in this class. - p:=pointer(vmt)+vmtDynamicTable; - If assigned(PPointer(p)^) then + p:=ovmt^.vDynamicTable; + If Assigned(p) then begin - msgtable:=pmsgtable(Pointer(p^)+4); - count:=pdword(p^)^; + msgtable:=pmsgtable(p+4); + count:=pdword(p)^; end else Count:=0; @@ -453,14 +446,13 @@ begin if index=msgtable[i].index then begin - p:=msgtable[i].method; - tmessagehandlerrec(msghandler).proc:=p; - tmessagehandlerrec(msghandler).obj:=self; + TMethod(msghandler).Code:=msgtable[i].method; + TMethod(msghandler).Data:=self; msghandler(message); exit; end; end; - vmt:=pclass(pointer(vmt)+vmtParent)^; + ovmt:=ovmt^.vParent; end; DefaultHandler(message); end; @@ -474,20 +466,20 @@ name : shortstring; count,i : longint; msgstrtable : pmsgstrtable; - p : pointer; - vmt : tclass; + p: pstringmessagetable; + ovmt : PVmt; msghandler : tmessagehandler; begin name:=pshortstring(@message)^; - vmt:=ClassType; - while assigned(vmt) do - begin - p:=(pointer(vmt)+vmtMsgStrPtr); - If (P<>Nil) and (PPtruInt(P)^<>0) then + ovmt:=PVmt(ClassType); + while assigned(ovmt) do + begin + p := ovmt^.vMsgStrPtr; + if (P<>Nil) and (p^.count<>0) then begin - count:=Pptruint(PSizeUInt(p)^)^; - msgstrtable:=pmsgstrtable(PSizeUInt(P)^+sizeof(ptruint)); + count:=p^.count; + msgstrtable:=@p^.msgstrtable; end else Count:=0; @@ -496,15 +488,14 @@ begin if name=msgstrtable[i].name^ then begin - p:=msgstrtable[i].method; - tmessagehandlerrec(msghandler).proc:=p; - tmessagehandlerrec(msghandler).obj:=self; + TMethod(msghandler).Code:=msgstrtable[i].method; + TMethod(msghandler).Data:=self; msghandler(message); exit; end; end; - vmt:=pclass(pointer(vmt)+vmtParent)^; - end; + ovmt:=ovmt^.vParent; + end; DefaultHandlerStr(message); end; @@ -535,7 +526,7 @@ end; var - vmt : tclass; + vmt : PVmt; temp : pbyte; count, i : longint; @@ -543,12 +534,12 @@ recelem : TRecElem; {$endif FPC_REQUIRES_PROPER_ALIGNMENT} begin - vmt:=ClassType; + vmt := PVmt(ClassType); while vmt<>nil do begin { This need to be included here, because Finalize() has should support for tkClass } - Temp:=Pointer((Pointer(vmt)+vmtInitTable)^); + Temp:= vmt^.vInitTable; if Assigned(Temp) then begin inc(Temp); @@ -572,7 +563,7 @@ int_Finalize (pointer(self)+Offset,Info); {$endif FPC_REQUIRES_PROPER_ALIGNMENT} end; - vmt:=pclass(pointer(vmt)+vmtParent)^; + vmt:= vmt^.vParent; end; end; @@ -646,52 +637,55 @@ class function TObject.getinterfaceentry(const iid : tguid) : pinterfaceentry; var - i: integer; + i: longint; intftable: pinterfacetable; - Res: pinterfaceentry; + ovmt: PVmt; begin - getinterfaceentry:=nil; - intftable:=pinterfacetable((pointer(Self)+vmtIntfTable)^); - if assigned(intftable) then begin - i:=intftable^.EntryCount; - Res:=@intftable^.Entries[0]; - while (i>0) and - not (assigned(Res^.iid) and IsGUIDEqual(Res^.iid^,iid)) do begin - inc(Res); - dec(i); + ovmt := PVmt(Self); + while Assigned(ovmt) and (ovmt^.vIntfTable <> @emptyintf) do + begin + intftable:=ovmt^.vIntfTable; + if assigned(intftable) then + begin + for i:=0 to intftable^.EntryCount-1 do + begin + result:=@intftable^.Entries[i]; + if assigned(Result^.iid) and IsGUIDEqual(Result^.iid^,iid) then + Exit; + end; end; - if (i>0) then - getinterfaceentry:=Res; + ovmt := ovmt^.vParent; end; - if (getinterfaceentry=nil)and not(classparent=nil) then - getinterfaceentry:=classparent.getinterfaceentry(iid) + result := nil; end; class function TObject.getinterfaceentrybystr(const iidstr : string) : pinterfaceentry; var - i: integer; + i: longint; intftable: pinterfacetable; - Res: pinterfaceentry; + ovmt: PVmt; begin - getinterfaceentrybystr:=nil; - intftable:=pinterfacetable((pointer(Self)+vmtIntfTable)^); - if assigned(intftable) then begin - i:=intftable^.EntryCount; - Res:=@intftable^.Entries[0]; - while (i>0) and (Res^.iidstr^<>iidstr) do begin - inc(Res); - dec(i); + ovmt := PVmt(Self); + while Assigned(ovmt) and (ovmt^.vIntfTable <> @emptyintf) do + begin + intftable:=ovmt^.vIntfTable; + if assigned(intftable) then + begin + for i:=0 to intftable^.EntryCount-1 do + begin + result:=@intftable^.Entries[i]; + if result^.iidstr^ = iidstr then + Exit; + end; end; - if (i>0) then - getinterfaceentrybystr:=Res; + ovmt := ovmt^.vParent; end; - if (getinterfaceentrybystr=nil) and not(classparent=nil) then - getinterfaceentrybystr:=classparent.getinterfaceentrybystr(iidstr) + result:=nil; end; class function TObject.getinterfacetable : pinterfacetable; begin - getinterfacetable:=pinterfacetable((pointer(Self)+vmtIntfTable)^); + getinterfacetable:=PVmt(Self)^.vIntfTable; end; {**************************************************************************** diff --git a/rtl/inc/objpash.inc b/rtl/inc/objpash.inc index 405e0fc83a..330fbd5143 100644 --- a/rtl/inc/objpash.inc +++ b/rtl/inc/objpash.inc @@ -89,6 +89,31 @@ end; pstringmessagetable = ^tstringmessagetable; + pinterfacetable = ^tinterfacetable; + + PVmt = ^TVmt; + TVmt = record + vInstanceSize: SizeInt; + vInstanceSize2: SizeInt; + vParent: PVmt; + vClassName: PShortString; + vDynamicTable: Pointer; + vMethodTable: Pointer; + vFieldTable: Pointer; + vTypeInfo: Pointer; + vInitTable: Pointer; + vAutoTable: Pointer; + vIntfTable: PInterfaceTable; + vMsgStrPtr: pstringmessagetable; + vDestroy: Pointer; + vNewInstance: Pointer; + vFreeInstance: Pointer; + vSafeCallException: Pointer; + vDefaultHandler: Pointer; + vAfterConstruction: Pointer; + vBeforeDestruction: Pointer; + vDefaultHandlerStr: Pointer; + end; PGuid = ^TGuid; TGuid = packed record @@ -133,7 +158,6 @@ false : (__pad_dummy : pointer); end; - pinterfacetable = ^tinterfacetable; tinterfacetable = record EntryCount : ptruint; Entries : array[0..0] of tinterfaceentry; |