except.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. PushExceptObj(Obj,AnAddr);
  96. If ExceptAddrStack=Nil then
  97. DoUnhandledException (Obj,AnAddr);
  98. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  99. end;
  100. Procedure PopAddrStack ;[Public, Alias : 'FPC_POPADDRSTACK'];
  101. begin
  102. {$ifdef excdebug}
  103. writeln ('In Popaddrstack');
  104. {$endif}
  105. If ExceptAddrStack=nil then
  106. begin
  107. writeln ('At end of ExceptionAddresStack');
  108. halt (1);
  109. end
  110. else
  111. ExceptAddrStack:=ExceptAddrStack^.Next;
  112. end;
  113. Procedure PopObjectStack ;
  114. begin
  115. {$ifdef excdebug}
  116. writeln ('In PopObjectstack');
  117. {$endif}
  118. If ExceptObjectStack=nil then
  119. begin
  120. writeln ('At end of ExceptionObjectStack');
  121. halt (1);
  122. end
  123. else
  124. ExceptObjectStack:=ExceptObjectStack^.Next;
  125. end;
  126. Procedure ReRaise;[Public, Alias : 'FPC_RERAISE'];
  127. begin
  128. {$ifdef excdebug}
  129. writeln ('In reraise');
  130. {$endif}
  131. PopAddrStack;
  132. If ExceptAddrStack=Nil then
  133. DoUnHandledException (ExceptObjectStack^.FObject,
  134. ExceptObjectStack^.Addr);
  135. longjmp(ExceptAddrStack^.Buf^,FPC_Exception);
  136. end;
  137. Function Catches (Objtype : TExceptObjectClass) : TObject; [Public, Alias : 'FPC_CATCHES'];
  138. begin
  139. If ExceptObjectStack=Nil then
  140. begin
  141. Writeln ('Internal error.');
  142. halt (255);
  143. end;
  144. if Not ((Objtype = TExceptObjectClass(CatchAllExceptions)) or
  145. (ExceptObjectStack^.FObject is ObjType)) then
  146. Catches:=Nil
  147. else
  148. begin
  149. // catch !
  150. Catches:=ExceptObjectStack^.FObject;
  151. PopObjectStack;
  152. PopAddrStack;
  153. end;
  154. end;
  155. Procedure InitExceptions;
  156. {
  157. Initialize exceptionsupport
  158. }
  159. begin
  160. ExceptObjectstack:=Nil;
  161. ExceptAddrStack:=Nil;
  162. end;