Improve unsafe reflect value handling.

This commit modifies the unsafeReflectValue function to recognize
reference types even when the indirection flag is not set for the series
of golang commits after ecccf07e7f9d and before 82f48826c6c7 which
introduced the additional scalar field in the reflect.Value struct.  That
additional field has since been removed, but the intention of this code is
to work properly across all Go versions and other packages make use of the
logic.

Thanks to @shurcooL for providing example code which wasn't working
properly with the function when it was exported and therefore being called
in ways which spew itself does not.
This commit is contained in:
Dave Collins 2014-11-15 19:57:16 -06:00
parent 128854244a
commit 83f84dc933
1 changed files with 13 additions and 1 deletions

View File

@ -109,7 +109,19 @@ func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
vt = reflect.PtrTo(v.Type())
indirects++
} else if offsetScalar != 0 {
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetScalar)
// The value is in the scalar field when it's not one of the
// reference types.
switch vt.Kind() {
case reflect.Uintptr:
case reflect.Chan:
case reflect.Func:
case reflect.Map:
case reflect.Ptr:
case reflect.UnsafePointer:
default:
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
offsetScalar)
}
}
pv := reflect.NewAt(vt, upv)