except.inc 4.1 KB

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