interp: fix closure in a struct field

Functions in a struct fields are always wrapped (as potentially
used by the runtime), so generate a function wrapper also for
closure when assigned to a struct field.

When such a function is called from the interpreter, ensure that
interface arguments are also wrapped so method and receiver resolution
can be performed.

Fixes partially #1043.
This commit is contained in:
Marc Vertes
2021-03-11 15:26:04 +01:00
committed by GitHub
parent fdfcb9c1df
commit 7d8fdbc1fc
5 changed files with 70 additions and 10 deletions

View File

@@ -1334,16 +1334,18 @@ func callBin(n *node) {
tnext := getExec(n.tnext)
fnext := getExec(n.fnext)
child := n.child[1:]
value := genValue(n.child[0])
c0 := n.child[0]
value := genValue(c0)
var values []func(*frame) reflect.Value
funcType := n.child[0].typ.rtype
funcType := c0.typ.rtype
wt := wrappedType(c0)
variadic := -1
if funcType.IsVariadic() {
variadic = funcType.NumIn() - 1
}
// A method signature obtained from reflect.Type includes receiver as 1st arg, except for interface types.
rcvrOffset := 0
if recv := n.child[0].recv; recv != nil && !isInterface(recv.node.typ) {
if recv := c0.recv; recv != nil && !isInterface(recv.node.typ) {
if variadic > 0 || funcType.NumIn() > len(child) {
rcvrOffset = 1
}
@@ -1392,6 +1394,11 @@ func callBin(n *node) {
}
}
if wt != nil && wt.arg[i].cat == interfaceT {
values = append(values, genValueInterface(c))
break
}
switch c.typ.cat {
case funcT:
values = append(values, genFunctionWrapper(c))