callspec.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. {
  2. $Id$
  3. This unit provides compiler-independent mechanisms to call special
  4. functions, i.e. local functions/procedures, constructors, methods,
  5. destructors, etc. As there are no procedural variables for these
  6. special functions, there is no Pascal way to call them directly.
  7. Copyright (c) 1997 Matthias K"oppe <[email protected]>
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Library General Public
  10. License as published by the Free Software Foundation; either
  11. version 2 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Library General Public License for more details.
  16. You should have received a copy of the GNU Library General Public
  17. License along with this library; if not, write to the Free
  18. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ****************************************************************************}
  20. unit CallSpec;
  21. {
  22. As of this version, the following compilers are supported. Please
  23. port CallSpec to other compilers (including earlier versions) and
  24. send your code to the above address.
  25. Compiler Comments
  26. --------------------------- -------------------------------------
  27. Turbo Pascal 6.0
  28. Borland/Turbo Pascal 7.0
  29. FPC Pascal 0.99.8
  30. }
  31. interface
  32. {$i platform.inc}
  33. {
  34. The frame pointer points to the local variables of a procedure.
  35. Use CurrentFramePointer to address the locals of the current procedure;
  36. use PreviousFramePointer to addess the locals of the calling procedure.
  37. }
  38. type
  39. {$ifdef BIT_16}
  40. FramePointer = Word;
  41. {$endif}
  42. {$ifdef BIT_32}
  43. FramePointer = pointer;
  44. {$endif}
  45. function CurrentFramePointer: FramePointer;
  46. function PreviousFramePointer: FramePointer;
  47. { This version of CallSpec supports four classes of special functions.
  48. (Please write if you need other classes.)
  49. For each, two types of argument lists are allowed:
  50. `Void' indicates special functions with no explicit arguments.
  51. Sample: constructor T.Init;
  52. `Pointer' indicates special functions with one explicit pointer argument.
  53. Sample: constructor T.Load(var S: TStream);
  54. }
  55. { Constructor calls.
  56. Ctor Pointer to the constructor.
  57. Obj Pointer to the instance. NIL if new instance to be allocated.
  58. VMT Pointer to the VMT (obtained by TypeOf()).
  59. returns Pointer to the instance.
  60. }
  61. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  62. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  63. { Method calls.
  64. Method Pointer to the method.
  65. Obj Pointer to the instance. NIL if new instance to be allocated.
  66. returns Pointer to the instance.
  67. }
  68. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  69. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  70. { Local-function/procedure calls.
  71. Func Pointer to the local function (which must be far-coded).
  72. Frame Frame pointer of the wrapping function.
  73. }
  74. function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer;
  75. function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer;
  76. { Calls of functions/procedures local to methods.
  77. Func Pointer to the local function (which must be far-coded).
  78. Frame Frame pointer of the wrapping method.
  79. Obj Pointer to the object that the method belongs to.
  80. }
  81. function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer;
  82. function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer;
  83. implementation
  84. {$ifdef PPC_FPC}
  85. {$ifdef CPUI386}
  86. {$ASMMODE ATT}
  87. {$endif CPUI386}
  88. { This indicates an FPC version which uses the same call scheme for
  89. method-local and procedure-local procedures, but which expects the
  90. ESI register be loaded with the Self pointer in method-local procs. }
  91. type
  92. VoidLocal = function(_EBP: FramePointer): pointer;
  93. PointerLocal = function(_EBP: FramePointer; Param1: pointer): pointer;
  94. VoidMethodLocal = function(_EBP: FRAMEPOINTER): pointer;
  95. PointerMethodLocal = function(_EBP: FRAMEPOINTER; Param1: pointer): pointer;
  96. VoidConstructor = function(VMT: pointer; Obj: pointer): pointer;
  97. PointerConstructor = function(VMT: pointer; Obj: pointer; Param1: pointer): pointer;
  98. VoidMethod = function(Obj: pointer): pointer;
  99. PointerMethod = function(Obj: pointer; Param1: pointer): pointer;
  100. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  101. begin
  102. {$ifdef VER1_0}
  103. { load the object pointer }
  104. {$ifdef CPUI386}
  105. asm
  106. movl Obj, %esi
  107. end;
  108. {$endif CPUI386}
  109. {$ifdef CPU68K}
  110. asm
  111. move.l Obj, a5
  112. end;
  113. {$endif CPU68K}
  114. {$endif VER1_0}
  115. CallVoidConstructor := VoidConstructor(Ctor)(VMT, Obj)
  116. end;
  117. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  118. begin
  119. {$ifdef VER1_0}
  120. { load the object pointer }
  121. {$ifdef CPUI386}
  122. asm
  123. movl Obj, %esi
  124. end;
  125. {$endif CPUI386}
  126. {$ifdef CPU68K}
  127. asm
  128. move.l Obj, a5
  129. end;
  130. {$endif CPU68K}
  131. {$endif VER1_0}
  132. CallPointerConstructor := PointerConstructor(Ctor)(VMT, Obj, Param1)
  133. end;
  134. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  135. begin
  136. {$ifdef VER1_0}
  137. { load the object pointer }
  138. {$ifdef CPUI386}
  139. asm
  140. movl Obj, %esi
  141. end;
  142. {$endif CPUI386}
  143. {$ifdef CPU68K}
  144. asm
  145. move.l Obj, a5
  146. end;
  147. {$endif CPU68K}
  148. {$endif VER1_0}
  149. CallVoidMethod := VoidMethod(Method)(Obj)
  150. end;
  151. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  152. begin
  153. {$ifdef VER1_0}
  154. { load the object pointer }
  155. {$ifdef CPUI386}
  156. asm
  157. movl Obj, %esi
  158. end;
  159. {$endif CPUI386}
  160. {$ifdef CPU68K}
  161. asm
  162. move.l Obj, a5
  163. end;
  164. {$endif CPU68K}
  165. {$endif VER1_0}
  166. CallPointerMethod := PointerMethod(Method)(Obj, Param1)
  167. end;
  168. function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer;
  169. begin
  170. CallVoidLocal := VoidLocal(Func)(Frame)
  171. end;
  172. function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer;
  173. begin
  174. CallPointerLocal := PointerLocal(Func)(Frame, Param1)
  175. end;
  176. function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer;
  177. begin
  178. {$ifdef VER1_0}
  179. { load the object pointer }
  180. {$ifdef CPUI386}
  181. asm
  182. movl Obj, %esi
  183. end;
  184. {$endif CPUI386}
  185. {$ifdef CPU68K}
  186. asm
  187. move.l Obj, a5
  188. end;
  189. {$endif CPU68K}
  190. {$endif VER1_0}
  191. CallVoidMethodLocal := VoidMethodLocal(Func)(Frame)
  192. end;
  193. function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer;
  194. begin
  195. {$ifdef VER1_0}
  196. { load the object pointer }
  197. {$ifdef CPUI386}
  198. asm
  199. movl Obj, %esi
  200. end;
  201. {$endif CPUI386}
  202. {$ifdef CPU68K}
  203. asm
  204. move.l Obj, a5
  205. end;
  206. {$endif CPU68K}
  207. {$endif VER1_0}
  208. CallPointerMethodLocal := PointerMethodLocal(Func)(Frame, Param1)
  209. end;
  210. function CurrentFramePointer: FramePointer;assembler;
  211. {$ifdef CPUI386}
  212. asm
  213. movl %ebp,%eax
  214. end ['EAX'];
  215. {$endif CPUI386}
  216. {$ifdef CPU68K}
  217. asm
  218. move.l a6, d0
  219. end['D0'];
  220. {$endif CPU68K}
  221. {$ifdef CPUPOWERPC}
  222. asm
  223. mr r3,r1
  224. end;
  225. {$endif CPUPOWERPC}
  226. function PreviousFramePointer: FramePointer;assembler;
  227. {$ifdef CPUI386}
  228. asm
  229. movl (%ebp),%eax
  230. end ['EAX'];
  231. {$endif CPUI386}
  232. {$ifdef CPU68K}
  233. asm
  234. move.l (a6), d0
  235. end['D0'];
  236. {$endif CPU68K}
  237. {$ifdef CPUPOWERPC}
  238. asm
  239. lwz r3,0(r1)
  240. end;
  241. {$endif CPUPOWERPC}
  242. {$endif PPC_FPC}
  243. {$ifdef PPC_BP}
  244. type
  245. VoidConstructor = function(VmtOfs: Word; Obj: pointer): pointer;
  246. PointerConstructor = function(Param1: pointer; VmtOfs: Word; Obj: pointer): pointer;
  247. VoidMethod = function(Obj: pointer): pointer;
  248. PointerMethod = function(Param1: pointer; Obj: pointer): pointer;
  249. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  250. begin
  251. CallVoidConstructor := VoidConstructor(Ctor)(Ofs(VMT^), Obj)
  252. end;
  253. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  254. begin
  255. CallPointerConstructor := PointerConstructor(Ctor)(Param1, Ofs(VMT^), Obj)
  256. end;
  257. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  258. begin
  259. CallVoidMethod := VoidMethod(Method)(Obj)
  260. end;
  261. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  262. begin
  263. CallPointerMethod := PointerMethod(Method)(Param1, Obj)
  264. end;
  265. function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer; assembler;
  266. asm
  267. {$IFDEF Windows}
  268. MOV AX,[Frame]
  269. AND AL,0FEH
  270. PUSH AX
  271. {$ELSE}
  272. push [Frame]
  273. {$ENDIF}
  274. call dword ptr Func
  275. end;
  276. function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer; assembler;
  277. asm
  278. mov ax, word ptr Param1
  279. mov dx, word ptr Param1+2
  280. push dx
  281. push ax
  282. {$IFDEF Windows}
  283. MOV AX,[Frame]
  284. AND AL,0FEH
  285. PUSH AX
  286. {$ELSE}
  287. push [Frame]
  288. {$ENDIF}
  289. call dword ptr Func
  290. end;
  291. function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer; assembler;
  292. asm
  293. {$IFDEF Windows}
  294. MOV AX,[Frame]
  295. AND AL,0FEH
  296. PUSH AX
  297. {$ELSE}
  298. push [Frame]
  299. {$ENDIF}
  300. call dword ptr Func
  301. end;
  302. function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer; assembler;
  303. asm
  304. mov ax, word ptr Param1
  305. mov dx, word ptr Param1+2
  306. push dx
  307. push ax
  308. {$IFDEF Windows}
  309. MOV AX,[Frame]
  310. AND AL,0FEH
  311. PUSH AX
  312. {$ELSE}
  313. push [Frame]
  314. {$ENDIF}
  315. call dword ptr Func
  316. end;
  317. function CurrentFramePointer: FramePointer; assembler;
  318. asm
  319. mov ax, bp
  320. end;
  321. function PreviousFramePointer: FramePointer; assembler;
  322. asm
  323. mov ax, ss:[bp]
  324. end;
  325. {$endif PPC_BP}
  326. end.
  327. {
  328. $Log$
  329. Revision 1.4 2004-02-06 20:56:38 jonas
  330. + powerpc support
  331. Revision 1.3 2004/02/06 20:08:58 jonas
  332. * version from FV
  333. Revision 1.4 2003/11/12 15:49:59 peter
  334. * fix crash with 1.9
  335. Revision 1.3 2001/07/30 08:27:58 pierre
  336. * fix I386 compilation problem
  337. Revision 1.2 2001/07/29 20:23:18 pierre
  338. * support for m68k cpu
  339. Revision 1.1 2001/01/29 21:56:04 peter
  340. * updates for new fpcmake
  341. Revision 1.1 2001/01/29 11:31:26 marco
  342. * added from API. callspec renamed to .pp
  343. Revision 1.1 2000/07/13 06:29:38 michael
  344. + Initial import
  345. Revision 1.1 2000/01/06 01:20:30 peter
  346. * moved out of packages/ back to topdir
  347. Revision 1.1 1999/12/23 19:36:47 peter
  348. * place unitfiles in target dirs
  349. Revision 1.1 1999/11/24 23:36:37 peter
  350. * moved to packages dir
  351. Revision 1.2 1998/12/16 21:57:16 peter
  352. * fixed currentframe,previousframe
  353. + testcall to test the callspec unit
  354. Revision 1.1 1998/12/04 12:48:24 peter
  355. * moved some dirs
  356. Revision 1.5 1998/12/04 09:53:44 peter
  357. * removed objtemp global var
  358. Revision 1.4 1998/11/24 17:14:24 peter
  359. * fixed esi loading
  360. Date Version Who Comments
  361. ---------- -------- ------- -------------------------------------
  362. 19-Sep-97 0.1 mkoeppe Initial version.
  363. 22-Sep-97 0.11 fk 0.9.3 support added, self isn't expected
  364. on the stack in local procedures of methods
  365. 23-Sep-97 0.12 mkoeppe Cleaned up 0.9.3 conditionals.
  366. 03-Oct-97 0.13 mkoeppe Fixed esi load in FPC 0.9
  367. 22-Oct-98 0.14 pfv 0.99.8 support for FPC
  368. }