pointer_reflect.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  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. // apply adds an offset to the pointer to derive a new pointer
  27. // to a specified field. The current pointer must be pointing at a struct.
  28. func (p pointer) apply(f offset) pointer {
  29. // TODO: Handle unexported fields in an API that hides XXX fields?
  30. return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
  31. }
  32. // asType treats p as a pointer to an object of type t and returns the value.
  33. func (p pointer) asType(t reflect.Type) reflect.Value {
  34. if p.v.Type().Elem() != t {
  35. panic(fmt.Sprintf("invalid type: got %v, want %v", p.v.Type(), t))
  36. }
  37. return p.v
  38. }