callspec.pas 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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. {$ASMMODE ATT}
  86. { This indicates an FPC version which uses the same call scheme for
  87. method-local and procedure-local procedures, but which expects the
  88. ESI register be loaded with the Self pointer in method-local procs. }
  89. type
  90. VoidLocal = function(_EBP: FramePointer): pointer;
  91. PointerLocal = function(_EBP: FramePointer; Param1: pointer): pointer;
  92. VoidMethodLocal = function(_EBP: FRAMEPOINTER): pointer;
  93. PointerMethodLocal = function(_EBP: FRAMEPOINTER; Param1: pointer): pointer;
  94. VoidConstructor = function(VMT: pointer; Obj: pointer): pointer;
  95. PointerConstructor = function(VMT: pointer; Obj: pointer; Param1: pointer): pointer;
  96. VoidMethod = function(Obj: pointer): pointer;
  97. PointerMethod = function(Obj: pointer; Param1: pointer): pointer;
  98. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  99. begin
  100. { load the object pointer }
  101. asm
  102. movl Obj, %esi
  103. end;
  104. CallVoidConstructor := VoidConstructor(Ctor)(VMT, Obj)
  105. end;
  106. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  107. begin
  108. { load the object pointer }
  109. asm
  110. movl Obj, %esi
  111. end;
  112. CallPointerConstructor := PointerConstructor(Ctor)(VMT, Obj, Param1)
  113. end;
  114. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  115. begin
  116. { load the object pointer }
  117. asm
  118. movl Obj, %esi
  119. end;
  120. CallVoidMethod := VoidMethod(Method)(Obj)
  121. end;
  122. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  123. begin
  124. { load the object pointer }
  125. asm
  126. movl Obj, %esi
  127. end;
  128. CallPointerMethod := PointerMethod(Method)(Obj, Param1)
  129. end;
  130. function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer;
  131. begin
  132. CallVoidLocal := VoidLocal(Func)(Frame)
  133. end;
  134. function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer;
  135. begin
  136. CallPointerLocal := PointerLocal(Func)(Frame, Param1)
  137. end;
  138. function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer;
  139. begin
  140. { load the object pointer }
  141. asm
  142. movl Obj, %esi
  143. end;
  144. CallVoidMethodLocal := VoidMethodLocal(Func)(Frame)
  145. end;
  146. function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer;
  147. begin
  148. { load the object pointer }
  149. asm
  150. movl Obj, %esi
  151. end;
  152. CallPointerMethodLocal := PointerMethodLocal(Func)(Frame, Param1)
  153. end;
  154. function CurrentFramePointer: FramePointer;assembler;
  155. asm
  156. movl %ebp,%eax
  157. end ['EAX'];
  158. function PreviousFramePointer: FramePointer;assembler;
  159. asm
  160. movl (%ebp), %eax
  161. end ['EAX'];
  162. {$endif PPC_FPC}
  163. {$ifdef PPC_BP}
  164. type
  165. VoidConstructor = function(VmtOfs: Word; Obj: pointer): pointer;
  166. PointerConstructor = function(Param1: pointer; VmtOfs: Word; Obj: pointer): pointer;
  167. VoidMethod = function(Obj: pointer): pointer;
  168. PointerMethod = function(Param1: pointer; Obj: pointer): pointer;
  169. function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
  170. begin
  171. CallVoidConstructor := VoidConstructor(Ctor)(Ofs(VMT^), Obj)
  172. end;
  173. function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
  174. begin
  175. CallPointerConstructor := PointerConstructor(Ctor)(Param1, Ofs(VMT^), Obj)
  176. end;
  177. function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
  178. begin
  179. CallVoidMethod := VoidMethod(Method)(Obj)
  180. end;
  181. function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
  182. begin
  183. CallPointerMethod := PointerMethod(Method)(Param1, Obj)
  184. end;
  185. function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer; assembler;
  186. asm
  187. {$IFDEF Windows}
  188. MOV AX,[Frame]
  189. AND AL,0FEH
  190. PUSH AX
  191. {$ELSE}
  192. push [Frame]
  193. {$ENDIF}
  194. call dword ptr Func
  195. end;
  196. function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer; assembler;
  197. asm
  198. mov ax, word ptr Param1
  199. mov dx, word ptr Param1+2
  200. push dx
  201. push ax
  202. {$IFDEF Windows}
  203. MOV AX,[Frame]
  204. AND AL,0FEH
  205. PUSH AX
  206. {$ELSE}
  207. push [Frame]
  208. {$ENDIF}
  209. call dword ptr Func
  210. end;
  211. function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer; assembler;
  212. asm
  213. {$IFDEF Windows}
  214. MOV AX,[Frame]
  215. AND AL,0FEH
  216. PUSH AX
  217. {$ELSE}
  218. push [Frame]
  219. {$ENDIF}
  220. call dword ptr Func
  221. end;
  222. function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer; assembler;
  223. asm
  224. mov ax, word ptr Param1
  225. mov dx, word ptr Param1+2
  226. push dx
  227. push ax
  228. {$IFDEF Windows}
  229. MOV AX,[Frame]
  230. AND AL,0FEH
  231. PUSH AX
  232. {$ELSE}
  233. push [Frame]
  234. {$ENDIF}
  235. call dword ptr Func
  236. end;
  237. function CurrentFramePointer: FramePointer; assembler;
  238. asm
  239. mov ax, bp
  240. end;
  241. function PreviousFramePointer: FramePointer; assembler;
  242. asm
  243. mov ax, ss:[bp]
  244. end;
  245. {$endif PPC_BP}
  246. end.
  247. {
  248. $Log$
  249. Revision 1.1 2000-01-06 01:20:30 peter
  250. * moved out of packages/ back to topdir
  251. Revision 1.1 1999/12/23 19:36:47 peter
  252. * place unitfiles in target dirs
  253. Revision 1.1 1999/11/24 23:36:37 peter
  254. * moved to packages dir
  255. Revision 1.2 1998/12/16 21:57:16 peter
  256. * fixed currentframe,previousframe
  257. + testcall to test the callspec unit
  258. Revision 1.1 1998/12/04 12:48:24 peter
  259. * moved some dirs
  260. Revision 1.5 1998/12/04 09:53:44 peter
  261. * removed objtemp global var
  262. Revision 1.4 1998/11/24 17:14:24 peter
  263. * fixed esi loading
  264. Date Version Who Comments
  265. ---------- -------- ------- -------------------------------------
  266. 19-Sep-97 0.1 mkoeppe Initial version.
  267. 22-Sep-97 0.11 fk 0.9.3 support added, self isn't expected
  268. on the stack in local procedures of methods
  269. 23-Sep-97 0.12 mkoeppe Cleaned up 0.9.3 conditionals.
  270. 03-Oct-97 0.13 mkoeppe Fixed esi load in FPC 0.9
  271. 22-Oct-98 0.14 pfv 0.99.8 support for FPC
  272. }