fix: improve setting results in multiple output functions
This commit is contained in:
17
_test/fun19.go
Normal file
17
_test/fun19.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func foo() ([]string, error) {
|
||||||
|
return nil, fmt.Errorf("bar")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a, b := foo()
|
||||||
|
fmt.Println(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [] bar
|
||||||
19
_test/fun20.go
Normal file
19
_test/fun20.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var myerr error = fmt.Errorf("bar")
|
||||||
|
|
||||||
|
func ferr() error { return myerr }
|
||||||
|
|
||||||
|
func foo() ([]string, error) {
|
||||||
|
return nil, ferr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a, b := foo()
|
||||||
|
fmt.Println(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [] bar
|
||||||
@@ -823,12 +823,16 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n.typ = &itype{cat: valueT, rtype: typ.Out(0)}
|
n.typ = &itype{cat: valueT, rtype: typ.Out(0)}
|
||||||
|
if n.anc.kind == returnStmt {
|
||||||
|
n.findex = childPos(n)
|
||||||
|
} else {
|
||||||
n.findex = sc.add(n.typ)
|
n.findex = sc.add(n.typ)
|
||||||
for i := 1; i < typ.NumOut(); i++ {
|
for i := 1; i < typ.NumOut(); i++ {
|
||||||
sc.add(&itype{cat: valueT, rtype: typ.Out(i)})
|
sc.add(&itype{cat: valueT, rtype: typ.Out(i)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if n.child[0].action == aGetFunc {
|
if n.child[0].action == aGetFunc {
|
||||||
// Allocate a frame entry to store the anonymous function definition.
|
// Allocate a frame entry to store the anonymous function definition.
|
||||||
@@ -836,10 +840,14 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
|
|||||||
}
|
}
|
||||||
if typ := n.child[0].typ; len(typ.ret) > 0 {
|
if typ := n.child[0].typ; len(typ.ret) > 0 {
|
||||||
n.typ = typ.ret[0]
|
n.typ = typ.ret[0]
|
||||||
|
if n.anc.kind == returnStmt {
|
||||||
|
n.findex = childPos(n)
|
||||||
|
} else {
|
||||||
n.findex = sc.add(n.typ)
|
n.findex = sc.add(n.typ)
|
||||||
for _, t := range typ.ret[1:] {
|
for _, t := range typ.ret[1:] {
|
||||||
sc.add(t)
|
sc.add(t)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
n.findex = -1
|
n.findex = -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ func call(n *node) {
|
|||||||
case returnStmt:
|
case returnStmt:
|
||||||
// Function call from a return statement: forward return values (always at frame start).
|
// Function call from a return statement: forward return values (always at frame start).
|
||||||
for i := range rtypes {
|
for i := range rtypes {
|
||||||
j := i
|
j := n.findex + i
|
||||||
ret := n.child[0].typ.ret[i]
|
ret := n.child[0].typ.ret[i]
|
||||||
callret := n.anc.val.(*node).typ.ret[i]
|
callret := n.anc.val.(*node).typ.ret[i]
|
||||||
if callret.cat == interfaceT && ret.cat != interfaceT {
|
if callret.cat == interfaceT && ret.cat != interfaceT {
|
||||||
@@ -983,6 +983,7 @@ func callBin(n *node) {
|
|||||||
case aReturn:
|
case aReturn:
|
||||||
// The function call is part of a return statement, store output results
|
// The function call is part of a return statement, store output results
|
||||||
// directly in the frame location of outputs of the current function.
|
// directly in the frame location of outputs of the current function.
|
||||||
|
b := childPos(n)
|
||||||
n.exec = func(f *frame) bltn {
|
n.exec = func(f *frame) bltn {
|
||||||
in := make([]reflect.Value, l)
|
in := make([]reflect.Value, l)
|
||||||
for i, v := range values {
|
for i, v := range values {
|
||||||
@@ -990,7 +991,7 @@ func callBin(n *node) {
|
|||||||
}
|
}
|
||||||
out := value(f).Call(in)
|
out := value(f).Call(in)
|
||||||
for i, v := range out {
|
for i, v := range out {
|
||||||
f.data[i].Set(v)
|
f.data[b+i].Set(v)
|
||||||
}
|
}
|
||||||
return tnext
|
return tnext
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user