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:
parent
c1d197a96e
commit
74f0ccb68b
@ -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(®Args.Ptrs[st.ireg]))
|
||||
fallthrough
|
||||
case abiStepIntReg:
|
||||
storeRcvr(rcvr, unsafe.Pointer(®Args.Ints[st.ireg]))
|
||||
case abiStepFloatReg:
|
||||
storeRcvr(rcvr, unsafe.Pointer(®Args.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.
|
||||
|
Loading…
Reference in New Issue
Block a user