objpas.pp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1997,98 by Florian Klaempfl
  5. member of the Free Pascal development team
  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. { this unit makes Free Pascal as much as possible Delphi compatible }
  13. unit objpas;
  14. {$ifdef VER0_99_5}
  15. {$warning objpas can't be compiled with FPC 0.99.5}
  16. interface
  17. implementation
  18. end.
  19. {$else}
  20. interface
  21. const
  22. // vmtSelfPtr = -36; { not implemented yet }
  23. vmtIntfTable = -32;
  24. vmtAutoTable = -28;
  25. vmtInitTable = -24;
  26. vmtTypeInfo = -20;
  27. vmtFieldTable = -16;
  28. vmtMethodTable = -12;
  29. vmtDynamicTable = -8;
  30. vmtClassName = -4;
  31. vmtInstanceSize = 0;
  32. vmtParent = 8;
  33. vmtDestroy = 12;
  34. vmtNewInstance = 16;
  35. vmtFreeInstance = 20;
  36. vmtSafeCallException = 24;
  37. vmtDefaultHandler = 28;
  38. type
  39. { first, in object pascal, the types must be redefined }
  40. smallint = system.integer;
  41. integer = system.longint;
  42. { define some more types }
  43. shortstring = string;
  44. { some pointer definitions }
  45. pshortstring = ^shortstring;
  46. plongstring = ^longstring;
  47. pansistring = ^ansistring;
  48. pwidestring = ^widestring;
  49. // pstring = pansistring;
  50. pextended = ^extended;
  51. ppointer = ^pointer;
  52. { now the let's declare the base classes for the class object }
  53. { model }
  54. tobject = class;
  55. tclass = class of tobject;
  56. pclass = ^tclass;
  57. tobject = class
  58. { please don't change the order of virtual methods, because }
  59. { their vmt offsets are used by some assembler code which uses }
  60. { hard coded addresses (FK) }
  61. constructor create;
  62. { the virtual procedures must be in THAT order }
  63. destructor destroy;virtual;
  64. class function newinstance : tobject;virtual;
  65. procedure freeinstance;virtual;
  66. function safecallexception(exceptobject : tobject;
  67. exceptaddr : pointer) : integer;virtual;
  68. procedure defaulthandler(var message);virtual;
  69. procedure free;
  70. class function initinstance(instance : pointer) : tobject;
  71. procedure cleanupinstance;
  72. function classtype : tclass;
  73. class function classinfo : pointer;
  74. class function classname : shortstring;
  75. class function classnameis(const name : string) : boolean;
  76. class function classparent : tclass;
  77. class function instancesize : longint;
  78. class function inheritsfrom(aclass : tclass) : boolean;
  79. { message handling routines }
  80. procedure dispatch(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. { 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. implementation
  97. procedure finalize(data,typeinfo : pointer);external name 'FINALIZE';
  98. { the reverse order of the parameters make code generation easier }
  99. function _is(aclass : tclass;aobject : tobject) : boolean;[public,alias: 'DO_IS'];
  100. begin
  101. _is:=aobject.inheritsfrom(aclass);
  102. end;
  103. { the reverse order of the parameters make code generation easier }
  104. procedure _as(aclass : tclass;aobject : tobject);[public,alias: 'DO_AS'];
  105. begin
  106. if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
  107. runerror(219);
  108. end;
  109. procedure abstracterror;[public,alias: 'ABSTRACTERROR'];
  110. type
  111. proc = procedure;
  112. begin
  113. if assigned(abstracterrorproc) then
  114. proc(abstracterrorproc)()
  115. else
  116. runerror(210);
  117. end;
  118. {************************************************************************}
  119. { TOBJECT }
  120. {************************************************************************}
  121. constructor TObject.Create;
  122. begin
  123. end;
  124. destructor TObject.Destroy;
  125. begin
  126. end;
  127. procedure TObject.Free;
  128. begin
  129. // the call via self avoids a warning
  130. if self<>nil then
  131. self.destroy;
  132. end;
  133. class function TObject.InstanceSize : LongInt;
  134. type
  135. plongint = ^longint;
  136. begin
  137. { type of self is class of tobject => it points to the vmt }
  138. { the size is saved at offset 0 }
  139. InstanceSize:=plongint(self)^;
  140. end;
  141. class function TObject.InitInstance(instance : pointer) : tobject;
  142. begin
  143. fillchar(instance^,self.instancesize,0);
  144. { insert VMT pointer into the new created memory area }
  145. { (in class methods self contains the VMT!) }
  146. ppointer(instance)^:=pointer(self);
  147. InitInstance:=TObject(Instance);
  148. end;
  149. class function TObject.ClassParent : tclass;
  150. begin
  151. { type of self is class of tobject => it points to the vmt }
  152. { the parent vmt is saved at offset vmtParent }
  153. classparent:=(pclass(self)+vmtParent)^;
  154. end;
  155. class function TObject.NewInstance : tobject;
  156. var
  157. p : pointer;
  158. begin
  159. getmem(p,instancesize);
  160. InitInstance(p);
  161. NewInstance:=TObject(p);
  162. end;
  163. procedure TObject.FreeInstance;
  164. var
  165. p : Pointer;
  166. begin
  167. CleanupInstance;
  168. { self is a register, so we can't pass it call by reference }
  169. p:=Pointer(Self);
  170. FreeMem(p,InstanceSize);
  171. end;
  172. function TObject.ClassType : TClass;
  173. begin
  174. ClassType:=TClass(Pointer(Self)^)
  175. end;
  176. class function TObject.MethodAddress(const name : shortstring) : pointer;
  177. begin
  178. methodaddress:=nil;
  179. end;
  180. class function TObject.MethodName(address : pointer) : shortstring;
  181. begin
  182. methodname:='';
  183. end;
  184. function TObject.FieldAddress(const name : shortstring) : pointer;
  185. begin
  186. fieldaddress:=nil;
  187. end;
  188. function TObject.safecallexception(exceptobject : tobject;
  189. exceptaddr : pointer) : integer;
  190. begin
  191. safecallexception:=0;
  192. end;
  193. class function TObject.ClassInfo : pointer;
  194. begin
  195. ClassInfo:=(PPointer(self)+vmtTypeInfo)^;
  196. end;
  197. class function TObject.ClassName : ShortString;
  198. begin
  199. ClassName:=PShortString((PPointer(Self)+vmtClassName)^)^;
  200. end;
  201. class function TObject.ClassNameIs(const name : string) : boolean;
  202. begin
  203. ClassNameIs:=ClassName=name;
  204. end;
  205. class function TObject.InheritsFrom(aclass : TClass) : Boolean;
  206. var
  207. c : tclass;
  208. begin
  209. c:=self;
  210. while assigned(c) do
  211. begin
  212. if c=aclass then
  213. begin
  214. InheritsFrom:=true;
  215. exit;
  216. end;
  217. c:=c.ClassParent;
  218. end;
  219. InheritsFrom:=false;
  220. end;
  221. procedure TObject.Dispatch(var message);
  222. begin
  223. end;
  224. procedure TObject.DefaultHandler(var message);
  225. begin
  226. end;
  227. procedure TObject.CleanupInstance;
  228. var
  229. vmt : tclass;
  230. begin
  231. vmt:=ClassType;
  232. while vmt<>nil do
  233. begin
  234. if Assigned(Pointer((Pointer(vmt)+vmtInitTable)^)) then
  235. Finalize(Pointer(Self),Pointer((Pointer(vmt)+vmtInitTable)^));
  236. vmt:=vmt.ClassParent;
  237. end;
  238. end;
  239. {$i except.inc}
  240. begin
  241. InitExceptions
  242. end.
  243. {$endif VER0_99_5}
  244. {
  245. $Log$
  246. Revision 1.8 1998-09-06 21:27:31 florian
  247. + method tobject.classinfo added
  248. Revision 1.7 1998/09/04 08:49:06 peter
  249. * 0.99.5 doesn't compile a whole objpas anymore to overcome crashes
  250. Revision 1.6 1998/08/23 20:58:52 florian
  251. + rtti for objects and classes
  252. + TObject.GetClassName implemented
  253. Revision 1.5 1998/07/30 16:10:11 michael
  254. + Added support for ExceptProc+
  255. Revision 1.4 1998/07/29 15:44:33 michael
  256. included sysutils and math.pp as target. They compile now.
  257. Revision 1.3 1998/07/29 10:09:28 michael
  258. + put in exception support
  259. Revision 1.2 1998/03/25 23:40:24 florian
  260. + stuff from old objpash.inc and objpas.inc merged in
  261. }