tpexcept.pas 8.2 KB

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