mirror of
https://github.com/golang/go
synced 2024-11-23 14:30:02 -07:00
reflect: fix variadic arg for funcs created by MakeFunc.
Short circuit for calling values funcs by MakeFunc was placed before variadic arg rearrangement code in reflect.call. Fixes #7534. LGTM=khr R=golang-codereviews, bradfitz, khr, rsc CC=golang-codereviews https://golang.org/cl/75370043
This commit is contained in:
parent
89e128dd76
commit
772d22885b
@ -1512,6 +1512,23 @@ func TestMakeFuncInterface(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeFuncVariadic(t *testing.T) {
|
||||
// Test that variadic arguments are packed into a slice and passed as last arg
|
||||
fn := func(_ int, is ...int) []int { return nil }
|
||||
fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
|
||||
ValueOf(&fn).Elem().Set(fv)
|
||||
|
||||
r := fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
|
||||
if r[0] != 2 || r[1] != 3 {
|
||||
t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
|
||||
}
|
||||
|
||||
r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
|
||||
if r[0] != 2 || r[1] != 3 {
|
||||
t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
|
||||
}
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
x, y int
|
||||
}
|
||||
|
@ -453,17 +453,6 @@ func (v Value) call(op string, in []Value) []Value {
|
||||
panic("reflect.Value.Call: call of nil function")
|
||||
}
|
||||
|
||||
// If target is makeFuncStub, short circuit the unpack onto stack /
|
||||
// pack back into []Value for the args and return values. Just do the
|
||||
// call directly.
|
||||
// We need to do this here because otherwise we have a situation where
|
||||
// reflect.callXX calls makeFuncStub, neither of which knows the
|
||||
// layout of the args. That's bad for precise gc & stack copying.
|
||||
x := (*makeFuncImpl)(fn)
|
||||
if x.code == makeFuncStubCode {
|
||||
return x.fn(in)
|
||||
}
|
||||
|
||||
isSlice := op == "CallSlice"
|
||||
n := t.NumIn()
|
||||
if isSlice {
|
||||
@ -521,6 +510,17 @@ func (v Value) call(op string, in []Value) []Value {
|
||||
}
|
||||
nout := t.NumOut()
|
||||
|
||||
// If target is makeFuncStub, short circuit the unpack onto stack /
|
||||
// pack back into []Value for the args and return values. Just do the
|
||||
// call directly.
|
||||
// We need to do this here because otherwise we have a situation where
|
||||
// reflect.callXX calls makeFuncStub, neither of which knows the
|
||||
// layout of the args. That's bad for precise gc & stack copying.
|
||||
x := (*makeFuncImpl)(fn)
|
||||
if x.code == makeFuncStubCode {
|
||||
return x.fn(in)
|
||||
}
|
||||
|
||||
// If the target is methodValueCall, do its work here: add the receiver
|
||||
// argument and call the real target directly.
|
||||
// We need to do this here because otherwise we have a situation where
|
||||
|
Loading…
Reference in New Issue
Block a user