// 1. pop the caller
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
MOVL 4(SP), DX // fn
MOVL 8(SP), BX // caller sp
LEAL -4(BX), SP // caller sp after CALL
// 1. pop the caller
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
MOVQ 8(SP), DX // fn
MOVQ 16(SP), BX // caller sp
LEAQ -8(BX), SP // caller sp after CALL
// 1. grab stored LR for caller
// 2. sub 4 bytes to get back to BL deferreturn
// 3. B to fn
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
MOVW 0(SP), LR
MOVW $-4(LR), LR // BL deferreturn
MOVW fn+0(FP), R7
--- /dev/null
+// run
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type Closer interface {
+ Close()
+}
+
+func nilInterfaceDeferCall() {
+ var x Closer
+ defer x.Close()
+}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("did not panic")
+ }
+ }()
+ f()
+}
+
+func main() {
+ shouldPanic(nilInterfaceDeferCall)
+}