tpexcept.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. SetJmp and LongJmp implementation for recovery handling of the
  5. compiler
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. unit tpexcept;
  19. interface
  20. {$ifndef LINUX}
  21. {$S-}
  22. {$endif}
  23. type
  24. jmp_buf = record
  25. {$ifdef TP}
  26. _ax,_bx,_cx,_dx,_si,_di,_bp,_sp,_ip,flags : word;
  27. _cs,_ds,_es,_ss : word;
  28. {$else}
  29. eax,ebx,ecx,edx,esi,edi,ebp,esp,eip,flags : longint;
  30. cs,ds,es,fs,gs,ss : word;
  31. {$endif TP}
  32. end;
  33. pjmp_buf = ^jmp_buf;
  34. {$ifdef TP}
  35. function setjmp(var rec : jmp_buf) : integer;
  36. procedure longjmp(const rec : jmp_buf;return_value : integer);
  37. {$else}
  38. function setjmp(var rec : jmp_buf) : longint;
  39. procedure longjmp(const rec : jmp_buf;return_value : longint);
  40. {$endif TP}
  41. const
  42. recoverpospointer : pjmp_buf = nil;
  43. longjump_used : boolean = false;
  44. implementation
  45. {*****************************************************************************
  46. Exception Helpers
  47. *****************************************************************************}
  48. {$ifdef TP}
  49. function setjmp(var rec : jmp_buf) : integer;
  50. begin
  51. asm
  52. push di
  53. push es
  54. les di,rec
  55. mov es:[di].jmp_buf._ax,ax
  56. mov es:[di].jmp_buf._bx,bx
  57. mov es:[di].jmp_buf._cx,cx
  58. mov es:[di].jmp_buf._dx,dx
  59. mov es:[di].jmp_buf._si,si
  60. { load di }
  61. mov ax,[bp-4]
  62. { ... and store it }
  63. mov es:[di].jmp_buf._di,ax
  64. { load es }
  65. mov ax,[bp-6]
  66. { ... and store it }
  67. mov es:[di].jmp_buf._es,ax
  68. { bp ... }
  69. mov ax,[bp]
  70. mov es:[di].jmp_buf._bp,ax
  71. { sp ... }
  72. mov ax,bp
  73. add ax,10
  74. mov es:[di].jmp_buf._sp,ax
  75. { the return address }
  76. mov ax,[bp+2]
  77. mov es:[di].jmp_buf._ip,ax
  78. mov ax,[bp+4]
  79. mov es:[di].jmp_buf._cs,ax
  80. { flags ... }
  81. pushf
  82. pop word ptr es:[di].jmp_buf.flags
  83. mov es:[di].jmp_buf._ds,ds
  84. mov es:[di].jmp_buf._ss,ss
  85. { restore es:di }
  86. pop es
  87. pop di
  88. { we come from the initial call }
  89. xor ax,ax
  90. leave
  91. retf 4
  92. end;
  93. end;
  94. procedure longjmp(const rec : jmp_buf;return_value : integer);
  95. begin
  96. asm
  97. { this is the address of rec }
  98. lds di,rec
  99. { save return value }
  100. mov ax,return_value
  101. mov ds:[di].jmp_buf._ax,ax
  102. { restore compiler shit }
  103. pop bp
  104. { restore some registers }
  105. mov bx,ds:[di].jmp_buf._bx
  106. mov cx,ds:[di].jmp_buf._cx
  107. mov dx,ds:[di].jmp_buf._dx
  108. mov bp,ds:[di].jmp_buf._bp
  109. { create a stack frame for the return }
  110. mov es,ds:[di].jmp_buf._ss
  111. mov si,ds:[di].jmp_buf._sp
  112. sub si,12
  113. { store ds }
  114. mov ax,ds:[di].jmp_buf._ds
  115. mov es:[si],ax
  116. { store di }
  117. mov ax,ds:[di].jmp_buf._di
  118. mov es:[si+2],ax
  119. { store si }
  120. mov ax,ds:[di].jmp_buf._si
  121. mov es:[si+4],ax
  122. { store flags }
  123. mov ax,ds:[di].jmp_buf.flags
  124. mov es:[si+6],ax
  125. { store ip }
  126. mov ax,ds:[di].jmp_buf._ip
  127. mov es:[si+8],ax
  128. { store cs }
  129. mov ax,ds:[di].jmp_buf._cs
  130. mov es:[si+10],ax
  131. { load stack }
  132. mov ax,es
  133. mov ss,ax
  134. mov sp,si
  135. { load return value }
  136. mov ax,ds:[di].jmp_buf._ax
  137. { load old ES }
  138. mov es,ds:[di].jmp_buf._es
  139. pop ds
  140. pop di
  141. pop si
  142. popf
  143. retf
  144. end;
  145. end;
  146. {$else}
  147. {$ifdef Delphi}
  148. function setjmp(var rec : jmp_buf) : longint;
  149. begin
  150. result:=0;
  151. end;
  152. procedure longjmp(const rec : jmp_buf;return_value : longint);
  153. begin
  154. end;
  155. {$else Delphi}
  156. function setjmp(var rec : jmp_buf) : longint;
  157. begin
  158. asm
  159. pushl %edi
  160. movl rec,%edi
  161. movl %eax,(%edi)
  162. movl %ebx,4(%edi)
  163. movl %ecx,8(%edi)
  164. movl %edx,12(%edi)
  165. movl %esi,16(%edi)
  166. { load edi }
  167. movl -4(%ebp),%eax
  168. { ... and store it }
  169. movl %eax,20(%edi)
  170. { ebp ... }
  171. movl (%ebp),%eax
  172. movl %eax,24(%edi)
  173. { esp ... }
  174. movl %esp,%eax
  175. addl $12,%eax
  176. movl %eax,28(%edi)
  177. { the return address }
  178. movl 4(%ebp),%eax
  179. movl %eax,32(%edi)
  180. { flags ... }
  181. pushfl
  182. popl 36(%edi)
  183. { !!!!! the segment registers, not yet needed }
  184. { you need them if the exception comes from
  185. an interrupt or a seg_move }
  186. movw %cs,40(%edi)
  187. movw %ds,42(%edi)
  188. movw %es,44(%edi)
  189. movw %fs,46(%edi)
  190. movw %gs,48(%edi)
  191. movw %ss,50(%edi)
  192. { restore EDI }
  193. pop %edi
  194. { we come from the initial call }
  195. xorl %eax,%eax
  196. leave
  197. ret $4
  198. end;
  199. end;
  200. procedure longjmp(const rec : jmp_buf;return_value : longint);
  201. begin
  202. asm
  203. { restore compiler shit }
  204. popl %ebp
  205. { this is the address of rec }
  206. movl 4(%esp),%edi
  207. { save return value }
  208. movl 8(%esp),%eax
  209. movl %eax,0(%edi)
  210. { !!!!! load segment registers }
  211. movw 46(%edi),%fs
  212. movw 48(%edi),%gs
  213. { ... and some other registers }
  214. movl 4(%edi),%ebx
  215. movl 8(%edi),%ecx
  216. movl 12(%edi),%edx
  217. movl 24(%edi),%ebp
  218. { !!!!! movw 50(%edi),%es }
  219. movl 28(%edi),%esi
  220. { create a stack frame for the return }
  221. subl $16,%esi
  222. {
  223. movzwl 42(%edi),%eax
  224. !!!!! es
  225. movl %eax,(%esi)
  226. }
  227. { edi }
  228. movl 20(%edi),%eax
  229. { !!!!! es }
  230. movl %eax,(%esi)
  231. { esi }
  232. movl 16(%edi),%eax
  233. { !!!!! es }
  234. movl %eax,4(%esi)
  235. { eip }
  236. movl 32(%edi),%eax
  237. { !!!!! es }
  238. movl %eax,12(%esi)
  239. { !!!!! cs
  240. movl 40(%edi),%eax
  241. es
  242. movl %eax,16(%esi)
  243. }
  244. { load and store flags }
  245. movl 36(%edi),%eax
  246. { !!!!!
  247. es
  248. }
  249. movl %eax,8(%esi)
  250. { load return value }
  251. movl 0(%edi),%eax
  252. { load old ES
  253. !!!!! movw 44(%edi),%es
  254. }
  255. { load stack
  256. !!!!! movw 50(%edi),%ss }
  257. movl %esi,%esp
  258. { !!!!
  259. popl %ds
  260. }
  261. popl %edi
  262. popl %esi
  263. popfl
  264. ret
  265. end;
  266. end;
  267. {$endif Delphi}
  268. {$endif TP}
  269. end.
  270. {
  271. $Log$
  272. Revision 1.6 1999-05-04 21:45:08 florian
  273. * changes to compile it with Delphi 4.0
  274. Revision 1.5 1998/10/28 18:26:23 pierre
  275. * removed some erros after other errors (introduced by useexcept)
  276. * stabs works again correctly (for how long !)
  277. Revision 1.4 1998/10/26 22:58:24 florian
  278. * new introduded problem with classes fix, the parent class wasn't set
  279. correct, if the class was defined forward before
  280. Revision 1.3 1998/10/26 17:15:19 pierre
  281. + added two level of longjump to
  282. allow clean freeing of used memory on errors
  283. Revision 1.2 1998/08/28 10:57:03 peter
  284. * removed warnings
  285. Revision 1.1 1998/08/10 10:18:36 peter
  286. + Compiler,Comphook unit which are the new interface units to the
  287. compiler
  288. }