diff --git a/src/cpfront/posix/generic/System/Mod/Kernel.cp b/src/cpfront/posix/generic/System/Mod/Kernel.cp
index 279fef9483a2960fa170d6ef66c71e7771eae372..87ea635fc7524de0eca557d825ed0fc6dfee3f8c 100644 (file)
(* init fpu? *)
(* add signal blocking to avoid race conditions in Try/Trap/TrapHandler *)
(* add BeepHook for Beep *)
- (* implement Call using libffi *)
CONST
nameLen* = 256;
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;
FreeMem(modAdr, modSize)
END InvalModMem;
- PROCEDURE TryRead (from, to, c: INTEGER);
- VAR i: INTEGER; x: BYTE;
+ PROCEDURE IsReadable* (from, to: INTEGER): BOOLEAN;
+ VAR r: BOOLEAN; jmp: setjmp.sigjmp_buf; res: setjmp.int; i: INTEGER; x: BYTE;
BEGIN
- 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)
+ r := checkReadable;
+ jmp := checkReadableEnv;
+ 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;
- END TryRead;
-
- PROCEDURE^ Try* (h: TryHandler; a, b, c: INTEGER);
-
- PROCEDURE IsReadable* (from, to: INTEGER): BOOLEAN;
- VAR i: INTEGER;
- BEGIN
- i := trapCount;
- Try(TryRead, from, to, 0);
- RETURN trapCount = i
+ checkReadableEnv := jmp;
+ checkReadable := r;
+ RETURN res = 0
END IsReadable;
(* --------------------- NEW implementation (portable) -------------------- *)
farg[cn] := S.VAL(Ptype, S.ADR(typ));
END SetType;
- PROCEDURE PushVal (size: INTEGER);
+ PROCEDURE PushAdr (size: INTEGER);
BEGIN
ASSERT(size IN {1, 2, 4, 8}, 20);
- ASSERT(littleEndian); (* !!! swap 64bit value *)
+ ASSERT(littleEndian OR (size <= 4), 100); (* !!! swap 64bit value *)
varg[cn] := S.ADR(par[d]);
INC(cn); INC(d, MAX(1, size DIV 4))
+ END PushAdr;
+
+ PROCEDURE PushVal (size: INTEGER);
+ BEGIN
+ ASSERT(size IN {1, 2, 4, 8}, 20);
+ ASSERT(littleEndian OR (size <= 4), 100); (* !!! swap 64bit value *)
+ varg[cn] := par[d];
+ INC(cn); INC(d, MAX(1, size DIV 4))
END PushVal;
PROCEDURE Push (IN typ: LibFFI.type);
BEGIN
- SetType(typ); PushVal(typ.size)
+ SetType(typ); PushAdr(typ.size)
END Push;
BEGIN
targ[ut].type := LibFFI.TYPE_STRUCT;
targ[ut].elements := S.VAL(PPtype, S.ADR(earg[ue]));
SetType(targ[ut]); INC(ut);
- size := MIN(1, typ.size);
+ size := MAX(1, typ.size);
(* !!! better to pass original layout *)
WHILE size >= 8 DO
earg[ue] := S.VAL(Ptype, S.ADR(LibFFI.type_uint64));
FOR i := 0 TO typ.id DIV 16 - 1 DO
Push(LibFFI.type_sint32) (* dim size *)
END
+ ELSE (* fix array *)
+ INC(d) (* skip size *)
END
END
END;
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)
- (* !!! err := halt code *)
END;
ELSE (* unknown *)
END;
(* !!! 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