Advertisement
Guest User

Untitled

a guest
Jun 16th, 2014
343
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.00 KB | None | 0 0
  1. unit VmtUtils;
  2.  
  3. interface
  4.  
  5. uses
  6.   TypInfo;
  7.  
  8. type
  9.   PVmtMethodTable = ^TVmtMethodTable;
  10.   TVmtMethodTable = packed record
  11.    {Count: Word;}
  12.    {Entry: array[1..Count] of TVmtMethodEntry;}
  13.     ExCount: Word;
  14.     ExEntry: array[0..0] of TVmtMethodExEntry;
  15.   end;
  16.  
  17. function GetMethodTable(AClass: TClass): PVmtMethodTable;
  18. function GetVirtualIndex(AClass: TClass; AMethod: Pointer): SmallInt;
  19. function GetVirtualMethodAddress(AClass: TClass; AVirtualIndex: SmallInt): Pointer;
  20. function IsOverridden(ABaseClass, AChildClass: TClass; AMethod: Pointer): Boolean;
  21.  
  22. implementation
  23.  
  24. function GetMethodTable(AClass: TClass): PVmtMethodTable;
  25. begin
  26.   Result := PPointer(PByte(AClass) + vmtMethodTable)^;
  27.   if Result <> nil then
  28.   begin
  29.     // skip the first entries
  30.     Inc(PByte(Result), Result.ExCount * SizeOf(Pointer));
  31.     Inc(PByte(Result), SizeOf(Word));
  32.   end;
  33. end;
  34.  
  35. function GetVirtualIndex(AClass: TClass; AMethod: Pointer): SmallInt;
  36. var
  37.   table: PVmtMethodTable;
  38.   i: Word;
  39. begin
  40.   while AClass <> nil do
  41.   begin
  42.     table := GetMethodTable(AClass);
  43.     if table <> nil then
  44.       for i := 0 to table.ExCount - 1 do
  45.         if table.ExEntry[i].Entry.CodeAddress = AMethod then
  46.           Exit(table.ExEntry[i].VirtualIndex);
  47.     AClass := AClass.ClassParent;
  48.   end;
  49.   Result := -1;
  50. end;
  51.  
  52. function GetVirtualMethodAddress(AClass: TClass; AVirtualIndex: SmallInt): Pointer;
  53. var
  54.   table: PVmtMethodTable;
  55.   i: Word;
  56. begin
  57.   while AClass <> nil do
  58.   begin
  59.     table := GetMethodTable(AClass);
  60.     if table <> nil then
  61.       for i := 0 to table.ExCount - 1 do
  62.         if table.ExEntry[i].VirtualIndex = AVirtualIndex then
  63.           Exit(table.ExEntry[i].Entry.CodeAddress);
  64.     AClass := AClass.ClassParent;
  65.   end;
  66.   Result := nil;
  67. end;
  68.  
  69. function IsOverridden(ABaseClass, AChildClass: TClass; AMethod: Pointer): Boolean;
  70. var
  71.   index: SmallInt;
  72. begin
  73.   index := GetVirtualIndex(ABaseClass, AMethod);
  74.   Result := AMethod <> GetVirtualMethodAddress(AChildClass, index);
  75. end;
  76.  
  77. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement