internal/lib/reflect: fix call method

This commit is contained in:
visualfc
2024-12-18 09:57:58 +08:00
parent d81c5e750d
commit 114c6bd6fc

View File

@@ -2213,11 +2213,9 @@ func (v Value) call(op string, in []Value) (out []Value) {
tin = append([]*abi.Type{rcvrtype}, ft.In...) tin = append([]*abi.Type{rcvrtype}, ft.In...)
tout = ft.Out tout = ft.Out
ioff = 1 ioff = 1
if v.flag&flagIndir != 0 { var ptr unsafe.Pointer
args = append(args, v.ptr) storeRcvr(v, unsafe.Pointer(&ptr))
} else { args = append(args, unsafe.Pointer(&ptr))
args = append(args, unsafe.Pointer(&v.ptr))
}
} else { } else {
if v.flag&flagIndir != 0 { if v.flag&flagIndir != 0 {
fn = *(*unsafe.Pointer)(v.ptr) fn = *(*unsafe.Pointer)(v.ptr)
@@ -2314,6 +2312,23 @@ func (v Value) call(op string, in []Value) (out []Value) {
return return
} }
// v is a method receiver. Store at p the word which is used to
// encode that receiver at the start of the argument list.
// Reflect uses the "interface" calling convention for
// methods, which always uses one word to record the receiver.
func storeRcvr(v Value, p unsafe.Pointer) {
t := v.typ()
if t.Kind() == abi.Interface {
// the interface data word becomes the receiver word
iface := (*nonEmptyInterface)(v.ptr)
*(*unsafe.Pointer)(p) = iface.word
} else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
} else {
*(*unsafe.Pointer)(p) = v.ptr
}
}
var stringType = rtypeOf("") var stringType = rtypeOf("")
// MapIndex returns the value associated with key in the map v. // MapIndex returns the value associated with key in the map v.