tpexcept.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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. function setjmp(var rec : jmp_buf) : longint;
  148. begin
  149. asm
  150. pushl %edi
  151. movl rec,%edi
  152. movl %eax,(%edi)
  153. movl %ebx,4(%edi)
  154. movl %ecx,8(%edi)
  155. movl %edx,12(%edi)
  156. movl %esi,16(%edi)
  157. { load edi }
  158. movl -4(%ebp),%eax
  159. { ... and store it }
  160. movl %eax,20(%edi)
  161. { ebp ... }
  162. movl (%ebp),%eax
  163. movl %eax,24(%edi)
  164. { esp ... }
  165. movl %esp,%eax
  166. addl $12,%eax
  167. movl %eax,28(%edi)
  168. { the return address }
  169. movl 4(%ebp),%eax
  170. movl %eax,32(%edi)
  171. { flags ... }
  172. pushfl
  173. popl 36(%edi)
  174. { !!!!! the segment registers, not yet needed }
  175. { you need them if the exception comes from
  176. an interrupt or a seg_move }
  177. movw %cs,40(%edi)
  178. movw %ds,42(%edi)
  179. movw %es,44(%edi)
  180. movw %fs,46(%edi)
  181. movw %gs,48(%edi)
  182. movw %ss,50(%edi)
  183. { restore EDI }
  184. pop %edi
  185. { we come from the initial call }
  186. xorl %eax,%eax
  187. leave
  188. ret $4
  189. end;
  190. end;
  191. procedure longjmp(const rec : jmp_buf;return_value : longint);
  192. begin
  193. asm
  194. { restore compiler shit }
  195. popl %ebp
  196. { this is the address of rec }
  197. movl 4(%esp),%edi
  198. { save return value }
  199. movl 8(%esp),%eax
  200. movl %eax,0(%edi)
  201. { !!!!! load segment registers }
  202. movw 46(%edi),%fs
  203. movw 48(%edi),%gs
  204. { ... and some other registers }
  205. movl 4(%edi),%ebx
  206. movl 8(%edi),%ecx
  207. movl 12(%edi),%edx
  208. movl 24(%edi),%ebp
  209. { !!!!! movw 50(%edi),%es }
  210. movl 28(%edi),%esi
  211. { create a stack frame for the return }
  212. subl $16,%esi
  213. {
  214. movzwl 42(%edi),%eax
  215. !!!!! es
  216. movl %eax,(%esi)
  217. }
  218. { edi }
  219. movl 20(%edi),%eax
  220. { !!!!! es }
  221. movl %eax,(%esi)
  222. { esi }
  223. movl 16(%edi),%eax
  224. { !!!!! es }
  225. movl %eax,4(%esi)
  226. { eip }
  227. movl 32(%edi),%eax
  228. { !!!!! es }
  229. movl %eax,12(%esi)
  230. { !!!!! cs
  231. movl 40(%edi),%eax
  232. es
  233. movl %eax,16(%esi)
  234. }
  235. { load and store flags }
  236. movl 36(%edi),%eax
  237. { !!!!!
  238. es
  239. }
  240. movl %eax,8(%esi)
  241. { load return value }
  242. movl 0(%edi),%eax
  243. { load old ES
  244. !!!!! movw 44(%edi),%es
  245. }
  246. { load stack
  247. !!!!! movw 50(%edi),%ss }
  248. movl %esi,%esp
  249. { !!!!
  250. popl %ds
  251. }
  252. popl %edi
  253. popl %esi
  254. popfl
  255. ret
  256. end;
  257. end;
  258. {$endif TP}
  259. end.
  260. {
  261. $Log$
  262. Revision 1.5 1998-10-28 18:26:23 pierre
  263. * removed some erros after other errors (introduced by useexcept)
  264. * stabs works again correctly (for how long !)
  265. Revision 1.4 1998/10/26 22:58:24 florian
  266. * new introduded problem with classes fix, the parent class wasn't set
  267. correct, if the class was defined forward before
  268. Revision 1.3 1998/10/26 17:15:19 pierre
  269. + added two level of longjump to
  270. allow clean freeing of used memory on errors
  271. Revision 1.2 1998/08/28 10:57:03 peter
  272. * removed warnings
  273. Revision 1.1 1998/08/10 10:18:36 peter
  274. + Compiler,Comphook unit which are the new interface units to the
  275. compiler
  276. }