blob: 001d0274ecc87ddaaa4be04728a861953c46e182 [file] [log] [blame]
Rob Pikefac3dfe2008-10-22 11:02:56 -07001// 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
Rob Pikefac3dfe2008-10-22 11:02:56 -07005package reflect
6
7import (
Russ Cox45bdf032010-06-20 12:16:25 -07008 "math"
Robert Griesemerd65a5cc2009-12-15 15:40:16 -08009 "runtime"
10 "unsafe"
Rob Pikefac3dfe2008-10-22 11:02:56 -070011)
12
Russ Cox512f75e2015-05-08 01:43:18 -040013const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
Russ Coxe46acb02011-03-03 13:20:17 -050014const cannotSet = "cannot set value obtained from unexported struct field"
Robert Griesemer77334b982009-11-05 14:23:20 -080015
Russ Coxfb175cf2011-04-08 12:26:51 -040016// 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.
Russ Coxbabbf942012-03-07 14:55:09 -050029//
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.
Shenghou Maa1c9e102015-01-05 00:20:45 -050033//
34// Using == on two Values does not compare the underlying values
35// they represent, but rather the contents of the Value structs.
36// To compare two Values, compare the results of the Interface method.
Russ Coxfb175cf2011-04-08 12:26:51 -040037type Value struct {
Russ Coxa479a452011-11-16 19:18:25 -050038 // typ holds the type of the value represented by a Value.
Russ Cox11209822012-11-13 13:06:29 -050039 typ *rtype
Russ Coxa479a452011-11-16 19:18:25 -050040
Keith Randallcbc565a2013-12-19 15:15:24 -080041 // 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
Russ Coxa479a452011-11-16 19:18:25 -050045 // flag holds metadata about the value.
46 // The lowest bits are flag bits:
47 // - flagRO: obtained via unexported field, so read-only
48 // - flagIndir: val holds a pointer to the data
49 // - flagAddr: v.CanAddr is true (implies flagIndir)
50 // - flagMethod: v is a method value.
51 // The next five bits give the Kind of the value.
52 // This repeats typ.Kind() except for method values.
53 // The remaining 23+ bits give a method number for method values.
54 // If flag.kind() != Func, code can assume that flagMethod is unset.
Russ Coxa1616d42014-10-15 14:24:18 -040055 // If ifaceIndir(typ), code can assume that flagIndir is set.
Russ Coxa479a452011-11-16 19:18:25 -050056 flag
57
58 // A method value represents a curried method invocation
59 // like r.Read for some receiver r. The typ+val+flag bits describe
60 // the receiver r, but the flag's Kind bits say Func (methods are
61 // functions), and the top bits of the flag give the method number
62 // in r's type's method table.
63}
64
65type flag uintptr
66
67const (
Russ Coxa479a452011-11-16 19:18:25 -050068 flagKindWidth = 5 // there are 27 kinds
69 flagKindMask flag = 1<<flagKindWidth - 1
Russ Cox0d81b722014-10-17 12:54:31 -040070 flagRO flag = 1 << 5
71 flagIndir flag = 1 << 6
72 flagAddr flag = 1 << 7
73 flagMethod flag = 1 << 8
74 flagMethodShift = 9
Russ Coxa479a452011-11-16 19:18:25 -050075)
76
77func (f flag) kind() Kind {
Russ Cox0d81b722014-10-17 12:54:31 -040078 return Kind(f & flagKindMask)
Russ Coxfb175cf2011-04-08 12:26:51 -040079}
80
Keith Randallcbc565a2013-12-19 15:15:24 -080081// pointer returns the underlying pointer represented by v.
82// v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
83func (v Value) pointer() unsafe.Pointer {
84 if v.typ.size != ptrSize || !v.typ.pointers() {
85 panic("can't call pointer on a non-pointer Value")
86 }
87 if v.flag&flagIndir != 0 {
88 return *(*unsafe.Pointer)(v.ptr)
89 }
90 return v.ptr
91}
92
93// packEface converts v to the empty interface.
94func packEface(v Value) interface{} {
95 t := v.typ
96 var i interface{}
97 e := (*emptyInterface)(unsafe.Pointer(&i))
98 // First, fill in the data portion of the interface.
99 switch {
Russ Coxa1616d42014-10-15 14:24:18 -0400100 case ifaceIndir(t):
Russ Cox1806a572014-08-18 21:13:11 -0400101 if v.flag&flagIndir == 0 {
102 panic("bad indir")
103 }
Keith Randallcbc565a2013-12-19 15:15:24 -0800104 // Value is indirect, and so is the interface we're making.
105 ptr := v.ptr
106 if v.flag&flagAddr != 0 {
107 // TODO: pass safe boolean from valueInterface so
108 // we don't need to copy if safe==true?
109 c := unsafe_New(t)
Russ Coxdf027ac2014-12-30 13:59:55 -0500110 typedmemmove(t, c, ptr)
Keith Randallcbc565a2013-12-19 15:15:24 -0800111 ptr = c
112 }
Russ Cox0d81b722014-10-17 12:54:31 -0400113 e.word = ptr
Keith Randallcbc565a2013-12-19 15:15:24 -0800114 case v.flag&flagIndir != 0:
115 // Value is indirect, but interface is direct. We need
116 // to load the data at v.ptr into the interface data word.
Russ Cox0d81b722014-10-17 12:54:31 -0400117 e.word = *(*unsafe.Pointer)(v.ptr)
Keith Randallcbc565a2013-12-19 15:15:24 -0800118 default:
119 // Value is direct, and so is the interface.
Russ Cox0d81b722014-10-17 12:54:31 -0400120 e.word = v.ptr
Keith Randallcbc565a2013-12-19 15:15:24 -0800121 }
122 // Now, fill in the type portion. We're very careful here not
123 // to have any operation between the e.word and e.typ assignments
124 // that would let the garbage collector observe the partially-built
125 // interface value.
126 e.typ = t
127 return i
128}
129
130// unpackEface converts the empty interface i to a Value.
131func unpackEface(i interface{}) Value {
132 e := (*emptyInterface)(unsafe.Pointer(&i))
133 // NOTE: don't read e.word until we know whether it is really a pointer or not.
134 t := e.typ
135 if t == nil {
136 return Value{}
137 }
Russ Cox0d81b722014-10-17 12:54:31 -0400138 f := flag(t.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -0400139 if ifaceIndir(t) {
140 f |= flagIndir
Keith Randallcbc565a2013-12-19 15:15:24 -0800141 }
Russ Coxa1616d42014-10-15 14:24:18 -0400142 return Value{t, unsafe.Pointer(e.word), f}
Keith Randallcbc565a2013-12-19 15:15:24 -0800143}
144
Russ Coxfb175cf2011-04-08 12:26:51 -0400145// A ValueError occurs when a Value method is invoked on
146// a Value that does not support it. Such cases are documented
147// in the description of each method.
148type ValueError struct {
149 Method string
150 Kind Kind
151}
152
Russ Coxeb692922011-11-01 22:05:34 -0400153func (e *ValueError) Error() string {
Russ Coxfb175cf2011-04-08 12:26:51 -0400154 if e.Kind == 0 {
155 return "reflect: call of " + e.Method + " on zero Value"
156 }
157 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
158}
159
160// methodName returns the name of the calling method,
161// assumed to be two stack frames above.
162func methodName() string {
163 pc, _, _, _ := runtime.Caller(2)
164 f := runtime.FuncForPC(pc)
165 if f == nil {
166 return "unknown method"
167 }
168 return f.Name()
169}
170
Russ Cox40fccbc2011-04-18 14:35:33 -0400171// emptyInterface is the header for an interface{} value.
172type emptyInterface struct {
Russ Cox11209822012-11-13 13:06:29 -0500173 typ *rtype
Russ Cox0d81b722014-10-17 12:54:31 -0400174 word unsafe.Pointer
Russ Cox40fccbc2011-04-18 14:35:33 -0400175}
176
177// nonEmptyInterface is the header for a interface value with methods.
178type nonEmptyInterface struct {
Keith Randallcd5b1442015-03-11 12:58:47 -0700179 // see ../runtime/iface.go:/Itab
Russ Cox40fccbc2011-04-18 14:35:33 -0400180 itab *struct {
Russ Cox11209822012-11-13 13:06:29 -0500181 ityp *rtype // static interface type
182 typ *rtype // dynamic concrete type
Russ Cox40fccbc2011-04-18 14:35:33 -0400183 link unsafe.Pointer
184 bad int32
185 unused int32
186 fun [100000]unsafe.Pointer // method table
Russ Coxfb175cf2011-04-08 12:26:51 -0400187 }
Russ Cox0d81b722014-10-17 12:54:31 -0400188 word unsafe.Pointer
Russ Cox40fccbc2011-04-18 14:35:33 -0400189}
190
Russ Coxa479a452011-11-16 19:18:25 -0500191// mustBe panics if f's kind is not expected.
192// Making this a method on flag instead of on Value
193// (and embedding flag in Value) means that we can write
194// the very clear v.mustBe(Bool) and have it compile into
195// v.flag.mustBe(Bool), which will only bother to copy the
196// single important word for the receiver.
197func (f flag) mustBe(expected Kind) {
Russ Cox0d81b722014-10-17 12:54:31 -0400198 if f.kind() != expected {
199 panic(&ValueError{methodName(), f.kind()})
Russ Coxdb5f9da2011-08-28 12:05:00 -0400200 }
201}
202
Russ Coxa479a452011-11-16 19:18:25 -0500203// mustBeExported panics if f records that the value was obtained using
204// an unexported field.
205func (f flag) mustBeExported() {
206 if f == 0 {
207 panic(&ValueError{methodName(), 0})
Russ Cox40fccbc2011-04-18 14:35:33 -0400208 }
Russ Coxa479a452011-11-16 19:18:25 -0500209 if f&flagRO != 0 {
Russ Cox3be70362013-03-21 16:59:16 -0400210 panic("reflect: " + methodName() + " using value obtained using unexported field")
Russ Cox40fccbc2011-04-18 14:35:33 -0400211 }
212}
213
Russ Coxa479a452011-11-16 19:18:25 -0500214// mustBeAssignable panics if f records that the value is not assignable,
215// which is to say that either it was obtained using an unexported field
216// or it is not addressable.
217func (f flag) mustBeAssignable() {
218 if f == 0 {
219 panic(&ValueError{methodName(), Invalid})
Russ Coxe1ee3b52011-04-20 16:24:45 -0400220 }
Russ Cox40fccbc2011-04-18 14:35:33 -0400221 // Assignable if addressable and not read-only.
Russ Coxa479a452011-11-16 19:18:25 -0500222 if f&flagRO != 0 {
Russ Cox3be70362013-03-21 16:59:16 -0400223 panic("reflect: " + methodName() + " using value obtained using unexported field")
Russ Cox40fccbc2011-04-18 14:35:33 -0400224 }
Russ Coxa479a452011-11-16 19:18:25 -0500225 if f&flagAddr == 0 {
Russ Cox3be70362013-03-21 16:59:16 -0400226 panic("reflect: " + methodName() + " using unaddressable value")
Russ Cox40fccbc2011-04-18 14:35:33 -0400227 }
Russ Coxfb175cf2011-04-08 12:26:51 -0400228}
229
230// Addr returns a pointer value representing the address of v.
231// It panics if CanAddr() returns false.
232// Addr is typically used to obtain a pointer to a struct field
233// or slice element in order to call a method that requires a
234// pointer receiver.
235func (v Value) Addr() Value {
Russ Coxa479a452011-11-16 19:18:25 -0500236 if v.flag&flagAddr == 0 {
Russ Cox40fccbc2011-04-18 14:35:33 -0400237 panic("reflect.Value.Addr of unaddressable value")
238 }
Russ Cox0d81b722014-10-17 12:54:31 -0400239 return Value{v.typ.ptrTo(), v.ptr, (v.flag & flagRO) | flag(Ptr)}
Russ Coxfb175cf2011-04-08 12:26:51 -0400240}
241
242// Bool returns v's underlying value.
243// It panics if v's kind is not Bool.
244func (v Value) Bool() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500245 v.mustBe(Bool)
Russ Coxa1616d42014-10-15 14:24:18 -0400246 return *(*bool)(v.ptr)
Russ Coxfb175cf2011-04-08 12:26:51 -0400247}
248
Russ Cox00d64c72011-08-23 22:50:08 -0400249// Bytes returns v's underlying value.
250// It panics if v's underlying value is not a slice of bytes.
251func (v Value) Bytes() []byte {
Russ Coxa479a452011-11-16 19:18:25 -0500252 v.mustBe(Slice)
253 if v.typ.Elem().Kind() != Uint8 {
Russ Cox00d64c72011-08-23 22:50:08 -0400254 panic("reflect.Value.Bytes of non-byte slice")
255 }
Russ Coxa479a452011-11-16 19:18:25 -0500256 // Slice is always bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -0800257 return *(*[]byte)(v.ptr)
Russ Cox00d64c72011-08-23 22:50:08 -0400258}
259
Russ Cox46f379c2012-09-22 08:52:27 -0400260// runes returns v's underlying value.
261// It panics if v's underlying value is not a slice of runes (int32s).
262func (v Value) runes() []rune {
263 v.mustBe(Slice)
264 if v.typ.Elem().Kind() != Int32 {
265 panic("reflect.Value.Bytes of non-rune slice")
266 }
267 // Slice is always bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -0800268 return *(*[]rune)(v.ptr)
Russ Cox46f379c2012-09-22 08:52:27 -0400269}
270
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800271// CanAddr reports whether the value's address can be obtained with Addr.
Russ Coxfb175cf2011-04-08 12:26:51 -0400272// Such values are called addressable. A value is addressable if it is
273// an element of a slice, an element of an addressable array,
Russ Cox64787e32011-04-20 15:04:04 -0400274// a field of an addressable struct, or the result of dereferencing a pointer.
Russ Coxfb175cf2011-04-08 12:26:51 -0400275// If CanAddr returns false, calling Addr will panic.
276func (v Value) CanAddr() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500277 return v.flag&flagAddr != 0
Russ Coxfb175cf2011-04-08 12:26:51 -0400278}
279
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800280// CanSet reports whether the value of v can be changed.
Russ Cox64787e32011-04-20 15:04:04 -0400281// A Value can be changed only if it is addressable and was not
282// obtained by the use of unexported struct fields.
Russ Coxfb175cf2011-04-08 12:26:51 -0400283// If CanSet returns false, calling Set or any type-specific
Robert Griesemer3cfc34a2015-08-04 13:44:01 -0700284// setter (e.g., SetBool, SetInt) will panic.
Russ Coxfb175cf2011-04-08 12:26:51 -0400285func (v Value) CanSet() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500286 return v.flag&(flagAddr|flagRO) == flagAddr
Russ Coxfb175cf2011-04-08 12:26:51 -0400287}
288
Russ Coxe1ee3b52011-04-20 16:24:45 -0400289// Call calls the function v with the input arguments in.
290// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
291// Call panics if v's Kind is not Func.
292// It returns the output results as Values.
293// As in Go, each input argument must be assignable to the
294// type of the function's corresponding input parameter.
295// If v is a variadic function, Call creates the variadic slice parameter
296// itself, copying in the corresponding values.
Russ Coxfb175cf2011-04-08 12:26:51 -0400297func (v Value) Call(in []Value) []Value {
Russ Coxa479a452011-11-16 19:18:25 -0500298 v.mustBe(Func)
299 v.mustBeExported()
300 return v.call("Call", in)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400301}
Russ Cox40fccbc2011-04-18 14:35:33 -0400302
Russ Coxe1ee3b52011-04-20 16:24:45 -0400303// CallSlice calls the variadic function v with the input arguments in,
Robert Griesemer465b9c32012-10-30 13:38:01 -0700304// assigning the slice in[len(in)-1] to v's final variadic argument.
Mark Bucciarelli4e408e02015-02-21 21:14:45 -0500305// For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...).
306// CallSlice panics if v's Kind is not Func or if v is not variadic.
Russ Coxe1ee3b52011-04-20 16:24:45 -0400307// It returns the output results as Values.
308// As in Go, each input argument must be assignable to the
309// type of the function's corresponding input parameter.
310func (v Value) CallSlice(in []Value) []Value {
Russ Coxa479a452011-11-16 19:18:25 -0500311 v.mustBe(Func)
312 v.mustBeExported()
313 return v.call("CallSlice", in)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400314}
315
Russ Cox72c5d5e2014-04-08 11:11:35 -0400316var callGC bool // for testing; see TestCallMethodJump
317
Russ Cox3be70362013-03-21 16:59:16 -0400318func (v Value) call(op string, in []Value) []Value {
Russ Coxa479a452011-11-16 19:18:25 -0500319 // Get function pointer, type.
320 t := v.typ
321 var (
Keith Randall2af7a262014-01-15 13:56:59 -0800322 fn unsafe.Pointer
323 rcvr Value
324 rcvrtype *rtype
Russ Coxa479a452011-11-16 19:18:25 -0500325 )
326 if v.flag&flagMethod != 0 {
Keith Randall2af7a262014-01-15 13:56:59 -0800327 rcvr = v
Russ Coxfcf8a772014-04-16 11:52:27 -0400328 rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
Russ Coxa479a452011-11-16 19:18:25 -0500329 } else if v.flag&flagIndir != 0 {
Keith Randallcbc565a2013-12-19 15:15:24 -0800330 fn = *(*unsafe.Pointer)(v.ptr)
Russ Coxa479a452011-11-16 19:18:25 -0500331 } else {
Keith Randallcbc565a2013-12-19 15:15:24 -0800332 fn = v.ptr
Russ Coxa479a452011-11-16 19:18:25 -0500333 }
334
335 if fn == nil {
Russ Cox40fccbc2011-04-18 14:35:33 -0400336 panic("reflect.Value.Call: call of nil function")
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400337 }
Russ Cox40fccbc2011-04-18 14:35:33 -0400338
Russ Cox3be70362013-03-21 16:59:16 -0400339 isSlice := op == "CallSlice"
Russ Coxe1ee3b52011-04-20 16:24:45 -0400340 n := t.NumIn()
341 if isSlice {
342 if !t.IsVariadic() {
343 panic("reflect: CallSlice of non-variadic function")
344 }
345 if len(in) < n {
346 panic("reflect: CallSlice with too few input arguments")
347 }
348 if len(in) > n {
349 panic("reflect: CallSlice with too many input arguments")
350 }
351 } else {
352 if t.IsVariadic() {
353 n--
354 }
355 if len(in) < n {
356 panic("reflect: Call with too few input arguments")
357 }
358 if !t.IsVariadic() && len(in) > n {
359 panic("reflect: Call with too many input arguments")
360 }
361 }
362 for _, x := range in {
363 if x.Kind() == Invalid {
Russ Cox3be70362013-03-21 16:59:16 -0400364 panic("reflect: " + op + " using zero Value argument")
Russ Coxe1ee3b52011-04-20 16:24:45 -0400365 }
366 }
367 for i := 0; i < n; i++ {
368 if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
Russ Cox3be70362013-03-21 16:59:16 -0400369 panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
Russ Coxe1ee3b52011-04-20 16:24:45 -0400370 }
371 }
372 if !isSlice && t.IsVariadic() {
373 // prepare slice for remaining values
374 m := len(in) - n
375 slice := MakeSlice(t.In(n), m, m)
376 elem := t.In(n).Elem()
377 for i := 0; i < m; i++ {
378 x := in[n+i]
379 if xt := x.Type(); !xt.AssignableTo(elem) {
Russ Cox3be70362013-03-21 16:59:16 -0400380 panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400381 }
382 slice.Index(i).Set(x)
383 }
384 origIn := in
385 in = make([]Value, n+1)
386 copy(in[:n], origIn)
387 in[n] = slice
388 }
389
Russ Cox40fccbc2011-04-18 14:35:33 -0400390 nin := len(in)
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400391 if nin != t.NumIn() {
Russ Cox40fccbc2011-04-18 14:35:33 -0400392 panic("reflect.Value.Call: wrong argument count")
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400393 }
394 nout := t.NumOut()
395
Dmitry Vyukov67f8a812014-12-22 22:31:55 +0300396 // Compute frame type.
397 frametype, _, retOffset, _, framePool := funcLayout(t, rcvrtype)
398
399 // Allocate a chunk of memory for frame.
400 var args unsafe.Pointer
401 if nout == 0 {
402 args = framePool.Get().(unsafe.Pointer)
403 } else {
404 // Can't use pool if the function has return values.
405 // We will leak pointer to args in ret, so its lifetime is not scoped.
406 args = unsafe_New(frametype)
407 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400408 off := uintptr(0)
Keith Randall2af7a262014-01-15 13:56:59 -0800409
410 // Copy inputs into args.
411 if rcvrtype != nil {
412 storeRcvr(rcvr, args)
Russ Cox40fccbc2011-04-18 14:35:33 -0400413 off = ptrSize
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400414 }
415 for i, v := range in {
Russ Coxa479a452011-11-16 19:18:25 -0500416 v.mustBeExported()
Russ Cox11209822012-11-13 13:06:29 -0500417 targ := t.In(i).(*rtype)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400418 a := uintptr(targ.align)
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400419 off = (off + a - 1) &^ (a - 1)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400420 n := targ.size
Keith Randall2af7a262014-01-15 13:56:59 -0800421 addr := unsafe.Pointer(uintptr(args) + off)
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -0700422 v = v.assignTo("reflect.Value.Call", targ, addr)
Keith Randallcbc565a2013-12-19 15:15:24 -0800423 if v.flag&flagIndir != 0 {
Russ Coxdf027ac2014-12-30 13:59:55 -0500424 typedmemmove(targ, addr, v.ptr)
Russ Cox40fccbc2011-04-18 14:35:33 -0400425 } else {
Russ Coxa1616d42014-10-15 14:24:18 -0400426 *(*unsafe.Pointer)(addr) = v.ptr
Russ Cox40fccbc2011-04-18 14:35:33 -0400427 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400428 off += n
429 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400430
Russ Cox40fccbc2011-04-18 14:35:33 -0400431 // Call.
Russ Coxdf027ac2014-12-30 13:59:55 -0500432 call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
Russ Cox72c5d5e2014-04-08 11:11:35 -0400433
434 // For testing; see TestCallMethodJump.
435 if callGC {
436 runtime.GC()
437 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400438
Dmitry Vyukov67f8a812014-12-22 22:31:55 +0300439 var ret []Value
440 if nout == 0 {
441 memclr(args, frametype.size)
442 framePool.Put(args)
443 } else {
444 // Zero the now unused input area of args,
445 // because the Values returned by this function contain pointers to the args object,
446 // and will thus keep the args object alive indefinitely.
447 memclr(args, retOffset)
448 // Copy return values out of args.
449 ret = make([]Value, nout)
450 off = retOffset
451 for i := 0; i < nout; i++ {
452 tv := t.Out(i)
453 a := uintptr(tv.Align())
454 off = (off + a - 1) &^ (a - 1)
455 fl := flagIndir | flag(tv.Kind())
456 ret[i] = Value{tv.common(), unsafe.Pointer(uintptr(args) + off), fl}
457 off += tv.Size()
458 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400459 }
460
461 return ret
Russ Coxfb175cf2011-04-08 12:26:51 -0400462}
463
Russ Coxba4625c2012-09-24 20:06:32 -0400464// callReflect is the call implementation used by a function
465// returned by MakeFunc. In many ways it is the opposite of the
466// method Value.call above. The method above converts a call using Values
467// into a call of a function with a concrete argument frame, while
468// callReflect converts a call of a function with a concrete argument
469// frame into a call using Values.
470// It is in this file so that it can be next to the call method above.
471// The remainder of the MakeFunc implementation is in makefunc.go.
Russ Cox7276c022013-09-12 14:00:16 -0400472//
473// NOTE: This function must be marked as a "wrapper" in the generated code,
474// so that the linker can make it work correctly for panic and recover.
475// The gc compilers know to do that for the name "reflect.callReflect".
Russ Coxb1b67a32013-02-22 15:23:57 -0500476func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
477 ftyp := ctxt.typ
478 f := ctxt.fn
479
Russ Coxba4625c2012-09-24 20:06:32 -0400480 // Copy argument frame into Values.
481 ptr := frame
482 off := uintptr(0)
483 in := make([]Value, 0, len(ftyp.in))
484 for _, arg := range ftyp.in {
Russ Cox11209822012-11-13 13:06:29 -0500485 typ := arg
Russ Coxba4625c2012-09-24 20:06:32 -0400486 off += -off & uintptr(typ.align-1)
Keith Randallcbc565a2013-12-19 15:15:24 -0800487 addr := unsafe.Pointer(uintptr(ptr) + off)
Russ Cox0d81b722014-10-17 12:54:31 -0400488 v := Value{typ, nil, flag(typ.Kind())}
Russ Coxa1616d42014-10-15 14:24:18 -0400489 if ifaceIndir(typ) {
Russ Cox1806a572014-08-18 21:13:11 -0400490 // value cannot be inlined in interface data.
Russ Coxba4625c2012-09-24 20:06:32 -0400491 // Must make a copy, because f might keep a reference to it,
492 // and we cannot let f keep a reference to the stack frame
493 // after this function returns, not even a read-only reference.
Keith Randallcbc565a2013-12-19 15:15:24 -0800494 v.ptr = unsafe_New(typ)
Russ Coxdf027ac2014-12-30 13:59:55 -0500495 typedmemmove(typ, v.ptr, addr)
Russ Coxba4625c2012-09-24 20:06:32 -0400496 v.flag |= flagIndir
Keith Randallcbc565a2013-12-19 15:15:24 -0800497 } else {
Russ Coxa1616d42014-10-15 14:24:18 -0400498 v.ptr = *(*unsafe.Pointer)(addr)
Russ Coxba4625c2012-09-24 20:06:32 -0400499 }
500 in = append(in, v)
501 off += typ.size
502 }
503
504 // Call underlying function.
505 out := f(in)
506 if len(out) != len(ftyp.out) {
507 panic("reflect: wrong return count from function created by MakeFunc")
508 }
509
510 // Copy results back into argument frame.
511 if len(ftyp.out) > 0 {
512 off += -off & (ptrSize - 1)
Rémy Oudomphengea7d8012014-03-20 22:22:07 +0100513 if runtime.GOARCH == "amd64p32" {
514 off = align(off, 8)
515 }
Russ Coxba4625c2012-09-24 20:06:32 -0400516 for i, arg := range ftyp.out {
Russ Cox11209822012-11-13 13:06:29 -0500517 typ := arg
Russ Coxba4625c2012-09-24 20:06:32 -0400518 v := out[i]
519 if v.typ != typ {
520 panic("reflect: function created by MakeFunc using " + funcName(f) +
521 " returned wrong type: have " +
522 out[i].typ.String() + " for " + typ.String())
523 }
524 if v.flag&flagRO != 0 {
525 panic("reflect: function created by MakeFunc using " + funcName(f) +
526 " returned value obtained from unexported field")
527 }
528 off += -off & uintptr(typ.align-1)
529 addr := unsafe.Pointer(uintptr(ptr) + off)
Keith Randallcbc565a2013-12-19 15:15:24 -0800530 if v.flag&flagIndir != 0 {
Russ Coxdf027ac2014-12-30 13:59:55 -0500531 typedmemmove(typ, addr, v.ptr)
Russ Coxba4625c2012-09-24 20:06:32 -0400532 } else {
Russ Coxa1616d42014-10-15 14:24:18 -0400533 *(*unsafe.Pointer)(addr) = v.ptr
Russ Coxba4625c2012-09-24 20:06:32 -0400534 }
535 off += typ.size
536 }
537 }
538}
539
Russ Cox3be70362013-03-21 16:59:16 -0400540// methodReceiver returns information about the receiver
541// described by v. The Value v may or may not have the
542// flagMethod bit set, so the kind cached in v.flag should
543// not be used.
Russ Coxfcf8a772014-04-16 11:52:27 -0400544// The return value rcvrtype gives the method's actual receiver type.
Keith Randall2af7a262014-01-15 13:56:59 -0800545// The return value t gives the method type signature (without the receiver).
546// The return value fn is a pointer to the method code.
Russ Coxfcf8a772014-04-16 11:52:27 -0400547func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) {
Russ Cox3be70362013-03-21 16:59:16 -0400548 i := methodIndex
549 if v.typ.Kind() == Interface {
550 tt := (*interfaceType)(unsafe.Pointer(v.typ))
Russ Cox0d81b722014-10-17 12:54:31 -0400551 if uint(i) >= uint(len(tt.methods)) {
Russ Cox3be70362013-03-21 16:59:16 -0400552 panic("reflect: internal error: invalid method index")
553 }
554 m := &tt.methods[i]
555 if m.pkgPath != nil {
556 panic("reflect: " + op + " of unexported method")
557 }
Keith Randallcbc565a2013-12-19 15:15:24 -0800558 iface := (*nonEmptyInterface)(v.ptr)
Russ Cox3be70362013-03-21 16:59:16 -0400559 if iface.itab == nil {
560 panic("reflect: " + op + " of method on nil interface value")
561 }
Russ Coxfcf8a772014-04-16 11:52:27 -0400562 rcvrtype = iface.itab.typ
Russ Cox3be70362013-03-21 16:59:16 -0400563 fn = unsafe.Pointer(&iface.itab.fun[i])
Keith Randall2af7a262014-01-15 13:56:59 -0800564 t = m.typ
Russ Cox3be70362013-03-21 16:59:16 -0400565 } else {
Russ Coxfcf8a772014-04-16 11:52:27 -0400566 rcvrtype = v.typ
Russ Cox3be70362013-03-21 16:59:16 -0400567 ut := v.typ.uncommon()
Russ Cox0d81b722014-10-17 12:54:31 -0400568 if ut == nil || uint(i) >= uint(len(ut.methods)) {
Russ Cox3be70362013-03-21 16:59:16 -0400569 panic("reflect: internal error: invalid method index")
570 }
571 m := &ut.methods[i]
572 if m.pkgPath != nil {
573 panic("reflect: " + op + " of unexported method")
574 }
575 fn = unsafe.Pointer(&m.ifn)
576 t = m.mtyp
Russ Cox3be70362013-03-21 16:59:16 -0400577 }
578 return
579}
580
Keith Randall2af7a262014-01-15 13:56:59 -0800581// v is a method receiver. Store at p the word which is used to
582// encode that receiver at the start of the argument list.
583// Reflect uses the "interface" calling convention for
584// methods, which always uses one word to record the receiver.
585func storeRcvr(v Value, p unsafe.Pointer) {
586 t := v.typ
587 if t.Kind() == Interface {
588 // the interface data word becomes the receiver word
589 iface := (*nonEmptyInterface)(v.ptr)
590 *(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
Russ Coxa1616d42014-10-15 14:24:18 -0400591 } else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
592 *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
Keith Randall2af7a262014-01-15 13:56:59 -0800593 } else {
Russ Coxa1616d42014-10-15 14:24:18 -0400594 *(*unsafe.Pointer)(p) = v.ptr
Keith Randall2af7a262014-01-15 13:56:59 -0800595 }
596}
597
Russ Cox3be70362013-03-21 16:59:16 -0400598// align returns the result of rounding x up to a multiple of n.
599// n must be a power of two.
600func align(x, n uintptr) uintptr {
601 return (x + n - 1) &^ (n - 1)
602}
603
Russ Cox3be70362013-03-21 16:59:16 -0400604// callMethod is the call implementation used by a function returned
605// by makeMethodValue (used by v.Method(i).Interface()).
606// It is a streamlined version of the usual reflect call: the caller has
607// already laid out the argument frame for us, so we don't have
608// to deal with individual Values for each argument.
609// It is in this file so that it can be next to the two similar functions above.
610// The remainder of the makeMethodValue implementation is in makefunc.go.
Russ Cox7276c022013-09-12 14:00:16 -0400611//
612// NOTE: This function must be marked as a "wrapper" in the generated code,
613// so that the linker can make it work correctly for panic and recover.
614// The gc compilers know to do that for the name "reflect.callMethod".
Russ Cox3be70362013-03-21 16:59:16 -0400615func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
Keith Randall2af7a262014-01-15 13:56:59 -0800616 rcvr := ctxt.rcvr
Russ Coxfcf8a772014-04-16 11:52:27 -0400617 rcvrtype, t, fn := methodReceiver("call", rcvr, ctxt.method)
Dmitry Vyukov67f8a812014-12-22 22:31:55 +0300618 frametype, argSize, retOffset, _, framePool := funcLayout(t, rcvrtype)
Russ Cox3be70362013-03-21 16:59:16 -0400619
Keith Randall2af7a262014-01-15 13:56:59 -0800620 // Make a new frame that is one word bigger so we can store the receiver.
Dmitry Vyukov67f8a812014-12-22 22:31:55 +0300621 args := framePool.Get().(unsafe.Pointer)
Keith Randall2af7a262014-01-15 13:56:59 -0800622
623 // Copy in receiver and rest of args.
624 storeRcvr(rcvr, args)
Russ Coxdf027ac2014-12-30 13:59:55 -0500625 typedmemmovepartial(frametype, unsafe.Pointer(uintptr(args)+ptrSize), frame, ptrSize, argSize-ptrSize)
Russ Cox3be70362013-03-21 16:59:16 -0400626
627 // Call.
Russ Coxdf027ac2014-12-30 13:59:55 -0500628 call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
Russ Cox3be70362013-03-21 16:59:16 -0400629
Rémy Oudomphengea7d8012014-03-20 22:22:07 +0100630 // Copy return values. On amd64p32, the beginning of return values
631 // is 64-bit aligned, so the caller's frame layout (which doesn't have
632 // a receiver) is different from the layout of the fn call, which has
633 // a receiver.
634 // Ignore any changes to args and just copy return values.
635 callerRetOffset := retOffset - ptrSize
636 if runtime.GOARCH == "amd64p32" {
637 callerRetOffset = align(argSize-ptrSize, 8)
638 }
Russ Coxdf027ac2014-12-30 13:59:55 -0500639 typedmemmovepartial(frametype,
640 unsafe.Pointer(uintptr(frame)+callerRetOffset),
641 unsafe.Pointer(uintptr(args)+retOffset),
642 retOffset,
643 frametype.size-retOffset)
Dmitry Vyukov67f8a812014-12-22 22:31:55 +0300644
645 memclr(args, frametype.size)
646 framePool.Put(args)
Russ Cox3be70362013-03-21 16:59:16 -0400647}
648
Russ Coxba4625c2012-09-24 20:06:32 -0400649// funcName returns the name of f, for use in error messages.
650func funcName(f func([]Value) []Value) string {
651 pc := *(*uintptr)(unsafe.Pointer(&f))
652 rf := runtime.FuncForPC(pc)
653 if rf != nil {
654 return rf.Name()
655 }
656 return "closure"
657}
658
Russ Coxfb175cf2011-04-08 12:26:51 -0400659// Cap returns v's capacity.
660// It panics if v's Kind is not Array, Chan, or Slice.
661func (v Value) Cap() int {
Russ Coxa479a452011-11-16 19:18:25 -0500662 k := v.kind()
663 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -0400664 case Array:
Russ Coxa479a452011-11-16 19:18:25 -0500665 return v.typ.Len()
Russ Cox40fccbc2011-04-18 14:35:33 -0400666 case Chan:
Keith Randallcbc565a2013-12-19 15:15:24 -0800667 return int(chancap(v.pointer()))
Russ Cox40fccbc2011-04-18 14:35:33 -0400668 case Slice:
Russ Coxa479a452011-11-16 19:18:25 -0500669 // Slice is always bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -0800670 return (*sliceHeader)(v.ptr).Cap
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400671 }
Russ Cox0d81b722014-10-17 12:54:31 -0400672 panic(&ValueError{"reflect.Value.Cap", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400673}
674
675// Close closes the channel v.
676// It panics if v's Kind is not Chan.
677func (v Value) Close() {
Russ Coxa479a452011-11-16 19:18:25 -0500678 v.mustBe(Chan)
679 v.mustBeExported()
Keith Randallcbc565a2013-12-19 15:15:24 -0800680 chanclose(v.pointer())
Russ Coxfb175cf2011-04-08 12:26:51 -0400681}
682
Russ Coxfb175cf2011-04-08 12:26:51 -0400683// Complex returns v's underlying value, as a complex128.
684// It panics if v's Kind is not Complex64 or Complex128
685func (v Value) Complex() complex128 {
Russ Coxa479a452011-11-16 19:18:25 -0500686 k := v.kind()
687 switch k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400688 case Complex64:
Russ Coxa1616d42014-10-15 14:24:18 -0400689 return complex128(*(*complex64)(v.ptr))
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400690 case Complex128:
Keith Randallcbc565a2013-12-19 15:15:24 -0800691 return *(*complex128)(v.ptr)
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400692 }
Russ Cox0d81b722014-10-17 12:54:31 -0400693 panic(&ValueError{"reflect.Value.Complex", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400694}
695
Russ Coxfb175cf2011-04-08 12:26:51 -0400696// Elem returns the value that the interface v contains
697// or that the pointer v points to.
698// It panics if v's Kind is not Interface or Ptr.
699// It returns the zero Value if v is nil.
700func (v Value) Elem() Value {
Russ Coxa479a452011-11-16 19:18:25 -0500701 k := v.kind()
702 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -0400703 case Interface:
Keith Randallcbc565a2013-12-19 15:15:24 -0800704 var eface interface{}
Russ Coxa479a452011-11-16 19:18:25 -0500705 if v.typ.NumMethod() == 0 {
Keith Randallcbc565a2013-12-19 15:15:24 -0800706 eface = *(*interface{})(v.ptr)
Russ Coxa479a452011-11-16 19:18:25 -0500707 } else {
Keith Randallcbc565a2013-12-19 15:15:24 -0800708 eface = (interface{})(*(*interface {
709 M()
710 })(v.ptr))
Russ Cox40fccbc2011-04-18 14:35:33 -0400711 }
Keith Randallcbc565a2013-12-19 15:15:24 -0800712 x := unpackEface(eface)
Russ Cox62d32022014-10-01 16:51:32 -0400713 if x.flag != 0 {
714 x.flag |= v.flag & flagRO
715 }
Keith Randallcbc565a2013-12-19 15:15:24 -0800716 return x
Russ Cox40fccbc2011-04-18 14:35:33 -0400717 case Ptr:
Keith Randallcbc565a2013-12-19 15:15:24 -0800718 ptr := v.ptr
Russ Coxa479a452011-11-16 19:18:25 -0500719 if v.flag&flagIndir != 0 {
Keith Randallcbc565a2013-12-19 15:15:24 -0800720 ptr = *(*unsafe.Pointer)(ptr)
Russ Coxa479a452011-11-16 19:18:25 -0500721 }
Russ Cox40fccbc2011-04-18 14:35:33 -0400722 // The returned value's address is v's value.
Keith Randallcbc565a2013-12-19 15:15:24 -0800723 if ptr == nil {
Russ Cox40fccbc2011-04-18 14:35:33 -0400724 return Value{}
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400725 }
Russ Coxa479a452011-11-16 19:18:25 -0500726 tt := (*ptrType)(unsafe.Pointer(v.typ))
Russ Cox11209822012-11-13 13:06:29 -0500727 typ := tt.elem
Russ Coxa479a452011-11-16 19:18:25 -0500728 fl := v.flag&flagRO | flagIndir | flagAddr
Russ Cox0d81b722014-10-17 12:54:31 -0400729 fl |= flag(typ.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -0400730 return Value{typ, ptr, fl}
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400731 }
Russ Cox0d81b722014-10-17 12:54:31 -0400732 panic(&ValueError{"reflect.Value.Elem", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400733}
734
735// Field returns the i'th field of the struct v.
Russ Cox40fccbc2011-04-18 14:35:33 -0400736// It panics if v's Kind is not Struct or i is out of range.
Russ Coxfb175cf2011-04-08 12:26:51 -0400737func (v Value) Field(i int) Value {
Russ Cox0d81b722014-10-17 12:54:31 -0400738 if v.kind() != Struct {
739 panic(&ValueError{"reflect.Value.Field", v.kind()})
740 }
Russ Coxa479a452011-11-16 19:18:25 -0500741 tt := (*structType)(unsafe.Pointer(v.typ))
Russ Cox0d81b722014-10-17 12:54:31 -0400742 if uint(i) >= uint(len(tt.fields)) {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400743 panic("reflect: Field index out of range")
744 }
Russ Coxa479a452011-11-16 19:18:25 -0500745 field := &tt.fields[i]
Russ Cox11209822012-11-13 13:06:29 -0500746 typ := field.typ
Russ Cox40fccbc2011-04-18 14:35:33 -0400747
748 // Inherit permission bits from v.
Russ Cox0d81b722014-10-17 12:54:31 -0400749 fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind())
Russ Cox40fccbc2011-04-18 14:35:33 -0400750 // Using an unexported field forces flagRO.
Russ Coxa479a452011-11-16 19:18:25 -0500751 if field.pkgPath != nil {
752 fl |= flagRO
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400753 }
Russ Cox0d81b722014-10-17 12:54:31 -0400754 // Either flagIndir is set and v.ptr points at struct,
755 // or flagIndir is not set and v.ptr is the actual struct data.
756 // In the former case, we want v.ptr + offset.
Ian Lance Taylorc5f810f2015-01-13 10:40:15 -0800757 // In the latter case, we must have field.offset = 0,
Russ Cox0d81b722014-10-17 12:54:31 -0400758 // so v.ptr + field.offset is still okay.
759 ptr := unsafe.Pointer(uintptr(v.ptr) + field.offset)
Russ Coxa1616d42014-10-15 14:24:18 -0400760 return Value{typ, ptr, fl}
Russ Coxfb175cf2011-04-08 12:26:51 -0400761}
762
763// FieldByIndex returns the nested field corresponding to index.
764// It panics if v's Kind is not struct.
765func (v Value) FieldByIndex(index []int) Value {
Russ Cox94950af2014-10-15 13:33:00 -0400766 if len(index) == 1 {
767 return v.Field(index[0])
768 }
Russ Coxa479a452011-11-16 19:18:25 -0500769 v.mustBe(Struct)
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400770 for i, x := range index {
771 if i > 0 {
Russ Cox59847322014-02-21 13:51:22 -0500772 if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
773 if v.IsNil() {
774 panic("reflect: indirection through nil pointer to embedded struct")
775 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400776 v = v.Elem()
777 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400778 }
779 v = v.Field(x)
780 }
781 return v
Russ Coxfb175cf2011-04-08 12:26:51 -0400782}
783
784// FieldByName returns the struct field with the given name.
785// It returns the zero Value if no field was found.
786// It panics if v's Kind is not struct.
787func (v Value) FieldByName(name string) Value {
Russ Coxa479a452011-11-16 19:18:25 -0500788 v.mustBe(Struct)
789 if f, ok := v.typ.FieldByName(name); ok {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400790 return v.FieldByIndex(f.Index)
791 }
792 return Value{}
Russ Coxfb175cf2011-04-08 12:26:51 -0400793}
794
795// FieldByNameFunc returns the struct field with a name
796// that satisfies the match function.
797// It panics if v's Kind is not struct.
798// It returns the zero Value if no field was found.
799func (v Value) FieldByNameFunc(match func(string) bool) Value {
Russ Coxa479a452011-11-16 19:18:25 -0500800 if f, ok := v.typ.FieldByNameFunc(match); ok {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400801 return v.FieldByIndex(f.Index)
802 }
803 return Value{}
Russ Coxfb175cf2011-04-08 12:26:51 -0400804}
805
Rob Pike9bcfc572012-02-10 15:09:09 +1100806// Float returns v's underlying value, as a float64.
Russ Coxfb175cf2011-04-08 12:26:51 -0400807// It panics if v's Kind is not Float32 or Float64
808func (v Value) Float() float64 {
Russ Coxa479a452011-11-16 19:18:25 -0500809 k := v.kind()
810 switch k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400811 case Float32:
Russ Coxa1616d42014-10-15 14:24:18 -0400812 return float64(*(*float32)(v.ptr))
Russ Coxa479a452011-11-16 19:18:25 -0500813 case Float64:
Russ Coxa1616d42014-10-15 14:24:18 -0400814 return *(*float64)(v.ptr)
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400815 }
Russ Cox0d81b722014-10-17 12:54:31 -0400816 panic(&ValueError{"reflect.Value.Float", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400817}
818
Russ Cox11209822012-11-13 13:06:29 -0500819var uint8Type = TypeOf(uint8(0)).(*rtype)
Evan Shaw772decb2012-10-21 17:02:10 -0400820
Russ Coxfb175cf2011-04-08 12:26:51 -0400821// Index returns v's i'th element.
Evan Shaw772decb2012-10-21 17:02:10 -0400822// It panics if v's Kind is not Array, Slice, or String or i is out of range.
Russ Coxfb175cf2011-04-08 12:26:51 -0400823func (v Value) Index(i int) Value {
Russ Cox0d81b722014-10-17 12:54:31 -0400824 switch v.kind() {
Russ Cox40fccbc2011-04-18 14:35:33 -0400825 case Array:
Russ Coxa479a452011-11-16 19:18:25 -0500826 tt := (*arrayType)(unsafe.Pointer(v.typ))
Russ Cox0d81b722014-10-17 12:54:31 -0400827 if uint(i) >= uint(tt.len) {
Russ Cox40fccbc2011-04-18 14:35:33 -0400828 panic("reflect: array index out of range")
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400829 }
Russ Cox11209822012-11-13 13:06:29 -0500830 typ := tt.elem
Russ Coxa479a452011-11-16 19:18:25 -0500831 offset := uintptr(i) * typ.size
832
Russ Cox0d81b722014-10-17 12:54:31 -0400833 // Either flagIndir is set and v.ptr points at array,
834 // or flagIndir is not set and v.ptr is the actual array data.
835 // In the former case, we want v.ptr + offset.
836 // In the latter case, we must be doing Index(0), so offset = 0,
837 // so v.ptr + offset is still okay.
838 val := unsafe.Pointer(uintptr(v.ptr) + offset)
839 fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind()) // bits same as overall array
Russ Coxa1616d42014-10-15 14:24:18 -0400840 return Value{typ, val, fl}
Russ Cox40fccbc2011-04-18 14:35:33 -0400841
842 case Slice:
843 // Element flag same as Elem of Ptr.
Russ Coxa479a452011-11-16 19:18:25 -0500844 // Addressable, indirect, possibly read-only.
Keith Randallcbc565a2013-12-19 15:15:24 -0800845 s := (*sliceHeader)(v.ptr)
Russ Cox0d81b722014-10-17 12:54:31 -0400846 if uint(i) >= uint(s.Len) {
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400847 panic("reflect: slice index out of range")
848 }
Russ Coxa479a452011-11-16 19:18:25 -0500849 tt := (*sliceType)(unsafe.Pointer(v.typ))
Russ Cox11209822012-11-13 13:06:29 -0500850 typ := tt.elem
Sebastien Binete00e6562015-01-27 10:04:11 +0100851 val := arrayAt(s.Data, i, typ.size)
Russ Cox0d81b722014-10-17 12:54:31 -0400852 fl := flagAddr | flagIndir | v.flag&flagRO | flag(typ.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -0400853 return Value{typ, val, fl}
Evan Shaw772decb2012-10-21 17:02:10 -0400854
855 case String:
Keith Randallcbc565a2013-12-19 15:15:24 -0800856 s := (*stringHeader)(v.ptr)
Russ Cox0d81b722014-10-17 12:54:31 -0400857 if uint(i) >= uint(s.Len) {
Evan Shaw772decb2012-10-21 17:02:10 -0400858 panic("reflect: string index out of range")
859 }
Sebastien Binete00e6562015-01-27 10:04:11 +0100860 p := arrayAt(s.Data, i, 1)
Russ Cox0d81b722014-10-17 12:54:31 -0400861 fl := v.flag&flagRO | flag(Uint8) | flagIndir
Russ Coxa1616d42014-10-15 14:24:18 -0400862 return Value{uint8Type, p, fl}
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400863 }
Russ Cox0d81b722014-10-17 12:54:31 -0400864 panic(&ValueError{"reflect.Value.Index", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400865}
866
Russ Coxfb175cf2011-04-08 12:26:51 -0400867// Int returns v's underlying value, as an int64.
Russ Cox40fccbc2011-04-18 14:35:33 -0400868// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
Russ Coxfb175cf2011-04-08 12:26:51 -0400869func (v Value) Int() int64 {
Russ Coxa479a452011-11-16 19:18:25 -0500870 k := v.kind()
Russ Coxa1616d42014-10-15 14:24:18 -0400871 p := v.ptr
Russ Coxa479a452011-11-16 19:18:25 -0500872 switch k {
873 case Int:
874 return int64(*(*int)(p))
875 case Int8:
876 return int64(*(*int8)(p))
877 case Int16:
878 return int64(*(*int16)(p))
879 case Int32:
880 return int64(*(*int32)(p))
881 case Int64:
882 return int64(*(*int64)(p))
883 }
Russ Cox0d81b722014-10-17 12:54:31 -0400884 panic(&ValueError{"reflect.Value.Int", v.kind()})
Russ Cox40fccbc2011-04-18 14:35:33 -0400885}
886
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800887// CanInterface reports whether Interface can be used without panicking.
Russ Cox40fccbc2011-04-18 14:35:33 -0400888func (v Value) CanInterface() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500889 if v.flag == 0 {
890 panic(&ValueError{"reflect.Value.CanInterface", Invalid})
Russ Cox40fccbc2011-04-18 14:35:33 -0400891 }
Russ Cox3be70362013-03-21 16:59:16 -0400892 return v.flag&flagRO == 0
Russ Coxfb175cf2011-04-08 12:26:51 -0400893}
894
Russ Coxaf954992012-03-01 17:55:47 -0500895// Interface returns v's current value as an interface{}.
896// It is equivalent to:
897// var i interface{} = (v's underlying value)
Andrew Gerrand2d2ae532013-09-24 10:49:54 +1000898// It panics if the Value was obtained by accessing
Rob Pike9bcfc572012-02-10 15:09:09 +1100899// unexported struct fields.
Russ Coxaf954992012-03-01 17:55:47 -0500900func (v Value) Interface() (i interface{}) {
Russ Cox304cf4d2011-10-17 18:48:45 -0400901 return valueInterface(v, true)
Russ Coxe1ee3b52011-04-20 16:24:45 -0400902}
903
Russ Cox304cf4d2011-10-17 18:48:45 -0400904func valueInterface(v Value, safe bool) interface{} {
Russ Coxa479a452011-11-16 19:18:25 -0500905 if v.flag == 0 {
906 panic(&ValueError{"reflect.Value.Interface", 0})
Gustavo Niemeyera2bb0152011-08-15 14:14:15 -0300907 }
Russ Coxa479a452011-11-16 19:18:25 -0500908 if safe && v.flag&flagRO != 0 {
Russ Cox304cf4d2011-10-17 18:48:45 -0400909 // Do not allow access to unexported values via Interface,
Robert Griesemer465b9c32012-10-30 13:38:01 -0700910 // because they might be pointers that should not be
Russ Cox304cf4d2011-10-17 18:48:45 -0400911 // writable or methods or function that should not be callable.
912 panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
913 }
Russ Cox3be70362013-03-21 16:59:16 -0400914 if v.flag&flagMethod != 0 {
915 v = makeMethodValue("Interface", v)
916 }
Russ Coxa479a452011-11-16 19:18:25 -0500917
Keith Randallcbc565a2013-12-19 15:15:24 -0800918 if v.kind() == Interface {
Russ Cox40fccbc2011-04-18 14:35:33 -0400919 // Special case: return the element inside the interface.
Russ Coxa479a452011-11-16 19:18:25 -0500920 // Empty interface has one layout, all interfaces with
921 // methods have a second layout.
922 if v.NumMethod() == 0 {
Keith Randallcbc565a2013-12-19 15:15:24 -0800923 return *(*interface{})(v.ptr)
Russ Cox40fccbc2011-04-18 14:35:33 -0400924 }
Russ Coxa479a452011-11-16 19:18:25 -0500925 return *(*interface {
926 M()
Keith Randallcbc565a2013-12-19 15:15:24 -0800927 })(v.ptr)
Russ Cox40fccbc2011-04-18 14:35:33 -0400928 }
929
Keith Randallcbc565a2013-12-19 15:15:24 -0800930 // TODO: pass safe to packEface so we don't need to copy if safe==true?
931 return packEface(v)
Russ Coxfb175cf2011-04-08 12:26:51 -0400932}
933
934// InterfaceData returns the interface v's value as a uintptr pair.
935// It panics if v's Kind is not Interface.
936func (v Value) InterfaceData() [2]uintptr {
Keith Randallcbc565a2013-12-19 15:15:24 -0800937 // TODO: deprecate this
Russ Coxa479a452011-11-16 19:18:25 -0500938 v.mustBe(Interface)
Russ Cox40fccbc2011-04-18 14:35:33 -0400939 // We treat this as a read operation, so we allow
940 // it even for unexported data, because the caller
941 // has to import "unsafe" to turn it into something
942 // that can be abused.
Russ Coxa479a452011-11-16 19:18:25 -0500943 // Interface value is always bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -0800944 return *(*[2]uintptr)(v.ptr)
Russ Coxfb175cf2011-04-08 12:26:51 -0400945}
946
Rob Pike8b0b9942014-02-18 22:33:59 -0800947// IsNil reports whether its argument v is nil. The argument must be
948// a chan, func, interface, map, pointer, or slice value; if it is
949// not, IsNil panics. Note that IsNil is not always equivalent to a
950// regular comparison with nil in Go. For example, if v was created
951// by calling ValueOf with an uninitialized interface variable i,
952// i==nil will be true but v.IsNil will panic as v will be the zero
953// Value.
Russ Coxfb175cf2011-04-08 12:26:51 -0400954func (v Value) IsNil() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500955 k := v.kind()
956 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -0400957 case Chan, Func, Map, Ptr:
Russ Coxa479a452011-11-16 19:18:25 -0500958 if v.flag&flagMethod != 0 {
Russ Cox3be70362013-03-21 16:59:16 -0400959 return false
Russ Cox40fccbc2011-04-18 14:35:33 -0400960 }
Keith Randallcbc565a2013-12-19 15:15:24 -0800961 ptr := v.ptr
Russ Coxa479a452011-11-16 19:18:25 -0500962 if v.flag&flagIndir != 0 {
963 ptr = *(*unsafe.Pointer)(ptr)
964 }
965 return ptr == nil
Russ Cox40fccbc2011-04-18 14:35:33 -0400966 case Interface, Slice:
967 // Both interface and slice are nil if first word is 0.
Russ Coxa479a452011-11-16 19:18:25 -0500968 // Both are always bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -0800969 return *(*unsafe.Pointer)(v.ptr) == nil
Russ Cox7b6ee1a2011-04-13 16:55:20 -0400970 }
Russ Cox0d81b722014-10-17 12:54:31 -0400971 panic(&ValueError{"reflect.Value.IsNil", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -0400972}
973
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800974// IsValid reports whether v represents a value.
Russ Coxfb175cf2011-04-08 12:26:51 -0400975// It returns false if v is the zero Value.
976// If IsValid returns false, all other methods except String panic.
977// Most functions and methods never return an invalid value.
978// If one does, its documentation states the conditions explicitly.
979func (v Value) IsValid() bool {
Russ Coxa479a452011-11-16 19:18:25 -0500980 return v.flag != 0
Russ Coxfb175cf2011-04-08 12:26:51 -0400981}
982
983// Kind returns v's Kind.
984// If v is the zero Value (IsValid returns false), Kind returns Invalid.
985func (v Value) Kind() Kind {
Russ Coxa479a452011-11-16 19:18:25 -0500986 return v.kind()
Russ Coxfb175cf2011-04-08 12:26:51 -0400987}
988
Russ Coxfb175cf2011-04-08 12:26:51 -0400989// Len returns v's length.
Rob Pikedb0e3582011-07-04 11:45:31 +1000990// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
Russ Coxfb175cf2011-04-08 12:26:51 -0400991func (v Value) Len() int {
Russ Coxa479a452011-11-16 19:18:25 -0500992 k := v.kind()
993 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -0400994 case Array:
Russ Coxa479a452011-11-16 19:18:25 -0500995 tt := (*arrayType)(unsafe.Pointer(v.typ))
996 return int(tt.len)
Russ Cox40fccbc2011-04-18 14:35:33 -0400997 case Chan:
Keith Randallcbc565a2013-12-19 15:15:24 -0800998 return chanlen(v.pointer())
Russ Cox40fccbc2011-04-18 14:35:33 -0400999 case Map:
Keith Randallcbc565a2013-12-19 15:15:24 -08001000 return maplen(v.pointer())
Russ Cox40fccbc2011-04-18 14:35:33 -04001001 case Slice:
Russ Coxa479a452011-11-16 19:18:25 -05001002 // Slice is bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -08001003 return (*sliceHeader)(v.ptr).Len
Rob Pikedb0e3582011-07-04 11:45:31 +10001004 case String:
Russ Coxa479a452011-11-16 19:18:25 -05001005 // String is bigger than a word; assume flagIndir.
Keith Randallcbc565a2013-12-19 15:15:24 -08001006 return (*stringHeader)(v.ptr).Len
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001007 }
Russ Cox0d81b722014-10-17 12:54:31 -04001008 panic(&ValueError{"reflect.Value.Len", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001009}
1010
1011// MapIndex returns the value associated with key in the map v.
1012// It panics if v's Kind is not Map.
Russ Cox40fccbc2011-04-18 14:35:33 -04001013// It returns the zero Value if key is not found in the map or if v represents a nil map.
Russ Coxe1ee3b52011-04-20 16:24:45 -04001014// As in Go, the key's value must be assignable to the map's key type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001015func (v Value) MapIndex(key Value) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001016 v.mustBe(Map)
1017 tt := (*mapType)(unsafe.Pointer(v.typ))
Russ Coxe1ee3b52011-04-20 16:24:45 -04001018
Russ Coxa479a452011-11-16 19:18:25 -05001019 // Do not require key to be exported, so that DeepEqual
Russ Cox86e6a442011-05-03 10:38:37 -04001020 // and other programs can use all the keys returned by
1021 // MapKeys as arguments to MapIndex. If either the map
1022 // or the key is unexported, though, the result will be
Russ Coxa479a452011-11-16 19:18:25 -05001023 // considered unexported. This is consistent with the
1024 // behavior for structs, which allow read but not write
1025 // of unexported fields.
Russ Cox11209822012-11-13 13:06:29 -05001026 key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
Russ Cox86e6a442011-05-03 10:38:37 -04001027
Keith Randallcbc565a2013-12-19 15:15:24 -08001028 var k unsafe.Pointer
1029 if key.flag&flagIndir != 0 {
1030 k = key.ptr
Keith Randallcbc565a2013-12-19 15:15:24 -08001031 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001032 k = unsafe.Pointer(&key.ptr)
Keith Randallcbc565a2013-12-19 15:15:24 -08001033 }
1034 e := mapaccess(v.typ, v.pointer(), k)
1035 if e == nil {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001036 return Value{}
1037 }
Russ Cox11209822012-11-13 13:06:29 -05001038 typ := tt.elem
Russ Coxa479a452011-11-16 19:18:25 -05001039 fl := (v.flag | key.flag) & flagRO
Russ Cox0d81b722014-10-17 12:54:31 -04001040 fl |= flag(typ.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -04001041 if ifaceIndir(typ) {
Keith Randallcbc565a2013-12-19 15:15:24 -08001042 // Copy result so future changes to the map
1043 // won't change the underlying value.
1044 c := unsafe_New(typ)
Russ Coxdf027ac2014-12-30 13:59:55 -05001045 typedmemmove(typ, c, e)
Russ Coxa1616d42014-10-15 14:24:18 -04001046 return Value{typ, c, fl | flagIndir}
Keith Randallcbc565a2013-12-19 15:15:24 -08001047 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001048 return Value{typ, *(*unsafe.Pointer)(e), fl}
Keith Randallcbc565a2013-12-19 15:15:24 -08001049 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001050}
1051
1052// MapKeys returns a slice containing all the keys present in the map,
1053// in unspecified order.
1054// It panics if v's Kind is not Map.
Russ Cox40fccbc2011-04-18 14:35:33 -04001055// It returns an empty slice if v represents a nil map.
Russ Coxfb175cf2011-04-08 12:26:51 -04001056func (v Value) MapKeys() []Value {
Russ Coxa479a452011-11-16 19:18:25 -05001057 v.mustBe(Map)
1058 tt := (*mapType)(unsafe.Pointer(v.typ))
Russ Cox11209822012-11-13 13:06:29 -05001059 keyType := tt.key
Russ Cox40fccbc2011-04-18 14:35:33 -04001060
Russ Cox0d81b722014-10-17 12:54:31 -04001061 fl := v.flag&flagRO | flag(keyType.Kind())
Russ Coxa479a452011-11-16 19:18:25 -05001062
Keith Randallcbc565a2013-12-19 15:15:24 -08001063 m := v.pointer()
Russ Cox0b08c942012-09-24 14:58:34 -04001064 mlen := int(0)
Russ Coxa479a452011-11-16 19:18:25 -05001065 if m != nil {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001066 mlen = maplen(m)
1067 }
Russ Cox11209822012-11-13 13:06:29 -05001068 it := mapiterinit(v.typ, m)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001069 a := make([]Value, mlen)
1070 var i int
1071 for i = 0; i < len(a); i++ {
Keith Randallcbc565a2013-12-19 15:15:24 -08001072 key := mapiterkey(it)
1073 if key == nil {
1074 // Someone deleted an entry from the map since we
1075 // called maplen above. It's a data race, but nothing
1076 // we can do about it.
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001077 break
1078 }
Russ Coxa1616d42014-10-15 14:24:18 -04001079 if ifaceIndir(keyType) {
Keith Randallcbc565a2013-12-19 15:15:24 -08001080 // Copy result so future changes to the map
1081 // won't change the underlying value.
1082 c := unsafe_New(keyType)
Russ Coxdf027ac2014-12-30 13:59:55 -05001083 typedmemmove(keyType, c, key)
Russ Coxa1616d42014-10-15 14:24:18 -04001084 a[i] = Value{keyType, c, fl | flagIndir}
Keith Randallcbc565a2013-12-19 15:15:24 -08001085 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001086 a[i] = Value{keyType, *(*unsafe.Pointer)(key), fl}
Keith Randallcbc565a2013-12-19 15:15:24 -08001087 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001088 mapiternext(it)
1089 }
Russ Cox40fccbc2011-04-18 14:35:33 -04001090 return a[:i]
Russ Coxfb175cf2011-04-08 12:26:51 -04001091}
1092
1093// Method returns a function value corresponding to v's i'th method.
1094// The arguments to a Call on the returned function should not include
1095// a receiver; the returned function will always use v as the receiver.
Russ Cox3be70362013-03-21 16:59:16 -04001096// Method panics if i is out of range or if v is a nil interface value.
Russ Coxfb175cf2011-04-08 12:26:51 -04001097func (v Value) Method(i int) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001098 if v.typ == nil {
Russ Cox40fccbc2011-04-18 14:35:33 -04001099 panic(&ValueError{"reflect.Value.Method", Invalid})
1100 }
Russ Cox0d81b722014-10-17 12:54:31 -04001101 if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
Russ Cox40fccbc2011-04-18 14:35:33 -04001102 panic("reflect: Method index out of range")
1103 }
Russ Cox3be70362013-03-21 16:59:16 -04001104 if v.typ.Kind() == Interface && v.IsNil() {
1105 panic("reflect: Method on nil interface value")
1106 }
1107 fl := v.flag & (flagRO | flagIndir)
Russ Cox0d81b722014-10-17 12:54:31 -04001108 fl |= flag(Func)
Russ Coxa479a452011-11-16 19:18:25 -05001109 fl |= flag(i)<<flagMethodShift | flagMethod
Russ Coxa1616d42014-10-15 14:24:18 -04001110 return Value{v.typ, v.ptr, fl}
Russ Coxfb175cf2011-04-08 12:26:51 -04001111}
1112
Rob Pike125e8272011-07-14 10:38:15 +10001113// NumMethod returns the number of methods in the value's method set.
1114func (v Value) NumMethod() int {
Russ Coxa479a452011-11-16 19:18:25 -05001115 if v.typ == nil {
Rob Pike125e8272011-07-14 10:38:15 +10001116 panic(&ValueError{"reflect.Value.NumMethod", Invalid})
1117 }
Russ Coxa479a452011-11-16 19:18:25 -05001118 if v.flag&flagMethod != 0 {
1119 return 0
1120 }
1121 return v.typ.NumMethod()
Rob Pike125e8272011-07-14 10:38:15 +10001122}
1123
Rob Pike22484e22011-06-29 13:11:49 +10001124// MethodByName returns a function value corresponding to the method
1125// of v with the given name.
1126// The arguments to a Call on the returned function should not include
1127// a receiver; the returned function will always use v as the receiver.
1128// It returns the zero Value if no method was found.
1129func (v Value) MethodByName(name string) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001130 if v.typ == nil {
Rob Pike22484e22011-06-29 13:11:49 +10001131 panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1132 }
Russ Coxa479a452011-11-16 19:18:25 -05001133 if v.flag&flagMethod != 0 {
1134 return Value{}
Rob Pike22484e22011-06-29 13:11:49 +10001135 }
Russ Coxa479a452011-11-16 19:18:25 -05001136 m, ok := v.typ.MethodByName(name)
1137 if !ok {
1138 return Value{}
1139 }
1140 return v.Method(m.Index)
Rob Pike22484e22011-06-29 13:11:49 +10001141}
1142
Russ Coxfb175cf2011-04-08 12:26:51 -04001143// NumField returns the number of fields in the struct v.
1144// It panics if v's Kind is not Struct.
1145func (v Value) NumField() int {
Russ Coxa479a452011-11-16 19:18:25 -05001146 v.mustBe(Struct)
1147 tt := (*structType)(unsafe.Pointer(v.typ))
1148 return len(tt.fields)
Russ Coxfb175cf2011-04-08 12:26:51 -04001149}
1150
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -08001151// OverflowComplex reports whether the complex128 x cannot be represented by v's type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001152// It panics if v's Kind is not Complex64 or Complex128.
1153func (v Value) OverflowComplex(x complex128) bool {
Russ Coxa479a452011-11-16 19:18:25 -05001154 k := v.kind()
1155 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -04001156 case Complex64:
1157 return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1158 case Complex128:
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001159 return false
1160 }
Russ Cox0d81b722014-10-17 12:54:31 -04001161 panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001162}
1163
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -08001164// OverflowFloat reports whether the float64 x cannot be represented by v's type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001165// It panics if v's Kind is not Float32 or Float64.
1166func (v Value) OverflowFloat(x float64) bool {
Russ Coxa479a452011-11-16 19:18:25 -05001167 k := v.kind()
1168 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -04001169 case Float32:
1170 return overflowFloat32(x)
1171 case Float64:
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001172 return false
1173 }
Russ Cox0d81b722014-10-17 12:54:31 -04001174 panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
Russ Cox40fccbc2011-04-18 14:35:33 -04001175}
1176
1177func overflowFloat32(x float64) bool {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001178 if x < 0 {
1179 x = -x
1180 }
Rémy Oudompheng38070a72012-10-26 08:39:36 +02001181 return math.MaxFloat32 < x && x <= math.MaxFloat64
Russ Coxfb175cf2011-04-08 12:26:51 -04001182}
1183
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -08001184// OverflowInt reports whether the int64 x cannot be represented by v's type.
Russ Cox40fccbc2011-04-18 14:35:33 -04001185// It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
Russ Coxfb175cf2011-04-08 12:26:51 -04001186func (v Value) OverflowInt(x int64) bool {
Russ Coxa479a452011-11-16 19:18:25 -05001187 k := v.kind()
1188 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -04001189 case Int, Int8, Int16, Int32, Int64:
Russ Coxa479a452011-11-16 19:18:25 -05001190 bitSize := v.typ.size * 8
Russ Cox40fccbc2011-04-18 14:35:33 -04001191 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1192 return x != trunc
1193 }
Russ Cox0d81b722014-10-17 12:54:31 -04001194 panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001195}
1196
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -08001197// OverflowUint reports whether the uint64 x cannot be represented by v's type.
Russ Cox40fccbc2011-04-18 14:35:33 -04001198// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
Russ Coxfb175cf2011-04-08 12:26:51 -04001199func (v Value) OverflowUint(x uint64) bool {
Russ Coxa479a452011-11-16 19:18:25 -05001200 k := v.kind()
1201 switch k {
Russ Cox40fccbc2011-04-18 14:35:33 -04001202 case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
Russ Coxa479a452011-11-16 19:18:25 -05001203 bitSize := v.typ.size * 8
Russ Cox40fccbc2011-04-18 14:35:33 -04001204 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1205 return x != trunc
1206 }
Russ Cox0d81b722014-10-17 12:54:31 -04001207 panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001208}
1209
Russ Coxfb175cf2011-04-08 12:26:51 -04001210// Pointer returns v's value as a uintptr.
1211// It returns uintptr instead of unsafe.Pointer so that
1212// code using reflect cannot obtain unsafe.Pointers
1213// without importing the unsafe package explicitly.
1214// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
Russ Cox1903ad72013-02-21 17:01:13 -05001215//
1216// If v's Kind is Func, the returned pointer is an underlying
1217// code pointer, but not necessarily enough to identify a
1218// single function uniquely. The only guarantee is that the
1219// result is zero if and only if v is a nil func Value.
Keith Randallcbc565a2013-12-19 15:15:24 -08001220//
1221// If v's Kind is Slice, the returned pointer is to the first
1222// element of the slice. If the slice is nil the returned value
1223// is 0. If the slice is empty but non-nil the return value is non-zero.
Russ Coxfb175cf2011-04-08 12:26:51 -04001224func (v Value) Pointer() uintptr {
Keith Randallcbc565a2013-12-19 15:15:24 -08001225 // TODO: deprecate
Russ Coxa479a452011-11-16 19:18:25 -05001226 k := v.kind()
1227 switch k {
Russ Cox1903ad72013-02-21 17:01:13 -05001228 case Chan, Map, Ptr, UnsafePointer:
Keith Randallcbc565a2013-12-19 15:15:24 -08001229 return uintptr(v.pointer())
Russ Cox1903ad72013-02-21 17:01:13 -05001230 case Func:
1231 if v.flag&flagMethod != 0 {
Russ Cox3be70362013-03-21 16:59:16 -04001232 // As the doc comment says, the returned pointer is an
1233 // underlying code pointer but not necessarily enough to
1234 // identify a single function uniquely. All method expressions
1235 // created via reflect have the same underlying code pointer,
1236 // so their Pointers are equal. The function used here must
1237 // match the one used in makeMethodValue.
1238 f := methodValueCall
1239 return **(**uintptr)(unsafe.Pointer(&f))
Russ Cox40fccbc2011-04-18 14:35:33 -04001240 }
Keith Randallcbc565a2013-12-19 15:15:24 -08001241 p := v.pointer()
Russ Cox1903ad72013-02-21 17:01:13 -05001242 // Non-nil func value points at data block.
1243 // First word of data block is actual code.
1244 if p != nil {
1245 p = *(*unsafe.Pointer)(p)
1246 }
Russ Coxa479a452011-11-16 19:18:25 -05001247 return uintptr(p)
Russ Cox1903ad72013-02-21 17:01:13 -05001248
Russ Cox40fccbc2011-04-18 14:35:33 -04001249 case Slice:
Keith Randallcbc565a2013-12-19 15:15:24 -08001250 return (*SliceHeader)(v.ptr).Data
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001251 }
Russ Cox0d81b722014-10-17 12:54:31 -04001252 panic(&ValueError{"reflect.Value.Pointer", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001253}
1254
Russ Coxfb175cf2011-04-08 12:26:51 -04001255// Recv receives and returns a value from the channel v.
1256// It panics if v's Kind is not Chan.
1257// The receive blocks until a value is ready.
1258// The boolean value ok is true if the value x corresponds to a send
1259// on the channel, false if it is a zero value received because the channel is closed.
1260func (v Value) Recv() (x Value, ok bool) {
Russ Coxa479a452011-11-16 19:18:25 -05001261 v.mustBe(Chan)
1262 v.mustBeExported()
1263 return v.recv(false)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001264}
1265
Russ Coxa479a452011-11-16 19:18:25 -05001266// internal recv, possibly non-blocking (nb).
1267// v is known to be a channel.
1268func (v Value) recv(nb bool) (val Value, ok bool) {
1269 tt := (*chanType)(unsafe.Pointer(v.typ))
1270 if ChanDir(tt.dir)&RecvDir == 0 {
Russ Cox3be70362013-03-21 16:59:16 -04001271 panic("reflect: recv on send-only channel")
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001272 }
Keith Randall873aaa52014-01-16 13:35:29 -08001273 t := tt.elem
Russ Cox0d81b722014-10-17 12:54:31 -04001274 val = Value{t, nil, flag(t.Kind())}
Keith Randall873aaa52014-01-16 13:35:29 -08001275 var p unsafe.Pointer
Russ Coxa1616d42014-10-15 14:24:18 -04001276 if ifaceIndir(t) {
Keith Randall873aaa52014-01-16 13:35:29 -08001277 p = unsafe_New(t)
1278 val.ptr = p
1279 val.flag |= flagIndir
Keith Randall873aaa52014-01-16 13:35:29 -08001280 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001281 p = unsafe.Pointer(&val.ptr)
Keith Randall873aaa52014-01-16 13:35:29 -08001282 }
1283 selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
1284 if !selected {
1285 val = Value{}
Russ Cox40fccbc2011-04-18 14:35:33 -04001286 }
1287 return
Russ Coxfb175cf2011-04-08 12:26:51 -04001288}
1289
1290// Send sends x on the channel v.
1291// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
Russ Coxe1ee3b52011-04-20 16:24:45 -04001292// As in Go, x's value must be assignable to the channel's element type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001293func (v Value) Send(x Value) {
Russ Coxa479a452011-11-16 19:18:25 -05001294 v.mustBe(Chan)
1295 v.mustBeExported()
1296 v.send(x, false)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001297}
1298
Russ Coxa479a452011-11-16 19:18:25 -05001299// internal send, possibly non-blocking.
1300// v is known to be a channel.
1301func (v Value) send(x Value, nb bool) (selected bool) {
1302 tt := (*chanType)(unsafe.Pointer(v.typ))
1303 if ChanDir(tt.dir)&SendDir == 0 {
Russ Cox3be70362013-03-21 16:59:16 -04001304 panic("reflect: send on recv-only channel")
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001305 }
Russ Coxa479a452011-11-16 19:18:25 -05001306 x.mustBeExported()
Russ Cox11209822012-11-13 13:06:29 -05001307 x = x.assignTo("reflect.Value.Send", tt.elem, nil)
Keith Randall873aaa52014-01-16 13:35:29 -08001308 var p unsafe.Pointer
1309 if x.flag&flagIndir != 0 {
1310 p = x.ptr
Keith Randall873aaa52014-01-16 13:35:29 -08001311 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001312 p = unsafe.Pointer(&x.ptr)
Keith Randall873aaa52014-01-16 13:35:29 -08001313 }
1314 return chansend(v.typ, v.pointer(), p, nb)
Russ Coxfb175cf2011-04-08 12:26:51 -04001315}
1316
Russ Coxe1ee3b52011-04-20 16:24:45 -04001317// Set assigns x to the value v.
1318// It panics if CanSet returns false.
1319// As in Go, x's value must be assignable to v's type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001320func (v Value) Set(x Value) {
Russ Coxa479a452011-11-16 19:18:25 -05001321 v.mustBeAssignable()
1322 x.mustBeExported() // do not let unexported x leak
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07001323 var target unsafe.Pointer
Russ Coxa479a452011-11-16 19:18:25 -05001324 if v.kind() == Interface {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07001325 target = v.ptr
Russ Coxa479a452011-11-16 19:18:25 -05001326 }
1327 x = x.assignTo("reflect.Set", v.typ, target)
1328 if x.flag&flagIndir != 0 {
Russ Coxdf027ac2014-12-30 13:59:55 -05001329 typedmemmove(v.typ, v.ptr, x.ptr)
Russ Cox40fccbc2011-04-18 14:35:33 -04001330 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001331 *(*unsafe.Pointer)(v.ptr) = x.ptr
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001332 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001333}
1334
1335// SetBool sets v's underlying value.
1336// It panics if v's Kind is not Bool or if CanSet() is false.
1337func (v Value) SetBool(x bool) {
Russ Coxa479a452011-11-16 19:18:25 -05001338 v.mustBeAssignable()
1339 v.mustBe(Bool)
Keith Randallcbc565a2013-12-19 15:15:24 -08001340 *(*bool)(v.ptr) = x
Russ Coxfb175cf2011-04-08 12:26:51 -04001341}
1342
Russ Cox00d64c72011-08-23 22:50:08 -04001343// SetBytes sets v's underlying value.
1344// It panics if v's underlying value is not a slice of bytes.
1345func (v Value) SetBytes(x []byte) {
Russ Coxa479a452011-11-16 19:18:25 -05001346 v.mustBeAssignable()
1347 v.mustBe(Slice)
1348 if v.typ.Elem().Kind() != Uint8 {
Russ Cox00d64c72011-08-23 22:50:08 -04001349 panic("reflect.Value.SetBytes of non-byte slice")
1350 }
Keith Randallcbc565a2013-12-19 15:15:24 -08001351 *(*[]byte)(v.ptr) = x
Russ Cox00d64c72011-08-23 22:50:08 -04001352}
1353
Russ Cox46f379c2012-09-22 08:52:27 -04001354// setRunes sets v's underlying value.
1355// It panics if v's underlying value is not a slice of runes (int32s).
1356func (v Value) setRunes(x []rune) {
1357 v.mustBeAssignable()
1358 v.mustBe(Slice)
1359 if v.typ.Elem().Kind() != Int32 {
1360 panic("reflect.Value.setRunes of non-rune slice")
1361 }
Keith Randallcbc565a2013-12-19 15:15:24 -08001362 *(*[]rune)(v.ptr) = x
Russ Cox46f379c2012-09-22 08:52:27 -04001363}
1364
Russ Coxfb175cf2011-04-08 12:26:51 -04001365// SetComplex sets v's underlying value to x.
1366// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
1367func (v Value) SetComplex(x complex128) {
Russ Coxa479a452011-11-16 19:18:25 -05001368 v.mustBeAssignable()
1369 switch k := v.kind(); k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001370 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001371 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001372 case Complex64:
Keith Randallcbc565a2013-12-19 15:15:24 -08001373 *(*complex64)(v.ptr) = complex64(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001374 case Complex128:
Keith Randallcbc565a2013-12-19 15:15:24 -08001375 *(*complex128)(v.ptr) = x
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001376 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001377}
1378
1379// SetFloat sets v's underlying value to x.
1380// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
1381func (v Value) SetFloat(x float64) {
Russ Coxa479a452011-11-16 19:18:25 -05001382 v.mustBeAssignable()
1383 switch k := v.kind(); k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001384 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001385 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001386 case Float32:
Keith Randallcbc565a2013-12-19 15:15:24 -08001387 *(*float32)(v.ptr) = float32(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001388 case Float64:
Keith Randallcbc565a2013-12-19 15:15:24 -08001389 *(*float64)(v.ptr) = x
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001390 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001391}
1392
1393// SetInt sets v's underlying value to x.
Russ Cox40fccbc2011-04-18 14:35:33 -04001394// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
Russ Coxfb175cf2011-04-08 12:26:51 -04001395func (v Value) SetInt(x int64) {
Russ Coxa479a452011-11-16 19:18:25 -05001396 v.mustBeAssignable()
1397 switch k := v.kind(); k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001398 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001399 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001400 case Int:
Keith Randallcbc565a2013-12-19 15:15:24 -08001401 *(*int)(v.ptr) = int(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001402 case Int8:
Keith Randallcbc565a2013-12-19 15:15:24 -08001403 *(*int8)(v.ptr) = int8(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001404 case Int16:
Keith Randallcbc565a2013-12-19 15:15:24 -08001405 *(*int16)(v.ptr) = int16(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001406 case Int32:
Keith Randallcbc565a2013-12-19 15:15:24 -08001407 *(*int32)(v.ptr) = int32(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001408 case Int64:
Keith Randallcbc565a2013-12-19 15:15:24 -08001409 *(*int64)(v.ptr) = x
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001410 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001411}
1412
1413// SetLen sets v's length to n.
Rob Pike9bcfc572012-02-10 15:09:09 +11001414// It panics if v's Kind is not Slice or if n is negative or
1415// greater than the capacity of the slice.
Russ Coxfb175cf2011-04-08 12:26:51 -04001416func (v Value) SetLen(n int) {
Russ Coxa479a452011-11-16 19:18:25 -05001417 v.mustBeAssignable()
1418 v.mustBe(Slice)
Keith Randallcbc565a2013-12-19 15:15:24 -08001419 s := (*sliceHeader)(v.ptr)
Russ Cox0d81b722014-10-17 12:54:31 -04001420 if uint(n) > uint(s.Cap) {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001421 panic("reflect: slice length out of range in SetLen")
1422 }
1423 s.Len = n
Russ Coxfb175cf2011-04-08 12:26:51 -04001424}
1425
Russ Cox4d8aefd2013-07-01 20:32:53 -04001426// SetCap sets v's capacity to n.
1427// It panics if v's Kind is not Slice or if n is smaller than the length or
1428// greater than the capacity of the slice.
1429func (v Value) SetCap(n int) {
1430 v.mustBeAssignable()
1431 v.mustBe(Slice)
Keith Randallcbc565a2013-12-19 15:15:24 -08001432 s := (*sliceHeader)(v.ptr)
Russ Cox4d8aefd2013-07-01 20:32:53 -04001433 if n < int(s.Len) || n > int(s.Cap) {
1434 panic("reflect: slice capacity out of range in SetCap")
1435 }
1436 s.Cap = n
1437}
1438
Russ Coxfb175cf2011-04-08 12:26:51 -04001439// SetMapIndex sets the value associated with key in the map v to val.
1440// It panics if v's Kind is not Map.
1441// If val is the zero Value, SetMapIndex deletes the key from the map.
Keith Randall4b3019b2014-05-23 17:39:58 -07001442// Otherwise if v holds a nil map, SetMapIndex will panic.
Russ Coxe1ee3b52011-04-20 16:24:45 -04001443// As in Go, key's value must be assignable to the map's key type,
1444// and val's value must be assignable to the map's value type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001445func (v Value) SetMapIndex(key, val Value) {
Russ Coxa479a452011-11-16 19:18:25 -05001446 v.mustBe(Map)
1447 v.mustBeExported()
1448 key.mustBeExported()
1449 tt := (*mapType)(unsafe.Pointer(v.typ))
Russ Cox11209822012-11-13 13:06:29 -05001450 key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
Keith Randallcbc565a2013-12-19 15:15:24 -08001451 var k unsafe.Pointer
1452 if key.flag&flagIndir != 0 {
1453 k = key.ptr
Keith Randallcbc565a2013-12-19 15:15:24 -08001454 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001455 k = unsafe.Pointer(&key.ptr)
Russ Coxe1ee3b52011-04-20 16:24:45 -04001456 }
Keith Randallcbc565a2013-12-19 15:15:24 -08001457 if val.typ == nil {
1458 mapdelete(v.typ, v.pointer(), k)
1459 return
1460 }
1461 val.mustBeExported()
1462 val = val.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
1463 var e unsafe.Pointer
1464 if val.flag&flagIndir != 0 {
1465 e = val.ptr
Keith Randallcbc565a2013-12-19 15:15:24 -08001466 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001467 e = unsafe.Pointer(&val.ptr)
Keith Randallcbc565a2013-12-19 15:15:24 -08001468 }
1469 mapassign(v.typ, v.pointer(), k, e)
Russ Coxfb175cf2011-04-08 12:26:51 -04001470}
1471
1472// SetUint sets v's underlying value to x.
Russ Cox40fccbc2011-04-18 14:35:33 -04001473// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
Russ Coxfb175cf2011-04-08 12:26:51 -04001474func (v Value) SetUint(x uint64) {
Russ Coxa479a452011-11-16 19:18:25 -05001475 v.mustBeAssignable()
1476 switch k := v.kind(); k {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001477 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001478 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001479 case Uint:
Keith Randallcbc565a2013-12-19 15:15:24 -08001480 *(*uint)(v.ptr) = uint(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001481 case Uint8:
Keith Randallcbc565a2013-12-19 15:15:24 -08001482 *(*uint8)(v.ptr) = uint8(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001483 case Uint16:
Keith Randallcbc565a2013-12-19 15:15:24 -08001484 *(*uint16)(v.ptr) = uint16(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001485 case Uint32:
Keith Randallcbc565a2013-12-19 15:15:24 -08001486 *(*uint32)(v.ptr) = uint32(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001487 case Uint64:
Keith Randallcbc565a2013-12-19 15:15:24 -08001488 *(*uint64)(v.ptr) = x
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001489 case Uintptr:
Keith Randallcbc565a2013-12-19 15:15:24 -08001490 *(*uintptr)(v.ptr) = uintptr(x)
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001491 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001492}
1493
1494// SetPointer sets the unsafe.Pointer value v to x.
1495// It panics if v's Kind is not UnsafePointer.
1496func (v Value) SetPointer(x unsafe.Pointer) {
Russ Coxa479a452011-11-16 19:18:25 -05001497 v.mustBeAssignable()
1498 v.mustBe(UnsafePointer)
Keith Randallcbc565a2013-12-19 15:15:24 -08001499 *(*unsafe.Pointer)(v.ptr) = x
Russ Coxfb175cf2011-04-08 12:26:51 -04001500}
1501
1502// SetString sets v's underlying value to x.
1503// It panics if v's Kind is not String or if CanSet() is false.
1504func (v Value) SetString(x string) {
Russ Coxa479a452011-11-16 19:18:25 -05001505 v.mustBeAssignable()
1506 v.mustBe(String)
Keith Randallcbc565a2013-12-19 15:15:24 -08001507 *(*string)(v.ptr) = x
Russ Coxfb175cf2011-04-08 12:26:51 -04001508}
1509
Russ Cox4d8aefd2013-07-01 20:32:53 -04001510// Slice returns v[i:j].
1511// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,
1512// or if the indexes are out of bounds.
1513func (v Value) Slice(i, j int) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001514 var (
1515 cap int
1516 typ *sliceType
1517 base unsafe.Pointer
1518 )
Russ Cox4d8aefd2013-07-01 20:32:53 -04001519 switch kind := v.kind(); kind {
Russ Coxa479a452011-11-16 19:18:25 -05001520 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001521 panic(&ValueError{"reflect.Value.Slice", v.kind()})
Evan Shaw772decb2012-10-21 17:02:10 -04001522
Russ Cox3bac16a2011-04-18 20:00:42 -04001523 case Array:
Russ Coxa479a452011-11-16 19:18:25 -05001524 if v.flag&flagAddr == 0 {
Russ Cox3bac16a2011-04-18 20:00:42 -04001525 panic("reflect.Value.Slice: slice of unaddressable array")
1526 }
Russ Coxa479a452011-11-16 19:18:25 -05001527 tt := (*arrayType)(unsafe.Pointer(v.typ))
1528 cap = int(tt.len)
Russ Cox11209822012-11-13 13:06:29 -05001529 typ = (*sliceType)(unsafe.Pointer(tt.slice))
Keith Randallcbc565a2013-12-19 15:15:24 -08001530 base = v.ptr
Evan Shaw772decb2012-10-21 17:02:10 -04001531
Russ Cox3bac16a2011-04-18 20:00:42 -04001532 case Slice:
Russ Coxa479a452011-11-16 19:18:25 -05001533 typ = (*sliceType)(unsafe.Pointer(v.typ))
Keith Randallcbc565a2013-12-19 15:15:24 -08001534 s := (*sliceHeader)(v.ptr)
Russ Coxa479a452011-11-16 19:18:25 -05001535 base = unsafe.Pointer(s.Data)
1536 cap = s.Cap
1537
Evan Shaw772decb2012-10-21 17:02:10 -04001538 case String:
Keith Randallcbc565a2013-12-19 15:15:24 -08001539 s := (*stringHeader)(v.ptr)
Russ Cox4d8aefd2013-07-01 20:32:53 -04001540 if i < 0 || j < i || j > s.Len {
Evan Shaw772decb2012-10-21 17:02:10 -04001541 panic("reflect.Value.Slice: string slice index out of bounds")
1542 }
Sebastien Binete00e6562015-01-27 10:04:11 +01001543 t := stringHeader{arrayAt(s.Data, i, 1), j - i}
Russ Coxa1616d42014-10-15 14:24:18 -04001544 return Value{v.typ, unsafe.Pointer(&t), v.flag}
Russ Coxa479a452011-11-16 19:18:25 -05001545 }
Evan Shaw772decb2012-10-21 17:02:10 -04001546
Russ Cox4d8aefd2013-07-01 20:32:53 -04001547 if i < 0 || j < i || j > cap {
Russ Coxa479a452011-11-16 19:18:25 -05001548 panic("reflect.Value.Slice: slice index out of bounds")
Russ Cox3bac16a2011-04-18 20:00:42 -04001549 }
Russ Cox4e7aac52011-10-18 10:03:37 -04001550
1551 // Declare slice so that gc can see the base pointer in it.
Jan Ziak90f9bec2012-12-28 02:35:04 +08001552 var x []unsafe.Pointer
Russ Cox4e7aac52011-10-18 10:03:37 -04001553
Keith Randallcbc565a2013-12-19 15:15:24 -08001554 // Reinterpret as *sliceHeader to edit.
1555 s := (*sliceHeader)(unsafe.Pointer(&x))
Russ Cox4d8aefd2013-07-01 20:32:53 -04001556 s.Len = j - i
1557 s.Cap = cap - i
Russ Cox613383c2014-08-25 14:38:19 -04001558 if cap-i > 0 {
Sebastien Binete00e6562015-01-27 10:04:11 +01001559 s.Data = arrayAt(base, i, typ.elem.Size())
Russ Cox613383c2014-08-25 14:38:19 -04001560 } else {
1561 // do not advance pointer, to avoid pointing beyond end of slice
1562 s.Data = base
1563 }
Russ Cox4d8aefd2013-07-01 20:32:53 -04001564
Russ Cox0d81b722014-10-17 12:54:31 -04001565 fl := v.flag&flagRO | flagIndir | flag(Slice)
Russ Coxa1616d42014-10-15 14:24:18 -04001566 return Value{typ.common(), unsafe.Pointer(&x), fl}
Russ Cox4d8aefd2013-07-01 20:32:53 -04001567}
1568
1569// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].
1570// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,
1571// or if the indexes are out of bounds.
1572func (v Value) Slice3(i, j, k int) Value {
1573 var (
1574 cap int
1575 typ *sliceType
1576 base unsafe.Pointer
1577 )
1578 switch kind := v.kind(); kind {
1579 default:
Russ Cox0d81b722014-10-17 12:54:31 -04001580 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
Russ Cox4d8aefd2013-07-01 20:32:53 -04001581
1582 case Array:
1583 if v.flag&flagAddr == 0 {
Richard Musiol7ff57e22013-12-30 11:41:01 -08001584 panic("reflect.Value.Slice3: slice of unaddressable array")
Russ Cox4d8aefd2013-07-01 20:32:53 -04001585 }
1586 tt := (*arrayType)(unsafe.Pointer(v.typ))
1587 cap = int(tt.len)
1588 typ = (*sliceType)(unsafe.Pointer(tt.slice))
Keith Randallcbc565a2013-12-19 15:15:24 -08001589 base = v.ptr
Russ Cox4d8aefd2013-07-01 20:32:53 -04001590
1591 case Slice:
1592 typ = (*sliceType)(unsafe.Pointer(v.typ))
Keith Randallcbc565a2013-12-19 15:15:24 -08001593 s := (*sliceHeader)(v.ptr)
1594 base = s.Data
Russ Cox4d8aefd2013-07-01 20:32:53 -04001595 cap = s.Cap
1596 }
1597
1598 if i < 0 || j < i || k < j || k > cap {
1599 panic("reflect.Value.Slice3: slice index out of bounds")
1600 }
1601
1602 // Declare slice so that the garbage collector
1603 // can see the base pointer in it.
1604 var x []unsafe.Pointer
1605
Keith Randallcbc565a2013-12-19 15:15:24 -08001606 // Reinterpret as *sliceHeader to edit.
1607 s := (*sliceHeader)(unsafe.Pointer(&x))
Russ Cox4d8aefd2013-07-01 20:32:53 -04001608 s.Len = j - i
1609 s.Cap = k - i
Russ Cox613383c2014-08-25 14:38:19 -04001610 if k-i > 0 {
Sebastien Binete00e6562015-01-27 10:04:11 +01001611 s.Data = arrayAt(base, i, typ.elem.Size())
Russ Cox613383c2014-08-25 14:38:19 -04001612 } else {
1613 // do not advance pointer, to avoid pointing beyond end of slice
1614 s.Data = base
1615 }
Russ Cox4e7aac52011-10-18 10:03:37 -04001616
Russ Cox0d81b722014-10-17 12:54:31 -04001617 fl := v.flag&flagRO | flagIndir | flag(Slice)
Russ Coxa1616d42014-10-15 14:24:18 -04001618 return Value{typ.common(), unsafe.Pointer(&x), fl}
Russ Coxfb175cf2011-04-08 12:26:51 -04001619}
1620
1621// String returns the string v's underlying value, as a string.
1622// String is a special case because of Go's String method convention.
1623// Unlike the other getters, it does not panic if v's Kind is not String.
1624// Instead, it returns a string of the form "<T value>" where T is v's type.
Rob Pike049b89d2015-04-09 16:30:48 -07001625// The fmt package treats Values specially. It does not call their String
1626// method implicitly but instead prints the concrete values they hold.
Russ Coxfb175cf2011-04-08 12:26:51 -04001627func (v Value) String() string {
Russ Coxa479a452011-11-16 19:18:25 -05001628 switch k := v.kind(); k {
Russ Cox40fccbc2011-04-18 14:35:33 -04001629 case Invalid:
Russ Coxfb175cf2011-04-08 12:26:51 -04001630 return "<invalid Value>"
Russ Cox40fccbc2011-04-18 14:35:33 -04001631 case String:
Keith Randallcbc565a2013-12-19 15:15:24 -08001632 return *(*string)(v.ptr)
Russ Coxfb175cf2011-04-08 12:26:51 -04001633 }
Rob Pike86e65ba2011-09-20 13:26:57 -07001634 // If you call String on a reflect.Value of other type, it's better to
1635 // print something than to panic. Useful in debugging.
Russ Coxdd8f29e2014-09-18 21:19:18 -04001636 return "<" + v.Type().String() + " Value>"
Russ Coxfb175cf2011-04-08 12:26:51 -04001637}
1638
1639// TryRecv attempts to receive a value from the channel v but will not block.
1640// It panics if v's Kind is not Chan.
Rob Pike591265f2014-01-14 15:04:16 -08001641// If the receive delivers a value, x is the transferred value and ok is true.
1642// If the receive cannot finish without blocking, x is the zero Value and ok is false.
1643// If the channel is closed, x is the zero value for the channel's element type and ok is false.
Russ Coxfb175cf2011-04-08 12:26:51 -04001644func (v Value) TryRecv() (x Value, ok bool) {
Russ Coxa479a452011-11-16 19:18:25 -05001645 v.mustBe(Chan)
1646 v.mustBeExported()
1647 return v.recv(true)
Russ Coxfb175cf2011-04-08 12:26:51 -04001648}
1649
1650// TrySend attempts to send x on the channel v but will not block.
1651// It panics if v's Kind is not Chan.
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -08001652// It reports whether the value was sent.
Russ Coxe1ee3b52011-04-20 16:24:45 -04001653// As in Go, x's value must be assignable to the channel's element type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001654func (v Value) TrySend(x Value) bool {
Russ Coxa479a452011-11-16 19:18:25 -05001655 v.mustBe(Chan)
1656 v.mustBeExported()
1657 return v.send(x, true)
Russ Coxfb175cf2011-04-08 12:26:51 -04001658}
1659
1660// Type returns v's type.
1661func (v Value) Type() Type {
Russ Coxa479a452011-11-16 19:18:25 -05001662 f := v.flag
1663 if f == 0 {
Russ Cox40fccbc2011-04-18 14:35:33 -04001664 panic(&ValueError{"reflect.Value.Type", Invalid})
1665 }
Russ Coxa479a452011-11-16 19:18:25 -05001666 if f&flagMethod == 0 {
1667 // Easy case
1668 return v.typ
1669 }
1670
1671 // Method value.
1672 // v.typ describes the receiver, not the method type.
1673 i := int(v.flag) >> flagMethodShift
1674 if v.typ.Kind() == Interface {
1675 // Method on interface.
1676 tt := (*interfaceType)(unsafe.Pointer(v.typ))
Russ Cox0d81b722014-10-17 12:54:31 -04001677 if uint(i) >= uint(len(tt.methods)) {
Russ Cox3be70362013-03-21 16:59:16 -04001678 panic("reflect: internal error: invalid method index")
Russ Coxa479a452011-11-16 19:18:25 -05001679 }
1680 m := &tt.methods[i]
Russ Cox11209822012-11-13 13:06:29 -05001681 return m.typ
Russ Coxa479a452011-11-16 19:18:25 -05001682 }
1683 // Method on concrete type.
1684 ut := v.typ.uncommon()
Russ Cox0d81b722014-10-17 12:54:31 -04001685 if ut == nil || uint(i) >= uint(len(ut.methods)) {
Russ Cox3be70362013-03-21 16:59:16 -04001686 panic("reflect: internal error: invalid method index")
Russ Coxa479a452011-11-16 19:18:25 -05001687 }
1688 m := &ut.methods[i]
Russ Cox11209822012-11-13 13:06:29 -05001689 return m.mtyp
Russ Coxfb175cf2011-04-08 12:26:51 -04001690}
1691
Russ Coxfb175cf2011-04-08 12:26:51 -04001692// Uint returns v's underlying value, as a uint64.
Russ Cox40fccbc2011-04-18 14:35:33 -04001693// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
Russ Coxfb175cf2011-04-08 12:26:51 -04001694func (v Value) Uint() uint64 {
Russ Coxa479a452011-11-16 19:18:25 -05001695 k := v.kind()
Russ Coxa1616d42014-10-15 14:24:18 -04001696 p := v.ptr
Russ Coxa479a452011-11-16 19:18:25 -05001697 switch k {
1698 case Uint:
1699 return uint64(*(*uint)(p))
1700 case Uint8:
1701 return uint64(*(*uint8)(p))
1702 case Uint16:
1703 return uint64(*(*uint16)(p))
1704 case Uint32:
1705 return uint64(*(*uint32)(p))
1706 case Uint64:
1707 return uint64(*(*uint64)(p))
1708 case Uintptr:
1709 return uint64(*(*uintptr)(p))
1710 }
Russ Cox0d81b722014-10-17 12:54:31 -04001711 panic(&ValueError{"reflect.Value.Uint", v.kind()})
Russ Coxfb175cf2011-04-08 12:26:51 -04001712}
1713
1714// UnsafeAddr returns a pointer to v's data.
1715// It is for advanced clients that also import the "unsafe" package.
Russ Cox40fccbc2011-04-18 14:35:33 -04001716// It panics if v is not addressable.
Russ Coxfb175cf2011-04-08 12:26:51 -04001717func (v Value) UnsafeAddr() uintptr {
Keith Randallcbc565a2013-12-19 15:15:24 -08001718 // TODO: deprecate
Russ Coxa479a452011-11-16 19:18:25 -05001719 if v.typ == nil {
1720 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
Russ Coxe46acb02011-03-03 13:20:17 -05001721 }
Russ Coxa479a452011-11-16 19:18:25 -05001722 if v.flag&flagAddr == 0 {
Russ Cox40fccbc2011-04-18 14:35:33 -04001723 panic("reflect.Value.UnsafeAddr of unaddressable value")
Russ Coxe46acb02011-03-03 13:20:17 -05001724 }
Keith Randallcbc565a2013-12-19 15:15:24 -08001725 return uintptr(v.ptr)
Russ Coxce2e4502009-07-07 11:02:44 -07001726}
1727
Rob Pike16ddb6c2010-01-29 12:43:46 +11001728// StringHeader is the runtime representation of a string.
Rob Pike092c4812013-04-07 18:42:47 -07001729// It cannot be used safely or portably and its representation may
1730// change in a later release.
1731// Moreover, the Data field is not sufficient to guarantee the data
1732// it references will not be garbage collected, so programs must keep
1733// a separate, correctly typed pointer to the underlying data.
Ken Thompsond7a5ccf2010-01-28 17:14:29 -08001734type StringHeader struct {
David Symonds2be84a82013-04-08 07:59:47 +10001735 Data uintptr
Ken Thompsond7a5ccf2010-01-28 17:14:29 -08001736 Len int
1737}
Rob Pike16ddb6c2010-01-29 12:43:46 +11001738
Keith Randallcbc565a2013-12-19 15:15:24 -08001739// stringHeader is a safe version of StringHeader used within this package.
1740type stringHeader struct {
1741 Data unsafe.Pointer
1742 Len int
1743}
1744
Russ Cox40fccbc2011-04-18 14:35:33 -04001745// SliceHeader is the runtime representation of a slice.
Rob Pike092c4812013-04-07 18:42:47 -07001746// It cannot be used safely or portably and its representation may
1747// change in a later release.
1748// Moreover, the Data field is not sufficient to guarantee the data
1749// it references will not be garbage collected, so programs must keep
1750// a separate, correctly typed pointer to the underlying data.
Russ Cox40fccbc2011-04-18 14:35:33 -04001751type SliceHeader struct {
David Symonds2be84a82013-04-08 07:59:47 +10001752 Data uintptr
Russ Cox40fccbc2011-04-18 14:35:33 -04001753 Len int
1754 Cap int
Russ Coxce2e4502009-07-07 11:02:44 -07001755}
1756
Keith Randallcbc565a2013-12-19 15:15:24 -08001757// sliceHeader is a safe version of SliceHeader used within this package.
1758type sliceHeader struct {
1759 Data unsafe.Pointer
1760 Len int
1761 Cap int
1762}
1763
Russ Cox40fccbc2011-04-18 14:35:33 -04001764func typesMustMatch(what string, t1, t2 Type) {
Russ Coxce2e4502009-07-07 11:02:44 -07001765 if t1 != t2 {
Russ Coxa479a452011-11-16 19:18:25 -05001766 panic(what + ": " + t1.String() + " != " + t2.String())
Russ Coxce2e4502009-07-07 11:02:44 -07001767 }
1768}
1769
Sebastien Binet918fdae2015-01-27 10:04:11 +01001770// arrayAt returns the i-th element of p, a C-array whose elements are
1771// eltSize wide (in bytes).
1772func arrayAt(p unsafe.Pointer, i int, eltSize uintptr) unsafe.Pointer {
1773 return unsafe.Pointer(uintptr(p) + uintptr(i)*eltSize)
1774}
1775
Nigel Tao8b64cd92010-12-15 08:50:08 +11001776// grow grows the slice s so that it can hold extra more values, allocating
1777// more capacity if needed. It also returns the old and new slice lengths.
Russ Coxfb175cf2011-04-08 12:26:51 -04001778func grow(s Value, extra int) (Value, int, int) {
Nigel Tao8b64cd92010-12-15 08:50:08 +11001779 i0 := s.Len()
1780 i1 := i0 + extra
1781 if i1 < i0 {
Russ Cox40fccbc2011-04-18 14:35:33 -04001782 panic("reflect.Append: slice overflow")
Nigel Tao8b64cd92010-12-15 08:50:08 +11001783 }
1784 m := s.Cap()
1785 if i1 <= m {
1786 return s.Slice(0, i1), i0, i1
1787 }
1788 if m == 0 {
1789 m = extra
1790 } else {
1791 for m < i1 {
1792 if i0 < 1024 {
1793 m += m
1794 } else {
1795 m += m / 4
1796 }
1797 }
1798 }
Russ Coxfb175cf2011-04-08 12:26:51 -04001799 t := MakeSlice(s.Type(), i1, m)
Nigel Tao8b64cd92010-12-15 08:50:08 +11001800 Copy(t, s)
1801 return t, i0, i1
1802}
1803
1804// Append appends the values x to a slice s and returns the resulting slice.
Russ Coxe1ee3b52011-04-20 16:24:45 -04001805// As in Go, each x's value must be assignable to the slice's element type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001806func Append(s Value, x ...Value) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001807 s.mustBe(Slice)
Nigel Tao8b64cd92010-12-15 08:50:08 +11001808 s, i0, i1 := grow(s, len(x))
1809 for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
Russ Cox7b6ee1a2011-04-13 16:55:20 -04001810 s.Index(i).Set(x[j])
Nigel Tao8b64cd92010-12-15 08:50:08 +11001811 }
1812 return s
1813}
1814
1815// AppendSlice appends a slice t to a slice s and returns the resulting slice.
1816// The slices s and t must have the same element type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001817func AppendSlice(s, t Value) Value {
Russ Coxa479a452011-11-16 19:18:25 -05001818 s.mustBe(Slice)
1819 t.mustBe(Slice)
Russ Cox40fccbc2011-04-18 14:35:33 -04001820 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
Nigel Tao8b64cd92010-12-15 08:50:08 +11001821 s, i0, i1 := grow(s, t.Len())
1822 Copy(s.Slice(i0, i1), t)
1823 return s
1824}
1825
Nigel Tao73fd2982010-12-12 20:27:29 +11001826// Copy copies the contents of src into dst until either
Russ Coxce2e4502009-07-07 11:02:44 -07001827// dst has been filled or src has been exhausted.
1828// It returns the number of elements copied.
Russ Cox40fccbc2011-04-18 14:35:33 -04001829// Dst and src each must have kind Slice or Array, and
1830// dst and src must have the same element type.
Russ Coxfb175cf2011-04-08 12:26:51 -04001831func Copy(dst, src Value) int {
Russ Coxa479a452011-11-16 19:18:25 -05001832 dk := dst.kind()
1833 if dk != Array && dk != Slice {
1834 panic(&ValueError{"reflect.Copy", dk})
1835 }
1836 if dk == Array {
1837 dst.mustBeAssignable()
1838 }
1839 dst.mustBeExported()
Russ Cox40fccbc2011-04-18 14:35:33 -04001840
Russ Coxa479a452011-11-16 19:18:25 -05001841 sk := src.kind()
1842 if sk != Array && sk != Slice {
1843 panic(&ValueError{"reflect.Copy", sk})
Russ Coxce2e4502009-07-07 11:02:44 -07001844 }
Russ Coxa479a452011-11-16 19:18:25 -05001845 src.mustBeExported()
Russ Cox40fccbc2011-04-18 14:35:33 -04001846
Russ Coxa479a452011-11-16 19:18:25 -05001847 de := dst.typ.Elem()
1848 se := src.typ.Elem()
Russ Cox40fccbc2011-04-18 14:35:33 -04001849 typesMustMatch("reflect.Copy", de, se)
1850
Russ Coxdf027ac2014-12-30 13:59:55 -05001851 var ds, ss sliceHeader
1852 if dk == Array {
1853 ds.Data = dst.ptr
1854 ds.Len = dst.Len()
1855 ds.Cap = ds.Len
1856 } else {
1857 ds = *(*sliceHeader)(dst.ptr)
1858 }
1859 if sk == Array {
1860 ss.Data = src.ptr
1861 ss.Len = src.Len()
1862 ss.Cap = ss.Len
1863 } else {
1864 ss = *(*sliceHeader)(src.ptr)
Russ Cox40fccbc2011-04-18 14:35:33 -04001865 }
1866
Russ Coxdf027ac2014-12-30 13:59:55 -05001867 return typedslicecopy(de.common(), ds, ss)
Russ Coxce2e4502009-07-07 11:02:44 -07001868}
1869
Russ Cox370ae052012-09-18 14:22:41 -04001870// A runtimeSelect is a single case passed to rselect.
Keith Randall1d8fa7f2014-09-02 14:13:29 -07001871// This must match ../runtime/select.go:/runtimeSelect
Russ Cox370ae052012-09-18 14:22:41 -04001872type runtimeSelect struct {
Keith Randall873aaa52014-01-16 13:35:29 -08001873 dir uintptr // 0, SendDir, or RecvDir
1874 typ *rtype // channel type
1875 ch unsafe.Pointer // channel
1876 val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
Russ Cox370ae052012-09-18 14:22:41 -04001877}
1878
Keith Randall873aaa52014-01-16 13:35:29 -08001879// rselect runs a select. It returns the index of the chosen case.
1880// If the case was a receive, val is filled in with the received value.
1881// The conventional OK bool indicates whether the receive corresponds
1882// to a sent value.
1883//go:noescape
1884func rselect([]runtimeSelect) (chosen int, recvOK bool)
Russ Cox370ae052012-09-18 14:22:41 -04001885
1886// A SelectDir describes the communication direction of a select case.
1887type SelectDir int
1888
Keith Randall1d8fa7f2014-09-02 14:13:29 -07001889// NOTE: These values must match ../runtime/select.go:/selectDir.
Russ Cox370ae052012-09-18 14:22:41 -04001890
1891const (
1892 _ SelectDir = iota
1893 SelectSend // case Chan <- Send
1894 SelectRecv // case <-Chan:
1895 SelectDefault // default
1896)
1897
1898// A SelectCase describes a single case in a select operation.
1899// The kind of case depends on Dir, the communication direction.
1900//
1901// If Dir is SelectDefault, the case represents a default case.
1902// Chan and Send must be zero Values.
1903//
1904// If Dir is SelectSend, the case represents a send operation.
1905// Normally Chan's underlying value must be a channel, and Send's underlying value must be
1906// assignable to the channel's element type. As a special case, if Chan is a zero Value,
1907// then the case is ignored, and the field Send will also be ignored and may be either zero
1908// or non-zero.
1909//
1910// If Dir is SelectRecv, the case represents a receive operation.
1911// Normally Chan's underlying value must be a channel and Send must be a zero Value.
1912// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
1913// When a receive operation is selected, the received Value is returned by Select.
1914//
1915type SelectCase struct {
1916 Dir SelectDir // direction of case
1917 Chan Value // channel to use (for send or receive)
1918 Send Value // value to send (for send)
1919}
1920
1921// Select executes a select operation described by the list of cases.
Russ Coxa6db2a82013-02-19 10:13:53 -05001922// Like the Go select statement, it blocks until at least one of the cases
1923// can proceed, makes a uniform pseudo-random choice,
1924// and then executes that case. It returns the index of the chosen case
Russ Cox370ae052012-09-18 14:22:41 -04001925// and, if that case was a receive operation, the value received and a
1926// boolean indicating whether the value corresponds to a send on the channel
1927// (as opposed to a zero value received because the channel is closed).
1928func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
1929 // NOTE: Do not trust that caller is not modifying cases data underfoot.
1930 // The range is safe because the caller cannot modify our copy of the len
1931 // and each iteration makes its own copy of the value c.
1932 runcases := make([]runtimeSelect, len(cases))
1933 haveDefault := false
1934 for i, c := range cases {
1935 rc := &runcases[i]
1936 rc.dir = uintptr(c.Dir)
1937 switch c.Dir {
1938 default:
1939 panic("reflect.Select: invalid Dir")
1940
Robert Griesemer465b9c32012-10-30 13:38:01 -07001941 case SelectDefault: // default
Russ Cox370ae052012-09-18 14:22:41 -04001942 if haveDefault {
1943 panic("reflect.Select: multiple default cases")
1944 }
1945 haveDefault = true
1946 if c.Chan.IsValid() {
1947 panic("reflect.Select: default case has Chan value")
1948 }
1949 if c.Send.IsValid() {
1950 panic("reflect.Select: default case has Send value")
1951 }
1952
1953 case SelectSend:
1954 ch := c.Chan
1955 if !ch.IsValid() {
1956 break
1957 }
1958 ch.mustBe(Chan)
1959 ch.mustBeExported()
1960 tt := (*chanType)(unsafe.Pointer(ch.typ))
1961 if ChanDir(tt.dir)&SendDir == 0 {
1962 panic("reflect.Select: SendDir case using recv-only channel")
1963 }
Keith Randall873aaa52014-01-16 13:35:29 -08001964 rc.ch = ch.pointer()
Russ Cox11209822012-11-13 13:06:29 -05001965 rc.typ = &tt.rtype
Russ Cox370ae052012-09-18 14:22:41 -04001966 v := c.Send
1967 if !v.IsValid() {
1968 panic("reflect.Select: SendDir case missing Send value")
1969 }
1970 v.mustBeExported()
Russ Cox11209822012-11-13 13:06:29 -05001971 v = v.assignTo("reflect.Select", tt.elem, nil)
Keith Randall873aaa52014-01-16 13:35:29 -08001972 if v.flag&flagIndir != 0 {
1973 rc.val = v.ptr
Keith Randall873aaa52014-01-16 13:35:29 -08001974 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04001975 rc.val = unsafe.Pointer(&v.ptr)
Keith Randall873aaa52014-01-16 13:35:29 -08001976 }
Russ Cox370ae052012-09-18 14:22:41 -04001977
1978 case SelectRecv:
1979 if c.Send.IsValid() {
1980 panic("reflect.Select: RecvDir case has Send value")
1981 }
1982 ch := c.Chan
1983 if !ch.IsValid() {
1984 break
1985 }
1986 ch.mustBe(Chan)
1987 ch.mustBeExported()
1988 tt := (*chanType)(unsafe.Pointer(ch.typ))
Russ Cox370ae052012-09-18 14:22:41 -04001989 if ChanDir(tt.dir)&RecvDir == 0 {
1990 panic("reflect.Select: RecvDir case using send-only channel")
1991 }
Keith Randall873aaa52014-01-16 13:35:29 -08001992 rc.ch = ch.pointer()
1993 rc.typ = &tt.rtype
1994 rc.val = unsafe_New(tt.elem)
Russ Cox370ae052012-09-18 14:22:41 -04001995 }
1996 }
1997
Keith Randall873aaa52014-01-16 13:35:29 -08001998 chosen, recvOK = rselect(runcases)
Russ Cox370ae052012-09-18 14:22:41 -04001999 if runcases[chosen].dir == uintptr(SelectRecv) {
Russ Cox11209822012-11-13 13:06:29 -05002000 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
Keith Randall873aaa52014-01-16 13:35:29 -08002001 t := tt.elem
2002 p := runcases[chosen].val
Russ Cox0d81b722014-10-17 12:54:31 -04002003 fl := flag(t.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -04002004 if ifaceIndir(t) {
2005 recv = Value{t, p, fl | flagIndir}
Keith Randall873aaa52014-01-16 13:35:29 -08002006 } else {
Russ Coxa1616d42014-10-15 14:24:18 -04002007 recv = Value{t, *(*unsafe.Pointer)(p), fl}
Keith Randall873aaa52014-01-16 13:35:29 -08002008 }
Russ Cox370ae052012-09-18 14:22:41 -04002009 }
2010 return chosen, recv, recvOK
2011}
2012
Russ Coxce2e4502009-07-07 11:02:44 -07002013/*
Russ Cox40fccbc2011-04-18 14:35:33 -04002014 * constructors
Russ Coxce2e4502009-07-07 11:02:44 -07002015 */
2016
Russ Cox6a75ece2012-02-12 23:26:20 -05002017// implemented in package runtime
Russ Cox11209822012-11-13 13:06:29 -05002018func unsafe_New(*rtype) unsafe.Pointer
2019func unsafe_NewArray(*rtype, int) unsafe.Pointer
Russ Cox6a75ece2012-02-12 23:26:20 -05002020
Russ Coxce2e4502009-07-07 11:02:44 -07002021// MakeSlice creates a new zero-initialized slice value
2022// for the specified slice type, length, and capacity.
Russ Coxfb175cf2011-04-08 12:26:51 -04002023func MakeSlice(typ Type, len, cap int) Value {
2024 if typ.Kind() != Slice {
Russ Coxa479a452011-11-16 19:18:25 -05002025 panic("reflect.MakeSlice of non-slice type")
Russ Coxfb175cf2011-04-08 12:26:51 -04002026 }
David Symonds11cc5a22012-03-16 17:28:16 +11002027 if len < 0 {
2028 panic("reflect.MakeSlice: negative len")
2029 }
2030 if cap < 0 {
2031 panic("reflect.MakeSlice: negative cap")
2032 }
2033 if len > cap {
2034 panic("reflect.MakeSlice: len > cap")
2035 }
Russ Cox4e7aac52011-10-18 10:03:37 -04002036
Keith Randallcbc565a2013-12-19 15:15:24 -08002037 s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap}
Russ Cox0d81b722014-10-17 12:54:31 -04002038 return Value{typ.common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
Russ Coxce2e4502009-07-07 11:02:44 -07002039}
2040
Russ Cox5ddaf9a2009-07-08 15:00:54 -07002041// MakeChan creates a new channel with the specified type and buffer size.
Russ Coxfb175cf2011-04-08 12:26:51 -04002042func MakeChan(typ Type, buffer int) Value {
2043 if typ.Kind() != Chan {
Russ Coxa479a452011-11-16 19:18:25 -05002044 panic("reflect.MakeChan of non-chan type")
Russ Coxfb175cf2011-04-08 12:26:51 -04002045 }
Russ Cox5ddaf9a2009-07-08 15:00:54 -07002046 if buffer < 0 {
Russ Coxa479a452011-11-16 19:18:25 -05002047 panic("reflect.MakeChan: negative buffer size")
Russ Cox5ddaf9a2009-07-08 15:00:54 -07002048 }
Russ Coxfb175cf2011-04-08 12:26:51 -04002049 if typ.ChanDir() != BothDir {
Russ Coxa479a452011-11-16 19:18:25 -05002050 panic("reflect.MakeChan: unidirectional channel type")
Russ Cox5ddaf9a2009-07-08 15:00:54 -07002051 }
Russ Cox11209822012-11-13 13:06:29 -05002052 ch := makechan(typ.(*rtype), uint64(buffer))
Russ Cox0d81b722014-10-17 12:54:31 -04002053 return Value{typ.common(), ch, flag(Chan)}
Russ Coxce2e4502009-07-07 11:02:44 -07002054}
2055
Russ Cox5ddaf9a2009-07-08 15:00:54 -07002056// MakeMap creates a new map of the specified type.
Russ Coxfb175cf2011-04-08 12:26:51 -04002057func MakeMap(typ Type) Value {
2058 if typ.Kind() != Map {
Russ Coxa479a452011-11-16 19:18:25 -05002059 panic("reflect.MakeMap of non-map type")
Russ Coxfb175cf2011-04-08 12:26:51 -04002060 }
Russ Cox11209822012-11-13 13:06:29 -05002061 m := makemap(typ.(*rtype))
Russ Cox0d81b722014-10-17 12:54:31 -04002062 return Value{typ.common(), m, flag(Map)}
Russ Coxce2e4502009-07-07 11:02:44 -07002063}
2064
Russ Coxce2e4502009-07-07 11:02:44 -07002065// Indirect returns the value that v points to.
Rob Pike9bcfc572012-02-10 15:09:09 +11002066// If v is a nil pointer, Indirect returns a zero Value.
Russ Coxce2e4502009-07-07 11:02:44 -07002067// If v is not a pointer, Indirect returns v.
2068func Indirect(v Value) Value {
Russ Coxfb175cf2011-04-08 12:26:51 -04002069 if v.Kind() != Ptr {
2070 return v
Russ Coxce2e4502009-07-07 11:02:44 -07002071 }
Russ Cox7b6ee1a2011-04-13 16:55:20 -04002072 return v.Elem()
Rob Pikefac3dfe2008-10-22 11:02:56 -07002073}
2074
Russ Cox0e2bb622011-04-25 13:39:16 -04002075// ValueOf returns a new Value initialized to the concrete value
2076// stored in the interface i. ValueOf(nil) returns the zero Value.
2077func ValueOf(i interface{}) Value {
Russ Coxac6ebfd2009-04-06 21:28:04 -07002078 if i == nil {
Russ Coxfb175cf2011-04-08 12:26:51 -04002079 return Value{}
Russ Coxac6ebfd2009-04-06 21:28:04 -07002080 }
Russ Coxdb5f9da2011-08-28 12:05:00 -04002081
2082 // TODO(rsc): Eliminate this terrible hack.
Keith Randallcbc565a2013-12-19 15:15:24 -08002083 // In the call to unpackEface, i.typ doesn't escape,
2084 // and i.word is an integer. So it looks like
2085 // i doesn't escape. But really it does,
2086 // because i.word is actually a pointer.
Russ Coxdb5f9da2011-08-28 12:05:00 -04002087 escapes(i)
2088
Keith Randallcbc565a2013-12-19 15:15:24 -08002089 return unpackEface(i)
Rob Pikefac3dfe2008-10-22 11:02:56 -07002090}
2091
Robert Griesemer6044dbd2012-07-03 16:06:24 -07002092// Zero returns a Value representing the zero value for the specified type.
Russ Coxfb175cf2011-04-08 12:26:51 -04002093// The result is different from the zero value of the Value struct,
2094// which represents no value at all.
Russ Cox0e2bb622011-04-25 13:39:16 -04002095// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
Robert Griesemer6044dbd2012-07-03 16:06:24 -07002096// The returned value is neither addressable nor settable.
Russ Coxfb175cf2011-04-08 12:26:51 -04002097func Zero(typ Type) Value {
Russ Cox33649bd2009-12-07 15:51:58 -08002098 if typ == nil {
Russ Coxfb175cf2011-04-08 12:26:51 -04002099 panic("reflect: Zero(nil)")
Rob Pikefac3dfe2008-10-22 11:02:56 -07002100 }
Russ Coxa479a452011-11-16 19:18:25 -05002101 t := typ.common()
Russ Cox0d81b722014-10-17 12:54:31 -04002102 fl := flag(t.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -04002103 if ifaceIndir(t) {
2104 return Value{t, unsafe_New(typ.(*rtype)), fl | flagIndir}
Russ Cox40fccbc2011-04-18 14:35:33 -04002105 }
Russ Coxa1616d42014-10-15 14:24:18 -04002106 return Value{t, nil, fl}
Rob Pike3a7df4d2009-04-08 23:33:31 -07002107}
Russ Cox40fccbc2011-04-18 14:35:33 -04002108
2109// New returns a Value representing a pointer to a new zero value
Lucio De Recd4c1f12014-04-18 08:11:31 -07002110// for the specified type. That is, the returned Value's Type is PtrTo(typ).
Russ Cox40fccbc2011-04-18 14:35:33 -04002111func New(typ Type) Value {
2112 if typ == nil {
2113 panic("reflect: New(nil)")
2114 }
Russ Cox11209822012-11-13 13:06:29 -05002115 ptr := unsafe_New(typ.(*rtype))
Russ Cox0d81b722014-10-17 12:54:31 -04002116 fl := flag(Ptr)
Russ Coxa1616d42014-10-15 14:24:18 -04002117 return Value{typ.common().ptrTo(), ptr, fl}
Russ Cox40fccbc2011-04-18 14:35:33 -04002118}
2119
Russ Cox6a75ece2012-02-12 23:26:20 -05002120// NewAt returns a Value representing a pointer to a value of the
2121// specified type, using p as that pointer.
2122func NewAt(typ Type, p unsafe.Pointer) Value {
Russ Cox0d81b722014-10-17 12:54:31 -04002123 fl := flag(Ptr)
Russ Coxa1616d42014-10-15 14:24:18 -04002124 return Value{typ.common().ptrTo(), p, fl}
Russ Cox6a75ece2012-02-12 23:26:20 -05002125}
2126
Russ Coxa479a452011-11-16 19:18:25 -05002127// assignTo returns a value v that can be assigned directly to typ.
2128// It panics if v is not assignable to typ.
2129// For a conversion to an interface type, target is a suggested scratch space to use.
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002130func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
Russ Coxa479a452011-11-16 19:18:25 -05002131 if v.flag&flagMethod != 0 {
Russ Cox3be70362013-03-21 16:59:16 -04002132 v = makeMethodValue(context, v)
Russ Coxe1ee3b52011-04-20 16:24:45 -04002133 }
2134
Russ Coxa479a452011-11-16 19:18:25 -05002135 switch {
2136 case directlyAssignable(dst, v.typ):
Russ Coxe1ee3b52011-04-20 16:24:45 -04002137 // Overwrite type so that they match.
2138 // Same memory layout, so no harm done.
Russ Coxa479a452011-11-16 19:18:25 -05002139 v.typ = dst
2140 fl := v.flag & (flagRO | flagAddr | flagIndir)
Russ Cox0d81b722014-10-17 12:54:31 -04002141 fl |= flag(dst.Kind())
Russ Coxa1616d42014-10-15 14:24:18 -04002142 return Value{dst, v.ptr, fl}
Russ Coxa479a452011-11-16 19:18:25 -05002143
2144 case implements(dst, v.typ):
2145 if target == nil {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002146 target = unsafe_New(dst)
Russ Coxe1ee3b52011-04-20 16:24:45 -04002147 }
Russ Coxa479a452011-11-16 19:18:25 -05002148 x := valueInterface(v, false)
Russ Coxe1ee3b52011-04-20 16:24:45 -04002149 if dst.NumMethod() == 0 {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002150 *(*interface{})(target) = x
Russ Coxe1ee3b52011-04-20 16:24:45 -04002151 } else {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002152 ifaceE2I(dst, x, target)
Russ Coxe1ee3b52011-04-20 16:24:45 -04002153 }
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002154 return Value{dst, target, flagIndir | flag(Interface)}
Russ Coxe1ee3b52011-04-20 16:24:45 -04002155 }
2156
2157 // Failed.
Russ Coxa479a452011-11-16 19:18:25 -05002158 panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
Russ Coxe1ee3b52011-04-20 16:24:45 -04002159}
2160
Russ Cox46f379c2012-09-22 08:52:27 -04002161// Convert returns the value v converted to type t.
2162// If the usual Go conversion rules do not allow conversion
2163// of the value v to type t, Convert panics.
2164func (v Value) Convert(t Type) Value {
2165 if v.flag&flagMethod != 0 {
Russ Cox3be70362013-03-21 16:59:16 -04002166 v = makeMethodValue("Convert", v)
Russ Cox46f379c2012-09-22 08:52:27 -04002167 }
2168 op := convertOp(t.common(), v.typ)
2169 if op == nil {
2170 panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
2171 }
2172 return op(v, t)
2173}
2174
2175// convertOp returns the function to convert a value of type src
2176// to a value of type dst. If the conversion is illegal, convertOp returns nil.
Russ Cox11209822012-11-13 13:06:29 -05002177func convertOp(dst, src *rtype) func(Value, Type) Value {
Russ Cox46f379c2012-09-22 08:52:27 -04002178 switch src.Kind() {
2179 case Int, Int8, Int16, Int32, Int64:
2180 switch dst.Kind() {
2181 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2182 return cvtInt
2183 case Float32, Float64:
2184 return cvtIntFloat
2185 case String:
2186 return cvtIntString
2187 }
2188
2189 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2190 switch dst.Kind() {
2191 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2192 return cvtUint
2193 case Float32, Float64:
2194 return cvtUintFloat
2195 case String:
2196 return cvtUintString
2197 }
2198
2199 case Float32, Float64:
2200 switch dst.Kind() {
2201 case Int, Int8, Int16, Int32, Int64:
2202 return cvtFloatInt
2203 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2204 return cvtFloatUint
2205 case Float32, Float64:
2206 return cvtFloat
2207 }
2208
2209 case Complex64, Complex128:
2210 switch dst.Kind() {
2211 case Complex64, Complex128:
2212 return cvtComplex
2213 }
2214
2215 case String:
2216 if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
2217 switch dst.Elem().Kind() {
2218 case Uint8:
2219 return cvtStringBytes
2220 case Int32:
2221 return cvtStringRunes
2222 }
2223 }
2224
2225 case Slice:
2226 if dst.Kind() == String && src.Elem().PkgPath() == "" {
2227 switch src.Elem().Kind() {
2228 case Uint8:
2229 return cvtBytesString
2230 case Int32:
2231 return cvtRunesString
2232 }
2233 }
2234 }
2235
2236 // dst and src have same underlying type.
2237 if haveIdenticalUnderlyingType(dst, src) {
2238 return cvtDirect
2239 }
2240
2241 // dst and src are unnamed pointer types with same underlying base type.
2242 if dst.Kind() == Ptr && dst.Name() == "" &&
2243 src.Kind() == Ptr && src.Name() == "" &&
2244 haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common()) {
2245 return cvtDirect
2246 }
2247
2248 if implements(dst, src) {
2249 if src.Kind() == Interface {
2250 return cvtI2I
2251 }
2252 return cvtT2I
2253 }
2254
2255 return nil
2256}
2257
2258// makeInt returns a Value of type t equal to bits (possibly truncated),
2259// where t is a signed or unsigned int type.
2260func makeInt(f flag, bits uint64, t Type) Value {
2261 typ := t.common()
Russ Coxa1616d42014-10-15 14:24:18 -04002262 ptr := unsafe_New(typ)
Russ Cox46f379c2012-09-22 08:52:27 -04002263 switch typ.size {
2264 case 1:
Russ Coxa1616d42014-10-15 14:24:18 -04002265 *(*uint8)(unsafe.Pointer(ptr)) = uint8(bits)
Russ Cox46f379c2012-09-22 08:52:27 -04002266 case 2:
Russ Coxa1616d42014-10-15 14:24:18 -04002267 *(*uint16)(unsafe.Pointer(ptr)) = uint16(bits)
Russ Cox46f379c2012-09-22 08:52:27 -04002268 case 4:
Russ Coxa1616d42014-10-15 14:24:18 -04002269 *(*uint32)(unsafe.Pointer(ptr)) = uint32(bits)
Russ Cox46f379c2012-09-22 08:52:27 -04002270 case 8:
Russ Coxa1616d42014-10-15 14:24:18 -04002271 *(*uint64)(unsafe.Pointer(ptr)) = bits
Russ Cox46f379c2012-09-22 08:52:27 -04002272 }
Russ Cox0d81b722014-10-17 12:54:31 -04002273 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
Russ Cox46f379c2012-09-22 08:52:27 -04002274}
2275
2276// makeFloat returns a Value of type t equal to v (possibly truncated to float32),
2277// where t is a float32 or float64 type.
2278func makeFloat(f flag, v float64, t Type) Value {
2279 typ := t.common()
Russ Coxa1616d42014-10-15 14:24:18 -04002280 ptr := unsafe_New(typ)
Russ Cox46f379c2012-09-22 08:52:27 -04002281 switch typ.size {
2282 case 4:
Russ Coxa1616d42014-10-15 14:24:18 -04002283 *(*float32)(unsafe.Pointer(ptr)) = float32(v)
Russ Cox46f379c2012-09-22 08:52:27 -04002284 case 8:
Russ Coxa1616d42014-10-15 14:24:18 -04002285 *(*float64)(unsafe.Pointer(ptr)) = v
Russ Cox46f379c2012-09-22 08:52:27 -04002286 }
Russ Cox0d81b722014-10-17 12:54:31 -04002287 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
Russ Cox46f379c2012-09-22 08:52:27 -04002288}
2289
2290// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),
2291// where t is a complex64 or complex128 type.
2292func makeComplex(f flag, v complex128, t Type) Value {
2293 typ := t.common()
Russ Coxa1616d42014-10-15 14:24:18 -04002294 ptr := unsafe_New(typ)
Russ Cox1806a572014-08-18 21:13:11 -04002295 switch typ.size {
2296 case 8:
Russ Coxa1616d42014-10-15 14:24:18 -04002297 *(*complex64)(unsafe.Pointer(ptr)) = complex64(v)
Russ Cox1806a572014-08-18 21:13:11 -04002298 case 16:
Russ Coxa1616d42014-10-15 14:24:18 -04002299 *(*complex128)(unsafe.Pointer(ptr)) = v
Russ Cox1806a572014-08-18 21:13:11 -04002300 }
Russ Cox0d81b722014-10-17 12:54:31 -04002301 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
Russ Cox46f379c2012-09-22 08:52:27 -04002302}
2303
2304func makeString(f flag, v string, t Type) Value {
2305 ret := New(t).Elem()
2306 ret.SetString(v)
2307 ret.flag = ret.flag&^flagAddr | f
2308 return ret
2309}
2310
2311func makeBytes(f flag, v []byte, t Type) Value {
2312 ret := New(t).Elem()
2313 ret.SetBytes(v)
2314 ret.flag = ret.flag&^flagAddr | f
2315 return ret
2316}
2317
2318func makeRunes(f flag, v []rune, t Type) Value {
2319 ret := New(t).Elem()
2320 ret.setRunes(v)
2321 ret.flag = ret.flag&^flagAddr | f
2322 return ret
2323}
2324
2325// These conversion functions are returned by convertOp
2326// for classes of conversions. For example, the first function, cvtInt,
2327// takes any value v of signed int type and returns the value converted
2328// to type t, where t is any signed or unsigned int type.
2329
2330// convertOp: intXX -> [u]intXX
2331func cvtInt(v Value, t Type) Value {
2332 return makeInt(v.flag&flagRO, uint64(v.Int()), t)
2333}
2334
2335// convertOp: uintXX -> [u]intXX
2336func cvtUint(v Value, t Type) Value {
2337 return makeInt(v.flag&flagRO, v.Uint(), t)
2338}
2339
2340// convertOp: floatXX -> intXX
2341func cvtFloatInt(v Value, t Type) Value {
2342 return makeInt(v.flag&flagRO, uint64(int64(v.Float())), t)
2343}
2344
2345// convertOp: floatXX -> uintXX
2346func cvtFloatUint(v Value, t Type) Value {
2347 return makeInt(v.flag&flagRO, uint64(v.Float()), t)
2348}
2349
2350// convertOp: intXX -> floatXX
2351func cvtIntFloat(v Value, t Type) Value {
2352 return makeFloat(v.flag&flagRO, float64(v.Int()), t)
2353}
2354
2355// convertOp: uintXX -> floatXX
2356func cvtUintFloat(v Value, t Type) Value {
2357 return makeFloat(v.flag&flagRO, float64(v.Uint()), t)
2358}
2359
2360// convertOp: floatXX -> floatXX
2361func cvtFloat(v Value, t Type) Value {
2362 return makeFloat(v.flag&flagRO, v.Float(), t)
2363}
2364
2365// convertOp: complexXX -> complexXX
2366func cvtComplex(v Value, t Type) Value {
2367 return makeComplex(v.flag&flagRO, v.Complex(), t)
2368}
2369
2370// convertOp: intXX -> string
2371func cvtIntString(v Value, t Type) Value {
2372 return makeString(v.flag&flagRO, string(v.Int()), t)
2373}
2374
2375// convertOp: uintXX -> string
2376func cvtUintString(v Value, t Type) Value {
2377 return makeString(v.flag&flagRO, string(v.Uint()), t)
2378}
2379
2380// convertOp: []byte -> string
2381func cvtBytesString(v Value, t Type) Value {
2382 return makeString(v.flag&flagRO, string(v.Bytes()), t)
2383}
2384
2385// convertOp: string -> []byte
2386func cvtStringBytes(v Value, t Type) Value {
2387 return makeBytes(v.flag&flagRO, []byte(v.String()), t)
2388}
2389
2390// convertOp: []rune -> string
2391func cvtRunesString(v Value, t Type) Value {
2392 return makeString(v.flag&flagRO, string(v.runes()), t)
2393}
2394
2395// convertOp: string -> []rune
2396func cvtStringRunes(v Value, t Type) Value {
2397 return makeRunes(v.flag&flagRO, []rune(v.String()), t)
2398}
2399
2400// convertOp: direct copy
2401func cvtDirect(v Value, typ Type) Value {
2402 f := v.flag
2403 t := typ.common()
Keith Randallcbc565a2013-12-19 15:15:24 -08002404 ptr := v.ptr
Russ Cox46f379c2012-09-22 08:52:27 -04002405 if f&flagAddr != 0 {
2406 // indirect, mutable word - make a copy
Keith Randallcbc565a2013-12-19 15:15:24 -08002407 c := unsafe_New(t)
Russ Coxdf027ac2014-12-30 13:59:55 -05002408 typedmemmove(t, c, ptr)
Keith Randallcbc565a2013-12-19 15:15:24 -08002409 ptr = c
Russ Cox46f379c2012-09-22 08:52:27 -04002410 f &^= flagAddr
2411 }
Russ Coxa1616d42014-10-15 14:24:18 -04002412 return Value{t, ptr, v.flag&flagRO | f} // v.flag&flagRO|f == f?
Russ Cox46f379c2012-09-22 08:52:27 -04002413}
2414
2415// convertOp: concrete -> interface
2416func cvtT2I(v Value, typ Type) Value {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002417 target := unsafe_New(typ.common())
Russ Cox46f379c2012-09-22 08:52:27 -04002418 x := valueInterface(v, false)
2419 if typ.NumMethod() == 0 {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002420 *(*interface{})(target) = x
Russ Cox46f379c2012-09-22 08:52:27 -04002421 } else {
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002422 ifaceE2I(typ.(*rtype), x, target)
Russ Cox46f379c2012-09-22 08:52:27 -04002423 }
Ian Lance Taylor7b9c5ec2014-10-20 10:43:43 -07002424 return Value{typ.common(), target, v.flag&flagRO | flagIndir | flag(Interface)}
Russ Cox46f379c2012-09-22 08:52:27 -04002425}
2426
2427// convertOp: interface -> interface
2428func cvtI2I(v Value, typ Type) Value {
2429 if v.IsNil() {
2430 ret := Zero(typ)
2431 ret.flag |= v.flag & flagRO
2432 return ret
2433 }
2434 return cvtT2I(v.Elem(), typ)
2435}
2436
Russ Cox220a6de2014-09-08 00:06:45 -04002437// implemented in ../runtime
Keith Randallcbc565a2013-12-19 15:15:24 -08002438func chancap(ch unsafe.Pointer) int
2439func chanclose(ch unsafe.Pointer)
2440func chanlen(ch unsafe.Pointer) int
Keith Randall873aaa52014-01-16 13:35:29 -08002441
2442//go:noescape
2443func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
2444
2445//go:noescape
2446func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
Russ Cox40fccbc2011-04-18 14:35:33 -04002447
Keith Randallcbc565a2013-12-19 15:15:24 -08002448func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
2449func makemap(t *rtype) (m unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002450
2451//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002452func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002453
Keith Randallcbc565a2013-12-19 15:15:24 -08002454func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002455
2456//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002457func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002458
2459// m escapes into the return value, but the caller of mapiterinit
2460// doesn't let the return value escape.
2461//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002462func mapiterinit(t *rtype, m unsafe.Pointer) unsafe.Pointer
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002463
2464//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002465func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002466
2467//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002468func mapiternext(it unsafe.Pointer)
Dmitry Vyukov84e25672015-02-03 11:54:11 +03002469
2470//go:noescape
Keith Randallcbc565a2013-12-19 15:15:24 -08002471func maplen(m unsafe.Pointer) int
Russ Coxdf027ac2014-12-30 13:59:55 -05002472
2473// call calls fn with a copy of the n argument bytes pointed at by arg.
2474// After fn returns, reflectcall copies n-retoffset result bytes
2475// back into arg+retoffset before returning. If copying result bytes back,
2476// the caller must pass the argument frame type as argtype, so that
2477// call can execute appropriate write barriers during the copy.
2478func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)
Russ Coxf8f630f2014-09-05 16:51:45 -04002479
Russ Cox11209822012-11-13 13:06:29 -05002480func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
Russ Coxa479a452011-11-16 19:18:25 -05002481
Russ Coxdf027ac2014-12-30 13:59:55 -05002482// typedmemmove copies a value of type t to dst from src.
Keith Randallb78d7b72014-09-10 12:37:28 -07002483//go:noescape
Russ Coxdf027ac2014-12-30 13:59:55 -05002484func typedmemmove(t *rtype, dst, src unsafe.Pointer)
2485
2486// typedmemmovepartial is like typedmemmove but assumes that
2487// dst and src point off bytes into the value and only copies size bytes.
2488//go:noescape
2489func typedmemmovepartial(t *rtype, dst, src unsafe.Pointer, off, size uintptr)
2490
2491// typedslicecopy copies a slice of elemType values from src to dst,
2492// returning the number of elements copied.
2493//go:noescape
2494func typedslicecopy(elemType *rtype, dst, src sliceHeader) int
Keith Randallb78d7b72014-09-10 12:37:28 -07002495
Dmitry Vyukov67f8a812014-12-22 22:31:55 +03002496//go:noescape
2497func memclr(ptr unsafe.Pointer, n uintptr)
2498
Russ Coxa479a452011-11-16 19:18:25 -05002499// Dummy annotation marking that the value x escapes,
2500// for use in cases where the reflect code is so clever that
2501// the compiler cannot follow.
2502func escapes(x interface{}) {
2503 if dummy.b {
2504 dummy.x = x
2505 }
2506}
2507
2508var dummy struct {
2509 b bool
2510 x interface{}
2511}