objpas.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998 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. unit objpas;
  13. {$I-,S-}
  14. interface
  15. {*****************************************************************************
  16. Basic Types/constants
  17. *****************************************************************************}
  18. const
  19. // vmtSelfPtr = -36; { not implemented yet }
  20. vmtMsgStrPtr = -36;
  21. vmtIntfTable = -32;
  22. vmtAutoTable = -28;
  23. vmtInitTable = -24;
  24. vmtTypeInfo = -20;
  25. vmtFieldTable = -16;
  26. vmtMethodTable = -12;
  27. vmtDynamicTable = -8;
  28. vmtClassName = -4;
  29. vmtInstanceSize = 0;
  30. vmtParent = 8;
  31. vmtDestroy = 12;
  32. vmtNewInstance = 16;
  33. vmtFreeInstance = 20;
  34. vmtSafeCallException = 24;
  35. vmtDefaultHandler = 28;
  36. vmtAfterConstruction = 32;
  37. vmtBeforeDestruction = 36;
  38. vmtDefaultHandlerStr = 40;
  39. type
  40. { first, in object pascal, the types must be redefined }
  41. smallint = system.integer;
  42. integer = system.longint;
  43. { some pointer definitions }
  44. pshortstring = ^shortstring;
  45. plongstring = ^longstring;
  46. pansistring = ^ansistring;
  47. pwidestring = ^widestring;
  48. // pstring = pansistring;
  49. pextended = ^extended;
  50. ppointer = ^pointer;
  51. { now the let's declare the base classes for the class object }
  52. { model }
  53. tobject = class;
  54. tclass = class of tobject;
  55. pclass = ^tclass;
  56. tobject = class
  57. { please don't change the order of virtual methods, because }
  58. { their vmt offsets are used by some assembler code which uses }
  59. { hard coded addresses (FK) }
  60. constructor create;
  61. { the virtual procedures must be in THAT order }
  62. destructor destroy;virtual;
  63. class function newinstance : tobject;virtual;
  64. procedure freeinstance;virtual;
  65. function safecallexception(exceptobject : tobject;
  66. exceptaddr : pointer) : integer;virtual;
  67. procedure defaulthandler(var message);virtual;
  68. procedure free;
  69. class function initinstance(instance : pointer) : tobject;
  70. procedure cleanupinstance;
  71. function classtype : tclass;
  72. class function classinfo : pointer;
  73. class function classname : shortstring;
  74. class function classnameis(const name : string) : boolean;
  75. class function classparent : tclass;
  76. class function instancesize : longint;
  77. class function inheritsfrom(aclass : tclass) : boolean;
  78. { message handling routines }
  79. procedure dispatch(var message);
  80. procedure dispatchstr(var message);
  81. class function methodaddress(const name : shortstring) : pointer;
  82. class function methodname(address : pointer) : shortstring;
  83. function fieldaddress(const name : shortstring) : pointer;
  84. { new since Delphi 4 }
  85. procedure AfterConstruction;virtual;
  86. procedure BeforeDestruction;virtual;
  87. { new for gtk, default handler for text based messages }
  88. procedure DefaultHandlerStr(var message);virtual;
  89. { interface functions, I don't know if we need this }
  90. {
  91. function getinterface(const iid : tguid;out obj) : boolean;
  92. class function getinterfaceentry(const iid : tguid) : pinterfaceentry;
  93. class function getinterfacetable : pinterfacetable;
  94. }
  95. end;
  96. TExceptProc = Procedure (Obj : TObject; Addr: Pointer);
  97. Const
  98. ExceptProc : Pointer {TExceptProc} = Nil;
  99. {*****************************************************************************
  100. Variant Type
  101. *****************************************************************************}
  102. Const
  103. varEmpty = $0000;
  104. varNull = $0001;
  105. varSmallint = $0002;
  106. varInteger = $0003;
  107. varSingle = $0004;
  108. varDouble = $0005;
  109. varCurrency = $0006;
  110. varDate = $0007;
  111. varOleStr = $0008;
  112. varDispatch = $0009;
  113. varError = $000A;
  114. varBoolean = $000B;
  115. varVariant = $000C;
  116. varUnknown = $000D;
  117. varByte = $0011;
  118. varString = $0100;
  119. varAny = $0101;
  120. varTypeMask = $0FFF;
  121. varArray = $2000;
  122. varByRef = $4000;
  123. vtInteger = 0;
  124. vtBoolean = 1;
  125. vtChar = 2;
  126. vtExtended = 3;
  127. vtString = 4;
  128. vtPointer = 5;
  129. vtPChar = 6;
  130. vtObject = 7;
  131. vtClass = 8;
  132. vtWideChar = 9;
  133. vtPWideChar = 10;
  134. vtAnsiString = 11;
  135. vtCurrency = 12;
  136. vtVariant = 13;
  137. vtInterface = 14;
  138. vtWideString = 15;
  139. vtInt64 = 16;
  140. Type
  141. PVarRec = ^TVarRec;
  142. TVarRec = record
  143. case VType : Longint of
  144. vtInteger : (VInteger: Integer);
  145. vtBoolean : (VBoolean: Boolean);
  146. vtChar : (VChar: Char);
  147. vtExtended : (VExtended: PExtended);
  148. vtString : (VString: PShortString);
  149. vtPointer : (VPointer: Pointer);
  150. vtPChar : (VPChar: PChar);
  151. vtObject : (VObject: TObject);
  152. vtClass : (VClass: TClass);
  153. // vtWideChar : (VWideChar: WideChar);
  154. // vtPWideChar : (VPWideChar: PWideChar);
  155. vtAnsiString : (VAnsiString: Pointer);
  156. // vtCurrency : (VCurrency: PCurrency);
  157. // vtVariant : (VVariant: PVariant);
  158. // vtInterface : (VInterface: Pointer);
  159. vtWideString : (VWideString: Pointer);
  160. // vtInt64 : (VInt64: PInt64);
  161. end;
  162. {****************************************************************************
  163. Compatibiity routines.
  164. ****************************************************************************}
  165. { Untyped file support }
  166. Procedure AssignFile(Var f:File;const Name:string);
  167. Procedure AssignFile(Var f:File;p:pchar);
  168. Procedure AssignFile(Var f:File;c:char);
  169. Procedure CloseFile(Var f:File);
  170. { Text file support }
  171. Procedure AssignFile(Var t:Text;const s:string);
  172. Procedure AssignFile(Var t:Text;p:pchar);
  173. Procedure AssignFile(Var t:Text;c:char);
  174. Procedure CloseFile(Var t:Text);
  175. { Typed file supoort }
  176. Procedure AssignFile(Var f:TypedFile;const Name:string);
  177. Procedure AssignFile(Var f:TypedFile;p:pchar);
  178. Procedure AssignFile(Var f:TypedFile;c:char);
  179. implementation
  180. Procedure HandleError (Errno : longint);external name 'FPC_HANDLEERROR';
  181. {****************************************************************************
  182. Internal Routines called from the Compiler
  183. ****************************************************************************}
  184. procedure finalize(data,typeinfo : pointer);external name 'FPC_FINALIZE';
  185. { the reverse order of the parameters make code generation easier }
  186. function int_do_is(aclass : tclass;aobject : tobject) : boolean;[public,alias: 'FPC_DO_IS'];
  187. begin
  188. int_do_is:=aobject.inheritsfrom(aclass);
  189. end;
  190. { the reverse order of the parameters make code generation easier }
  191. procedure int_do_as(aclass : tclass;aobject : tobject);[public,alias: 'FPC_DO_AS'];
  192. begin
  193. if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
  194. handleerror(219);
  195. end;
  196. {****************************************************************************
  197. TOBJECT
  198. ****************************************************************************}
  199. constructor TObject.Create;
  200. begin
  201. end;
  202. destructor TObject.Destroy;
  203. begin
  204. end;
  205. procedure TObject.Free;
  206. begin
  207. // the call via self avoids a warning
  208. if self<>nil then
  209. self.destroy;
  210. end;
  211. class function TObject.InstanceSize : LongInt;
  212. type
  213. plongint = ^longint;
  214. begin
  215. { type of self is class of tobject => it points to the vmt }
  216. { the size is saved at offset 0 }
  217. InstanceSize:=plongint(self)^;
  218. end;
  219. class function TObject.InitInstance(instance : pointer) : tobject;
  220. begin
  221. fillchar(instance^,self.instancesize,0);
  222. { insert VMT pointer into the new created memory area }
  223. { (in class methods self contains the VMT!) }
  224. ppointer(instance)^:=pointer(self);
  225. InitInstance:=TObject(Instance);
  226. end;
  227. class function TObject.ClassParent : tclass;
  228. begin
  229. { type of self is class of tobject => it points to the vmt }
  230. { the parent vmt is saved at offset vmtParent }
  231. classparent:=(pclass(self)+vmtParent)^;
  232. end;
  233. class function TObject.NewInstance : tobject;
  234. var
  235. p : pointer;
  236. begin
  237. getmem(p,instancesize);
  238. InitInstance(p);
  239. NewInstance:=TObject(p);
  240. end;
  241. procedure TObject.FreeInstance;
  242. var
  243. p : Pointer;
  244. begin
  245. CleanupInstance;
  246. { self is a register, so we can't pass it call by reference }
  247. p:=Pointer(Self);
  248. FreeMem(p,InstanceSize);
  249. end;
  250. function TObject.ClassType : TClass;
  251. begin
  252. ClassType:=TClass(Pointer(Self)^)
  253. end;
  254. class function TObject.MethodAddress(const name : shortstring) : pointer;
  255. begin
  256. methodaddress:=nil;
  257. end;
  258. class function TObject.MethodName(address : pointer) : shortstring;
  259. begin
  260. methodname:='';
  261. end;
  262. function TObject.FieldAddress(const name : shortstring) : pointer;
  263. begin
  264. fieldaddress:=nil;
  265. end;
  266. function TObject.SafeCallException(exceptobject : tobject;
  267. exceptaddr : pointer) : integer;
  268. begin
  269. safecallexception:=0;
  270. end;
  271. class function TObject.ClassInfo : pointer;
  272. begin
  273. ClassInfo:=(PPointer(self)+vmtTypeInfo)^;
  274. end;
  275. class function TObject.ClassName : ShortString;
  276. begin
  277. ClassName:=PShortString((PPointer(Self)+vmtClassName)^)^;
  278. end;
  279. class function TObject.ClassNameIs(const name : string) : boolean;
  280. begin
  281. ClassNameIs:=ClassName=name;
  282. end;
  283. class function TObject.InheritsFrom(aclass : TClass) : Boolean;
  284. var
  285. c : tclass;
  286. begin
  287. c:=self;
  288. while assigned(c) do
  289. begin
  290. if c=aclass then
  291. begin
  292. InheritsFrom:=true;
  293. exit;
  294. end;
  295. c:=c.ClassParent;
  296. end;
  297. InheritsFrom:=false;
  298. end;
  299. procedure TObject.Dispatch(var message);
  300. type
  301. tmsgtable = record
  302. index : dword;
  303. method : pointer;
  304. end;
  305. pmsgtable = ^tmsgtable;
  306. pdword = ^dword;
  307. var
  308. index : dword;
  309. count,i : longint;
  310. msgtable : pmsgtable;
  311. p : pointer;
  312. vmt : tclass;
  313. begin
  314. index:=dword(message);
  315. vmt:=ClassType;
  316. while assigned(vmt) do
  317. begin
  318. msgtable:=pmsgtable((pdword(vmt)+vmtDynamicTable)^+4);
  319. count:=pdword((pdword(vmt)+vmtDynamicTable)^)^;
  320. { later, we can implement a binary search here }
  321. for i:=0 to count-1 do
  322. begin
  323. if index=msgtable[i].index then
  324. begin
  325. p:=msgtable[i].method;
  326. asm
  327. pushl message
  328. pushl %esi
  329. movl p,%edi
  330. call *%edi
  331. end;
  332. exit;
  333. end;
  334. end;
  335. vmt:=vmt.ClassParent;
  336. end;
  337. DefaultHandler(message);
  338. end;
  339. procedure TObject.DispatchStr(var message);
  340. type
  341. tmsgstrtable = record
  342. name : pshortstring;
  343. method : pointer;
  344. end;
  345. pmsgstrtable = ^tmsgstrtable;
  346. pdword = ^dword;
  347. var
  348. name : shortstring;
  349. count,i : longint;
  350. msgstrtable : pmsgstrtable;
  351. p : pointer;
  352. vmt : tclass;
  353. begin
  354. name:=pshortstring(message)^;
  355. vmt:=ClassType;
  356. while assigned(vmt) do
  357. begin
  358. count:=pdword((pdword(vmt)+vmtMsgStrPtr)^)^;
  359. msgstrtable:=pmsgstrtable((pdword(vmt)+vmtMsgStrPtr)^+4);
  360. { later, we can implement a binary search here }
  361. for i:=0 to count-1 do
  362. begin
  363. if name=msgstrtable[i].name^ then
  364. begin
  365. p:=msgstrtable[i].method;
  366. asm
  367. pushl message
  368. pushl %esi
  369. movl p,%edi
  370. call *%edi
  371. end;
  372. exit;
  373. end;
  374. end;
  375. vmt:=vmt.ClassParent;
  376. end;
  377. DefaultHandlerStr(message);
  378. end;
  379. procedure TObject.DefaultHandler(var message);
  380. begin
  381. end;
  382. procedure TObject.DefaultHandlerStr(var message);
  383. begin
  384. end;
  385. procedure TObject.CleanupInstance;
  386. var
  387. vmt : tclass;
  388. begin
  389. vmt:=ClassType;
  390. while vmt<>nil do
  391. begin
  392. if Assigned(Pointer((Pointer(vmt)+vmtInitTable)^)) then
  393. Finalize(Pointer(Self),Pointer((Pointer(vmt)+vmtInitTable)^));
  394. vmt:=vmt.ClassParent;
  395. end;
  396. end;
  397. procedure TObject.AfterConstruction;
  398. begin
  399. end;
  400. procedure TObject.BeforeDestruction;
  401. begin
  402. end;
  403. {****************************************************************************
  404. Compatibiity routines.
  405. ****************************************************************************}
  406. { Untyped file support }
  407. Procedure AssignFile(Var f:File;const Name:string);
  408. begin
  409. System.Assign (F,Name);
  410. end;
  411. Procedure AssignFile(Var f:File;p:pchar);
  412. begin
  413. System.Assign (F,P);
  414. end;
  415. Procedure AssignFile(Var f:File;c:char);
  416. begin
  417. System.Assign (F,C);
  418. end;
  419. Procedure CloseFile(Var f:File);
  420. begin
  421. System.Close(f);
  422. end;
  423. { Text file support }
  424. Procedure AssignFile(Var t:Text;const s:string);
  425. begin
  426. System.Assign (T,S);
  427. end;
  428. Procedure AssignFile(Var t:Text;p:pchar);
  429. begin
  430. System.Assign (T,P);
  431. end;
  432. Procedure AssignFile(Var t:Text;c:char);
  433. begin
  434. System.Assign (T,C);
  435. end;
  436. Procedure CloseFile(Var t:Text);
  437. begin
  438. Close(T);
  439. end;
  440. { Typed file supoort }
  441. Procedure AssignFile(Var f:TypedFile;const Name:string);
  442. begin
  443. system.Assign(F,Name);
  444. end;
  445. Procedure AssignFile(Var f:TypedFile;p:pchar);
  446. begin
  447. system.Assign (F,p);
  448. end;
  449. Procedure AssignFile(Var f:TypedFile;c:char);
  450. begin
  451. system.Assign (F,C);
  452. end;
  453. {****************************************************************************
  454. Exception Support
  455. ****************************************************************************}
  456. {$i except.inc}
  457. {****************************************************************************
  458. Initialize
  459. ****************************************************************************}
  460. begin
  461. InitExceptions;
  462. end.
  463. {
  464. $Log$
  465. Revision 1.21 1999-02-23 14:04:36 pierre
  466. * call %edi => call *%edi
  467. Revision 1.20 1999/02/22 23:30:54 florian
  468. + TObject.Dispatch and TObject.DispatchStr added, working
  469. Revision 1.19 1998/12/24 10:12:03 michael
  470. Implemented AssignFile and CloseFile compatibility
  471. Revision 1.18 1998/10/12 12:42:58 florian
  472. * as operator runtime error can be now caught by an errorproc
  473. Revision 1.17 1998/10/05 12:32:53 peter
  474. + assert() support
  475. Revision 1.16 1998/10/03 15:07:16 florian
  476. + TObject.AfterConstruction and TObject.BeforeDestruction of Delphi 4
  477. Revision 1.15 1998/09/24 16:13:48 michael
  478. Changes in exception and open array handling
  479. Revision 1.14 1998/09/23 12:40:43 michael
  480. Fixed TVarRec again. Should be OK now
  481. Revision 1.13 1998/09/23 12:18:32 michael
  482. + added VType in TVArRec
  483. Revision 1.12 1998/09/23 10:00:47 peter
  484. * tvarrec should be 8 bytes
  485. Revision 1.11 1998/09/22 15:30:07 peter
  486. * array of const update
  487. Revision 1.9 1998/09/16 13:08:19 michael
  488. Added AbstractErrorHandler
  489. Revision 1.8 1998/09/06 21:27:31 florian
  490. + method tobject.classinfo added
  491. Revision 1.7 1998/09/04 08:49:06 peter
  492. * 0.99.5 doesn't compile a whole objpas anymore to overcome crashes
  493. Revision 1.6 1998/08/23 20:58:52 florian
  494. + rtti for objects and classes
  495. + TObject.GetClassName implemented
  496. Revision 1.5 1998/07/30 16:10:11 michael
  497. + Added support for ExceptProc+
  498. Revision 1.4 1998/07/29 15:44:33 michael
  499. included sysutils and math.pp as target. They compile now.
  500. Revision 1.3 1998/07/29 10:09:28 michael
  501. + put in exception support
  502. Revision 1.2 1998/03/25 23:40:24 florian
  503. + stuff from old objpash.inc and objpas.inc merged in
  504. }