pointer_reflect.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. "fmt"
  8. "reflect"
  9. )
  10. // offset represents the offset to a struct field, accessible from a pointer.
  11. // The offset is the field index into a struct.
  12. type offset []int
  13. // offsetOf returns a field offset for the struct field.
  14. func offsetOf(f reflect.StructField) offset {
  15. if len(f.Index) != 1 {
  16. panic("embedded structs are not supported")
  17. }
  18. return f.Index
  19. }
  20. // pointer is an abstract representation of a pointer to a struct or field.
  21. type pointer struct{ v reflect.Value }
  22. // pointerOfValue returns v as a pointer.
  23. func pointerOfValue(v reflect.Value) pointer {
  24. return pointer{v: v}
  25. }
  26. // pointerOfIface returns the pointer portion of an interface.
  27. func pointerOfIface(v *interface{}) pointer {
  28. return pointer{v: reflect.ValueOf(*v)}
  29. }
  30. // apply adds an offset to the pointer to derive a new pointer
  31. // to a specified field. The current pointer must be pointing at a struct.
  32. func (p pointer) apply(f offset) pointer {
  33. // TODO: Handle unexported fields in an API that hides XXX fields?
  34. return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
  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. if p.v.Type().Elem() != t {
  39. panic(fmt.Sprintf("invalid type: got %v, want %v", p.v.Type(), t))
  40. }
  41. return p.v
  42. }