objpas.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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. vmtIntfTable = -32;
  21. vmtAutoTable = -28;
  22. vmtInitTable = -24;
  23. vmtTypeInfo = -20;
  24. vmtFieldTable = -16;
  25. vmtMethodTable = -12;
  26. vmtDynamicTable = -8;
  27. vmtClassName = -4;
  28. vmtInstanceSize = 0;
  29. vmtParent = 8;
  30. vmtDestroy = 12;
  31. vmtNewInstance = 16;
  32. vmtFreeInstance = 20;
  33. vmtSafeCallException = 24;
  34. vmtDefaultHandler = 28;
  35. vmtAfterConstruction = 32;
  36. vmtBeforeDestruction = 36;
  37. type
  38. { first, in object pascal, the types must be redefined }
  39. smallint = system.integer;
  40. integer = system.longint;
  41. { some pointer definitions }
  42. pshortstring = ^shortstring;
  43. plongstring = ^longstring;
  44. pansistring = ^ansistring;
  45. pwidestring = ^widestring;
  46. // pstring = pansistring;
  47. pextended = ^extended;
  48. ppointer = ^pointer;
  49. { now the let's declare the base classes for the class object }
  50. { model }
  51. tobject = class;
  52. tclass = class of tobject;
  53. pclass = ^tclass;
  54. tobject = class
  55. { please don't change the order of virtual methods, because }
  56. { their vmt offsets are used by some assembler code which uses }
  57. { hard coded addresses (FK) }
  58. constructor create;
  59. { the virtual procedures must be in THAT order }
  60. destructor destroy;virtual;
  61. class function newinstance : tobject;virtual;
  62. procedure freeinstance;virtual;
  63. function safecallexception(exceptobject : tobject;
  64. exceptaddr : pointer) : integer;virtual;
  65. procedure defaulthandler(var message);virtual;
  66. procedure free;
  67. class function initinstance(instance : pointer) : tobject;
  68. procedure cleanupinstance;
  69. function classtype : tclass;
  70. class function classinfo : pointer;
  71. class function classname : shortstring;
  72. class function classnameis(const name : string) : boolean;
  73. class function classparent : tclass;
  74. class function instancesize : longint;
  75. class function inheritsfrom(aclass : tclass) : boolean;
  76. { message handling routines }
  77. procedure dispatch(var message);
  78. class function methodaddress(const name : shortstring) : pointer;
  79. class function methodname(address : pointer) : shortstring;
  80. function fieldaddress(const name : shortstring) : pointer;
  81. { new since Delphi 4 }
  82. procedure AfterConstruction;virtual;
  83. procedure BeforeDestruction;virtual;
  84. { interface functions, I don't know if we need this }
  85. {
  86. function getinterface(const iid : tguid;out obj) : boolean;
  87. class function getinterfaceentry(const iid : tguid) : pinterfaceentry;
  88. class function getinterfacetable : pinterfacetable;
  89. }
  90. end;
  91. TExceptProc = Procedure (Obj : TObject; Addr: Pointer);
  92. var
  93. abstracterrorproc : pointer;
  94. Const
  95. ExceptProc : Pointer {TExceptProc} = Nil;
  96. {*****************************************************************************
  97. Variant Type
  98. *****************************************************************************}
  99. Const
  100. varEmpty = $0000;
  101. varNull = $0001;
  102. varSmallint = $0002;
  103. varInteger = $0003;
  104. varSingle = $0004;
  105. varDouble = $0005;
  106. varCurrency = $0006;
  107. varDate = $0007;
  108. varOleStr = $0008;
  109. varDispatch = $0009;
  110. varError = $000A;
  111. varBoolean = $000B;
  112. varVariant = $000C;
  113. varUnknown = $000D;
  114. varByte = $0011;
  115. varString = $0100;
  116. varAny = $0101;
  117. varTypeMask = $0FFF;
  118. varArray = $2000;
  119. varByRef = $4000;
  120. vtInteger = 0;
  121. vtBoolean = 1;
  122. vtChar = 2;
  123. vtExtended = 3;
  124. vtString = 4;
  125. vtPointer = 5;
  126. vtPChar = 6;
  127. vtObject = 7;
  128. vtClass = 8;
  129. vtWideChar = 9;
  130. vtPWideChar = 10;
  131. vtAnsiString = 11;
  132. vtCurrency = 12;
  133. vtVariant = 13;
  134. vtInterface = 14;
  135. vtWideString = 15;
  136. vtInt64 = 16;
  137. Type
  138. PVarRec = ^TVarRec;
  139. TVarRec = record
  140. case VType : Longint of
  141. vtInteger : (VInteger: Integer);
  142. vtBoolean : (VBoolean: Boolean);
  143. vtChar : (VChar: Char);
  144. vtExtended : (VExtended: PExtended);
  145. vtString : (VString: PShortString);
  146. vtPointer : (VPointer: Pointer);
  147. vtPChar : (VPChar: PChar);
  148. vtObject : (VObject: TObject);
  149. vtClass : (VClass: TClass);
  150. // vtWideChar : (VWideChar: WideChar);
  151. // vtPWideChar : (VPWideChar: PWideChar);
  152. vtAnsiString : (VAnsiString: Pointer);
  153. // vtCurrency : (VCurrency: PCurrency);
  154. // vtVariant : (VVariant: PVariant);
  155. // vtInterface : (VInterface: Pointer);
  156. vtWideString : (VWideString: Pointer);
  157. // vtInt64 : (VInt64: PInt64);
  158. end;
  159. implementation
  160. {****************************************************************************
  161. Internal Routines called from the Compiler
  162. ****************************************************************************}
  163. procedure finalize(data,typeinfo : pointer);external name 'FPC_FINALIZE';
  164. { the reverse order of the parameters make code generation easier }
  165. function int_do_is(aclass : tclass;aobject : tobject) : boolean;[public,alias: 'FPC_DO_IS'];
  166. begin
  167. int_do_is:=aobject.inheritsfrom(aclass);
  168. end;
  169. { the reverse order of the parameters make code generation easier }
  170. procedure int_do_as(aclass : tclass;aobject : tobject);[public,alias: 'FPC_DO_AS'];
  171. begin
  172. if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
  173. runerror(219);
  174. end;
  175. procedure abstracterror;
  176. type
  177. proc = procedure;
  178. begin
  179. if assigned(abstracterrorproc) then
  180. proc(abstracterrorproc)()
  181. else
  182. runerror(211);
  183. end;
  184. {****************************************************************************
  185. TOBJECT
  186. ****************************************************************************}
  187. constructor TObject.Create;
  188. begin
  189. end;
  190. destructor TObject.Destroy;
  191. begin
  192. end;
  193. procedure TObject.Free;
  194. begin
  195. // the call via self avoids a warning
  196. if self<>nil then
  197. self.destroy;
  198. end;
  199. class function TObject.InstanceSize : LongInt;
  200. type
  201. plongint = ^longint;
  202. begin
  203. { type of self is class of tobject => it points to the vmt }
  204. { the size is saved at offset 0 }
  205. InstanceSize:=plongint(self)^;
  206. end;
  207. class function TObject.InitInstance(instance : pointer) : tobject;
  208. begin
  209. fillchar(instance^,self.instancesize,0);
  210. { insert VMT pointer into the new created memory area }
  211. { (in class methods self contains the VMT!) }
  212. ppointer(instance)^:=pointer(self);
  213. InitInstance:=TObject(Instance);
  214. end;
  215. class function TObject.ClassParent : tclass;
  216. begin
  217. { type of self is class of tobject => it points to the vmt }
  218. { the parent vmt is saved at offset vmtParent }
  219. classparent:=(pclass(self)+vmtParent)^;
  220. end;
  221. class function TObject.NewInstance : tobject;
  222. var
  223. p : pointer;
  224. begin
  225. getmem(p,instancesize);
  226. InitInstance(p);
  227. NewInstance:=TObject(p);
  228. end;
  229. procedure TObject.FreeInstance;
  230. var
  231. p : Pointer;
  232. begin
  233. CleanupInstance;
  234. { self is a register, so we can't pass it call by reference }
  235. p:=Pointer(Self);
  236. FreeMem(p,InstanceSize);
  237. end;
  238. function TObject.ClassType : TClass;
  239. begin
  240. ClassType:=TClass(Pointer(Self)^)
  241. end;
  242. class function TObject.MethodAddress(const name : shortstring) : pointer;
  243. begin
  244. methodaddress:=nil;
  245. end;
  246. class function TObject.MethodName(address : pointer) : shortstring;
  247. begin
  248. methodname:='';
  249. end;
  250. function TObject.FieldAddress(const name : shortstring) : pointer;
  251. begin
  252. fieldaddress:=nil;
  253. end;
  254. function TObject.SafeCallException(exceptobject : tobject;
  255. exceptaddr : pointer) : integer;
  256. begin
  257. safecallexception:=0;
  258. end;
  259. class function TObject.ClassInfo : pointer;
  260. begin
  261. ClassInfo:=(PPointer(self)+vmtTypeInfo)^;
  262. end;
  263. class function TObject.ClassName : ShortString;
  264. begin
  265. ClassName:=PShortString((PPointer(Self)+vmtClassName)^)^;
  266. end;
  267. class function TObject.ClassNameIs(const name : string) : boolean;
  268. begin
  269. ClassNameIs:=ClassName=name;
  270. end;
  271. class function TObject.InheritsFrom(aclass : TClass) : Boolean;
  272. var
  273. c : tclass;
  274. begin
  275. c:=self;
  276. while assigned(c) do
  277. begin
  278. if c=aclass then
  279. begin
  280. InheritsFrom:=true;
  281. exit;
  282. end;
  283. c:=c.ClassParent;
  284. end;
  285. InheritsFrom:=false;
  286. end;
  287. procedure TObject.Dispatch(var message);
  288. begin
  289. end;
  290. procedure TObject.DefaultHandler(var message);
  291. begin
  292. end;
  293. procedure TObject.CleanupInstance;
  294. var
  295. vmt : tclass;
  296. begin
  297. vmt:=ClassType;
  298. while vmt<>nil do
  299. begin
  300. if Assigned(Pointer((Pointer(vmt)+vmtInitTable)^)) then
  301. Finalize(Pointer(Self),Pointer((Pointer(vmt)+vmtInitTable)^));
  302. vmt:=vmt.ClassParent;
  303. end;
  304. end;
  305. procedure TObject.AfterConstruction;
  306. begin
  307. end;
  308. procedure TObject.BeforeDestruction;
  309. begin
  310. end;
  311. {****************************************************************************
  312. Exception Support
  313. ****************************************************************************}
  314. {$i except.inc}
  315. {****************************************************************************
  316. Initialize
  317. ****************************************************************************}
  318. begin
  319. InitExceptions;
  320. AbstractErrorHandler:=@AbstractError;
  321. end.
  322. {
  323. $Log$
  324. Revision 1.16 1998-10-03 15:07:16 florian
  325. + TObject.AfterConstruction and TObject.BeforeDestruction of Delphi 4
  326. Revision 1.15 1998/09/24 16:13:48 michael
  327. Changes in exception and open array handling
  328. Revision 1.14 1998/09/23 12:40:43 michael
  329. Fixed TVarRec again. Should be OK now
  330. Revision 1.13 1998/09/23 12:18:32 michael
  331. + added VType in TVArRec
  332. Revision 1.12 1998/09/23 10:00:47 peter
  333. * tvarrec should be 8 bytes
  334. Revision 1.11 1998/09/22 15:30:07 peter
  335. * array of const update
  336. Revision 1.9 1998/09/16 13:08:19 michael
  337. Added AbstractErrorHandler
  338. Revision 1.8 1998/09/06 21:27:31 florian
  339. + method tobject.classinfo added
  340. Revision 1.7 1998/09/04 08:49:06 peter
  341. * 0.99.5 doesn't compile a whole objpas anymore to overcome crashes
  342. Revision 1.6 1998/08/23 20:58:52 florian
  343. + rtti for objects and classes
  344. + TObject.GetClassName implemented
  345. Revision 1.5 1998/07/30 16:10:11 michael
  346. + Added support for ExceptProc+
  347. Revision 1.4 1998/07/29 15:44:33 michael
  348. included sysutils and math.pp as target. They compile now.
  349. Revision 1.3 1998/07/29 10:09:28 michael
  350. + put in exception support
  351. Revision 1.2 1998/03/25 23:40:24 florian
  352. + stuff from old objpash.inc and objpas.inc merged in
  353. }