except.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. Exception support
  14. ****************************************************************************}
  15. Const
  16. { Type of exception. Currently only one. }
  17. FPC_EXCEPTION = 1;
  18. { types of frames for the exception address stack }
  19. cExceptionFrame = 1;
  20. cFinalizeFrame = 2;
  21. Type
  22. PExceptAddr = ^TExceptAddr;
  23. TExceptAddr = record
  24. buf : pjmp_buf;
  25. frametype : Longint;
  26. next : PExceptAddr;
  27. end;
  28. PExceptObject = ^TExceptObject;
  29. TExceptObject = record
  30. FObject : TObject;
  31. Addr : pointer;
  32. Next : PExceptObject;
  33. end;
  34. TExceptObjectClass = Class of TObject;
  35. Const
  36. CatchAllExceptions = -1;
  37. Var
  38. ExceptAddrStack : PExceptAddr;
  39. ExceptObjectStack : PExceptObject;
  40. Function PushExceptAddr (Ft: Longint): PJmp_buf ;[Public, Alias : 'FPC_PUSHEXCEPTADDR'];
  41. var
  42. Buf : PJmp_buf;
  43. NewAddr : PExceptAddr;
  44. begin
  45. {$ifdef excdebug}
  46. writeln ('In PushExceptAddr');
  47. {$endif}
  48. If ExceptAddrstack=Nil then
  49. begin
  50. New(ExceptAddrStack);
  51. ExceptAddrStack^.Next:=Nil;
  52. end
  53. else
  54. begin
  55. New(NewAddr);
  56. NewAddr^.Next:=ExceptAddrStack;
  57. ExceptAddrStack:=NewAddr;
  58. end;
  59. new(buf);
  60. ExceptAddrStack^.Buf:=Buf;
  61. ExceptAddrStack^.FrameType:=ft;
  62. PushExceptAddr:=Buf;
  63. end;
  64. Procedure PushExceptObj (Obj : TObject; AnAddr : Pointer); [Public, Alias : 'FPC_PUSHEXCEPTOBJECT'];
  65. var
  66. Newobj : PExceptObject;
  67. begin
  68. {$ifdef excdebug}
  69. writeln ('In PushExceptObject');
  70. {$endif}
  71. If ExceptObjectStack=Nil then
  72. begin
  73. New(ExceptObjectStack);
  74. ExceptObjectStack^.Next:=Nil;
  75. end
  76. else
  77. begin
  78. New(NewObj);
  79. NewObj^.Next:=ExceptObjectStack;
  80. ExceptObjectStack:=NewObj;
  81. end;
  82. ExceptObjectStack^.FObject:=Obj;
  83. ExceptObjectStack^.Addr:=AnAddr;
  84. end;
  85. Procedure DoUnHandledException;
  86. begin
  87. If ExceptProc<>Nil then
  88. If ExceptObjectStack<>Nil then
  89. TExceptPRoc(ExceptProc)(ExceptObjectStack^.FObject,ExceptObjectStack^.Addr);
  90. RunError(217);
  91. end;
  92. Function Raiseexcept (Obj : TObject; AnAddr : Pointer) : TObject;[Public, Alias : 'FPC_RAISEEXCEPTION'];
  93. begin
  94. {$ifdef excdebug}
  95. writeln ('In RaiseException');
  96. {$endif}
  97. Raiseexcept:=nil;
  98. PushExceptObj(Obj,AnAddr);
  99. If ExceptAddrStack=Nil then
  100. DoUnhandledException;
  101. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  102. end;
  103. Procedure PopAddrStack;[Public, Alias : 'FPC_POPADDRSTACK'];
  104. var
  105. hp : PExceptAddr;
  106. begin
  107. {$ifdef excdebug}
  108. writeln ('In Popaddrstack');
  109. {$endif}
  110. If ExceptAddrStack=nil then
  111. begin
  112. writeln ('At end of ExceptionAddresStack');
  113. halt (255);
  114. end
  115. else
  116. begin
  117. hp:=ExceptAddrStack;
  118. ExceptAddrStack:=ExceptAddrStack^.Next;
  119. dispose(hp^.buf);
  120. dispose(hp);
  121. end;
  122. end;
  123. function PopObjectStack : TObject;[Public, Alias : 'FPC_POPOBJECTSTACK'];
  124. var
  125. hp : PExceptObject;
  126. begin
  127. {$ifdef excdebug}
  128. writeln ('In PopObjectstack');
  129. {$endif}
  130. If ExceptObjectStack=nil then
  131. begin
  132. writeln ('At end of ExceptionObjectStack');
  133. halt (1);
  134. end
  135. else
  136. begin
  137. { we need to return the exception object to dispose it }
  138. PopObjectStack:=ExceptObjectStack^.FObject;
  139. hp:=ExceptObjectStack;
  140. ExceptObjectStack:=ExceptObjectStack^.next;
  141. dispose(hp);
  142. end;
  143. end;
  144. { this is for popping exception objects when a second exception is risen }
  145. { in an except/on }
  146. function PopSecondObjectStack : TObject;[Public, Alias : 'FPC_POPSECONDOBJECTSTACK'];
  147. var
  148. hp : PExceptObject;
  149. begin
  150. {$ifdef excdebug}
  151. writeln ('In PopObjectstack');
  152. {$endif}
  153. If not(assigned(ExceptObjectStack)) or
  154. not(assigned(ExceptObjectStack^.next)) then
  155. begin
  156. writeln ('At end of ExceptionObjectStack');
  157. halt (1);
  158. end
  159. else
  160. begin
  161. { we need to return the exception object to dispose it }
  162. PopSecondObjectStack:=ExceptObjectStack^.next^.FObject;
  163. hp:=ExceptObjectStack^.next;
  164. ExceptObjectStack^.next:=hp^.next;
  165. dispose(hp);
  166. end;
  167. end;
  168. Procedure ReRaise;[Public, Alias : 'FPC_RERAISE'];
  169. begin
  170. {$ifdef excdebug}
  171. writeln ('In reraise');
  172. {$endif}
  173. If ExceptAddrStack=Nil then
  174. DoUnHandledException;
  175. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  176. end;
  177. Function Catches(Objtype : TExceptObjectClass) : TObject;[Public, Alias : 'FPC_CATCHES'];
  178. begin
  179. If ExceptObjectStack=Nil then
  180. begin
  181. Writeln ('Internal error.');
  182. halt (255);
  183. end;
  184. if Not ((Objtype = TExceptObjectClass(CatchAllExceptions)) or
  185. (ExceptObjectStack^.FObject is ObjType)) then
  186. Catches:=Nil
  187. else
  188. begin
  189. // catch !
  190. Catches:=ExceptObjectStack^.FObject;
  191. { this can't be done, because there could be a reraise (PFV)
  192. PopObjectStack;
  193. Also the PopAddrStack shouldn't be done, we do it now
  194. immediatly in the exception handler (FK)
  195. PopAddrStack; }
  196. end;
  197. end;
  198. Procedure DestroyException(o : TObject);[Public, Alias : 'FPC_DESTROYEXCEPTION'];
  199. begin
  200. { with free we're on the really save side }
  201. o.Free;
  202. end;
  203. Procedure InitExceptions;
  204. {
  205. Initialize exceptionsupport
  206. }
  207. begin
  208. ExceptObjectstack:=Nil;
  209. ExceptAddrStack:=Nil;
  210. end;
  211. {
  212. $Log$
  213. Revision 1.17 2000-02-09 22:16:50 florian
  214. + popsecondobjectstack added
  215. Revision 1.16 2000/02/09 16:59:29 peter
  216. * truncated log
  217. Revision 1.15 2000/02/06 17:17:57 florian
  218. * popobjectstack is now a function
  219. Revision 1.14 2000/01/07 16:41:33 daniel
  220. * copyright 2000
  221. Revision 1.13 1999/07/27 08:14:15 florian
  222. * catch doesn't call popaddrstack anymore, this is done now by the compiler
  223. Revision 1.12 1999/07/26 12:11:28 florian
  224. * reraise doesn't call popaddrstack anymode
  225. }