diff --git a/src/cpfront/posix/generic/System/Mod/Kernel.cp b/src/cpfront/posix/generic/System/Mod/Kernel.cp
index bf9e33d9a4f94021cbdae310e7884ba6d5e9a673..7c2c0bf26f9052a1bf73235b000c60cb52b07596 100644 (file)
trapCount-: INTEGER;
err-, pc-, sp-, fp-, stack-, val-: INTEGER;
- isTry: BOOLEAN;
- startEnv: setjmp.sigjmp_buf;
+ isTry, checkReadable: BOOLEAN;
+ startEnv, checkReadableEnv: setjmp.sigjmp_buf;
tryEnv: setjmp.jmp_buf;
startDLink, tryDLink: DLink;
PROCEDURE^ Try* (h: TryHandler; a, b, c: INTEGER);
PROCEDURE IsReadable* (from, to: INTEGER): BOOLEAN;
- VAR i: INTEGER;
+ VAR r: BOOLEAN; res: setjmp.int; i: INTEGER; x: BYTE;
BEGIN
- i := trapCount;
- Try(TryRead, from, to, 0);
- RETURN trapCount = i
+ r := checkReadable;
+ checkReadable := TRUE;
+ res := setjmp.sigsetjmp(checkReadableEnv, 1);
+ IF res = 0 THEN
+ IF from <= to THEN
+ FOR i := from TO to DO
+ S.GET(i, x)
+ END
+ ELSE
+ FOR i := to TO from BY -1 DO
+ S.GET(i, x)
+ END
+ END
+ END;
+ checkReadable := r;
+ RETURN res = 0
END IsReadable;
(* --------------------- NEW implementation (portable) -------------------- *)
stdlib.abort
END Trap;
- PROCEDURE [ccall] TrapHandler (signo: signal.int; IN _info: signal.siginfo_t; context: ADDRESS);
- TYPE SigInfo = POINTER [untagged] TO signal._siginfo_t;
- VAR res: signal.int; info: SigInfo;
+ PROCEDURE [ccall] TrapHandler (signo: signal.int; IN info: signal.siginfo_t; context: ADDRESS);
+ VAR res: signal.int;
BEGIN
- info := S.VAL(SigInfo, S.ADR(_info)); (* !!! hack for CPfront *)
+ IF checkReadable THEN
+ setjmp.siglongjmp(checkReadableEnv, 1)
+ END;
IF trapped THEN
DefaultTrapViewer;
IF ~secondTrap THEN trapped := FALSE; secondTrap := TRUE END
END;
- err := -signo; pc := 0; sp := 0; fp := 0; stack := 0; val := 0;
+ err := -signo; pc := 0; sp := 0; fp := 0; stack := baseStack; val := 0;
CASE signo OF
| signal.SIGFPE:
- pc := info.si_addr;
val := info.si_code;
+ pc := info.info.sigfpe.si_addr;
CASE info.si_code OF
| signal.FPE_INTDIV: err := 139 (* division by zero *)
| signal.FPE_INTOVF: err := 138 (* integer overflow *)
val := info.si_code;
err := 200 (* keyboard interrupt *)
| signal.SIGSEGV:
- val := info.si_addr;
+ val := info.info.sigsegv.si_addr;
err := 203 (* illigal read *)
| signal.SIGBUS:
- val := info.si_addr;
+ val := info.info.sigbus.si_addr;
err := 10001H (* bus error *)
| signal.SIGILL:
- pc := info.si_addr;
+ pc := info.info.sigill.si_addr;
err := 202; (* illigal instruction *)
IF IsReadable(pc, pc + 4) THEN
S.GET(pc, val)
(* !!! InitFPU *)
TrapCleanup;
IF isTry THEN
- SetDLink(tryDLink);
setjmp._longjmp(tryEnv, 1)
END;
IF (err = 128) OR (err = 200) & ~intTrap THEN (* do nothing *)
END;
trapped := FALSE; secondTrap := FALSE;
IF restart # NIL THEN
- SetDLink(startDLink);
setjmp.siglongjmp(startEnv, 1)
END;
stdlib.abort