Skip to content

Commit

Permalink
interp: avoid useless interface wrapping
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
mvertes authored Nov 12, 2020
1 parent ed626f3 commit 1378388
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,7 @@ func callBin(n *node) {
c.val = reflect.Zero(argType)
}
}

switch c.typ.cat {
case funcT:
values = append(values, genFunctionWrapper(c))
Expand All @@ -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))
}
Expand Down

0 comments on commit 1378388

Please sign in to comment.