No setjump in GC for emscripten/wasm (#9386)

This commit is contained in:
Yuriy Glukhov 2018-10-17 01:46:13 +03:00 • committed by Andreas Rumpf
commit dc72cf7564

View file

@ -236,7 +236,7 @@ else:
# ----------------- stack management -------------------------------------- # ----------------- stack management --------------------------------------
# inspired from Smart Eiffel # inspired from Smart Eiffel
when defined(emscripten): when defined(emscripten) or defined(wasm):
const stackIncreases = true const stackIncreases = true
elif defined(sparc): elif defined(sparc):
const stackIncreases = false const stackIncreases = false
@ -332,21 +332,28 @@ elif stackIncreases:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Generic code for architectures where addresses increase as the stack grows. # Generic code for architectures where addresses increase as the stack grows.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
var when defined(emscripten) or defined(wasm):
jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int var
# a little hack to get the size of a JmpBuf in the generated C code jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
# in a platform independent way # a little hack to get the size of a JmpBuf in the generated C code
# in a platform independent way
template forEachStackSlotAux(gch, gcMark: untyped) {.dirty.} =
for stack in gch.stack.items():
var max = cast[ByteAddress](gch.stack.bottom)
var sp = cast[ByteAddress](addr(registers)) -% sizeof(pointer)
while sp >=% max:
gcMark(gch, cast[PPointer](sp)[])
sp = sp -% sizeof(pointer)
template forEachStackSlot(gch, gcMark: untyped) {.dirty.} = template forEachStackSlot(gch, gcMark: untyped) {.dirty.} =
var registers {.noinit.}: C_JmpBuf when defined(emscripten) or defined(wasm):
var registers: cint
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. forEachStackSlotAux(gch, gcMark)
for stack in gch.stack.items(): else:
var max = cast[ByteAddress](gch.stack.bottom) var registers {.noinit.}: C_JmpBuf
var sp = cast[ByteAddress](addr(registers)) -% sizeof(pointer) if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
while sp >=% max: forEachStackSlotAux(gch, gcMark)
gcMark(gch, cast[PPointer](sp)[])
sp = sp -% sizeof(pointer)
else: else:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------