123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #
- mes 2,_EM_WSIZE,_EM_PSIZE
- ;
- ; layout of a setjmp buffer:
- ;
- ; -----------------
- ; | flag | (!0 when blocked signals saved (POSIX))
- ; -----------------
- ; | signal mask/set | (for Berkeley 4.[2-] / POSIX)
- ; -----------------
- ; | |
- ; | 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
- inp $fill_ret_area
- exp $__setjmp
- pro $__setjmp,0
- #if defined(_POSIX_SOURCE)
- ; save mask of currently blocked signals.
- ; longjmp must restore this mask
- 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)
- loc 0
- cal $sigblock
- asp _EM_WSIZE
- lfr _EM_WSIZE
- lal 0
- loi _EM_PSIZE
- stf 3*_EM_PSIZE
- #endif
- ; create GTO descriptor for longjmp
- lxl 0
- dch ; Local Base of caller
- lxa 0 ; Stackpointer of caller
- lal _EM_PSIZE+_EM_WSIZE
- loi _EM_PSIZE ; Return address of caller
- lal 0
- loi _EM_PSIZE ; address of jmpbuf
- sti 3*_EM_PSIZE ; LB, SP, and PC stored in jmpbuf
- loc 0
- 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,?
- #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)
- ; restore signal mask
- lal 0
- loi _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 ; 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!
- inc
- 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
|