diff options
| author | Cherry Zhang <cherryyz@google.com> | 2019-10-15 17:51:32 -0400 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2019-10-16 00:05:37 +0000 |
| commit | c4817f5d4f64f65d65fbd78145fb2bf8e80b6e5f (patch) | |
| tree | f8e2a9844d11f18566209e7011c014e1ce5d7b79 /src/cmd/internal/obj/wasm | |
| parent | dc37bd2ac92c2fe0aaef9f15ac3e4f747f2bf341 (diff) | |
| download | go-c4817f5d4f64f65d65fbd78145fb2bf8e80b6e5f.tar.xz | |
cmd/compile: on Wasm and AIX, let deferred nil function panic at invocation
The Go spec requires
If a deferred function value evaluates to nil, execution
panics when the function is invoked, not when the "defer"
statement is executed.
On Wasm and AIX, currently we actually emit a nil check at the
point of defer statement, which will make it panic too early.
This CL fixes this.
Also, on Wasm, now the nil function will be passed through
deferreturn to jmpdefer, which does an explicit nil check and
calls sigpanic if it is nil. This sigpanic, being called from
assembly, is ABI0. So change the assembler backend to also
handle sigpanic in ABI0.
Fixes #34926.
Updates #8047.
Change-Id: I28489a571cee36d2aef041f917b8cfdc31d557d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/201297
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/internal/obj/wasm')
| -rw-r--r-- | src/cmd/internal/obj/wasm/wasmobj.go | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go index ed8edb064b..255e7b68a2 100644 --- a/src/cmd/internal/obj/wasm/wasmobj.go +++ b/src/cmd/internal/obj/wasm/wasmobj.go @@ -129,6 +129,7 @@ var ( morestackNoCtxt *obj.LSym gcWriteBarrier *obj.LSym sigpanic *obj.LSym + sigpanic0 *obj.LSym deferreturn *obj.LSym jmpdefer *obj.LSym ) @@ -143,6 +144,7 @@ func instinit(ctxt *obj.Link) { morestackNoCtxt = ctxt.Lookup("runtime.morestack_noctxt") gcWriteBarrier = ctxt.Lookup("runtime.gcWriteBarrier") sigpanic = ctxt.LookupABI("runtime.sigpanic", obj.ABIInternal) + sigpanic0 = ctxt.LookupABI("runtime.sigpanic", 0) // sigpanic called from assembly, which has ABI0 deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal) // jmpdefer is defined in assembly as ABI0, but what we're // looking for is the *call* to jmpdefer from the Go function @@ -491,7 +493,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } // return value of call is on the top of the stack, indicating whether to unwind the WebAssembly stack - if call.As == ACALLNORESUME && call.To.Sym != sigpanic { // sigpanic unwinds the stack, but it never resumes + if call.As == ACALLNORESUME && call.To.Sym != sigpanic && call.To.Sym != sigpanic0 { // sigpanic unwinds the stack, but it never resumes // trying to unwind WebAssembly stack but call has no resume point, terminate with error p = appendp(p, AIf) p = appendp(p, obj.AUNDEF) |
