func (e *Executor) run() { stackState := e.runner.prog.getStack() stackOffset := len(e.runner.stack) - len(stackState) copy(e.runner.stack[stackOffset:], stackState) resumeResult := 0 // don't resume if len(stackState) > 0 { resumeResult = -1 // resume; return this value to snapshot function caller } fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) if err != nil { return } done := make(chan struct{}) defer func() { syscall.Close(fds[1]) <-done }() go func() { defer close(done) e.slave(fds[0], e.sigs, e.printer, e.cont) }() runtime.LockOSThread() defer runtime.UnlockOSThread() setRunArg(e.arg) globalsMemoryAddr := (*reflect.SliceHeader)(unsafe.Pointer(&e.runner.globalsMemory)).Data memoryAddr := globalsMemoryAddr + uintptr(e.runner.memoryOffset) growMemorySize := len(e.runner.globalsMemory) - e.runner.memoryOffset trap, memorySize, stackPtr := run(e.runner.prog.getText(), int(e.runner.memorySize), memoryAddr, uintptr(growMemorySize), e.runner.stack, stackOffset, resumeResult, fds[1]) e.runner.memorySize = wasm.MemorySize(memorySize) e.runner.lastTrap = traps.Id(trap) e.runner.lastStackPtr = stackPtr if trap == 0 { e.result = getRunResult() } else { e.err = e.runner.lastTrap } return }
// MemoryLimits are available after preliminary sections have been loaded. func (m *Module) MemoryLimits() (initial, maximum wasm.MemorySize) { initial = wasm.MemorySize(m.memoryLimits.initial) maximum = wasm.MemorySize(m.memoryLimits.maximum) return }
func (s *Snapshot) NewRunner(growMemorySize wasm.MemorySize, stackSize int) (r *Runner, err error) { memorySize := wasm.MemorySize(len(s.data) - s.memoryOffset) return newRunner(s, memorySize, growMemorySize, stackSize) }