objpas.inc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. This unit makes Free Pascal as much as possible Delphi compatible
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. Internal Routines called from the Compiler
  14. ****************************************************************************}
  15. { the reverse order of the parameters make code generation easier }
  16. function fpc_do_is(aclass : tclass;aobject : tobject) : boolean;[public,alias: 'FPC_DO_IS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  17. begin
  18. fpc_do_is:=assigned(aobject) and assigned(aclass) and
  19. aobject.inheritsfrom(aclass);
  20. end;
  21. { the reverse order of the parameters make code generation easier }
  22. function fpc_do_as(aclass : tclass;aobject : tobject): tobject;[public,alias: 'FPC_DO_AS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  23. begin
  24. if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
  25. handleerrorframe(219,get_frame);
  26. result := aobject;
  27. end;
  28. {$ifndef HASINTF}
  29. { dummies for make cycle with 1.0.x }
  30. procedure intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF'];
  31. begin
  32. end;
  33. procedure intf_incr_ref(const i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF'];
  34. begin
  35. end;
  36. procedure intf_assign(var D: pointer; const S: pointer);[public,alias: 'FPC_INTF_ASSIGN'];
  37. begin
  38. end;
  39. procedure intf_as(var D: pointer; const S: pointer; const iid: TGUID);[public,alias: 'FPC_INTF_AS'];
  40. begin
  41. end;
  42. {$else HASINTF}
  43. { interface helpers }
  44. procedure fpc_intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  45. begin
  46. if assigned(i) then
  47. IUnknown(i)._Release;
  48. i:=nil;
  49. end;
  50. {$ifdef hascompilerproc}
  51. { local declaration for intf_decr_ref for local access }
  52. procedure intf_decr_ref(var i: pointer);saveregisters; [external name 'FPC_INTF_DECR_REF'];
  53. {$endif hascompilerproc}
  54. procedure fpc_intf_incr_ref(i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  55. begin
  56. if assigned(i) then
  57. IUnknown(i)._AddRef;
  58. end;
  59. {$ifdef hascompilerproc}
  60. { local declaration of intf_incr_ref for local access }
  61. procedure intf_incr_ref(i: pointer);saveregisters; [external name 'FPC_INTF_INCR_REF'];
  62. {$endif hascompilerproc}
  63. procedure fpc_intf_assign(var D: pointer; const S: pointer);[public,alias: 'FPC_INTF_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
  64. begin
  65. if assigned(S) then
  66. IUnknown(S)._AddRef;
  67. if assigned(D) then
  68. IUnknown(D)._Release;
  69. D:=S;
  70. end;
  71. procedure fpc_intf_as(var D: pointer; const S: pointer; const iid: TGUID);[public,alias: 'FPC_INTF_AS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  72. const
  73. S_OK = 0;
  74. var
  75. tmpi: pointer; // _AddRef before _Release
  76. begin
  77. if assigned(S) then
  78. begin
  79. if IUnknown(S).QueryInterface(iid,tmpi)<>S_OK then
  80. handleerror(219);
  81. if assigned(D) then IUnknown(D)._Release;
  82. D:=tmpi;
  83. end
  84. else
  85. intf_decr_ref(D);
  86. end;
  87. {$endif HASINTF}
  88. {****************************************************************************
  89. TOBJECT
  90. ****************************************************************************}
  91. constructor TObject.Create;
  92. begin
  93. end;
  94. destructor TObject.Destroy;
  95. begin
  96. end;
  97. procedure TObject.Free;
  98. begin
  99. // the call via self avoids a warning
  100. if self<>nil then
  101. self.destroy;
  102. end;
  103. class function TObject.InstanceSize : LongInt;
  104. type
  105. plongint = ^longint;
  106. begin
  107. { type of self is class of tobject => it points to the vmt }
  108. { the size is saved at offset 0 }
  109. InstanceSize:=plongint(self)^;
  110. end;
  111. procedure InitInterfacePointers(objclass: tclass;instance : pointer);
  112. {$ifdef HASINTF}
  113. var
  114. intftable : pinterfacetable;
  115. i : longint;
  116. begin
  117. if assigned(objclass.classparent) then
  118. InitInterfacePointers(objclass.classparent,instance);
  119. intftable:=objclass.getinterfacetable;
  120. if assigned(intftable) then
  121. for i:=0 to intftable^.EntryCount-1 do
  122. ppointer(@(PChar(instance)[intftable^.Entries[i].IOffset]))^:=
  123. pointer(intftable^.Entries[i].VTable);
  124. end;
  125. {$else HASINTF}
  126. begin
  127. end;
  128. {$endif HASINTF}
  129. class function TObject.InitInstance(instance : pointer) : tobject;
  130. begin
  131. fillchar(instance^,self.instancesize,0);
  132. { insert VMT pointer into the new created memory area }
  133. { (in class methods self contains the VMT!) }
  134. ppointer(instance)^:=pointer(self);
  135. {$ifdef HASINTF}
  136. InitInterfacePointers(self,instance);
  137. {$endif HASINTF}
  138. InitInstance:=TObject(Instance);
  139. end;
  140. class function TObject.ClassParent : tclass;
  141. begin
  142. { type of self is class of tobject => it points to the vmt }
  143. { the parent vmt is saved at offset vmtParent }
  144. classparent:=pclass(pointer(self)+vmtParent)^;
  145. end;
  146. class function TObject.NewInstance : tobject;
  147. var
  148. p : pointer;
  149. begin
  150. getmem(p,instancesize);
  151. if p <> nil then
  152. InitInstance(p);
  153. NewInstance:=TObject(p);
  154. end;
  155. procedure TObject.FreeInstance;
  156. var
  157. p : Pointer;
  158. begin
  159. CleanupInstance;
  160. { self is a register, so we can't pass it call by reference }
  161. p:=Pointer(Self);
  162. FreeMem(p,InstanceSize);
  163. end;
  164. function TObject.ClassType : TClass;
  165. begin
  166. ClassType:=TClass(Pointer(Self)^)
  167. end;
  168. type
  169. tmethodnamerec = packed record
  170. name : pshortstring;
  171. addr : pointer;
  172. end;
  173. tmethodnametable = packed record
  174. count : dword;
  175. entries : packed array[0..0] of tmethodnamerec;
  176. end;
  177. pmethodnametable = ^tmethodnametable;
  178. class function TObject.MethodAddress(const name : shortstring) : pointer;
  179. var
  180. UName : ShortString;
  181. methodtable : pmethodnametable;
  182. i : dword;
  183. c : tclass;
  184. begin
  185. UName := UpCase(name);
  186. c:=self;
  187. while assigned(c) do
  188. begin
  189. methodtable:=pmethodnametable((Pointer(c)+vmtMethodTable)^);
  190. if assigned(methodtable) then
  191. begin
  192. for i:=0 to methodtable^.count-1 do
  193. if UpCase(methodtable^.entries[i].name^)=UName then
  194. begin
  195. MethodAddress:=methodtable^.entries[i].addr;
  196. exit;
  197. end;
  198. end;
  199. c:=c.ClassParent;
  200. end;
  201. MethodAddress:=nil;
  202. end;
  203. class function TObject.MethodName(address : pointer) : shortstring;
  204. var
  205. methodtable : pmethodnametable;
  206. i : dword;
  207. c : tclass;
  208. begin
  209. c:=self;
  210. while assigned(c) do
  211. begin
  212. methodtable:=pmethodnametable((Pointer(c)+vmtMethodTable)^);
  213. if assigned(methodtable) then
  214. begin
  215. for i:=0 to methodtable^.count-1 do
  216. if methodtable^.entries[i].addr=address then
  217. begin
  218. MethodName:=methodtable^.entries[i].name^;
  219. exit;
  220. end;
  221. end;
  222. c:=c.ClassParent;
  223. end;
  224. MethodName:='';
  225. end;
  226. function TObject.FieldAddress(const name : shortstring) : pointer;
  227. type
  228. PFieldInfo = ^TFieldInfo;
  229. TFieldInfo = packed record
  230. FieldOffset: LongWord;
  231. ClassTypeIndex: Word;
  232. Name: ShortString;
  233. end;
  234. PFieldTable = ^TFieldTable;
  235. TFieldTable = packed record
  236. FieldCount: Word;
  237. ClassTable: Pointer;
  238. { Fields: array[Word] of TFieldInfo; Elements have variant size! }
  239. end;
  240. var
  241. UName: ShortString;
  242. CurClassType: TClass;
  243. FieldTable: PFieldTable;
  244. FieldInfo: PFieldInfo;
  245. i: Integer;
  246. begin
  247. if Length(name) > 0 then
  248. begin
  249. UName := UpCase(name);
  250. CurClassType := ClassType;
  251. while CurClassType <> nil do
  252. begin
  253. FieldTable := PFieldTable((Pointer(CurClassType) + vmtFieldTable)^);
  254. if FieldTable <> nil then
  255. begin
  256. FieldInfo := PFieldInfo(Pointer(FieldTable) + 6);
  257. for i := 0 to FieldTable^.FieldCount - 1 do
  258. begin
  259. if UpCase(FieldInfo^.Name) = UName then
  260. begin
  261. fieldaddress := Pointer(Self) + FieldInfo^.FieldOffset;
  262. exit;
  263. end;
  264. Inc(Pointer(FieldInfo), 7 + Length(FieldInfo^.Name));
  265. end;
  266. end;
  267. { Try again with the parent class type }
  268. CurClassType := CurClassType.ClassParent;
  269. end;
  270. end;
  271. fieldaddress:=nil;
  272. end;
  273. function TObject.SafeCallException(exceptobject : tobject;
  274. exceptaddr : pointer) : longint;
  275. begin
  276. safecallexception:=0;
  277. end;
  278. class function TObject.ClassInfo : pointer;
  279. begin
  280. ClassInfo:=ppointer(Pointer(self)+vmtTypeInfo)^;
  281. end;
  282. class function TObject.ClassName : ShortString;
  283. begin
  284. ClassName:=PShortString((Pointer(Self)+vmtClassName)^)^;
  285. end;
  286. class function TObject.ClassNameIs(const name : string) : boolean;
  287. begin
  288. ClassNameIs:=Upcase(ClassName)=Upcase(name);
  289. end;
  290. class function TObject.InheritsFrom(aclass : TClass) : Boolean;
  291. var
  292. c : tclass;
  293. begin
  294. c:=self;
  295. while assigned(c) do
  296. begin
  297. if c=aclass then
  298. begin
  299. InheritsFrom:=true;
  300. exit;
  301. end;
  302. c:=c.ClassParent;
  303. end;
  304. InheritsFrom:=false;
  305. end;
  306. class function TObject.stringmessagetable : pstringmessagetable;
  307. type
  308. pdword = ^dword;
  309. begin
  310. stringmessagetable:=pstringmessagetable((pointer(Self)+vmtMsgStrPtr)^);
  311. end;
  312. type
  313. tmessagehandler = procedure(var msg) of object;
  314. tmessagehandlerrec = packed record
  315. proc : pointer;
  316. obj : pointer;
  317. end;
  318. procedure TObject.Dispatch(var message);
  319. type
  320. tmsgtable = record
  321. index : dword;
  322. method : pointer;
  323. end;
  324. pmsgtable = ^tmsgtable;
  325. pdword = ^dword;
  326. var
  327. index : dword;
  328. count,i : longint;
  329. msgtable : pmsgtable;
  330. p : pointer;
  331. vmt : tclass;
  332. msghandler : tmessagehandler;
  333. begin
  334. index:=dword(message);
  335. vmt:=ClassType;
  336. while assigned(vmt) do
  337. begin
  338. // See if we have messages at all in this class.
  339. p:=pointer(vmt)+vmtDynamicTable;
  340. If Assigned(p) and (Pdword(p)^<>0) then
  341. begin
  342. msgtable:=pmsgtable(pdword(P)^+4);
  343. count:=pdword(pdword(P)^)^;
  344. end
  345. else
  346. Count:=0;
  347. { later, we can implement a binary search here }
  348. for i:=0 to count-1 do
  349. begin
  350. if index=msgtable[i].index then
  351. begin
  352. p:=msgtable[i].method;
  353. tmessagehandlerrec(msghandler).proc:=p;
  354. tmessagehandlerrec(msghandler).obj:=self;
  355. msghandler(message);
  356. { we don't need any longer the assembler
  357. solution
  358. asm
  359. pushl message
  360. pushl %esi
  361. movl p,%edi
  362. call *%edi
  363. end;
  364. }
  365. exit;
  366. end;
  367. end;
  368. vmt:=vmt.ClassParent;
  369. end;
  370. DefaultHandler(message);
  371. end;
  372. procedure TObject.DispatchStr(var message);
  373. type
  374. pdword = ^dword;
  375. var
  376. name : shortstring;
  377. count,i : longint;
  378. msgstrtable : pmsgstrtable;
  379. p : pointer;
  380. vmt : tclass;
  381. msghandler : tmessagehandler;
  382. begin
  383. name:=pshortstring(@message)^;
  384. vmt:=ClassType;
  385. while assigned(vmt) do
  386. begin
  387. p:=(pointer(vmt)+vmtMsgStrPtr);
  388. If (P<>Nil) and (PDWord(P)^<>0) then
  389. begin
  390. count:=pdword(pdword(p)^)^;
  391. msgstrtable:=pmsgstrtable(pdword(P)^+4);
  392. end
  393. else
  394. Count:=0;
  395. { later, we can implement a binary search here }
  396. for i:=0 to count-1 do
  397. begin
  398. if name=msgstrtable[i].name^ then
  399. begin
  400. p:=msgstrtable[i].method;
  401. tmessagehandlerrec(msghandler).proc:=p;
  402. tmessagehandlerrec(msghandler).obj:=self;
  403. msghandler(message);
  404. { we don't need any longer the assembler
  405. solution
  406. asm
  407. pushl message
  408. pushl %esi
  409. movl p,%edi
  410. call *%edi
  411. end;
  412. }
  413. exit;
  414. end;
  415. end;
  416. vmt:=vmt.ClassParent;
  417. end;
  418. DefaultHandlerStr(message);
  419. end;
  420. procedure TObject.DefaultHandler(var message);
  421. begin
  422. end;
  423. procedure TObject.DefaultHandlerStr(var message);
  424. begin
  425. end;
  426. procedure TObject.CleanupInstance;
  427. var
  428. vmt : tclass;
  429. begin
  430. vmt:=ClassType;
  431. while vmt<>nil do
  432. begin
  433. if Assigned(Pointer((Pointer(vmt)+vmtInitTable)^)) then
  434. int_finalize(Pointer(Self),Pointer((Pointer(vmt)+vmtInitTable)^));
  435. vmt:=vmt.ClassParent;
  436. end;
  437. end;
  438. procedure TObject.AfterConstruction;
  439. begin
  440. end;
  441. procedure TObject.BeforeDestruction;
  442. begin
  443. end;
  444. {$ifdef HASINTF}
  445. function IsGUIDEqual(const guid1, guid2: tguid): boolean;
  446. begin
  447. IsGUIDEqual:=
  448. (guid1.D1=guid2.D1) and
  449. (PDWORD(@guid1.D2)^=PDWORD(@guid2.D2)^) and
  450. (PDWORD(@guid1.D4[0])^=PDWORD(@guid2.D4[0])^) and
  451. (PDWORD(@guid1.D4[4])^=PDWORD(@guid2.D4[4])^);
  452. end;
  453. function TObject.getinterface(const iid : tguid;out obj) : boolean;
  454. var
  455. IEntry: pinterfaceentry;
  456. begin
  457. IEntry:=getinterfaceentry(iid);
  458. if Assigned(IEntry) then begin
  459. PDWORD(@obj)^:=DWORD(PDWORD(Self))+IEntry^.IOffset;
  460. intf_incr_ref(pointer(obj)); { it must be an com interface }
  461. getinterface:=True;
  462. end
  463. else begin
  464. PDWORD(@Obj)^:=0;
  465. getinterface:=False;
  466. end;
  467. end;
  468. function TObject.getinterfacebystr(const iidstr : string;out obj) : boolean;
  469. var
  470. IEntry: pinterfaceentry;
  471. begin
  472. IEntry:=getinterfaceentrybystr(iidstr);
  473. if Assigned(IEntry) then begin
  474. PDWORD(@obj)^:=DWORD(PDWORD(Self))+IEntry^.IOffset;
  475. if Assigned(IEntry^.iid) then { for Com interfaces }
  476. intf_incr_ref(pointer(obj));
  477. getinterfacebystr:=True;
  478. end
  479. else begin
  480. PDWORD(@Obj)^:=0;
  481. getinterfacebystr:=False;
  482. end;
  483. end;
  484. class function TObject.getinterfaceentry(const iid : tguid) : pinterfaceentry;
  485. var
  486. i: integer;
  487. intftable: pinterfacetable;
  488. Res: pinterfaceentry;
  489. begin
  490. getinterfaceentry:=nil;
  491. intftable:=getinterfacetable;
  492. if assigned(intftable) then begin
  493. i:=intftable^.EntryCount;
  494. Res:=@intftable^.Entries[0];
  495. while (i>0) and
  496. not (assigned(Res^.iid) and IsGUIDEqual(Res^.iid^,iid)) do begin
  497. inc(Res);
  498. dec(i);
  499. end;
  500. if (i>0) then
  501. getinterfaceentry:=Res;
  502. end;
  503. end;
  504. class function TObject.getinterfaceentrybystr(const iidstr : string) : pinterfaceentry;
  505. var
  506. i: integer;
  507. intftable: pinterfacetable;
  508. Res: pinterfaceentry;
  509. begin
  510. getinterfaceentrybystr:=nil;
  511. intftable:=getinterfacetable;
  512. if assigned(intftable) then begin
  513. i:=intftable^.EntryCount;
  514. Res:=@intftable^.Entries[0];
  515. while (i>0) and (Res^.iidstr^<>iidstr) do begin
  516. inc(Res);
  517. dec(i);
  518. end;
  519. if (i>0) then
  520. getinterfaceentrybystr:=Res;
  521. end;
  522. end;
  523. class function TObject.getinterfacetable : pinterfacetable;
  524. begin
  525. getinterfacetable:=pinterfacetable((pointer(Self)+vmtIntfTable)^);
  526. end;
  527. {****************************************************************************
  528. TINTERFACEDOBJECT
  529. ****************************************************************************}
  530. function TInterfacedObject.QueryInterface(
  531. const iid : tguid;out obj) : longint;stdcall;
  532. begin
  533. if getinterface(iid,obj) then
  534. result:=0
  535. else
  536. result:=longint($80004002);
  537. end;
  538. function TInterfacedObject._AddRef : longint;stdcall;
  539. begin
  540. inclocked(frefcount);
  541. _addref:=frefcount;
  542. end;
  543. function TInterfacedObject._Release : longint;stdcall;
  544. begin
  545. if declocked(frefcount) then
  546. begin
  547. destroy;
  548. _Release:=0;
  549. end
  550. else
  551. _Release:=frefcount;
  552. end;
  553. procedure TInterfacedObject.AfterConstruction;
  554. begin
  555. { we need to fix the refcount we forced in newinstance }
  556. { further, it must be done in a thread safe way }
  557. declocked(frefcount);
  558. end;
  559. procedure TInterfacedObject.BeforeDestruction;
  560. begin
  561. if frefcount<>0 then
  562. HandleError(204);
  563. end;
  564. class function TInterfacedObject.NewInstance : TObject;
  565. begin
  566. NewInstance:=inherited NewInstance;
  567. TInterfacedObject(NewInstance).frefcount:=1;
  568. end;
  569. {$endif HASINTF}
  570. {****************************************************************************
  571. Exception Support
  572. ****************************************************************************}
  573. {$i except.inc}
  574. {****************************************************************************
  575. Initialize
  576. ****************************************************************************}
  577. {
  578. $Log$
  579. Revision 1.21 2002-04-26 15:19:05 peter
  580. * use saveregisters for incr routines, saves also problems with
  581. the optimizer
  582. Revision 1.20 2002/04/25 20:14:57 peter
  583. * updated compilerprocs
  584. * incr ref count has now a value argument instead of var
  585. Revision 1.19 2002/03/30 14:52:59 carl
  586. * don't crash everything if the class allocation failed
  587. Revision 1.18 2001/12/26 21:03:56 peter
  588. * merged fixes from 1.0.x
  589. Revision 1.17 2001/09/29 21:32:47 jonas
  590. * almost all second pass typeconvnode helpers are now processor independent
  591. * fixed converting boolean to int64/qword
  592. * fixed register allocation bugs which could cause internalerror 10
  593. * isnode and asnode are completely processor indepent now as well
  594. * fpc_do_as now returns its class argument (necessary to be able to use it
  595. properly with compilerproc)
  596. Revision 1.16 2001/08/01 15:00:10 jonas
  597. + "compproc" helpers
  598. * renamed several helpers so that their name is the same as their
  599. "public alias", which should facilitate the conversion of processor
  600. specific code in the code generator to processor independent code
  601. * some small fixes to the val_ansistring and val_widestring helpers
  602. (always immediately exit if the source string is longer than 255
  603. chars)
  604. * fixed fpc_dynarray_high and fpc_dynarray_length if the dynarray is
  605. still nil (used to crash, now return resp -1 and 0)
  606. Revision 1.15 2001/05/27 14:28:44 florian
  607. + made the ref. couting MT safe
  608. Revision 1.14 2001/04/13 22:30:04 peter
  609. * remove warnings
  610. Revision 1.13 2000/12/20 21:38:23 florian
  611. * is-operator fixed
  612. Revision 1.12 2000/11/12 23:23:34 florian
  613. * interfaces are basically running
  614. Revision 1.11 2000/11/09 17:50:12 florian
  615. * Finalize to int_finalize renamed
  616. Revision 1.10 2000/11/07 23:42:21 florian
  617. + AfterConstruction and BeforeDestruction implemented
  618. + TInterfacedObject implemented
  619. Revision 1.9 2000/11/06 22:03:12 florian
  620. * another fix
  621. Revision 1.8 2000/11/06 21:53:38 florian
  622. * another fix for interfaces
  623. Revision 1.7 2000/11/06 21:35:59 peter
  624. * removed some warnings
  625. Revision 1.6 2000/11/06 20:34:24 peter
  626. * changed ver1_0 defines to temporary defs
  627. Revision 1.5 2000/11/04 17:52:46 florian
  628. * fixed linker errors
  629. Revision 1.4 2000/11/04 16:29:54 florian
  630. + interfaces support
  631. Revision 1.3 2000/07/22 14:52:01 sg
  632. * Resolved CVS conflicts for TObject.MethodAddress patch
  633. Revision 1.1.2.1 2000/07/22 14:46:57 sg
  634. * Made TObject.MethodAddress case independent
  635. }