tpexcept.pas 8.9 KB

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