Skip to content

Commit

Permalink
fix: handling values in map of interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
mvertes committed Apr 22, 2020
1 parent 3ed4ec3 commit 7b2d91b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 10 deletions.
18 changes: 18 additions & 0 deletions _test/map24.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"encoding/json"
"fmt"
)

func main() {
jb := []byte(`{"property": "test"}`)
params := map[string]interface{}{"foo": 1}
if err := json.Unmarshal(jb, &params); err != nil {
panic("marshal failed.")
}
fmt.Println(params["foo"], params["property"])
}

// Output:
// 1 test
26 changes: 26 additions & 0 deletions _test/map25.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"encoding/json"
"strconv"
)

func main() {
jb := []byte(`{"num": "2"}`)
params := map[string]interface{}{"foo": "1"}
if err := json.Unmarshal(jb, &params); err != nil {
panic(err)
}
sum := 0
for _, v := range params {
i, err := strconv.Atoi(v.(string))
if err != nil {
panic(err)
}
sum += i
}
println(sum)
}

// Output:
// 3
2 changes: 1 addition & 1 deletion interp/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
wireChild(n)
t := n.child[0].typ
switch t.cat {
case ptrT:
case aliasT, ptrT:
n.typ = t.val
if t.val.cat == valueT {
n.typ = &itype{cat: valueT, rtype: t.val.rtype.Elem()}
Expand Down
33 changes: 28 additions & 5 deletions interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,9 @@ func getIndexArray(n *node) {
}
}

// valueInterfaceType is the reflection type of valueInterface
var valueInterfaceType = reflect.TypeOf((*valueInterface)(nil)).Elem()

// getIndexMap retrieves map value from index
func getIndexMap(n *node) {
dest := genValue(n)
Expand All @@ -1057,7 +1060,11 @@ func getIndexMap(n *node) {
z = reflect.New(n.child[0].typ.val.frameType()).Elem()
n.exec = func(f *frame) bltn {
if v := value0(f).MapIndex(mi); v.IsValid() {
dest(f).Set(v.Elem())
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
dest(f).Set(e)
} else {
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
}
} else {
dest(f).Set(z)
}
Expand Down Expand Up @@ -1091,7 +1098,11 @@ func getIndexMap(n *node) {
z = reflect.New(n.child[0].typ.val.frameType()).Elem()
n.exec = func(f *frame) bltn {
if v := value0(f).MapIndex(value1(f)); v.IsValid() {
dest(f).Set(v.Elem())
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
dest(f).Set(e)
} else {
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
}
} else {
dest(f).Set(z)
}
Expand Down Expand Up @@ -1137,7 +1148,11 @@ func getIndexMap2(n *node) {
n.exec = func(f *frame) bltn {
v := value0(f).MapIndex(mi)
if v.IsValid() {
dest(f).Set(v.Elem())
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
dest(f).Set(e)
} else {
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
}
}
if doStatus {
value2(f).SetBool(v.IsValid())
Expand Down Expand Up @@ -1169,7 +1184,11 @@ func getIndexMap2(n *node) {
n.exec = func(f *frame) bltn {
v := value0(f).MapIndex(value1(f))
if v.IsValid() {
dest(f).Set(v.Elem())
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
dest(f).Set(e)
} else {
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
}
}
if doStatus {
value2(f).SetBool(v.IsValid())
Expand Down Expand Up @@ -1900,7 +1919,11 @@ func rangeMap(n *node) {
return fnext
}
f.data[index0].Set(iter.Key())
f.data[index1].Set(iter.Value().Elem())
if e := iter.Value().Elem(); e.Type().AssignableTo(valueInterfaceType) {
f.data[index1].Set(e)
} else {
f.data[index1].Set(reflect.ValueOf(valueInterface{n, e}))
}
return tnext
}
} else {
Expand Down
7 changes: 3 additions & 4 deletions interp/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func genValue(n *node) func(*frame) reflect.Value {
case basicLit:
v := n.rval
if !v.IsValid() {
v = reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()).Elem()
v = reflect.New(interf).Elem()
}
return func(f *frame) reflect.Value { return v }
case funcDecl:
Expand Down Expand Up @@ -149,10 +149,9 @@ func genValueRangeArray(n *node) func(*frame) reflect.Value {

func genValueInterfacePtr(n *node) func(*frame) reflect.Value {
value := genValue(n)
it := reflect.TypeOf((*interface{})(nil)).Elem()

return func(f *frame) reflect.Value {
v := reflect.New(it).Elem()
v := reflect.New(interf).Elem()
v.Set(value(f))
return v.Addr()
}
Expand All @@ -179,7 +178,7 @@ func genValueInterface(n *node) func(*frame) reflect.Value {

func zeroInterfaceValue() reflect.Value {
n := &node{kind: basicLit, typ: &itype{cat: nilT, untyped: true}}
v := reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()).Elem()
v := reflect.New(interf).Elem()
return reflect.ValueOf(valueInterface{n, v})
}

Expand Down

0 comments on commit 7b2d91b

Please sign in to comment.