1
0
mirror of https://github.com/golang/go synced 2024-11-27 03:21:18 -07:00

reflect: store receiver in pointer slot for reflect call

The code comment says that the receiver doesn't need to go into
the pointer slot as it will be kept alive in this frame. But it
doesn't. There is no direct reference of rcvr or v (the receiver)
after storing the arguments. Also, it is clearer to explicitly
keep it alive.

Fixes #52800.

Change-Id: Ie3fa8e83f6ecc69d62e8bfab767314d5181f5dc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/407508
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2022-05-20 19:35:44 -04:00
parent c1d197a96e
commit 74f0ccb68b

View File

@ -499,11 +499,10 @@ func (v Value) call(op string, in []Value) []Value {
switch st := abid.call.steps[0]; st.kind {
case abiStepStack:
storeRcvr(rcvr, stackArgs)
case abiStepIntReg, abiStepPointer:
// Even pointers can go into the uintptr slot because
// they'll be kept alive by the Values referenced by
// this frame. Reflection forces these to be heap-allocated,
// so we don't need to worry about stack copying.
case abiStepPointer:
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ptrs[st.ireg]))
fallthrough
case abiStepIntReg:
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
case abiStepFloatReg:
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
@ -972,13 +971,21 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *a
var methodRegs abi.RegArgs
// Deal with the receiver. It's guaranteed to only be one word in size.
if st := methodABI.call.steps[0]; st.kind == abiStepStack {
switch st := methodABI.call.steps[0]; st.kind {
case abiStepStack:
// Only copy the receiver to the stack if the ABI says so.
// Otherwise, it'll be in a register already.
storeRcvr(rcvr, methodFrame)
} else {
case abiStepPointer:
// Put the receiver in a register.
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints))
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ptrs[st.ireg]))
fallthrough
case abiStepIntReg:
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints[st.ireg]))
case abiStepFloatReg:
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Floats[st.freg]))
default:
panic("unknown ABI parameter kind")
}
// Translate the rest of the arguments.