github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/internal/reflectlite/value.go (about)

     1  // Copyright 2009 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  
     5  package reflectlite
     6  
     7  import (
     8  	"runtime"
     9  	"unsafe"
    10  
    11  	"github.com/hxx258456/ccgo/internal/unsafeheader"
    12  )
    13  
    14  const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
    15  
    16  // Value is the reflection interface to a Go value.
    17  //
    18  // Not all methods apply to all kinds of values. Restrictions,
    19  // if any, are noted in the documentation for each method.
    20  // Use the Kind method to find out the kind of value before
    21  // calling kind-specific methods. Calling a method
    22  // inappropriate to the kind of type causes a run time panic.
    23  //
    24  // The zero Value represents no value.
    25  // Its IsValid method returns false, its Kind method returns Invalid,
    26  // its String method returns "<invalid Value>", and all other methods panic.
    27  // Most functions and methods never return an invalid value.
    28  // If one does, its documentation states the conditions explicitly.
    29  //
    30  // A Value can be used concurrently by multiple goroutines provided that
    31  // the underlying Go value can be used concurrently for the equivalent
    32  // direct operations.
    33  //
    34  // To compare two Values, compare the results of the Interface method.
    35  // Using == on two Values does not compare the underlying values
    36  // they represent.
    37  type Value struct {
    38  	// typ holds the type of the value represented by a Value.
    39  	typ *rtype
    40  
    41  	// Pointer-valued data or, if flagIndir is set, pointer to data.
    42  	// Valid when either flagIndir is set or typ.pointers() is true.
    43  	ptr unsafe.Pointer
    44  
    45  	// flag holds metadata about the value.
    46  	// The lowest bits are flag bits:
    47  	//	- flagStickyRO: obtained via unexported not embedded field, so read-only
    48  	//	- flagEmbedRO: obtained via unexported embedded field, so read-only
    49  	//	- flagIndir: val holds a pointer to the data
    50  	//	- flagAddr: v.CanAddr is true (implies flagIndir)
    51  	// Value cannot represent method values.
    52  	// The next five bits give the Kind of the value.
    53  	// This repeats typ.Kind() except for method values.
    54  	// The remaining 23+ bits give a method number for method values.
    55  	// If flag.kind() != Func, code can assume that flagMethod is unset.
    56  	// If ifaceIndir(typ), code can assume that flagIndir is set.
    57  	flag
    58  
    59  	// A method value represents a curried method invocation
    60  	// like r.Read for some receiver r. The typ+val+flag bits describe
    61  	// the receiver r, but the flag's Kind bits say Func (methods are
    62  	// functions), and the top bits of the flag give the method number
    63  	// in r's type's method table.
    64  }
    65  
    66  type flag uintptr
    67  
    68  const (
    69  	flagKindWidth        = 5 // there are 27 kinds
    70  	flagKindMask    flag = 1<<flagKindWidth - 1
    71  	flagStickyRO    flag = 1 << 5
    72  	flagEmbedRO     flag = 1 << 6
    73  	flagIndir       flag = 1 << 7
    74  	flagAddr        flag = 1 << 8
    75  	flagMethod      flag = 1 << 9
    76  	flagMethodShift      = 10
    77  	flagRO          flag = flagStickyRO | flagEmbedRO
    78  )
    79  
    80  func (f flag) kind() Kind {
    81  	return Kind(f & flagKindMask)
    82  }
    83  
    84  func (f flag) ro() flag {
    85  	if f&flagRO != 0 {
    86  		return flagStickyRO
    87  	}
    88  	return 0
    89  }
    90  
    91  // pointer returns the underlying pointer represented by v.
    92  // v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
    93  func (v Value) pointer() unsafe.Pointer {
    94  	if v.typ.size != ptrSize || !v.typ.pointers() {
    95  		panic("can't call pointer on a non-pointer Value")
    96  	}
    97  	if v.flag&flagIndir != 0 {
    98  		return *(*unsafe.Pointer)(v.ptr)
    99  	}
   100  	return v.ptr
   101  }
   102  
   103  // packEface converts v to the empty interface.
   104  func packEface(v Value) interface{} {
   105  	t := v.typ
   106  	var i interface{}
   107  	e := (*emptyInterface)(unsafe.Pointer(&i))
   108  	// First, fill in the data portion of the interface.
   109  	switch {
   110  	case ifaceIndir(t):
   111  		if v.flag&flagIndir == 0 {
   112  			panic("bad indir")
   113  		}
   114  		// Value is indirect, and so is the interface we're making.
   115  		ptr := v.ptr
   116  		if v.flag&flagAddr != 0 {
   117  			// TODO: pass safe boolean from valueInterface so
   118  			// we don't need to copy if safe==true?
   119  			c := unsafe_New(t)
   120  			typedmemmove(t, c, ptr)
   121  			ptr = c
   122  		}
   123  		e.word = ptr
   124  	case v.flag&flagIndir != 0:
   125  		// Value is indirect, but interface is direct. We need
   126  		// to load the data at v.ptr into the interface data word.
   127  		e.word = *(*unsafe.Pointer)(v.ptr)
   128  	default:
   129  		// Value is direct, and so is the interface.
   130  		e.word = v.ptr
   131  	}
   132  	// Now, fill in the type portion. We're very careful here not
   133  	// to have any operation between the e.word and e.typ assignments
   134  	// that would let the garbage collector observe the partially-built
   135  	// interface value.
   136  	e.typ = t
   137  	return i
   138  }
   139  
   140  // unpackEface converts the empty interface i to a Value.
   141  func unpackEface(i interface{}) Value {
   142  	e := (*emptyInterface)(unsafe.Pointer(&i))
   143  	// NOTE: don't read e.word until we know whether it is really a pointer or not.
   144  	t := e.typ
   145  	if t == nil {
   146  		return Value{}
   147  	}
   148  	f := flag(t.Kind())
   149  	if ifaceIndir(t) {
   150  		f |= flagIndir
   151  	}
   152  	return Value{t, e.word, f}
   153  }
   154  
   155  // A ValueError occurs when a Value method is invoked on
   156  // a Value that does not support it. Such cases are documented
   157  // in the description of each method.
   158  type ValueError struct {
   159  	Method string
   160  	Kind   Kind
   161  }
   162  
   163  func (e *ValueError) Error() string {
   164  	if e.Kind == 0 {
   165  		return "reflect: call of " + e.Method + " on zero Value"
   166  	}
   167  	return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
   168  }
   169  
   170  // methodName returns the name of the calling method,
   171  // assumed to be two stack frames above.
   172  func methodName() string {
   173  	pc, _, _, _ := runtime.Caller(2)
   174  	f := runtime.FuncForPC(pc)
   175  	if f == nil {
   176  		return "unknown method"
   177  	}
   178  	return f.Name()
   179  }
   180  
   181  // emptyInterface is the header for an interface{} value.
   182  type emptyInterface struct {
   183  	typ  *rtype
   184  	word unsafe.Pointer
   185  }
   186  
   187  // mustBeExported panics if f records that the value was obtained using
   188  // an unexported field.
   189  func (f flag) mustBeExported() {
   190  	if f == 0 {
   191  		panic(&ValueError{methodName(), 0})
   192  	}
   193  	if f&flagRO != 0 {
   194  		panic("reflect: " + methodName() + " using value obtained using unexported field")
   195  	}
   196  }
   197  
   198  // mustBeAssignable panics if f records that the value is not assignable,
   199  // which is to say that either it was obtained using an unexported field
   200  // or it is not addressable.
   201  func (f flag) mustBeAssignable() {
   202  	if f == 0 {
   203  		panic(&ValueError{methodName(), Invalid})
   204  	}
   205  	// Assignable if addressable and not read-only.
   206  	if f&flagRO != 0 {
   207  		panic("reflect: " + methodName() + " using value obtained using unexported field")
   208  	}
   209  	if f&flagAddr == 0 {
   210  		panic("reflect: " + methodName() + " using unaddressable value")
   211  	}
   212  }
   213  
   214  // CanSet reports whether the value of v can be changed.
   215  // A Value can be changed only if it is addressable and was not
   216  // obtained by the use of unexported struct fields.
   217  // If CanSet returns false, calling Set or any type-specific
   218  // setter (e.g., SetBool, SetInt) will panic.
   219  func (v Value) CanSet() bool {
   220  	return v.flag&(flagAddr|flagRO) == flagAddr
   221  }
   222  
   223  // Elem returns the value that the interface v contains
   224  // or that the pointer v points to.
   225  // It panics if v's Kind is not Interface or Ptr.
   226  // It returns the zero Value if v is nil.
   227  func (v Value) Elem() Value {
   228  	k := v.kind()
   229  	switch k {
   230  	case Interface:
   231  		var eface interface{}
   232  		if v.typ.NumMethod() == 0 {
   233  			eface = *(*interface{})(v.ptr)
   234  		} else {
   235  			eface = (interface{})(*(*interface {
   236  				M()
   237  			})(v.ptr))
   238  		}
   239  		x := unpackEface(eface)
   240  		if x.flag != 0 {
   241  			x.flag |= v.flag.ro()
   242  		}
   243  		return x
   244  	case Ptr:
   245  		ptr := v.ptr
   246  		if v.flag&flagIndir != 0 {
   247  			ptr = *(*unsafe.Pointer)(ptr)
   248  		}
   249  		// The returned value's address is v's value.
   250  		if ptr == nil {
   251  			return Value{}
   252  		}
   253  		tt := (*ptrType)(unsafe.Pointer(v.typ))
   254  		typ := tt.elem
   255  		fl := v.flag&flagRO | flagIndir | flagAddr
   256  		fl |= flag(typ.Kind())
   257  		return Value{typ, ptr, fl}
   258  	}
   259  	panic(&ValueError{"reflectlite.Value.Elem", v.kind()})
   260  }
   261  
   262  func valueInterface(v Value) interface{} {
   263  	if v.flag == 0 {
   264  		panic(&ValueError{"reflectlite.Value.Interface", 0})
   265  	}
   266  
   267  	if v.kind() == Interface {
   268  		// Special case: return the element inside the interface.
   269  		// Empty interface has one layout, all interfaces with
   270  		// methods have a second layout.
   271  		if v.numMethod() == 0 {
   272  			return *(*interface{})(v.ptr)
   273  		}
   274  		return *(*interface {
   275  			M()
   276  		})(v.ptr)
   277  	}
   278  
   279  	// TODO: pass safe to packEface so we don't need to copy if safe==true?
   280  	return packEface(v)
   281  }
   282  
   283  // IsNil reports whether its argument v is nil. The argument must be
   284  // a chan, func, interface, map, pointer, or slice value; if it is
   285  // not, IsNil panics. Note that IsNil is not always equivalent to a
   286  // regular comparison with nil in Go. For example, if v was created
   287  // by calling ValueOf with an uninitialized interface variable i,
   288  // i==nil will be true but v.IsNil will panic as v will be the zero
   289  // Value.
   290  func (v Value) IsNil() bool {
   291  	k := v.kind()
   292  	switch k {
   293  	case Chan, Func, Map, Ptr, UnsafePointer:
   294  		// if v.flag&flagMethod != 0 {
   295  		// 	return false
   296  		// }
   297  		ptr := v.ptr
   298  		if v.flag&flagIndir != 0 {
   299  			ptr = *(*unsafe.Pointer)(ptr)
   300  		}
   301  		return ptr == nil
   302  	case Interface, Slice:
   303  		// Both interface and slice are nil if first word is 0.
   304  		// Both are always bigger than a word; assume flagIndir.
   305  		return *(*unsafe.Pointer)(v.ptr) == nil
   306  	}
   307  	panic(&ValueError{"reflectlite.Value.IsNil", v.kind()})
   308  }
   309  
   310  // IsValid reports whether v represents a value.
   311  // It returns false if v is the zero Value.
   312  // If IsValid returns false, all other methods except String panic.
   313  // Most functions and methods never return an invalid Value.
   314  // If one does, its documentation states the conditions explicitly.
   315  func (v Value) IsValid() bool {
   316  	return v.flag != 0
   317  }
   318  
   319  // Kind returns v's Kind.
   320  // If v is the zero Value (IsValid returns false), Kind returns Invalid.
   321  func (v Value) Kind() Kind {
   322  	return v.kind()
   323  }
   324  
   325  // implemented in runtime:
   326  func chanlen(unsafe.Pointer) int
   327  func maplen(unsafe.Pointer) int
   328  
   329  // Len returns v's length.
   330  // It panics if v's Kind is not Array, Chan, Map, Slice, or String.
   331  func (v Value) Len() int {
   332  	k := v.kind()
   333  	switch k {
   334  	case Array:
   335  		tt := (*arrayType)(unsafe.Pointer(v.typ))
   336  		return int(tt.len)
   337  	case Chan:
   338  		return chanlen(v.pointer())
   339  	case Map:
   340  		return maplen(v.pointer())
   341  	case Slice:
   342  		// Slice is bigger than a word; assume flagIndir.
   343  		return (*unsafeheader.Slice)(v.ptr).Len
   344  	case String:
   345  		// String is bigger than a word; assume flagIndir.
   346  		return (*unsafeheader.String)(v.ptr).Len
   347  	}
   348  	panic(&ValueError{"reflect.Value.Len", v.kind()})
   349  }
   350  
   351  // NumMethod returns the number of exported methods in the value's method set.
   352  func (v Value) numMethod() int {
   353  	if v.typ == nil {
   354  		panic(&ValueError{"reflectlite.Value.NumMethod", Invalid})
   355  	}
   356  	return v.typ.NumMethod()
   357  }
   358  
   359  // Set assigns x to the value v.
   360  // It panics if CanSet returns false.
   361  // As in Go, x's value must be assignable to v's type.
   362  func (v Value) Set(x Value) {
   363  	v.mustBeAssignable()
   364  	x.mustBeExported() // do not let unexported x leak
   365  	var target unsafe.Pointer
   366  	if v.kind() == Interface {
   367  		target = v.ptr
   368  	}
   369  	x = x.assignTo("reflectlite.Set", v.typ, target)
   370  	if x.flag&flagIndir != 0 {
   371  		typedmemmove(v.typ, v.ptr, x.ptr)
   372  	} else {
   373  		*(*unsafe.Pointer)(v.ptr) = x.ptr
   374  	}
   375  }
   376  
   377  // Type returns v's type.
   378  func (v Value) Type() Type {
   379  	f := v.flag
   380  	if f == 0 {
   381  		panic(&ValueError{"reflectlite.Value.Type", Invalid})
   382  	}
   383  	// Method values not supported.
   384  	return v.typ
   385  }
   386  
   387  /*
   388   * constructors
   389   */
   390  
   391  // implemented in package runtime
   392  func unsafe_New(*rtype) unsafe.Pointer
   393  
   394  // ValueOf returns a new Value initialized to the concrete value
   395  // stored in the interface i. ValueOf(nil) returns the zero Value.
   396  func ValueOf(i interface{}) Value {
   397  	if i == nil {
   398  		return Value{}
   399  	}
   400  
   401  	// TODO: Maybe allow contents of a Value to live on the stack.
   402  	// For now we make the contents always escape to the heap. It
   403  	// makes life easier in a few places (see chanrecv/mapassign
   404  	// comment below).
   405  	escapes(i)
   406  
   407  	return unpackEface(i)
   408  }
   409  
   410  // assignTo returns a value v that can be assigned directly to typ.
   411  // It panics if v is not assignable to typ.
   412  // For a conversion to an interface type, target is a suggested scratch space to use.
   413  func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
   414  	// if v.flag&flagMethod != 0 {
   415  	// 	v = makeMethodValue(context, v)
   416  	// }
   417  
   418  	switch {
   419  	case directlyAssignable(dst, v.typ):
   420  		// Overwrite type so that they match.
   421  		// Same memory layout, so no harm done.
   422  		fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
   423  		fl |= flag(dst.Kind())
   424  		return Value{dst, v.ptr, fl}
   425  
   426  	case implements(dst, v.typ):
   427  		if target == nil {
   428  			target = unsafe_New(dst)
   429  		}
   430  		if v.Kind() == Interface && v.IsNil() {
   431  			// A nil ReadWriter passed to nil Reader is OK,
   432  			// but using ifaceE2I below will panic.
   433  			// Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
   434  			return Value{dst, nil, flag(Interface)}
   435  		}
   436  		x := valueInterface(v)
   437  		if dst.NumMethod() == 0 {
   438  			*(*interface{})(target) = x
   439  		} else {
   440  			ifaceE2I(dst, x, target)
   441  		}
   442  		return Value{dst, target, flagIndir | flag(Interface)}
   443  	}
   444  
   445  	// Failed.
   446  	panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
   447  }
   448  
   449  // arrayAt returns the i-th element of p,
   450  // an array whose elements are eltSize bytes wide.
   451  // The array pointed at by p must have at least i+1 elements:
   452  // it is invalid (but impossible to check here) to pass i >= len,
   453  // because then the result will point outside the array.
   454  // whySafe must explain why i < len. (Passing "i < len" is fine;
   455  // the benefit is to surface this assumption at the call site.)
   456  func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
   457  	return add(p, uintptr(i)*eltSize, "i < len")
   458  }
   459  
   460  func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
   461  
   462  // typedmemmove copies a value of type t to dst from src.
   463  //go:noescape
   464  func typedmemmove(t *rtype, dst, src unsafe.Pointer)
   465  
   466  // Dummy annotation marking that the value x escapes,
   467  // for use in cases where the reflect code is so clever that
   468  // the compiler cannot follow.
   469  func escapes(x interface{}) {
   470  	if dummy.b {
   471  		dummy.x = x
   472  	}
   473  }
   474  
   475  var dummy struct {
   476  	b bool
   477  	x interface{}
   478  }