objpas.inc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998,99 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 int_do_is(aclass : tclass;aobject : tobject) : boolean;[public,alias: 'FPC_DO_IS'];
  17. begin
  18. int_do_is:=aobject.inheritsfrom(aclass);
  19. end;
  20. { the reverse order of the parameters make code generation easier }
  21. procedure int_do_as(aclass : tclass;aobject : tobject);[public,alias: 'FPC_DO_AS'];
  22. begin
  23. if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
  24. handleerror(219);
  25. end;
  26. {****************************************************************************
  27. TOBJECT
  28. ****************************************************************************}
  29. constructor TObject.Create;
  30. begin
  31. end;
  32. destructor TObject.Destroy;
  33. begin
  34. end;
  35. procedure TObject.Free;
  36. begin
  37. // the call via self avoids a warning
  38. if self<>nil then
  39. self.destroy;
  40. end;
  41. class function TObject.InstanceSize : LongInt;
  42. type
  43. plongint = ^longint;
  44. begin
  45. { type of self is class of tobject => it points to the vmt }
  46. { the size is saved at offset 0 }
  47. InstanceSize:=plongint(self)^;
  48. end;
  49. class function TObject.InitInstance(instance : pointer) : tobject;
  50. begin
  51. fillchar(instance^,self.instancesize,0);
  52. { insert VMT pointer into the new created memory area }
  53. { (in class methods self contains the VMT!) }
  54. ppointer(instance)^:=pointer(self);
  55. InitInstance:=TObject(Instance);
  56. end;
  57. class function TObject.ClassParent : tclass;
  58. begin
  59. { type of self is class of tobject => it points to the vmt }
  60. { the parent vmt is saved at offset vmtParent }
  61. classparent:=(pclass(self)+vmtParent)^;
  62. end;
  63. class function TObject.NewInstance : tobject;
  64. var
  65. p : pointer;
  66. begin
  67. getmem(p,instancesize);
  68. InitInstance(p);
  69. NewInstance:=TObject(p);
  70. end;
  71. procedure TObject.FreeInstance;
  72. var
  73. p : Pointer;
  74. begin
  75. CleanupInstance;
  76. { self is a register, so we can't pass it call by reference }
  77. p:=Pointer(Self);
  78. FreeMem(p,InstanceSize);
  79. end;
  80. function TObject.ClassType : TClass;
  81. begin
  82. ClassType:=TClass(Pointer(Self)^)
  83. end;
  84. class function TObject.MethodAddress(const name : shortstring) : pointer;
  85. begin
  86. methodaddress:=nil;
  87. end;
  88. class function TObject.MethodName(address : pointer) : shortstring;
  89. begin
  90. methodname:='';
  91. end;
  92. function TObject.FieldAddress(const name : shortstring) : pointer;
  93. begin
  94. fieldaddress:=nil;
  95. end;
  96. function TObject.SafeCallException(exceptobject : tobject;
  97. exceptaddr : pointer) : longint;
  98. begin
  99. safecallexception:=0;
  100. end;
  101. class function TObject.ClassInfo : pointer;
  102. begin
  103. ClassInfo:=(PPointer(self)+vmtTypeInfo)^;
  104. end;
  105. class function TObject.ClassName : ShortString;
  106. begin
  107. ClassName:=PShortString((PPointer(Self)+vmtClassName)^)^;
  108. end;
  109. class function TObject.ClassNameIs(const name : string) : boolean;
  110. begin
  111. ClassNameIs:=ClassName=name;
  112. end;
  113. class function TObject.InheritsFrom(aclass : TClass) : Boolean;
  114. var
  115. c : tclass;
  116. begin
  117. c:=self;
  118. while assigned(c) do
  119. begin
  120. if c=aclass then
  121. begin
  122. InheritsFrom:=true;
  123. exit;
  124. end;
  125. c:=c.ClassParent;
  126. end;
  127. InheritsFrom:=false;
  128. end;
  129. class function TObject.stringmessagetable : pstringmessagetable;
  130. type
  131. pdword = ^dword;
  132. begin
  133. stringmessagetable:=pstringmessagetable((pdword(Self)+vmtMsgStrPtr)^);
  134. end;
  135. procedure TObject.Dispatch(var message);
  136. type
  137. tmsgtable = record
  138. index : dword;
  139. method : pointer;
  140. end;
  141. pmsgtable = ^tmsgtable;
  142. pdword = ^dword;
  143. var
  144. index : dword;
  145. count,i : longint;
  146. msgtable : pmsgtable;
  147. p : pointer;
  148. vmt : tclass;
  149. begin
  150. index:=dword(message);
  151. vmt:=ClassType;
  152. while assigned(vmt) do
  153. begin
  154. // See if we have messages at all in this class.
  155. p:=pdword(vmt)+vmtDynamicTable;
  156. If Assigned(p) and (Pdword(p)^<>0) then
  157. begin
  158. msgtable:=pmsgtable(pdword(P)^+4);
  159. count:=pdword(pdword(P)^)^;
  160. end
  161. else
  162. Count:=0;
  163. { later, we can implement a binary search here }
  164. for i:=0 to count-1 do
  165. begin
  166. if index=msgtable[i].index then
  167. begin
  168. p:=msgtable[i].method;
  169. asm
  170. pushl message
  171. pushl %esi
  172. movl p,%edi
  173. {$ifdef ver0_99_10}
  174. call %edi
  175. {$else ver0_99_10}
  176. call *%edi
  177. {$endif ver0_99_10}
  178. end;
  179. exit;
  180. end;
  181. end;
  182. vmt:=vmt.ClassParent;
  183. end;
  184. DefaultHandler(message);
  185. end;
  186. procedure TObject.DispatchStr(const message:shortstring);
  187. type
  188. pdword = ^dword;
  189. var
  190. name : shortstring;
  191. count,i : longint;
  192. msgstrtable : pmsgstrtable;
  193. p : pointer;
  194. vmt : tclass;
  195. begin
  196. name:=message;
  197. vmt:=ClassType;
  198. while assigned(vmt) do
  199. begin
  200. p:=(pdword(vmt)+vmtMsgStrPtr);
  201. If (P<>Nil) and (PDWord(P)^<>0) then
  202. begin
  203. count:=pdword(pdword(p)^)^;
  204. msgstrtable:=pmsgstrtable(pdword(P)^+4);
  205. end
  206. else
  207. Count:=0;
  208. { later, we can implement a binary search here }
  209. for i:=0 to count-1 do
  210. begin
  211. if name=msgstrtable[i].name^ then
  212. begin
  213. p:=msgstrtable[i].method;
  214. asm
  215. pushl message
  216. pushl %esi
  217. movl p,%edi
  218. {$ifdef ver0_99_10}
  219. call %edi
  220. {$else ver0_99_10}
  221. call *%edi
  222. {$endif ver0_99_10}
  223. end;
  224. exit;
  225. end;
  226. end;
  227. vmt:=vmt.ClassParent;
  228. end;
  229. DefaultHandlerStr(message);
  230. end;
  231. procedure TObject.DefaultHandler(var message);
  232. begin
  233. end;
  234. procedure TObject.DefaultHandlerStr(var message);
  235. begin
  236. end;
  237. procedure TObject.CleanupInstance;
  238. var
  239. vmt : tclass;
  240. begin
  241. vmt:=ClassType;
  242. while vmt<>nil do
  243. begin
  244. if Assigned(Pointer((Pointer(vmt)+vmtInitTable)^)) then
  245. Finalize(Pointer(Self),Pointer((Pointer(vmt)+vmtInitTable)^));
  246. vmt:=vmt.ClassParent;
  247. end;
  248. end;
  249. procedure TObject.AfterConstruction;
  250. begin
  251. end;
  252. procedure TObject.BeforeDestruction;
  253. begin
  254. end;
  255. {****************************************************************************
  256. Exception Support
  257. ****************************************************************************}
  258. {$i except.inc}
  259. {****************************************************************************
  260. Initialize
  261. ****************************************************************************}
  262. {
  263. $Log$
  264. Revision 1.4.2.2 1999-07-11 20:04:51 peter
  265. * dispatch patch from main branch
  266. Revision 1.4.2.1 1999/07/10 10:09:59 peter
  267. * fixed dispatchstr()
  268. Revision 1.4 1999/05/19 13:20:09 peter
  269. * fixed dispatchstr
  270. Revision 1.3 1999/05/17 21:52:37 florian
  271. * most of the Object Pascal stuff moved to the system unit
  272. }