except.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. Procedure PopObjectStack;[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. hp:=ExceptObjectStack;
  138. ExceptObjectStack:=ExceptObjectStack^.next;
  139. dispose(hp);
  140. end;
  141. end;
  142. Procedure ReRaise;[Public, Alias : 'FPC_RERAISE'];
  143. begin
  144. {$ifdef excdebug}
  145. writeln ('In reraise');
  146. {$endif}
  147. If ExceptAddrStack=Nil then
  148. DoUnHandledException;
  149. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  150. end;
  151. Function Catches(Objtype : TExceptObjectClass) : TObject;[Public, Alias : 'FPC_CATCHES'];
  152. begin
  153. If ExceptObjectStack=Nil then
  154. begin
  155. Writeln ('Internal error.');
  156. halt (255);
  157. end;
  158. if Not ((Objtype = TExceptObjectClass(CatchAllExceptions)) or
  159. (ExceptObjectStack^.FObject is ObjType)) then
  160. Catches:=Nil
  161. else
  162. begin
  163. // catch !
  164. Catches:=ExceptObjectStack^.FObject;
  165. { this can't be done, because there could be a reraise (PFV)
  166. PopObjectStack;
  167. Also the PopAddrStack shouldn't be done, we do it now
  168. immediatly in the exception handler (FK)
  169. PopAddrStack; }
  170. end;
  171. end;
  172. Procedure DestroyException(o : TObject);[Public, Alias : 'FPC_DESTROYEXCEPTION'];
  173. begin
  174. o.Destroy;
  175. end;
  176. Procedure InitExceptions;
  177. {
  178. Initialize exceptionsupport
  179. }
  180. begin
  181. ExceptObjectstack:=Nil;
  182. ExceptAddrStack:=Nil;
  183. end;
  184. {
  185. $Log$
  186. Revision 1.14 2000-01-07 16:41:33 daniel
  187. * copyright 2000
  188. Revision 1.13 1999/07/27 08:14:15 florian
  189. * catch doesn't call popaddrstack anymore, this is done now by the compiler
  190. Revision 1.12 1999/07/26 12:11:28 florian
  191. * reraise doesn't call popaddrstack anymode
  192. Revision 1.11 1999/06/14 00:47:35 peter
  193. * merged
  194. Revision 1.10.2.1 1999/06/14 00:38:18 peter
  195. * don't pop object stack in catches, because it's needed for reraise
  196. Revision 1.10 1999/05/13 18:38:26 florian
  197. * more memory leaks fixed:
  198. - exceptaddrobject is now properly disposed
  199. - after the end of the on ... do block the exception
  200. class instance is disposed
  201. Revision 1.9 1999/05/13 16:30:18 florian
  202. * popaddrstack didn't release any memory, fixed
  203. }