; layout of a setjmp buffer:
;
; -----------------
-; | signal mask | (only for Berkeley 4.2)
+; | signal mask | (only for Berkeley 4.[2-])
; -----------------
; | |
; | GTO descriptor |
; the caller; This problem is solved by the front-end, which must pass
; it as an extra parameter to setjmp.
+; a GTO descriptor must be in the global data area
gtobuf
bss 3*EM_PSIZE,0,0
inp $fill_ret_area
exp $setjmp
pro $setjmp,0
- mes 11
#ifdef __BSD4_2
+; save mask of currently blocked signals.
+; longjmp must restore this mask
loc 0
cal $sigblock
asp EM_WSIZE
loi EM_PSIZE
stf 3*EM_PSIZE
#endif
- ; create GTO descriptor for longjmp
+; create GTO descriptor for longjmp
lxl 0
dch ; Local Base of caller
lxa 0 ; Stackpointer of caller
lal EM_PSIZE
- loi EM_PSIZE
+ loi EM_PSIZE ; Return address of caller
lal 0
- loi EM_PSIZE
- sti 3*EM_PSIZE ; stored in jmpbuf
+ loi EM_PSIZE ; address of jmpbuf
+ sti 3*EM_PSIZE ; LB, SP, and PC stored in jmpbuf
loc 0
- ret EM_WSIZE
+ ret EM_WSIZE ; setjmp must return 0
end 0
pro $fill_ret_area,0
+; put argument in function result area
lol 0
ret EM_WSIZE
end 0
exp $longjmp
pro $longjmp,?
+#ifdef __BSD4_2
+; restore signal mask
lal 0
loi EM_PSIZE
-#ifdef __BSD4_2
- dup EM_PSIZE
lof 3*EM_PSIZE
cal $sigsetmask
asp EM_WSIZE
lfr EM_WSIZE
asp EM_WSIZE
#endif
+ lal 0
+ loi EM_PSIZE ; address of jmpbuf
lae gtobuf
- blm 3*EM_PSIZE
- lol EM_PSIZE
+ blm 3*EM_PSIZE ; fill GTO descriptor from jmpbuf
+ lol EM_PSIZE ; second parameter of longjmp: the return value
dup EM_WSIZE
zne *3
- ; of course, longjmp may not return 0!
+; of course, longjmp may not return 0!
asp EM_WSIZE
loc 1
3
+; put return value in function result area
cal $fill_ret_area
asp EM_WSIZE
gto gtobuf ; there we go ...
+; ASP and GTO do not damage function result area
end 0