pointer_unsafe.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  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
  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. // apply adds an offset to the pointer to derive a new pointer
  32. // to a specified field. The current pointer must be pointing at a struct.
  33. func (p pointer) apply(f offset) pointer {
  34. return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
  35. }
  36. // asType treats p as a pointer to an object of type t and returns the value.
  37. func (p pointer) asType(t reflect.Type) reflect.Value {
  38. return reflect.NewAt(t, p.p)
  39. }