setjmp.e 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #
  2. mes 2,_EM_WSIZE,_EM_PSIZE
  3. ;
  4. ; layout of a setjmp buffer:
  5. ;
  6. ; -----------------
  7. ; | flag | (!0 when blocked signals saved (POSIX))
  8. ; -----------------
  9. ; | signal mask/set | (for Berkeley 4.[2-] / POSIX)
  10. ; -----------------
  11. ; | |
  12. ; | GTO descriptor |
  13. ; | (SP, LB, PC) |
  14. ; | |
  15. ; -----------------
  16. ;
  17. ; setjmp saves the signalmask, PC, SP, and LB of caller, and creates a
  18. ; GTO descriptor from this.
  19. ; The big problem here is how to get the return address, i.e. the PC of
  20. ; the caller; This problem is solved by the front-end, which must pass
  21. ; it as an extra parameter to setjmp.
  22. ; a GTO descriptor must be in the global data area
  23. gtobuf
  24. bss 3*_EM_PSIZE,0,0
  25. inp $fill_ret_area
  26. exp $__setjmp
  27. pro $__setjmp,0
  28. #if defined(_POSIX_SOURCE)
  29. ; save mask of currently blocked signals.
  30. ; longjmp must restore this mask
  31. lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
  32. lal 0
  33. loi _EM_PSIZE
  34. stf 3*_EM_PSIZE+_EM_LSIZE
  35. lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
  36. zeq *1
  37. lal 0
  38. loi _EM_PSIZE
  39. adp 3*_EM_PSIZE
  40. cal $__newsigset
  41. asp _EM_PSIZE
  42. 1
  43. #elif defined(__BSD4_2)
  44. loc 0
  45. cal $sigblock
  46. asp _EM_WSIZE
  47. lfr _EM_WSIZE
  48. lal 0
  49. loi _EM_PSIZE
  50. stf 3*_EM_PSIZE
  51. #endif
  52. ; create GTO descriptor for longjmp
  53. lxl 0
  54. dch ; Local Base of caller
  55. lxa 0 ; Stackpointer of caller
  56. lal _EM_PSIZE+_EM_WSIZE
  57. loi _EM_PSIZE ; Return address of caller
  58. lal 0
  59. loi _EM_PSIZE ; address of jmpbuf
  60. sti 3*_EM_PSIZE ; LB, SP, and PC stored in jmpbuf
  61. loc 0
  62. ret _EM_WSIZE ; setjmp must return 0
  63. end 0
  64. pro $fill_ret_area,0
  65. ; put argument in function result area
  66. lol 0
  67. ret _EM_WSIZE
  68. end 0
  69. exp $longjmp
  70. pro $longjmp,?
  71. #if defined(_POSIX_SOURCE)
  72. ; restore blocked mask
  73. lal 0
  74. loi _EM_PSIZE
  75. lof 3*_EM_PSIZE+_EM_LSIZE
  76. zeq *2
  77. lal 0
  78. loi _EM_PSIZE
  79. adp 3*_EM_PSIZE
  80. cal $__oldsigset
  81. asp _EM_PSIZE
  82. 2
  83. #elif defined(__BSD4_2)
  84. ; restore signal mask
  85. lal 0
  86. loi _EM_PSIZE
  87. lof 3*_EM_PSIZE
  88. cal $_sigsetmask
  89. asp _EM_WSIZE
  90. lfr _EM_WSIZE
  91. asp _EM_WSIZE
  92. #endif
  93. lal 0
  94. loi _EM_PSIZE ; address of jmpbuf
  95. lae gtobuf
  96. blm 3*_EM_PSIZE ; fill GTO descriptor from jmpbuf
  97. lol _EM_PSIZE ; second parameter of longjmp: the return value
  98. dup _EM_WSIZE
  99. zne *3
  100. ; of course, longjmp may not return 0!
  101. inc
  102. 3
  103. ; put return value in function result area
  104. cal $fill_ret_area
  105. asp _EM_WSIZE
  106. gto gtobuf ; there we go ...
  107. ; ASP and GTO do not damage function result area
  108. end 0