ack/lang/cem/libcc.ansi/core/setjmp/setjmp.e

114 lines
2.4 KiB
Plaintext
Raw Normal View History

1989-05-11 10:21:37 +00:00
#
mes 2,_EM_WSIZE,_EM_PSIZE
1989-05-11 10:21:37 +00:00
;
; layout of a setjmp buffer:
;
; -----------------
1990-01-22 12:53:21 +00:00
; | flag | (!0 when blocked signals saved (POSIX))
; -----------------
; | signal mask/set | (for Berkeley 4.[2-] / POSIX)
1989-05-11 10:21:37 +00:00
; -----------------
; | |
; | GTO descriptor |
; | (SP, LB, PC) |
; | |
; -----------------
;
; setjmp saves the signalmask, PC, SP, and LB of caller, and creates a
; GTO descriptor from this.
; The big problem here is how to get the return address, i.e. the PC of
; 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
1989-05-11 10:21:37 +00:00
inp $fill_ret_area
1990-01-22 12:53:21 +00:00
exp $__setjmp
pro $__setjmp,0
#if defined(_POSIX_SOURCE)
1989-05-11 10:21:37 +00:00
; save mask of currently blocked signals.
; longjmp must restore this mask
1990-01-22 12:53:21 +00:00
lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
lal 0
loi _EM_PSIZE
stf 3*_EM_PSIZE+_EM_LSIZE
lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
zeq *1
lal 0
loi _EM_PSIZE
adp 3*_EM_PSIZE
cal $__newsigset
asp _EM_PSIZE
1
#elif defined(__BSD4_2)
1989-05-11 10:21:37 +00:00
loc 0
cal $sigblock
asp _EM_WSIZE
lfr _EM_WSIZE
1989-05-11 10:21:37 +00:00
lal 0
loi _EM_PSIZE
stf 3*_EM_PSIZE
1989-05-11 10:21:37 +00:00
#endif
; create GTO descriptor for longjmp
lxl 0
dch ; Local Base of caller
lxa 0 ; Stackpointer of caller
1990-01-22 12:53:21 +00:00
lal _EM_PSIZE+_EM_WSIZE
loi _EM_PSIZE ; Return address of caller
1989-05-11 10:21:37 +00:00
lal 0
loi _EM_PSIZE ; address of jmpbuf
sti 3*_EM_PSIZE ; LB, SP, and PC stored in jmpbuf
1989-05-11 10:21:37 +00:00
loc 0
ret _EM_WSIZE ; setjmp must return 0
1989-05-11 10:21:37 +00:00
end 0
pro $fill_ret_area,0
; put argument in function result area
lol 0
ret _EM_WSIZE
1989-05-11 10:21:37 +00:00
end 0
exp $longjmp
pro $longjmp,?
1990-01-22 12:53:21 +00:00
#if defined(_POSIX_SOURCE)
; restore blocked mask
lal 0
loi _EM_PSIZE
lof 3*_EM_PSIZE+_EM_LSIZE
zeq *2
lal 0
loi _EM_PSIZE
adp 3*_EM_PSIZE
cal $__oldsigset
asp _EM_PSIZE
2
#elif defined(__BSD4_2)
1989-05-11 10:21:37 +00:00
; restore signal mask
lal 0
loi _EM_PSIZE
lof 3*_EM_PSIZE
1990-08-09 15:27:13 +00:00
cal $_sigsetmask
asp _EM_WSIZE
lfr _EM_WSIZE
asp _EM_WSIZE
1989-05-11 10:21:37 +00:00
#endif
1989-05-11 10:21:37 +00:00
lal 0
loi _EM_PSIZE ; address of jmpbuf
1989-05-11 10:21:37 +00:00
lae gtobuf
blm 3*_EM_PSIZE ; fill GTO descriptor from jmpbuf
lol _EM_PSIZE ; second parameter of longjmp: the return value
dup _EM_WSIZE
1989-05-11 10:21:37 +00:00
zne *3
; of course, longjmp may not return 0!
1990-01-22 12:53:21 +00:00
inc
1989-05-11 10:21:37 +00:00
3
; put return value in function result area
cal $fill_ret_area
asp _EM_WSIZE
1989-05-11 10:21:37 +00:00
gto gtobuf ; there we go ...
; ASP and GTO do not damage function result area
end 0