diff --git a/lib/wasm/wasm_exec.js b/lib/wasm/wasm_exec.js index af7e28f5f48..ec96d42db52 100644 --- a/lib/wasm/wasm_exec.js +++ b/lib/wasm/wasm_exec.js @@ -217,6 +217,7 @@ } const testCallExport = (a, b) => { + this._inst.exports.testExport0(); return this._inst.exports.testExport(a, b); } diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go index 28ecd20cd0e..48eee4e3ea1 100644 --- a/src/cmd/internal/obj/wasm/wasmobj.go +++ b/src/cmd/internal/obj/wasm/wasmobj.go @@ -974,6 +974,10 @@ func genWasmExportWrapper(s *obj.LSym, appendp func(p *obj.Prog, as obj.As, args Sym: s, // PC_F Offset: 1, // PC_B=1, past the prologue, so we have the right SP delta } + if framesize == 0 { + // Frameless function, no prologue. + retAddr.Offset = 0 + } p = appendp(p, AI64Const, retAddr) p = appendp(p, AI64Store, constAddr(0)) // Set PC_B parameter to function entry @@ -1014,11 +1018,13 @@ func genWasmExportWrapper(s *obj.LSym, appendp func(p *obj.Prog, as obj.As, args } // Epilogue. Cannot use ARET as we don't follow Go calling convention. - // SP += framesize - p = appendp(p, AGet, regAddr(REG_SP)) - p = appendp(p, AI32Const, constAddr(framesize)) - p = appendp(p, AI32Add) - p = appendp(p, ASet, regAddr(REG_SP)) + if framesize > 0 { + // SP += framesize + p = appendp(p, AGet, regAddr(REG_SP)) + p = appendp(p, AI32Const, constAddr(framesize)) + p = appendp(p, AI32Add) + p = appendp(p, ASet, regAddr(REG_SP)) + } p = appendp(p, AReturn) } diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go index 76fa4424425..9ab913f2abf 100644 --- a/src/syscall/js/js_test.go +++ b/src/syscall/js/js_test.go @@ -75,6 +75,11 @@ func testExport(a int32, b int64) int64 { return <-ch + <-ch } +//go:wasmexport testExport0 +func testExport0() { // no arg or result (see issue 69584) + runtime.GC() +} + var testExportCalled bool func growStack(n int64) {