Skip to content

Commit 74f0ccb

Browse files
committed
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 <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent c1d197a commit 74f0ccb

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

src/reflect/value.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,10 @@ func (v Value) call(op string, in []Value) []Value {
499499
switch st := abid.call.steps[0]; st.kind {
500500
case abiStepStack:
501501
storeRcvr(rcvr, stackArgs)
502-
case abiStepIntReg, abiStepPointer:
503-
// Even pointers can go into the uintptr slot because
504-
// they'll be kept alive by the Values referenced by
505-
// this frame. Reflection forces these to be heap-allocated,
506-
// so we don't need to worry about stack copying.
502+
case abiStepPointer:
503+
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ptrs[st.ireg]))
504+
fallthrough
505+
case abiStepIntReg:
507506
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
508507
case abiStepFloatReg:
509508
storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
@@ -972,13 +971,21 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *a
972971
var methodRegs abi.RegArgs
973972

974973
// Deal with the receiver. It's guaranteed to only be one word in size.
975-
if st := methodABI.call.steps[0]; st.kind == abiStepStack {
974+
switch st := methodABI.call.steps[0]; st.kind {
975+
case abiStepStack:
976976
// Only copy the receiver to the stack if the ABI says so.
977977
// Otherwise, it'll be in a register already.
978978
storeRcvr(rcvr, methodFrame)
979-
} else {
979+
case abiStepPointer:
980980
// Put the receiver in a register.
981-
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints))
981+
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ptrs[st.ireg]))
982+
fallthrough
983+
case abiStepIntReg:
984+
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints[st.ireg]))
985+
case abiStepFloatReg:
986+
storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Floats[st.freg]))
987+
default:
988+
panic("unknown ABI parameter kind")
982989
}
983990

984991
// Translate the rest of the arguments.

0 commit comments

Comments
 (0)