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:
22
_test/map30.go
Normal file
22
_test/map30.go
Normal 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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user