system.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. For details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. Local types
  13. ****************************************************************************}
  14. {
  15. TextRec and FileRec are put in a separate file to make it available to other
  16. units without putting it explicitly in systemh.
  17. This way we keep TP compatibility, and the TextRec definition is available
  18. for everyone who needs it.
  19. }
  20. {$i filerec.inc}
  21. {$i textrec.inc}
  22. Procedure HandleError (Errno : Longint); forward;
  23. Procedure HandleErrorFrame (Errno : longint;frame : Pointer); forward;
  24. type
  25. FileFunc = Procedure(var t : TextRec);
  26. const
  27. STACK_MARGIN = 16384; { Stack size margin for stack checking }
  28. { Random / Randomize constants }
  29. OldRandSeed : Cardinal = 0;
  30. InitialSeed : Boolean = TRUE;
  31. Seed2 : Cardinal = 0;
  32. Seed3 : Cardinal = 0;
  33. { For Error Handling.}
  34. ErrorBase : Pointer = nil;
  35. { Used by the ansistrings and maybe also other things in the future }
  36. var
  37. emptychar : char;public name 'FPC_EMPTYCHAR';
  38. initialstklen : longint;external name '__stklen';
  39. {****************************************************************************
  40. Routines which have compiler magic
  41. ****************************************************************************}
  42. {$I innr.inc}
  43. Function lo(i : Integer) : byte; [INTERNPROC: In_lo_Word];
  44. Function lo(w : Word) : byte; [INTERNPROC: In_lo_Word];
  45. Function lo(l : Longint) : Word; [INTERNPROC: In_lo_long];
  46. Function lo(l : DWord) : Word; [INTERNPROC: In_lo_long];
  47. Function hi(i : Integer) : byte; [INTERNPROC: In_hi_Word];
  48. Function hi(w : Word) : byte; [INTERNPROC: In_hi_Word];
  49. Function hi(l : Longint) : Word; [INTERNPROC: In_hi_long];
  50. Function hi(l : DWord) : Word; [INTERNPROC: In_hi_long];
  51. Function lo(q : QWord) : DWord; [INTERNPROC: In_lo_qword];
  52. Function lo(i : Int64) : DWord; [INTERNPROC: In_lo_qword];
  53. Function hi(q : QWord) : DWord; [INTERNPROC: In_hi_qword];
  54. Function hi(i : Int64) : DWord; [INTERNPROC: In_hi_qword];
  55. Function chr(b : byte) : Char; [INTERNPROC: In_chr_byte];
  56. {$ifndef INTERNLENGTH}
  57. Function Length(s : string) : byte; [INTERNPROC: In_Length_string];
  58. Function Length(c : char) : byte; [INTERNPROC: In_Length_string];
  59. {$endif INTERNLENGTH}
  60. Procedure Reset(var f : TypedFile); [INTERNPROC: In_Reset_TypedFile];
  61. Procedure Rewrite(var f : TypedFile); [INTERNPROC: In_Rewrite_TypedFile];
  62. {****************************************************************************
  63. Include processor specific routines
  64. ****************************************************************************}
  65. {$ifdef cpui386}
  66. {$ifdef SYSPROCDEFINED}
  67. {$Error Can't determine processor type !}
  68. {$endif}
  69. {$i i386.inc} { Case dependent, don't change }
  70. {$endif cpui386}
  71. {$ifdef cpum68k}
  72. {$ifdef SYSPROCDEFINED}
  73. {$Error Can't determine processor type !}
  74. {$endif}
  75. {$i m68k.inc} { Case dependent, don't change }
  76. {$define SYSPROCDEFINED}
  77. {$endif cpum68k}
  78. {$ifdef cpux86_64}
  79. {$ifdef SYSPROCDEFINED}
  80. {$Error Can't determine processor type !}
  81. {$endif}
  82. {$i x86_64.inc} { Case dependent, don't change }
  83. {$define SYSPROCDEFINED}
  84. {$endif cpux86_64}
  85. {$ifdef cpupowerpc}
  86. {$ifdef SYSPROCDEFINED}
  87. {$Error Can't determine processor type !}
  88. {$endif}
  89. {$i powerpc.inc} { Case dependent, don't change }
  90. {$define SYSPROCDEFINED}
  91. {$endif cpupowerpc}
  92. {$ifdef cpualpha}
  93. {$ifdef SYSPROCDEFINED}
  94. {$Error Can't determine processor type !}
  95. {$endif}
  96. {$i alpha.inc} { Case dependent, don't change }
  97. {$define SYSPROCDEFINED}
  98. {$endif cpualpha}
  99. {$ifdef cpuiA64}
  100. {$ifdef SYSPROCDEFINED}
  101. {$Error Can't determine processor type !}
  102. {$endif}
  103. {$i ia64.inc} { Case dependent, don't change }
  104. {$define SYSPROCDEFINED}
  105. {$endif cpuiA64}
  106. {$ifdef cpusparc}
  107. {$ifdef SYSPROCDEFINED}
  108. {$Error Can't determine processor type !}
  109. {$endif}
  110. {$i sparc.inc} { Case dependent, don't change }
  111. {$define SYSPROCDEFINED}
  112. {$endif cpusparc}
  113. {$ifdef cpuarm}
  114. {$ifdef SYSPROCDEFINED}
  115. {$Error Can't determine processor type !}
  116. {$endif}
  117. {$i arm.inc} { Case dependent, don't change }
  118. {$define SYSPROCDEFINED}
  119. {$endif cpuarm}
  120. procedure fillchar(var x;count : longint;value : boolean);{$ifdef SYSTEMINLINE}inline;{$endif}
  121. begin
  122. fillchar(x,count,byte(value));
  123. end;
  124. procedure fillchar(var x;count : longint;value : char);{$ifdef SYSTEMINLINE}inline;{$endif}
  125. begin
  126. fillchar(x,count,byte(value));
  127. end;
  128. { Include generic pascal only routines which are not defined in the processor
  129. specific include file }
  130. {$I generic.inc}
  131. {****************************************************************************
  132. Set Handling
  133. ****************************************************************************}
  134. { Include set support which is processor specific}
  135. {$i set.inc}
  136. { Include generic pascal routines for sets if the processor }
  137. { specific routines are not available. }
  138. {$i genset.inc}
  139. {****************************************************************************
  140. Math Routines
  141. ****************************************************************************}
  142. function Hi(b : byte): byte;{$ifdef SYSTEMINLINE}inline;{$endif}
  143. begin
  144. Hi := b shr 4
  145. end;
  146. function Lo(b : byte): byte;{$ifdef SYSTEMINLINE}inline;{$endif}
  147. begin
  148. Lo := b and $0f
  149. end;
  150. Function swap (X : Word) : Word;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_word];
  151. Begin
  152. swap:=(X and $ff) shl 8 + (X shr 8)
  153. End;
  154. Function Swap (X : Integer) : Integer;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_word];
  155. Begin
  156. swap:=(X and $ff) shl 8 + (X shr 8)
  157. End;
  158. Function swap (X : Longint) : Longint;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_long];
  159. Begin
  160. Swap:=(X and $ffff) shl 16 + (X shr 16)
  161. End;
  162. Function Swap (X : Cardinal) : Cardinal;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_long];
  163. Begin
  164. Swap:=(X and $ffff) shl 16 + (X shr 16)
  165. End;
  166. Function Swap (X : QWord) : QWord;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_qword];
  167. Begin
  168. Swap:=(X and $ffffffff) shl 32 + (X shr 32);
  169. End;
  170. Function swap (X : Int64) : Int64;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_swap_qword];
  171. Begin
  172. Swap:=(X and $ffffffff) shl 32 + (X shr 32);
  173. End;
  174. operator := (b:real48) d:double;
  175. begin
  176. D:=real2double(b);
  177. end;
  178. {$ifdef SUPPORT_EXTENDED}
  179. operator := (b:real48) e:extended;
  180. begin
  181. e:=real2double(b);
  182. end;
  183. {$endif SUPPORT_EXTENDED}
  184. { Include processor specific routines }
  185. {$I math.inc}
  186. { Include generic version }
  187. {$I genmath.inc}
  188. {****************************************************************************
  189. Subroutines for String handling
  190. ****************************************************************************}
  191. { Needs to be before RTTI handling }
  192. {$i sstrings.inc}
  193. { requires sstrings.inc for initval }
  194. {$I int64p.inc}
  195. {$I int64.inc}
  196. {Requires int64.inc, since that contains the VAL functions for int64 and qword}
  197. {$i astrings.inc}
  198. {$ifdef HASWIDESTRING}
  199. {$i wstrings.inc}
  200. {$endif HASWIDESTRING}
  201. {$i aliases.inc}
  202. {*****************************************************************************
  203. Dynamic Array support
  204. *****************************************************************************}
  205. {$i dynarr.inc}
  206. {*****************************************************************************
  207. Object Pascal support
  208. *****************************************************************************}
  209. {$i objpas.inc}
  210. {*****************************************************************************
  211. Variant support
  212. *****************************************************************************}
  213. {$ifdef HASVARIANT}
  214. {$i variant.inc}
  215. {$endif HASVARIANT}
  216. {****************************************************************************
  217. Run-Time Type Information (RTTI)
  218. ****************************************************************************}
  219. {$i rtti.inc}
  220. {****************************************************************************
  221. Random function routines
  222. This implements a very long cycle random number generator by combining
  223. three independant generators. The technique was described in the March
  224. 1987 issue of Byte.
  225. Taken and modified with permission from the PCQ Pascal rtl code.
  226. ****************************************************************************}
  227. {$R-}
  228. {$Q-}
  229. Procedure NewSeed;Forward;
  230. Function Random : Extended;
  231. begin
  232. if (InitialSeed) OR (RandSeed <> OldRandSeed) then
  233. Begin
  234. { This is a pretty complicated affair }
  235. { Initially we must call NewSeed when RandSeed is initalized }
  236. { We must also call NewSeed each time RandSeed is reinitialized }
  237. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  238. { UNLESS YOU WANT RANDON TO CRASH OF COURSE (CEC) }
  239. InitialSeed:=FALSE;
  240. OldRandSeed:=RandSeed;
  241. NewSeed;
  242. end;
  243. Inc(RandSeed);
  244. RandSeed := (RandSeed * 706) mod 500009;
  245. OldRandSeed:=RandSeed;
  246. INC(Seed2);
  247. Seed2 := (Seed2 * 774) MOD 600011;
  248. INC(Seed3);
  249. Seed3 := (Seed3 * 871) MOD 765241;
  250. Random :=
  251. frac(RandSeed/500009.0 +
  252. Seed2/600011.0 +
  253. Seed3/765241.0);
  254. end;
  255. Function internRandom(l : Cardinal) : Cardinal;
  256. begin
  257. if (InitialSeed) OR (RandSeed <> OldRandSeed) then
  258. Begin
  259. { This is a pretty complicated affair }
  260. { Initially we must call NewSeed when RandSeed is initalized }
  261. { We must also call NewSeed each time RandSeed is reinitialized }
  262. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  263. { UNLESS YOU WANT RANDOM TO CRASH OF COURSE (CEC) }
  264. InitialSeed:=FALSE;
  265. OldRandSeed:=RandSeed;
  266. NewSeed;
  267. end;
  268. Inc(RandSeed);
  269. RandSeed := (RandSeed * 998) mod 1000003;
  270. OldRandSeed:=RandSeed;
  271. if l<>0 then
  272. begin
  273. internRandom := RandSeed mod l;
  274. end
  275. else internRandom:=0;
  276. end;
  277. function random(l:cardinal): cardinal;
  278. begin
  279. random := trunc(random()*l);
  280. end;
  281. function random(l:longint): longint;
  282. begin
  283. random := trunc(random()*l);
  284. end;
  285. Procedure NewSeed;
  286. begin
  287. randseed := randseed mod 1000003;
  288. Seed2 := (internRandom(65000) * internRandom(65000)) mod 600011;
  289. Seed3 := (internRandom(65000) * internRandom(65000)) mod 765241;
  290. end;
  291. {****************************************************************************
  292. Memory Management
  293. ****************************************************************************}
  294. Function Ptr(sel,off : Longint) : farpointer;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:in_const_ptr];
  295. Begin
  296. ptr:=farpointer((sel shl 4)+off);
  297. End;
  298. Function CSeg : Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  299. Begin
  300. Cseg:=0;
  301. End;
  302. Function DSeg : Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  303. Begin
  304. Dseg:=0;
  305. End;
  306. Function SSeg : Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  307. Begin
  308. Sseg:=0;
  309. End;
  310. {*****************************************************************************
  311. Directory support.
  312. *****************************************************************************}
  313. Procedure getdir(drivenr:byte;Var dir:ansistring);
  314. { this is needed to also allow ansistrings, the shortstring version is
  315. OS dependent }
  316. var
  317. s : shortstring;
  318. begin
  319. getdir(drivenr,s);
  320. dir:=s;
  321. end;
  322. {$ifopt R+}
  323. {$define RangeCheckWasOn}
  324. {$R-}
  325. {$endif opt R+}
  326. {$ifopt I+}
  327. {$define IOCheckWasOn}
  328. {$I-}
  329. {$endif opt I+}
  330. {$ifopt Q+}
  331. {$define OverflowCheckWasOn}
  332. {$Q-}
  333. {$endif opt Q+}
  334. {*****************************************************************************
  335. Miscellaneous
  336. *****************************************************************************}
  337. procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  338. begin
  339. HandleErrorFrame(201,get_frame);
  340. end;
  341. procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; {$ifdef hascompilerproc} compilerproc; {$endif}
  342. begin
  343. HandleErrorFrame(215,get_frame);
  344. end;
  345. procedure fpc_iocheck;[saveregisters,public,alias:'FPC_IOCHECK']; {$ifdef hascompilerproc} compilerproc; {$endif}
  346. var
  347. l : longint;
  348. begin
  349. if InOutRes<>0 then
  350. begin
  351. l:=InOutRes;
  352. InOutRes:=0;
  353. HandleErrorFrame(l,get_frame);
  354. end;
  355. end;
  356. Function IOResult:Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  357. Begin
  358. IOResult:=InOutRes;
  359. InOutRes:=0;
  360. End;
  361. {*****************************************************************************
  362. Stack check code
  363. *****************************************************************************}
  364. {$IFNDEF NO_GENERIC_STACK_CHECK}
  365. {$IFOPT S+}
  366. {$DEFINE STACKCHECK}
  367. {$ENDIF}
  368. {$S-}
  369. procedure fpc_stackcheck(stack_size:Cardinal);[saveregisters,public,alias:'FPC_STACKCHECK'];
  370. var
  371. c : cardinal;
  372. begin
  373. { Avoid recursive calls when called from the exit routines }
  374. if StackError then
  375. exit;
  376. c := cardinal(Sptr) - stack_size - STACK_MARGIN;
  377. if (c <= StackBottom) then
  378. begin
  379. StackError:=true;
  380. HandleError(202);
  381. end;
  382. end;
  383. {$IFDEF STACKCHECK}
  384. {$S+}
  385. {$ENDIF}
  386. {$UNDEF STACKCHECK}
  387. {$ENDIF NO_GENERIC_STACK_CHECK}
  388. {*****************************************************************************
  389. Initialization / Finalization
  390. *****************************************************************************}
  391. const
  392. maxunits=1024; { See also files.pas of the compiler source }
  393. type
  394. TInitFinalRec=record
  395. InitProc,
  396. FinalProc : TProcedure;
  397. end;
  398. TInitFinalTable=record
  399. TableCount,
  400. InitCount : longint;
  401. Procs : array[1..maxunits] of TInitFinalRec;
  402. end;
  403. var
  404. InitFinalTable : TInitFinalTable;external name 'INITFINAL';
  405. procedure fpc_InitializeUnits;[public,alias:'FPC_INITIALIZEUNITS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  406. var
  407. i : longint;
  408. begin
  409. with InitFinalTable do
  410. begin
  411. for i:=1to TableCount do
  412. begin
  413. if assigned(Procs[i].InitProc) then
  414. Procs[i].InitProc();
  415. InitCount:=i;
  416. end;
  417. end;
  418. end;
  419. procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
  420. begin
  421. with InitFinalTable do
  422. begin
  423. while (InitCount>0) do
  424. begin
  425. // we've to decrement the cound before calling the final. code
  426. // else a halt in the final. code leads to a endless loop
  427. dec(InitCount);
  428. if assigned(Procs[InitCount+1].FinalProc) then
  429. Procs[InitCount+1].FinalProc();
  430. end;
  431. end;
  432. end;
  433. {*****************************************************************************
  434. Error / Exit / ExitProc
  435. *****************************************************************************}
  436. Procedure system_exit;forward;
  437. Procedure InternalExit;
  438. var
  439. current_exit : Procedure;
  440. Begin
  441. while exitProc<>nil Do
  442. Begin
  443. InOutRes:=0;
  444. current_exit:=tProcedure(exitProc);
  445. exitProc:=nil;
  446. current_exit();
  447. End;
  448. { Finalize units }
  449. FinalizeUnits;
  450. { Show runtime error and exit }
  451. If erroraddr<>nil Then
  452. Begin
  453. Writeln(stdout,'Runtime error ',Errorcode,' at 0x',hexstr(Longint(Erroraddr),8));
  454. { to get a nice symify }
  455. Writeln(stdout,BackTraceStrFunc(Erroraddr));
  456. dump_stack(stdout,ErrorBase);
  457. Writeln(stdout,'');
  458. End;
  459. End;
  460. Procedure do_exit;[Public,Alias:'FPC_DO_EXIT'];
  461. begin
  462. InternalExit;
  463. System_exit;
  464. end;
  465. Procedure lib_exit;saveregisters;[Public,Alias:'FPC_LIB_EXIT'];
  466. begin
  467. InternalExit;
  468. end;
  469. Procedure Halt(ErrNum: Byte);
  470. Begin
  471. ExitCode:=Errnum;
  472. Do_Exit;
  473. end;
  474. function SysBackTraceStr (Addr: Pointer): ShortString;
  475. begin
  476. SysBackTraceStr:=' 0x'+HexStr(Longint(addr),8);
  477. end;
  478. Procedure HandleErrorAddrFrame (Errno : longint;addr,frame : Pointer);[public,alias:'FPC_BREAK_ERROR'];
  479. begin
  480. If pointer(ErrorProc)<>Nil then
  481. ErrorProc(Errno,addr,frame);
  482. errorcode:=word(Errno);
  483. exitcode:=word(Errno);
  484. erroraddr:=addr;
  485. errorbase:=frame;
  486. halt(errorcode);
  487. end;
  488. Procedure HandleErrorFrame (Errno : longint;frame : Pointer);
  489. {
  490. Procedure to handle internal errors, i.e. not user-invoked errors
  491. Internal function should ALWAYS call HandleError instead of RunError.
  492. Can be used for exception handlers to specify the frame
  493. }
  494. begin
  495. HandleErrorAddrFrame(Errno,get_caller_addr(frame),get_caller_frame(frame));
  496. end;
  497. Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
  498. {
  499. Procedure to handle internal errors, i.e. not user-invoked errors
  500. Internal function should ALWAYS call HandleError instead of RunError.
  501. }
  502. begin
  503. HandleErrorFrame(Errno,get_frame);
  504. end;
  505. procedure runerror(w : word);[alias: 'FPC_RUNERROR'];
  506. begin
  507. errorcode:=w;
  508. exitcode:=w;
  509. erroraddr:=get_caller_addr(get_frame);
  510. errorbase:=get_caller_frame(get_frame);
  511. halt(errorcode);
  512. end;
  513. Procedure RunError;{$ifdef SYSTEMINLINE}inline;{$endif}
  514. Begin
  515. RunError (0);
  516. End;
  517. Procedure Halt;{$ifdef SYSTEMINLINE}inline;{$endif}
  518. Begin
  519. Halt(0);
  520. End;
  521. function do_isdevice(handle:longint):boolean;forward;
  522. Procedure dump_stack(var f : text;bp : Pointer);
  523. var
  524. i : Longint;
  525. prevbp : Pointer;
  526. is_dev : boolean;
  527. caller_addr : Pointer;
  528. Begin
  529. prevbp:=bp-1;
  530. i:=0;
  531. is_dev:=do_isdevice(textrec(f).Handle);
  532. while bp > prevbp Do
  533. Begin
  534. caller_addr := get_caller_addr(bp);
  535. if caller_addr <> nil then
  536. Writeln(f,BackTraceStrFunc(caller_addr));
  537. Inc(i);
  538. If ((i>max_frame_dump) and is_dev) or (i>256) Then
  539. exit;
  540. prevbp:=bp;
  541. bp:=get_caller_frame(bp);
  542. End;
  543. End;
  544. Type
  545. PExitProcInfo = ^TExitProcInfo;
  546. TExitProcInfo = Record
  547. Next : PExitProcInfo;
  548. SaveExit : Pointer;
  549. Proc : TProcedure;
  550. End;
  551. const
  552. ExitProcList: PExitProcInfo = nil;
  553. Procedure DoExitProc;
  554. var
  555. P : PExitProcInfo;
  556. Proc : TProcedure;
  557. Begin
  558. P:=ExitProcList;
  559. ExitProcList:=P^.Next;
  560. ExitProc:=P^.SaveExit;
  561. Proc:=P^.Proc;
  562. DisPose(P);
  563. Proc();
  564. End;
  565. Procedure AddExitProc(Proc: TProcedure);
  566. var
  567. P : PExitProcInfo;
  568. Begin
  569. New(P);
  570. P^.Next:=ExitProcList;
  571. P^.SaveExit:=ExitProc;
  572. P^.Proc:=Proc;
  573. ExitProcList:=P;
  574. ExitProc:=@DoExitProc;
  575. End;
  576. {*****************************************************************************
  577. Abstract/Assert support.
  578. *****************************************************************************}
  579. procedure AbstractError;[public,alias : 'FPC_ABSTRACTERROR'];
  580. begin
  581. If pointer(AbstractErrorProc)<>nil then
  582. AbstractErrorProc();
  583. HandleErrorFrame(211,get_frame);
  584. end;
  585. {$ifdef hascompilerproc}
  586. { alias for internal usage in the compiler }
  587. procedure fpc_AbstractErrorIntern; compilerproc; external name 'FPC_ABSTRACTERROR';
  588. {$endif hascompilerproc}
  589. Procedure fpc_assert(Const Msg,FName:Shortstring;LineNo:Longint;ErrorAddr:Pointer); [SaveRegisters,Public,Alias : 'FPC_ASSERT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  590. begin
  591. if pointer(AssertErrorProc)<>nil then
  592. AssertErrorProc(Msg,FName,LineNo,ErrorAddr)
  593. else
  594. HandleErrorFrame(227,get_frame);
  595. end;
  596. Procedure SysAssert(Const Msg,FName:Shortstring;LineNo:Longint;ErrorAddr:Pointer);
  597. begin
  598. If msg='' then
  599. write(stderr,'Assertion failed')
  600. else
  601. write(stderr,msg);
  602. Writeln(stderr,' (',FName,', line ',LineNo,').');
  603. Writeln(stderr,'');
  604. Halt(227);
  605. end;
  606. {*****************************************************************************
  607. SetJmp/LongJmp support.
  608. *****************************************************************************}
  609. {$i setjump.inc}
  610. {$ifdef IOCheckWasOn}
  611. {$I+}
  612. {$endif}
  613. {$ifdef RangeCheckWasOn}
  614. {$R+}
  615. {$endif}
  616. {$ifdef OverflowCheckWasOn}
  617. {$Q+}
  618. {$endif}
  619. {
  620. $Log$
  621. Revision 1.43 2003-09-14 11:34:13 peter
  622. * moved int64 asm code to int64p.inc
  623. * save ebx,esi
  624. Revision 1.42 2003/09/03 14:09:37 florian
  625. * arm fixes to the common rtl code
  626. * some generic math code fixed
  627. * ...
  628. Revision 1.41 2003/08/21 22:10:55 olle
  629. - removed parameter from fpc_iocheck
  630. * changed processor compiler directive * to cpu*
  631. Revision 1.40 2003/03/17 14:30:11 peter
  632. * changed address parameter/return values to pointer instead
  633. of longint
  634. Revision 1.39 2003/02/05 21:48:34 mazen
  635. * fixing run time errors related to unimplemented abstract methods in CG
  636. + giving empty emplementations for some RTL functions
  637. Revision 1.38 2002/12/07 14:36:33 carl
  638. - avoid warnings (add typecast)
  639. Revision 1.37 2002/11/18 18:33:51 peter
  640. * Swap(QWord) constant support
  641. Revision 1.36 2002/10/14 19:39:17 peter
  642. * threads unit added for thread support
  643. Revision 1.35 2002/09/18 18:32:01 carl
  644. * assert now halts with exitcode 227 (as Delphi does)
  645. Revision 1.34 2002/09/07 15:07:46 peter
  646. * old logs removed and tabs fixed
  647. Revision 1.33 2002/08/19 19:34:02 peter
  648. * SYSTEMINLINE define that will add inline directives for small
  649. functions and wrappers. This will be defined automaticly when
  650. the compiler defines the HASINLINE directive
  651. Revision 1.32 2002/07/28 20:43:48 florian
  652. * several fixes for linux/powerpc
  653. * several fixes to MT
  654. Revision 1.31 2002/07/26 22:46:06 florian
  655. * interface of system unit for Linux/PowerPC compiles
  656. Revision 1.30 2002/07/26 16:42:00 florian
  657. * endian directive for PowerPC fixed
  658. Revision 1.29 2002/07/04 20:40:09 florian
  659. + some x86-64 support added
  660. Revision 1.28 2002/04/21 15:51:50 carl
  661. * StackError is now a typed constant
  662. + $S can be used under unix
  663. Revision 1.27 2002/04/15 19:38:40 peter
  664. * stackcheck protected against infinite recursive after stack error
  665. * stackcheck requires saveregisters, because it can be called from
  666. iocheck and then will destroy the result of the original function
  667. Revision 1.26 2002/04/15 18:51:20 carl
  668. + generic stack checking can be overriden
  669. Revision 1.25 2002/04/12 17:37:36 carl
  670. + generic stack checking
  671. }