objpas.pp 9.0 KB

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