except.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. PopAddrStack;
  148. If ExceptAddrStack=Nil then
  149. DoUnHandledException;
  150. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  151. end;
  152. Function Catches(Objtype : TExceptObjectClass) : TObject;[Public, Alias : 'FPC_CATCHES'];
  153. begin
  154. If ExceptObjectStack=Nil then
  155. begin
  156. Writeln ('Internal error.');
  157. halt (255);
  158. end;
  159. if Not ((Objtype = TExceptObjectClass(CatchAllExceptions)) or
  160. (ExceptObjectStack^.FObject is ObjType)) then
  161. Catches:=Nil
  162. else
  163. begin
  164. // catch !
  165. Catches:=ExceptObjectStack^.FObject;
  166. { this can't be done, because there could be a reraise (PFV)
  167. PopObjectStack; }
  168. PopAddrStack;
  169. end;
  170. end;
  171. Procedure DestroyException(o : TObject);[Public, Alias : 'FPC_DESTROYEXCEPTION'];
  172. begin
  173. o.Destroy;
  174. end;
  175. Procedure InitExceptions;
  176. {
  177. Initialize exceptionsupport
  178. }
  179. begin
  180. ExceptObjectstack:=Nil;
  181. ExceptAddrStack:=Nil;
  182. end;
  183. {
  184. $Log$
  185. Revision 1.11 1999-06-14 00:47:35 peter
  186. * merged
  187. Revision 1.10.2.1 1999/06/14 00:38:18 peter
  188. * don't pop object stack in catches, because it's needed for reraise
  189. Revision 1.10 1999/05/13 18:38:26 florian
  190. * more memory leaks fixed:
  191. - exceptaddrobject is now properly disposed
  192. - after the end of the on ... do block the exception
  193. class instance is disposed
  194. Revision 1.9 1999/05/13 16:30:18 florian
  195. * popaddrstack didn't release any memory, fixed
  196. }