except.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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 ExceptAddrStack : PExceptAddr;
  38. ExceptObjectStack : PExceptObject;
  39. Function PushExceptAddr (Ft: Longint): PJmp_buf ;[Public, Alias : 'FPC_PUSHEXCEPTADDR'];
  40. var Buf : PJmp_buf;
  41. NewAddr : PExceptAddr;
  42. begin
  43. {$ifdef excdebug}
  44. writeln ('In PushExceptAddr');
  45. {$endif}
  46. If ExceptAddrstack=Nil then
  47. begin
  48. New(ExceptAddrStack);
  49. ExceptAddrStack^.Next:=Nil;
  50. end
  51. else
  52. begin
  53. New(NewAddr);
  54. NewAddr^.Next:=ExceptAddrStack;
  55. ExceptAddrStack:=NewAddr;
  56. end;
  57. new(buf);
  58. ExceptAddrStack^.Buf:=Buf;
  59. ExceptAddrStack^.FrameType:=ft;
  60. PushExceptAddr:=Buf;
  61. end;
  62. Procedure PushExceptObj (Obj : TObject; AnAddr : Pointer);
  63. var
  64. Newobj : PExceptObject;
  65. begin
  66. {$ifdef excdebug}
  67. writeln ('In PushExceptObject');
  68. {$endif}
  69. If ExceptObjectStack=Nil then
  70. begin
  71. New(ExceptObjectStack);
  72. ExceptObjectStack^.Next:=Nil;
  73. end
  74. else
  75. begin
  76. New(NewObj);
  77. NewObj^.Next:=ExceptObjectStack;
  78. ExceptObjectStack:=NewObj;
  79. end;
  80. ExceptObjectStack^.FObject:=Obj;
  81. ExceptObjectStack^.Addr:=AnAddr;
  82. end;
  83. Procedure DoUnHandledException (Var Obj : TObject; AnAddr : Pointer);
  84. begin
  85. If ExceptProc<>Nil then
  86. If ExceptObjectStack<>Nil then
  87. TExceptPRoc(ExceptProc)(Obj,AnAddr);
  88. RunError(217);
  89. end;
  90. Function Raiseexcept (Obj : TObject; AnAddr : Pointer) : TObject;[Public, Alias : 'FPC_RAISEEXCEPTION'];
  91. begin
  92. {$ifdef excdebug}
  93. writeln ('In RaiseException');
  94. {$endif}
  95. Raiseexcept:=nil;
  96. PushExceptObj(Obj,AnAddr);
  97. If ExceptAddrStack=Nil then
  98. DoUnhandledException (Obj,AnAddr);
  99. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  100. end;
  101. Procedure PopAddrStack ;[Public, Alias : 'FPC_POPADDRSTACK'];
  102. begin
  103. {$ifdef excdebug}
  104. writeln ('In Popaddrstack');
  105. {$endif}
  106. If ExceptAddrStack=nil then
  107. begin
  108. writeln ('At end of ExceptionAddresStack');
  109. halt (1);
  110. end
  111. else
  112. ExceptAddrStack:=ExceptAddrStack^.Next;
  113. end;
  114. Procedure PopObjectStack ;
  115. begin
  116. {$ifdef excdebug}
  117. writeln ('In PopObjectstack');
  118. {$endif}
  119. If ExceptObjectStack=nil then
  120. begin
  121. writeln ('At end of ExceptionObjectStack');
  122. halt (1);
  123. end
  124. else
  125. ExceptObjectStack:=ExceptObjectStack^.Next;
  126. end;
  127. Procedure ReRaise;[Public, Alias : 'FPC_RERAISE'];
  128. begin
  129. {$ifdef excdebug}
  130. writeln ('In reraise');
  131. {$endif}
  132. PopAddrStack;
  133. If ExceptAddrStack=Nil then
  134. DoUnHandledException (ExceptObjectStack^.FObject,
  135. ExceptObjectStack^.Addr);
  136. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  137. end;
  138. Function Catches (Objtype : TExceptObjectClass) : TObject; [Public, Alias : 'FPC_CATCHES'];
  139. begin
  140. If ExceptObjectStack=Nil then
  141. begin
  142. Writeln ('Internal error.');
  143. halt (255);
  144. end;
  145. if Not ((Objtype = TExceptObjectClass(CatchAllExceptions)) or
  146. (ExceptObjectStack^.FObject is ObjType)) then
  147. Catches:=Nil
  148. else
  149. begin
  150. // catch !
  151. Catches:=ExceptObjectStack^.FObject;
  152. PopObjectStack;
  153. PopAddrStack;
  154. end;
  155. end;
  156. Procedure InitExceptions;
  157. {
  158. Initialize exceptionsupport
  159. }
  160. begin
  161. ExceptObjectstack:=Nil;
  162. ExceptAddrStack:=Nil;
  163. end;