except.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998 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.13 1999-07-27 08:14:15 florian
  187. * catch doesn't call popaddrstack anymore, this is done now by the compiler
  188. Revision 1.12 1999/07/26 12:11:28 florian
  189. * reraise doesn't call popaddrstack anymode
  190. Revision 1.11 1999/06/14 00:47:35 peter
  191. * merged
  192. Revision 1.10.2.1 1999/06/14 00:38:18 peter
  193. * don't pop object stack in catches, because it's needed for reraise
  194. Revision 1.10 1999/05/13 18:38:26 florian
  195. * more memory leaks fixed:
  196. - exceptaddrobject is now properly disposed
  197. - after the end of the on ... do block the exception
  198. class instance is disposed
  199. Revision 1.9 1999/05/13 16:30:18 florian
  200. * popaddrstack didn't release any memory, fixed
  201. }