interp: avoid useless interface wrapping

in `callBin`, call arguments are converted to the corresponding
parameter type. In a case of an interface, the original concrete type
should be preserved instead, and only wrapped to an interface type for
internal interpreter types, as runtime values should already implement the
interface.

This change removes the interface wrapping when parameter is a runtime
value (valueT or ptrT to valueT).

This removes some overhead when handling runtime values, and keep a
similar behavior between interpreted and pre-compiled code. For
example, `io.Copy` preserves its internal optimisations when passed a
`bytes.Buffer`.
This commit is contained in:
Marc Vertes
2020-11-12 10:48:04 +01:00
committed by GitHub
parent ed626f3fb9
commit 13783889cb

View File

@@ -1187,6 +1187,7 @@ func callBin(n *node) {
c.val = reflect.Zero(argType)
}
}
switch c.typ.cat {
case funcT:
values = append(values, genFunctionWrapper(c))
@@ -1199,6 +1200,14 @@ func callBin(n *node) {
default:
values = append(values, genInterfaceWrapper(c, defType))
}
case ptrT:
if c.typ.val.cat == valueT {
values = append(values, genValue(c))
} else {
values = append(values, genInterfaceWrapper(c, defType))
}
case valueT:
values = append(values, genValue(c))
default:
values = append(values, genInterfaceWrapper(c, defType))
}