fix: return values of binary calls were not passed in nested calls (#121)
This commit is contained in:
committed by
Ludovic Fernandez
parent
1ccc36a690
commit
c773ad81d0
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user