interp: fix support of interpreted functions in map values

Interpreted functions were represented in an inconsistent way in the frame: as a node pointer by default, and wrapped in a function wrapper for maps. 

We now simply use the default (*node) representation, as elsewhere, so values can be assigned, passed and called as for the other types. The alternative (generating a function wrapper) is more complex, costly and reserved for cases where the interpreted function can be called from the runtime.

Test that a map of functions can store both binary functions from used packages and interpreted ones.

Fixes #1090.
This commit is contained in:
Marc Vertes
2021-04-30 11:26:04 +02:00
committed by GitHub
parent 5f8be70066
commit 17d5f1814a
3 changed files with 26 additions and 2 deletions

22
_test/map30.go Normal file
View File

@@ -0,0 +1,22 @@
package main
import "strings"
func f(s string) string { return "hello " + s }
func g(s string) string { return "hi " + s }
var methods = map[string]func(string) string{"f": f}
func main() {
methods["i"] = strings.ToUpper
methods["g"] = g
println(methods["f"]("test"))
println(methods["g"]("test"))
println(methods["i"]("test"))
}
// Output:
// hello test
// hi test
// TEST

View File

@@ -2349,7 +2349,7 @@ func mapLit(n *node) {
if n.nleft == 1 {
child = n.child[1:]
}
typ := n.typ.TypeOf()
typ := n.typ.frameType()
keys := make([]func(*frame) reflect.Value, len(child))
values := make([]func(*frame) reflect.Value, len(child))
for i, c := range child {
@@ -2384,7 +2384,7 @@ func compositeBinMap(n *node) {
if n.nleft == 1 {
child = n.child[1:]
}
typ := n.typ.TypeOf()
typ := n.typ.frameType()
keys := make([]func(*frame) reflect.Value, len(child))
values := make([]func(*frame) reflect.Value, len(child))
for i, c := range child {

View File

@@ -1554,6 +1554,8 @@ func (t *itype) frameType() (r reflect.Type) {
break
}
r = reflect.TypeOf((*valueInterface)(nil)).Elem()
case mapT:
r = reflect.MapOf(t.key.frameType(), t.val.frameType())
case ptrT:
r = reflect.PtrTo(t.val.frameType())
default: