mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-15 00:13:43 +00:00
compiler: key deferInvokeFuncs on distinct name
This commit is contained in:
+4
-4
@@ -372,12 +372,12 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||||||
// Method call on an interface.
|
// Method call on an interface.
|
||||||
|
|
||||||
// Get callback type number.
|
// Get callback type number.
|
||||||
methodName := instr.Call.Method.FullName()
|
key := b.getInvokeFunctionName(&instr.Call)
|
||||||
if _, ok := b.deferInvokeFuncs[methodName]; !ok {
|
if _, ok := b.deferInvokeFuncs[key]; !ok {
|
||||||
b.deferInvokeFuncs[methodName] = len(b.allDeferFuncs)
|
b.deferInvokeFuncs[key] = len(b.allDeferFuncs)
|
||||||
b.allDeferFuncs = append(b.allDeferFuncs, &instr.Call)
|
b.allDeferFuncs = append(b.allDeferFuncs, &instr.Call)
|
||||||
}
|
}
|
||||||
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferInvokeFuncs[methodName]), false)
|
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferInvokeFuncs[key]), false)
|
||||||
|
|
||||||
// Collect all values to be put in the struct (starting with
|
// Collect all values to be put in the struct (starting with
|
||||||
// runtime._defer fields, followed by the call parameters).
|
// runtime._defer fields, followed by the call parameters).
|
||||||
|
|||||||
@@ -1193,8 +1193,7 @@ func (c *compilerContext) getMethodSetValue(methods []*types.Func) llvm.Value {
|
|||||||
// thunk is declared, not defined: it will be defined by the interface lowering
|
// thunk is declared, not defined: it will be defined by the interface lowering
|
||||||
// pass.
|
// pass.
|
||||||
func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
|
func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
|
||||||
s, _ := c.getTypeCodeName(instr.Value.Type().Underlying())
|
fnName := c.getInvokeFunctionName(instr)
|
||||||
fnName := s + "." + instr.Method.Name() + "$invoke"
|
|
||||||
llvmFn := c.mod.NamedFunction(fnName)
|
llvmFn := c.mod.NamedFunction(fnName)
|
||||||
if llvmFn.IsNil() {
|
if llvmFn.IsNil() {
|
||||||
sig := instr.Method.Type().(*types.Signature)
|
sig := instr.Method.Type().(*types.Signature)
|
||||||
@@ -1213,6 +1212,11 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
|
|||||||
return llvmFn
|
return llvmFn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *compilerContext) getInvokeFunctionName(instr *ssa.CallCommon) string {
|
||||||
|
s, _ := c.getTypeCodeName(instr.Value.Type().Underlying())
|
||||||
|
return s + "." + instr.Method.Name() + "$invoke"
|
||||||
|
}
|
||||||
|
|
||||||
// createInterfaceTypeAssert creates a call to a declared-but-not-defined
|
// createInterfaceTypeAssert creates a call to a declared-but-not-defined
|
||||||
// $typeassert function for the given interface. This function will be defined
|
// $typeassert function for the given interface. This function will be defined
|
||||||
// by the interface lowering pass as a type-ID comparison chain, avoiding the
|
// by the interface lowering pass as a type-ID comparison chain, avoiding the
|
||||||
|
|||||||
Vendored
+41
@@ -70,6 +70,7 @@ func main() {
|
|||||||
|
|
||||||
// regression testing
|
// regression testing
|
||||||
regression1033()
|
regression1033()
|
||||||
|
regression5541()
|
||||||
|
|
||||||
//Test deferred builtins
|
//Test deferred builtins
|
||||||
testDeferBuiltinClose()
|
testDeferBuiltinClose()
|
||||||
@@ -224,6 +225,46 @@ func foo(bar *Bar) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regression5541RuntimeClosed, regression5541ModuleClosed int
|
||||||
|
|
||||||
|
type regression5541Closer interface {
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type regression5541Runtime interface {
|
||||||
|
Foo()
|
||||||
|
regression5541Closer
|
||||||
|
}
|
||||||
|
|
||||||
|
type regression5541RuntimeImpl struct{}
|
||||||
|
|
||||||
|
func (*regression5541RuntimeImpl) Foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*regression5541RuntimeImpl) Close() {
|
||||||
|
regression5541RuntimeClosed++
|
||||||
|
}
|
||||||
|
|
||||||
|
type regression5541Module struct{}
|
||||||
|
|
||||||
|
func (*regression5541Module) Close() {
|
||||||
|
regression5541ModuleClosed++
|
||||||
|
}
|
||||||
|
|
||||||
|
func regression5541() {
|
||||||
|
func() {
|
||||||
|
var runtime regression5541Runtime = ®ression5541RuntimeImpl{}
|
||||||
|
defer runtime.Close()
|
||||||
|
|
||||||
|
var module regression5541Closer = ®ression5541Module{}
|
||||||
|
defer module.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if regression5541RuntimeClosed != 1 || regression5541ModuleClosed != 1 {
|
||||||
|
println("deferred interface methods were not both called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type issue1304 struct {
|
type issue1304 struct {
|
||||||
a [0]int // zero-length field
|
a [0]int // zero-length field
|
||||||
b int // field 'b' covers entire struct
|
b int // field 'b' covers entire struct
|
||||||
|
|||||||
Reference in New Issue
Block a user