From 13783889cbcb9d5248dce91a2c96f2d39661b3f2 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 12 Nov 2020 10:48:04 +0100 Subject: [PATCH] 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`. --- interp/run.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interp/run.go b/interp/run.go index efb42a2b2..543beddbf 100644 --- a/interp/run.go +++ b/interp/run.go @@ -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)) }