pointer_unsafe.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build !purego,!appengine
  5. package impl
  6. import (
  7. "reflect"
  8. "unsafe"
  9. )
  10. // offset represents the offset to a struct field, accessible from a pointer.
  11. // The offset is the byte offset to the field from the start of the struct.
  12. type offset uintptr
  13. // offsetOf returns a field offset for the struct field.
  14. func offsetOf(f reflect.StructField) offset {
  15. return offset(f.Offset)
  16. }
  17. // pointer is a pointer to a message struct or field.
  18. type pointer struct{ p unsafe.Pointer }
  19. // pointerOfValue returns v as a pointer.
  20. func pointerOfValue(v reflect.Value) pointer {
  21. return pointer{p: unsafe.Pointer(v.Pointer())}
  22. }
  23. // pointerOfIface returns the pointer portion of an interface.
  24. func pointerOfIface(v interface{}) pointer {
  25. type ifaceHeader struct {
  26. Type unsafe.Pointer
  27. Data unsafe.Pointer
  28. }
  29. return pointer{p: (*ifaceHeader)(unsafe.Pointer(&v)).Data}
  30. }
  31. // IsNil reports whether the pointer is nil.
  32. func (p pointer) IsNil() bool {
  33. return p.p == nil
  34. }
  35. // Apply adds an offset to the pointer to derive a new pointer
  36. // to a specified field. The pointer must be valid and pointing at a struct.
  37. func (p pointer) Apply(f offset) pointer {
  38. if p.IsNil() {
  39. panic("invalid nil pointer")
  40. }
  41. return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
  42. }
  43. // AsValueOf treats p as a pointer to an object of type t and returns the value.
  44. // It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
  45. func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
  46. return reflect.NewAt(t, p.p)
  47. }
  48. // AsIfaceOf treats p as a pointer to an object of type t and returns the value.
  49. // It is equivalent to p.AsValueOf(t).Interface()
  50. func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
  51. // TODO: Use tricky unsafe magic to directly create ifaceHeader.
  52. return p.AsValueOf(t).Interface()
  53. }