fix: return values of binary calls were not passed in nested calls (#121)

This commit is contained in:
Marc Vertes
2019-03-17 15:51:28 +01:00
committed by Ludovic Fernandez
parent 1ccc36a690
commit c773ad81d0
4 changed files with 33 additions and 17 deletions

View File

@@ -10,3 +10,6 @@ func main() {
t := time.Date(2009, time.November, 10, 23, 4, 5, 0, time.UTC)
fmt.Println(t.Clock())
}
// Output:
// 23 4 5

View File

@@ -44,7 +44,6 @@ func TestInterpConsistencyBuild(t *testing.T) {
file.Name() == "heap.go" || // TODO not implemented yet
file.Name() == "chan6.go" || // FIXME related to channel #7
file.Name() == "select1.go" || // FIXME related to channel #7
file.Name() == "time3.go" || // FIXME related to named returns
file.Name() == "type5.go" || // used to illustrate a limitation with no workaround, related to the fact that the reflect package does not allow the creation of named types
file.Name() == "type6.go" || // used to illustrate a limitation with no workaround, related to the fact that the reflect package does not allow the creation of named types

View File

@@ -7306,7 +7306,8 @@ import (
func main() {
t := time.Date(2009, time.November, 10, 23, 4, 5, 0, time.UTC)
fmt.Println(t.Clock())
}`
}
`
i := interp.New(interp.Opt{Entry: "main"})
i.Use(stdlib.Value)
_, err := i.Eval(src)
@@ -7314,6 +7315,8 @@ func main() {
panic(err)
}
// Output:
// 23 4 5
}
func Example_time4() {

View File

@@ -478,13 +478,21 @@ func call(n *Node) {
// compute input argument value functions
for i, c := range child {
if isRegularCall(c) {
switch {
case isBinCall(c):
// Handle nested function calls: pass returned values as arguments
numOut := c.child[0].typ.rtype.NumOut()
for j := 0; j < numOut; j++ {
ind := c.findex + j
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
case isRegularCall(c):
// Arguments are return values of a nested function call
for j := range c.child[0].typ.ret {
ind := c.findex + j
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
} else {
default:
if c.kind == BasicLit {
var argType reflect.Type
if variadic >= 0 && i >= variadic {
@@ -605,13 +613,21 @@ func callBin(n *Node) {
}
for i, c := range child {
if isRegularCall(c) {
switch {
case isBinCall(c):
// Handle nested function calls: pass returned values as arguments
numOut := c.child[0].typ.rtype.NumOut()
for j := 0; j < numOut; j++ {
ind := c.findex + j
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
case isRegularCall(c):
// Handle nested function calls: pass returned values as arguments
for j := range c.child[0].typ.ret {
ind := c.findex + j
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
} else {
default:
if c.kind == BasicLit {
// Convert literal value (untyped) to function argument type (if not an interface{})
var argType reflect.Type
@@ -625,17 +641,12 @@ func callBin(n *Node) {
c.val = reflect.Zero(argType)
}
}
// FIXME: nil types are forbidden and should be handled at compile time (CFG)
if c.typ != nil {
switch c.typ.cat {
case FuncT:
values = append(values, genNodeWrapper(c))
case InterfaceT:
values = append(values, genValueInterfaceValue(c))
default:
values = append(values, genValue(c))
}
} else {
switch c.typ.cat {
case FuncT:
values = append(values, genNodeWrapper(c))
case InterfaceT:
values = append(values, genValueInterfaceValue(c))
default:
values = append(values, genValue(c))
}
}