]> Cypherpunks.ru repositories - gostls13.git/commitdiff
reflect: fix methodValueCall code pointer mismatched
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 19 Oct 2021 09:34:43 +0000 (16:34 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 19 Oct 2021 16:19:27 +0000 (16:19 +0000)
CL 322350 changed how to take address of assembly functions, using
abi.FuncPCABI0 intrinsic. But we forgot to update the code in
Value.UnsafePointer (was Value.Pointer) to reflect that change.

This CL fixes that bug, and also add a test to make sure the code
pointer is in sync.

Change-Id: I05ae7df31c706583a0f374d8af027066528f5ceb
Reviewed-on: https://go-review.googlesource.com/c/go/+/356809
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/reflect/all_test.go
src/reflect/export_test.go
src/reflect/makefunc.go
src/reflect/value.go

index 141cc8f73d433095cb551cf74bc52b3918d9f0a3..91aac9cccb287b996793634e54df005a9d00a11f 100644 (file)
@@ -7722,3 +7722,11 @@ func TestNotInHeapDeref(t *testing.T) {
        v = ValueOf((*nih)(unsafe.Pointer(new(int))))
        shouldPanic("reflect: reflect.Value.Elem on an invalid notinheap pointer", func() { v.Elem() })
 }
+
+func TestMethodCallValueCodePtr(t *testing.T) {
+       p := ValueOf(Point{}).Method(1).UnsafePointer()
+       want := MethodValueCallCodePtr()
+       if got := uintptr(p); got != want {
+               t.Errorf("methodValueCall code pointer mismatched, want: %v, got: %v", want, got)
+       }
+}
index 01749e30d85229a43ad976f738e60f324b9a7057..ba7fb68067a9370ca84e7f63a41dc7ff7c73af08 100644 (file)
@@ -161,3 +161,5 @@ func SetArgRegs(ints, floats int, floatSize uintptr) (oldInts, oldFloats int, ol
        clearLayoutCache()
        return
 }
+
+var MethodValueCallCodePtr = methodValueCallCodePtr
index 588be8bcc155602cdad79e7f4b7003444fbe7772..d0b0935cb8cb2944fadb591c04ff3b42f0207c05 100644 (file)
@@ -107,7 +107,7 @@ func makeMethodValue(op string, v Value) Value {
        // v.Type returns the actual type of the method value.
        ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
 
-       code := abi.FuncPCABI0(methodValueCall)
+       code := methodValueCallCodePtr()
 
        // methodValue contains a stack map for use by the runtime
        _, _, abi := funcLayout(ftyp, nil)
@@ -130,6 +130,10 @@ func makeMethodValue(op string, v Value) Value {
        return Value{&ftyp.rtype, unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
 }
 
+func methodValueCallCodePtr() uintptr {
+       return abi.FuncPCABI0(methodValueCall)
+}
+
 // methodValueCall is an assembly function that is the code half of
 // the function returned from makeMethodValue. It expects a *methodValue
 // as its context register, and its job is to invoke callMethod(ctxt, frame)
index a272714ac962a38027e910d9a6b0c945ade1d41f..1d385f6bf9f943473f72680b5cfa4cbd164a3356 100644 (file)
@@ -2488,8 +2488,8 @@ func (v Value) UnsafePointer() unsafe.Pointer {
                        // created via reflect have the same underlying code pointer,
                        // so their Pointers are equal. The function used here must
                        // match the one used in makeMethodValue.
-                       f := methodValueCall
-                       return **(**unsafe.Pointer)(unsafe.Pointer(&f))
+                       code := methodValueCallCodePtr()
+                       return *(*unsafe.Pointer)(unsafe.Pointer(&code))
                }
                p := v.pointer()
                // Non-nil func value points at data block.