OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [reflect/] [value.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package reflect
6
 
7
import (
8
        "math"
9
        "runtime"
10
        "strconv"
11
        "unsafe"
12
)
13
 
14
const bigEndian = false // can be smarter if we find a big-endian machine
15
const ptrSize = unsafe.Sizeof((*byte)(nil))
16
const cannotSet = "cannot set value obtained from unexported struct field"
17
 
18
// TODO: This will have to go away when
19
// the new gc goes in.
20
func memmove(adst, asrc unsafe.Pointer, n uintptr) {
21
        dst := uintptr(adst)
22
        src := uintptr(asrc)
23
        switch {
24
        case src < dst && src+n > dst:
25
                // byte copy backward
26
                // careful: i is unsigned
27
                for i := n; i > 0; {
28
                        i--
29
                        *(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
30
                }
31
        case (n|src|dst)&(ptrSize-1) != 0:
32
                // byte copy forward
33
                for i := uintptr(0); i < n; i++ {
34
                        *(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
35
                }
36
        default:
37
                // word copy forward
38
                for i := uintptr(0); i < n; i += ptrSize {
39
                        *(*uintptr)(unsafe.Pointer(dst + i)) = *(*uintptr)(unsafe.Pointer(src + i))
40
                }
41
        }
42
}
43
 
44
// Value is the reflection interface to a Go value.
45
//
46
// Not all methods apply to all kinds of values.  Restrictions,
47
// if any, are noted in the documentation for each method.
48
// Use the Kind method to find out the kind of value before
49
// calling kind-specific methods.  Calling a method
50
// inappropriate to the kind of type causes a run time panic.
51
//
52
// The zero Value represents no value.
53
// Its IsValid method returns false, its Kind method returns Invalid,
54
// its String method returns "", and all other methods panic.
55
// Most functions and methods never return an invalid value.
56
// If one does, its documentation states the conditions explicitly.
57
type Value struct {
58
        // typ holds the type of the value represented by a Value.
59
        typ *commonType
60
 
61
        // val holds the 1-word representation of the value.
62
        // If flag's flagIndir bit is set, then val is a pointer to the data.
63
        // Otherwise val is a word holding the actual data.
64
        // When the data is smaller than a word, it begins at
65
        // the first byte (in the memory address sense) of val.
66
        // We use unsafe.Pointer so that the garbage collector
67
        // knows that val could be a pointer.
68
        val unsafe.Pointer
69
 
70
        // flag holds metadata about the value.
71
        // The lowest bits are flag bits:
72
        //      - flagRO: obtained via unexported field, so read-only
73
        //      - flagIndir: val holds a pointer to the data
74
        //      - flagAddr: v.CanAddr is true (implies flagIndir)
75
        //      - flagMethod: v is a method value.
76
        // The next five bits give the Kind of the value.
77
        // This repeats typ.Kind() except for method values.
78
        // The remaining 23+ bits give a method number for method values.
79
        // If flag.kind() != Func, code can assume that flagMethod is unset.
80
        // If typ.size > ptrSize, code can assume that flagIndir is set.
81
        flag
82
 
83
        // A method value represents a curried method invocation
84
        // like r.Read for some receiver r.  The typ+val+flag bits describe
85
        // the receiver r, but the flag's Kind bits say Func (methods are
86
        // functions), and the top bits of the flag give the method number
87
        // in r's type's method table.
88
}
89
 
90
type flag uintptr
91
 
92
const (
93
        flagRO flag = 1 << iota
94
        flagIndir
95
        flagAddr
96
        flagMethod
97
        flagKindShift        = iota
98
        flagKindWidth        = 5 // there are 27 kinds
99
        flagKindMask    flag = 1<
100
        flagMethodShift      = flagKindShift + flagKindWidth
101
)
102
 
103
func (f flag) kind() Kind {
104
        return Kind((f >> flagKindShift) & flagKindMask)
105
}
106
 
107
// A ValueError occurs when a Value method is invoked on
108
// a Value that does not support it.  Such cases are documented
109
// in the description of each method.
110
type ValueError struct {
111
        Method string
112
        Kind   Kind
113
}
114
 
115
func (e *ValueError) Error() string {
116
        if e.Kind == 0 {
117
                return "reflect: call of " + e.Method + " on zero Value"
118
        }
119
        return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
120
}
121
 
122
// methodName returns the name of the calling method,
123
// assumed to be two stack frames above.
124
func methodName() string {
125
        pc, _, _, _ := runtime.Caller(2)
126
        f := runtime.FuncForPC(pc)
127
        if f == nil {
128
                return "unknown method"
129
        }
130
        return f.Name()
131
}
132
 
133
// An iword is the word that would be stored in an
134
// interface to represent a given value v.  Specifically, if v is
135
// bigger than a pointer, its word is a pointer to v's data.
136
// Otherwise, its word holds the data stored
137
// in its leading bytes (so is not a pointer).
138
// Because the value sometimes holds a pointer, we use
139
// unsafe.Pointer to represent it, so that if iword appears
140
// in a struct, the garbage collector knows that might be
141
// a pointer.
142
type iword unsafe.Pointer
143
 
144
func (v Value) iword() iword {
145
        if v.flag&flagIndir != 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) {
146
                // Have indirect but want direct word.
147
                return loadIword(v.val, v.typ.size)
148
        }
149
        return iword(v.val)
150
}
151
 
152
// loadIword loads n bytes at p from memory into an iword.
153
func loadIword(p unsafe.Pointer, n uintptr) iword {
154
        // Run the copy ourselves instead of calling memmove
155
        // to avoid moving w to the heap.
156
        var w iword
157
        switch n {
158
        default:
159
                panic("reflect: internal error: loadIword of " + strconv.Itoa(int(n)) + "-byte value")
160
        case 0:
161
        case 1:
162
                *(*uint8)(unsafe.Pointer(&w)) = *(*uint8)(p)
163
        case 2:
164
                *(*uint16)(unsafe.Pointer(&w)) = *(*uint16)(p)
165
        case 3:
166
                *(*[3]byte)(unsafe.Pointer(&w)) = *(*[3]byte)(p)
167
        case 4:
168
                *(*uint32)(unsafe.Pointer(&w)) = *(*uint32)(p)
169
        case 5:
170
                *(*[5]byte)(unsafe.Pointer(&w)) = *(*[5]byte)(p)
171
        case 6:
172
                *(*[6]byte)(unsafe.Pointer(&w)) = *(*[6]byte)(p)
173
        case 7:
174
                *(*[7]byte)(unsafe.Pointer(&w)) = *(*[7]byte)(p)
175
        case 8:
176
                *(*uint64)(unsafe.Pointer(&w)) = *(*uint64)(p)
177
        }
178
        return w
179
}
180
 
181
// storeIword stores n bytes from w into p.
182
func storeIword(p unsafe.Pointer, w iword, n uintptr) {
183
        // Run the copy ourselves instead of calling memmove
184
        // to avoid moving w to the heap.
185
        switch n {
186
        default:
187
                panic("reflect: internal error: storeIword of " + strconv.Itoa(int(n)) + "-byte value")
188
        case 0:
189
        case 1:
190
                *(*uint8)(p) = *(*uint8)(unsafe.Pointer(&w))
191
        case 2:
192
                *(*uint16)(p) = *(*uint16)(unsafe.Pointer(&w))
193
        case 3:
194
                *(*[3]byte)(p) = *(*[3]byte)(unsafe.Pointer(&w))
195
        case 4:
196
                *(*uint32)(p) = *(*uint32)(unsafe.Pointer(&w))
197
        case 5:
198
                *(*[5]byte)(p) = *(*[5]byte)(unsafe.Pointer(&w))
199
        case 6:
200
                *(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w))
201
        case 7:
202
                *(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w))
203
        case 8:
204
                *(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w))
205
        }
206
}
207
 
208
// emptyInterface is the header for an interface{} value.
209
type emptyInterface struct {
210
        typ  *runtime.Type
211
        word iword
212
}
213
 
214
// nonEmptyInterface is the header for a interface value with methods.
215
type nonEmptyInterface struct {
216
        // see ../runtime/iface.c:/Itab
217
        itab *struct {
218
                typ *runtime.Type          // dynamic concrete type
219
                fun [100000]unsafe.Pointer // method table
220
        }
221
        word iword
222
}
223
 
224
// mustBe panics if f's kind is not expected.
225
// Making this a method on flag instead of on Value
226
// (and embedding flag in Value) means that we can write
227
// the very clear v.mustBe(Bool) and have it compile into
228
// v.flag.mustBe(Bool), which will only bother to copy the
229
// single important word for the receiver.
230
func (f flag) mustBe(expected Kind) {
231
        k := f.kind()
232
        if k != expected {
233
                panic(&ValueError{methodName(), k})
234
        }
235
}
236
 
237
// mustBeExported panics if f records that the value was obtained using
238
// an unexported field.
239
func (f flag) mustBeExported() {
240
        if f == 0 {
241
                panic(&ValueError{methodName(), 0})
242
        }
243
        if f&flagRO != 0 {
244
                panic(methodName() + " using value obtained using unexported field")
245
        }
246
}
247
 
248
// mustBeAssignable panics if f records that the value is not assignable,
249
// which is to say that either it was obtained using an unexported field
250
// or it is not addressable.
251
func (f flag) mustBeAssignable() {
252
        if f == 0 {
253
                panic(&ValueError{methodName(), Invalid})
254
        }
255
        // Assignable if addressable and not read-only.
256
        if f&flagRO != 0 {
257
                panic(methodName() + " using value obtained using unexported field")
258
        }
259
        if f&flagAddr == 0 {
260
                panic(methodName() + " using unaddressable value")
261
        }
262
}
263
 
264
// Addr returns a pointer value representing the address of v.
265
// It panics if CanAddr() returns false.
266
// Addr is typically used to obtain a pointer to a struct field
267
// or slice element in order to call a method that requires a
268
// pointer receiver.
269
func (v Value) Addr() Value {
270
        if v.flag&flagAddr == 0 {
271
                panic("reflect.Value.Addr of unaddressable value")
272
        }
273
        return Value{v.typ.ptrTo(), v.val, (v.flag & flagRO) | flag(Ptr)<
274
}
275
 
276
// Bool returns v's underlying value.
277
// It panics if v's kind is not Bool.
278
func (v Value) Bool() bool {
279
        v.mustBe(Bool)
280
        if v.flag&flagIndir != 0 {
281
                return *(*bool)(v.val)
282
        }
283
        return *(*bool)(unsafe.Pointer(&v.val))
284
}
285
 
286
// Bytes returns v's underlying value.
287
// It panics if v's underlying value is not a slice of bytes.
288
func (v Value) Bytes() []byte {
289
        v.mustBe(Slice)
290
        if v.typ.Elem().Kind() != Uint8 {
291
                panic("reflect.Value.Bytes of non-byte slice")
292
        }
293
        // Slice is always bigger than a word; assume flagIndir.
294
        return *(*[]byte)(v.val)
295
}
296
 
297
// CanAddr returns true if the value's address can be obtained with Addr.
298
// Such values are called addressable.  A value is addressable if it is
299
// an element of a slice, an element of an addressable array,
300
// a field of an addressable struct, or the result of dereferencing a pointer.
301
// If CanAddr returns false, calling Addr will panic.
302
func (v Value) CanAddr() bool {
303
        return v.flag&flagAddr != 0
304
}
305
 
306
// CanSet returns true if the value of v can be changed.
307
// A Value can be changed only if it is addressable and was not
308
// obtained by the use of unexported struct fields.
309
// If CanSet returns false, calling Set or any type-specific
310
// setter (e.g., SetBool, SetInt64) will panic.
311
func (v Value) CanSet() bool {
312
        return v.flag&(flagAddr|flagRO) == flagAddr
313
}
314
 
315
// Call calls the function v with the input arguments in.
316
// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
317
// Call panics if v's Kind is not Func.
318
// It returns the output results as Values.
319
// As in Go, each input argument must be assignable to the
320
// type of the function's corresponding input parameter.
321
// If v is a variadic function, Call creates the variadic slice parameter
322
// itself, copying in the corresponding values.
323
func (v Value) Call(in []Value) []Value {
324
        v.mustBe(Func)
325
        v.mustBeExported()
326
        return v.call("Call", in)
327
}
328
 
329
// CallSlice calls the variadic function v with the input arguments in,
330
// assigning the slice in[len(in)-1] to v's final variadic argument.
331
// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
332
// Call panics if v's Kind is not Func or if v is not variadic.
333
// It returns the output results as Values.
334
// As in Go, each input argument must be assignable to the
335
// type of the function's corresponding input parameter.
336
func (v Value) CallSlice(in []Value) []Value {
337
        v.mustBe(Func)
338
        v.mustBeExported()
339
        return v.call("CallSlice", in)
340
}
341
 
342
func (v Value) call(method string, in []Value) []Value {
343
        // Get function pointer, type.
344
        t := v.typ
345
        var (
346
                fn   unsafe.Pointer
347
                rcvr iword
348
        )
349
        if v.flag&flagMethod != 0 {
350
                i := int(v.flag) >> flagMethodShift
351
                if v.typ.Kind() == Interface {
352
                        tt := (*interfaceType)(unsafe.Pointer(v.typ))
353
                        if i < 0 || i >= len(tt.methods) {
354
                                panic("reflect: broken Value")
355
                        }
356
                        m := &tt.methods[i]
357
                        if m.pkgPath != nil {
358
                                panic(method + " of unexported method")
359
                        }
360
                        t = toCommonType(m.typ)
361
                        iface := (*nonEmptyInterface)(v.val)
362
                        if iface.itab == nil {
363
                                panic(method + " of method on nil interface value")
364
                        }
365
                        fn = iface.itab.fun[i]
366
                        rcvr = iface.word
367
                } else {
368
                        ut := v.typ.uncommon()
369
                        if ut == nil || i < 0 || i >= len(ut.methods) {
370
                                panic("reflect: broken Value")
371
                        }
372
                        m := &ut.methods[i]
373
                        if m.pkgPath != nil {
374
                                panic(method + " of unexported method")
375
                        }
376
                        fn = m.tfn
377
                        t = toCommonType(m.mtyp)
378
                        rcvr = v.iword()
379
                }
380
        } else if v.flag&flagIndir != 0 {
381
                fn = *(*unsafe.Pointer)(v.val)
382
        } else {
383
                fn = v.val
384
        }
385
 
386
        if fn == nil {
387
                panic("reflect.Value.Call: call of nil function")
388
        }
389
 
390
        isSlice := method == "CallSlice"
391
        n := t.NumIn()
392
        if isSlice {
393
                if !t.IsVariadic() {
394
                        panic("reflect: CallSlice of non-variadic function")
395
                }
396
                if len(in) < n {
397
                        panic("reflect: CallSlice with too few input arguments")
398
                }
399
                if len(in) > n {
400
                        panic("reflect: CallSlice with too many input arguments")
401
                }
402
        } else {
403
                if t.IsVariadic() {
404
                        n--
405
                }
406
                if len(in) < n {
407
                        panic("reflect: Call with too few input arguments")
408
                }
409
                if !t.IsVariadic() && len(in) > n {
410
                        panic("reflect: Call with too many input arguments")
411
                }
412
        }
413
        for _, x := range in {
414
                if x.Kind() == Invalid {
415
                        panic("reflect: " + method + " using zero Value argument")
416
                }
417
        }
418
        for i := 0; i < n; i++ {
419
                if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
420
                        panic("reflect: " + method + " using " + xt.String() + " as type " + targ.String())
421
                }
422
        }
423
        if !isSlice && t.IsVariadic() {
424
                // prepare slice for remaining values
425
                m := len(in) - n
426
                slice := MakeSlice(t.In(n), m, m)
427
                elem := t.In(n).Elem()
428
                for i := 0; i < m; i++ {
429
                        x := in[n+i]
430
                        if xt := x.Type(); !xt.AssignableTo(elem) {
431
                                panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + method)
432
                        }
433
                        slice.Index(i).Set(x)
434
                }
435
                origIn := in
436
                in = make([]Value, n+1)
437
                copy(in[:n], origIn)
438
                in[n] = slice
439
        }
440
 
441
        nin := len(in)
442
        if nin != t.NumIn() {
443
                panic("reflect.Value.Call: wrong argument count")
444
        }
445
        nout := t.NumOut()
446
 
447
        if v.flag&flagMethod != 0 {
448
                nin++
449
        }
450
        params := make([]unsafe.Pointer, nin)
451
        off := 0
452
        if v.flag&flagMethod != 0 {
453
                // Hard-wired first argument.
454
                p := new(iword)
455
                *p = rcvr
456
                params[0] = unsafe.Pointer(p)
457
                off = 1
458
        }
459
        first_pointer := false
460
        for i, pv := range in {
461
                pv.mustBeExported()
462
                targ := t.In(i).(*commonType)
463
                pv = pv.assignTo("reflect.Value.Call", targ, nil)
464
                if pv.flag&flagIndir == 0 {
465
                        p := new(unsafe.Pointer)
466
                        *p = pv.val
467
                        params[off] = unsafe.Pointer(p)
468
                } else {
469
                        params[off] = pv.val
470
                }
471
                if i == 0 && Kind(targ.kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) {
472
                        p := new(unsafe.Pointer)
473
                        *p = params[off]
474
                        params[off] = unsafe.Pointer(p)
475
                        first_pointer = true
476
                }
477
                off++
478
        }
479
 
480
        ret := make([]Value, nout)
481
        results := make([]unsafe.Pointer, nout)
482
        for i := 0; i < nout; i++ {
483
                v := New(t.Out(i))
484
                results[i] = unsafe.Pointer(v.Pointer())
485
                ret[i] = Indirect(v)
486
        }
487
 
488
        var pp *unsafe.Pointer
489
        if len(params) > 0 {
490
                pp = ¶ms[0]
491
        }
492
        var pr *unsafe.Pointer
493
        if len(results) > 0 {
494
                pr = &results[0]
495
        }
496
 
497
        call(t, fn, v.flag&flagMethod != 0, first_pointer, pp, pr)
498
 
499
        return ret
500
}
501
 
502
// gccgo specific test to see if typ is a method.  We can tell by
503
// looking at the string to see if there is a receiver.  We need this
504
// because for gccgo all methods take pointer receivers.
505
func isMethod(t *commonType) bool {
506
        if Kind(t.kind) != Func {
507
                return false
508
        }
509
        s := *t.string
510
        parens := 0
511
        params := 0
512
        sawRet := false
513
        for i, c := range s {
514
                if c == '(' {
515
                        parens++
516
                        params++
517
                } else if c == ')' {
518
                        parens--
519
                } else if parens == 0 && c == ' ' && s[i+1] != '(' && !sawRet {
520
                        params++
521
                        sawRet = true
522
                }
523
        }
524
        return params > 2
525
}
526
 
527
// Cap returns v's capacity.
528
// It panics if v's Kind is not Array, Chan, or Slice.
529
func (v Value) Cap() int {
530
        k := v.kind()
531
        switch k {
532
        case Array:
533
                return v.typ.Len()
534
        case Chan:
535
                return int(chancap(*(*iword)(v.iword())))
536
        case Slice:
537
                // Slice is always bigger than a word; assume flagIndir.
538
                return (*SliceHeader)(v.val).Cap
539
        }
540
        panic(&ValueError{"reflect.Value.Cap", k})
541
}
542
 
543
// Close closes the channel v.
544
// It panics if v's Kind is not Chan.
545
func (v Value) Close() {
546
        v.mustBe(Chan)
547
        v.mustBeExported()
548
        chanclose(*(*iword)(v.iword()))
549
}
550
 
551
// Complex returns v's underlying value, as a complex128.
552
// It panics if v's Kind is not Complex64 or Complex128
553
func (v Value) Complex() complex128 {
554
        k := v.kind()
555
        switch k {
556
        case Complex64:
557
                if v.flag&flagIndir != 0 {
558
                        return complex128(*(*complex64)(v.val))
559
                }
560
                return complex128(*(*complex64)(unsafe.Pointer(&v.val)))
561
        case Complex128:
562
                // complex128 is always bigger than a word; assume flagIndir.
563
                return *(*complex128)(v.val)
564
        }
565
        panic(&ValueError{"reflect.Value.Complex", k})
566
}
567
 
568
// Elem returns the value that the interface v contains
569
// or that the pointer v points to.
570
// It panics if v's Kind is not Interface or Ptr.
571
// It returns the zero Value if v is nil.
572
func (v Value) Elem() Value {
573
        k := v.kind()
574
        switch k {
575
        case Interface:
576
                var (
577
                        typ *commonType
578
                        val unsafe.Pointer
579
                )
580
                if v.typ.NumMethod() == 0 {
581
                        eface := (*emptyInterface)(v.val)
582
                        if eface.typ == nil {
583
                                // nil interface value
584
                                return Value{}
585
                        }
586
                        typ = toCommonType(eface.typ)
587
                        val = unsafe.Pointer(eface.word)
588
                } else {
589
                        iface := (*nonEmptyInterface)(v.val)
590
                        if iface.itab == nil {
591
                                // nil interface value
592
                                return Value{}
593
                        }
594
                        typ = toCommonType(iface.itab.typ)
595
                        val = unsafe.Pointer(iface.word)
596
                }
597
                fl := v.flag & flagRO
598
                fl |= flag(typ.Kind()) << flagKindShift
599
                if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
600
                        fl |= flagIndir
601
                }
602
                return Value{typ, val, fl}
603
 
604
        case Ptr:
605
                val := v.val
606
                if v.flag&flagIndir != 0 {
607
                        val = *(*unsafe.Pointer)(val)
608
                }
609
                // The returned value's address is v's value.
610
                if val == nil {
611
                        return Value{}
612
                }
613
                tt := (*ptrType)(unsafe.Pointer(v.typ))
614
                typ := toCommonType(tt.elem)
615
                fl := v.flag&flagRO | flagIndir | flagAddr
616
                fl |= flag(typ.Kind() << flagKindShift)
617
                return Value{typ, val, fl}
618
        }
619
        panic(&ValueError{"reflect.Value.Elem", k})
620
}
621
 
622
// Field returns the i'th field of the struct v.
623
// It panics if v's Kind is not Struct or i is out of range.
624
func (v Value) Field(i int) Value {
625
        v.mustBe(Struct)
626
        tt := (*structType)(unsafe.Pointer(v.typ))
627
        if i < 0 || i >= len(tt.fields) {
628
                panic("reflect: Field index out of range")
629
        }
630
        field := &tt.fields[i]
631
        typ := toCommonType(field.typ)
632
 
633
        // Inherit permission bits from v.
634
        fl := v.flag & (flagRO | flagIndir | flagAddr)
635
        // Using an unexported field forces flagRO.
636
        if field.pkgPath != nil {
637
                fl |= flagRO
638
        }
639
        fl |= flag(typ.Kind()) << flagKindShift
640
 
641
        var val unsafe.Pointer
642
        switch {
643
        case fl&flagIndir != 0:
644
                // Indirect.  Just bump pointer.
645
                val = unsafe.Pointer(uintptr(v.val) + field.offset)
646
        case bigEndian:
647
                // Direct.  Discard leading bytes.
648
                val = unsafe.Pointer(uintptr(v.val) << (field.offset * 8))
649
        default:
650
                // Direct.  Discard leading bytes.
651
                val = unsafe.Pointer(uintptr(v.val) >> (field.offset * 8))
652
        }
653
 
654
        return Value{typ, val, fl}
655
}
656
 
657
// FieldByIndex returns the nested field corresponding to index.
658
// It panics if v's Kind is not struct.
659
func (v Value) FieldByIndex(index []int) Value {
660
        v.mustBe(Struct)
661
        for i, x := range index {
662
                if i > 0 {
663
                        if v.Kind() == Ptr && v.Elem().Kind() == Struct {
664
                                v = v.Elem()
665
                        }
666
                }
667
                v = v.Field(x)
668
        }
669
        return v
670
}
671
 
672
// FieldByName returns the struct field with the given name.
673
// It returns the zero Value if no field was found.
674
// It panics if v's Kind is not struct.
675
func (v Value) FieldByName(name string) Value {
676
        v.mustBe(Struct)
677
        if f, ok := v.typ.FieldByName(name); ok {
678
                return v.FieldByIndex(f.Index)
679
        }
680
        return Value{}
681
}
682
 
683
// FieldByNameFunc returns the struct field with a name
684
// that satisfies the match function.
685
// It panics if v's Kind is not struct.
686
// It returns the zero Value if no field was found.
687
func (v Value) FieldByNameFunc(match func(string) bool) Value {
688
        v.mustBe(Struct)
689
        if f, ok := v.typ.FieldByNameFunc(match); ok {
690
                return v.FieldByIndex(f.Index)
691
        }
692
        return Value{}
693
}
694
 
695
// Float returns v's underlying value, as an float64.
696
// It panics if v's Kind is not Float32 or Float64
697
func (v Value) Float() float64 {
698
        k := v.kind()
699
        switch k {
700
        case Float32:
701
                if v.flag&flagIndir != 0 {
702
                        return float64(*(*float32)(v.val))
703
                }
704
                return float64(*(*float32)(unsafe.Pointer(&v.val)))
705
        case Float64:
706
                if v.flag&flagIndir != 0 {
707
                        return *(*float64)(v.val)
708
                }
709
                return *(*float64)(unsafe.Pointer(&v.val))
710
        }
711
        panic(&ValueError{"reflect.Value.Float", k})
712
}
713
 
714
// Index returns v's i'th element.
715
// It panics if v's Kind is not Array or Slice or i is out of range.
716
func (v Value) Index(i int) Value {
717
        k := v.kind()
718
        switch k {
719
        case Array:
720
                tt := (*arrayType)(unsafe.Pointer(v.typ))
721
                if i < 0 || i > int(tt.len) {
722
                        panic("reflect: array index out of range")
723
                }
724
                typ := toCommonType(tt.elem)
725
                fl := v.flag & (flagRO | flagIndir | flagAddr) // bits same as overall array
726
                fl |= flag(typ.Kind()) << flagKindShift
727
                offset := uintptr(i) * typ.size
728
 
729
                var val unsafe.Pointer
730
                switch {
731
                case fl&flagIndir != 0:
732
                        // Indirect.  Just bump pointer.
733
                        val = unsafe.Pointer(uintptr(v.val) + offset)
734
                case bigEndian:
735
                        // Direct.  Discard leading bytes.
736
                        val = unsafe.Pointer(uintptr(v.val) << (offset * 8))
737
                default:
738
                        // Direct.  Discard leading bytes.
739
                        val = unsafe.Pointer(uintptr(v.val) >> (offset * 8))
740
                }
741
                return Value{typ, val, fl}
742
 
743
        case Slice:
744
                // Element flag same as Elem of Ptr.
745
                // Addressable, indirect, possibly read-only.
746
                fl := flagAddr | flagIndir | v.flag&flagRO
747
                s := (*SliceHeader)(v.val)
748
                if i < 0 || i >= s.Len {
749
                        panic("reflect: slice index out of range")
750
                }
751
                tt := (*sliceType)(unsafe.Pointer(v.typ))
752
                typ := toCommonType(tt.elem)
753
                fl |= flag(typ.Kind()) << flagKindShift
754
                val := unsafe.Pointer(s.Data + uintptr(i)*typ.size)
755
                return Value{typ, val, fl}
756
        }
757
        panic(&ValueError{"reflect.Value.Index", k})
758
}
759
 
760
// Int returns v's underlying value, as an int64.
761
// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
762
func (v Value) Int() int64 {
763
        k := v.kind()
764
        var p unsafe.Pointer
765
        if v.flag&flagIndir != 0 {
766
                p = v.val
767
        } else {
768
                // The escape analysis is good enough that &v.val
769
                // does not trigger a heap allocation.
770
                p = unsafe.Pointer(&v.val)
771
        }
772
        switch k {
773
        case Int:
774
                return int64(*(*int)(p))
775
        case Int8:
776
                return int64(*(*int8)(p))
777
        case Int16:
778
                return int64(*(*int16)(p))
779
        case Int32:
780
                return int64(*(*int32)(p))
781
        case Int64:
782
                return int64(*(*int64)(p))
783
        }
784
        panic(&ValueError{"reflect.Value.Int", k})
785
}
786
 
787
// CanInterface returns true if Interface can be used without panicking.
788
func (v Value) CanInterface() bool {
789
        if v.flag == 0 {
790
                panic(&ValueError{"reflect.Value.CanInterface", Invalid})
791
        }
792
        return v.flag&(flagMethod|flagRO) == 0
793
}
794
 
795
// Interface returns v's value as an interface{}.
796
// If v is a method obtained by invoking Value.Method
797
// (as opposed to Type.Method), Interface cannot return an
798
// interface value, so it panics.
799
func (v Value) Interface() interface{} {
800
        return valueInterface(v, true)
801
}
802
 
803
func valueInterface(v Value, safe bool) interface{} {
804
        if v.flag == 0 {
805
                panic(&ValueError{"reflect.Value.Interface", 0})
806
        }
807
        if v.flag&flagMethod != 0 {
808
                panic("reflect.Value.Interface: cannot create interface value for method with bound receiver")
809
        }
810
 
811
        if safe && v.flag&flagRO != 0 {
812
                // Do not allow access to unexported values via Interface,
813
                // because they might be pointers that should not be
814
                // writable or methods or function that should not be callable.
815
                panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
816
        }
817
 
818
        k := v.kind()
819
        if k == Interface {
820
                // Special case: return the element inside the interface.
821
                // Empty interface has one layout, all interfaces with
822
                // methods have a second layout.
823
                if v.NumMethod() == 0 {
824
                        return *(*interface{})(v.val)
825
                }
826
                return *(*interface {
827
                        M()
828
                })(v.val)
829
        }
830
 
831
        // Non-interface value.
832
        var eface emptyInterface
833
        eface.typ = v.typ.runtimeType()
834
        eface.word = v.iword()
835
        return *(*interface{})(unsafe.Pointer(&eface))
836
}
837
 
838
// InterfaceData returns the interface v's value as a uintptr pair.
839
// It panics if v's Kind is not Interface.
840
func (v Value) InterfaceData() [2]uintptr {
841
        v.mustBe(Interface)
842
        // We treat this as a read operation, so we allow
843
        // it even for unexported data, because the caller
844
        // has to import "unsafe" to turn it into something
845
        // that can be abused.
846
        // Interface value is always bigger than a word; assume flagIndir.
847
        return *(*[2]uintptr)(v.val)
848
}
849
 
850
// IsNil returns true if v is a nil value.
851
// It panics if v's Kind is not Chan, Func, Interface, Map, Ptr, or Slice.
852
func (v Value) IsNil() bool {
853
        k := v.kind()
854
        switch k {
855
        case Chan, Func, Map, Ptr:
856
                if v.flag&flagMethod != 0 {
857
                        panic("reflect: IsNil of method Value")
858
                }
859
                ptr := v.val
860
                if v.flag&flagIndir != 0 {
861
                        ptr = *(*unsafe.Pointer)(ptr)
862
                }
863
                return ptr == nil
864
        case Interface, Slice:
865
                // Both interface and slice are nil if first word is 0.
866
                // Both are always bigger than a word; assume flagIndir.
867
                return *(*unsafe.Pointer)(v.val) == nil
868
        }
869
        panic(&ValueError{"reflect.Value.IsNil", k})
870
}
871
 
872
// IsValid returns true if v represents a value.
873
// It returns false if v is the zero Value.
874
// If IsValid returns false, all other methods except String panic.
875
// Most functions and methods never return an invalid value.
876
// If one does, its documentation states the conditions explicitly.
877
func (v Value) IsValid() bool {
878
        return v.flag != 0
879
}
880
 
881
// Kind returns v's Kind.
882
// If v is the zero Value (IsValid returns false), Kind returns Invalid.
883
func (v Value) Kind() Kind {
884
        return v.kind()
885
}
886
 
887
// Len returns v's length.
888
// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
889
func (v Value) Len() int {
890
        k := v.kind()
891
        switch k {
892
        case Array:
893
                tt := (*arrayType)(unsafe.Pointer(v.typ))
894
                return int(tt.len)
895
        case Chan:
896
                return int(chanlen(*(*iword)(v.iword())))
897
        case Map:
898
                return int(maplen(*(*iword)(v.iword())))
899
        case Slice:
900
                // Slice is bigger than a word; assume flagIndir.
901
                return (*SliceHeader)(v.val).Len
902
        case String:
903
                // String is bigger than a word; assume flagIndir.
904
                return (*StringHeader)(v.val).Len
905
        }
906
        panic(&ValueError{"reflect.Value.Len", k})
907
}
908
 
909
// MapIndex returns the value associated with key in the map v.
910
// It panics if v's Kind is not Map.
911
// It returns the zero Value if key is not found in the map or if v represents a nil map.
912
// As in Go, the key's value must be assignable to the map's key type.
913
func (v Value) MapIndex(key Value) Value {
914
        v.mustBe(Map)
915
        tt := (*mapType)(unsafe.Pointer(v.typ))
916
 
917
        // Do not require key to be exported, so that DeepEqual
918
        // and other programs can use all the keys returned by
919
        // MapKeys as arguments to MapIndex.  If either the map
920
        // or the key is unexported, though, the result will be
921
        // considered unexported.  This is consistent with the
922
        // behavior for structs, which allow read but not write
923
        // of unexported fields.
924
        key = key.assignTo("reflect.Value.MapIndex", toCommonType(tt.key), nil)
925
 
926
        word, ok := mapaccess(v.typ.runtimeType(), *(*iword)(v.iword()), key.iword())
927
        if !ok {
928
                return Value{}
929
        }
930
        typ := toCommonType(tt.elem)
931
        fl := (v.flag | key.flag) & flagRO
932
        if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
933
                fl |= flagIndir
934
        }
935
        fl |= flag(typ.Kind()) << flagKindShift
936
        return Value{typ, unsafe.Pointer(word), fl}
937
}
938
 
939
// MapKeys returns a slice containing all the keys present in the map,
940
// in unspecified order.
941
// It panics if v's Kind is not Map.
942
// It returns an empty slice if v represents a nil map.
943
func (v Value) MapKeys() []Value {
944
        v.mustBe(Map)
945
        tt := (*mapType)(unsafe.Pointer(v.typ))
946
        keyType := toCommonType(tt.key)
947
 
948
        fl := v.flag & flagRO
949
        fl |= flag(keyType.Kind()) << flagKindShift
950
        if keyType.Kind() != Ptr && keyType.Kind() != UnsafePointer {
951
                fl |= flagIndir
952
        }
953
 
954
        m := *(*iword)(v.iword())
955
        mlen := int32(0)
956
        if m != nil {
957
                mlen = maplen(m)
958
        }
959
        it := mapiterinit(v.typ.runtimeType(), m)
960
        a := make([]Value, mlen)
961
        var i int
962
        for i = 0; i < len(a); i++ {
963
                keyWord, ok := mapiterkey(it)
964
                if !ok {
965
                        break
966
                }
967
                a[i] = Value{keyType, unsafe.Pointer(keyWord), fl}
968
                mapiternext(it)
969
        }
970
        return a[:i]
971
}
972
 
973
// Method returns a function value corresponding to v's i'th method.
974
// The arguments to a Call on the returned function should not include
975
// a receiver; the returned function will always use v as the receiver.
976
// Method panics if i is out of range.
977
func (v Value) Method(i int) Value {
978
        if v.typ == nil {
979
                panic(&ValueError{"reflect.Value.Method", Invalid})
980
        }
981
        if v.flag&flagMethod != 0 || i < 0 || i >= v.typ.NumMethod() {
982
                panic("reflect: Method index out of range")
983
        }
984
        fl := v.flag & (flagRO | flagAddr | flagIndir)
985
        fl |= flag(Func) << flagKindShift
986
        fl |= flag(i)<
987
        return Value{v.typ, v.val, fl}
988
}
989
 
990
// NumMethod returns the number of methods in the value's method set.
991
func (v Value) NumMethod() int {
992
        if v.typ == nil {
993
                panic(&ValueError{"reflect.Value.NumMethod", Invalid})
994
        }
995
        if v.flag&flagMethod != 0 {
996
                return 0
997
        }
998
        return v.typ.NumMethod()
999
}
1000
 
1001
// MethodByName returns a function value corresponding to the method
1002
// of v with the given name.
1003
// The arguments to a Call on the returned function should not include
1004
// a receiver; the returned function will always use v as the receiver.
1005
// It returns the zero Value if no method was found.
1006
func (v Value) MethodByName(name string) Value {
1007
        if v.typ == nil {
1008
                panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1009
        }
1010
        if v.flag&flagMethod != 0 {
1011
                return Value{}
1012
        }
1013
        m, ok := v.typ.MethodByName(name)
1014
        if !ok {
1015
                return Value{}
1016
        }
1017
        return v.Method(m.Index)
1018
}
1019
 
1020
// NumField returns the number of fields in the struct v.
1021
// It panics if v's Kind is not Struct.
1022
func (v Value) NumField() int {
1023
        v.mustBe(Struct)
1024
        tt := (*structType)(unsafe.Pointer(v.typ))
1025
        return len(tt.fields)
1026
}
1027
 
1028
// OverflowComplex returns true if the complex128 x cannot be represented by v's type.
1029
// It panics if v's Kind is not Complex64 or Complex128.
1030
func (v Value) OverflowComplex(x complex128) bool {
1031
        k := v.kind()
1032
        switch k {
1033
        case Complex64:
1034
                return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1035
        case Complex128:
1036
                return false
1037
        }
1038
        panic(&ValueError{"reflect.Value.OverflowComplex", k})
1039
}
1040
 
1041
// OverflowFloat returns true if the float64 x cannot be represented by v's type.
1042
// It panics if v's Kind is not Float32 or Float64.
1043
func (v Value) OverflowFloat(x float64) bool {
1044
        k := v.kind()
1045
        switch k {
1046
        case Float32:
1047
                return overflowFloat32(x)
1048
        case Float64:
1049
                return false
1050
        }
1051
        panic(&ValueError{"reflect.Value.OverflowFloat", k})
1052
}
1053
 
1054
func overflowFloat32(x float64) bool {
1055
        if x < 0 {
1056
                x = -x
1057
        }
1058
        return math.MaxFloat32 <= x && x <= math.MaxFloat64
1059
}
1060
 
1061
// OverflowInt returns true if the int64 x cannot be represented by v's type.
1062
// It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
1063
func (v Value) OverflowInt(x int64) bool {
1064
        k := v.kind()
1065
        switch k {
1066
        case Int, Int8, Int16, Int32, Int64:
1067
                bitSize := v.typ.size * 8
1068
                trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1069
                return x != trunc
1070
        }
1071
        panic(&ValueError{"reflect.Value.OverflowInt", k})
1072
}
1073
 
1074
// OverflowUint returns true if the uint64 x cannot be represented by v's type.
1075
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
1076
func (v Value) OverflowUint(x uint64) bool {
1077
        k := v.kind()
1078
        switch k {
1079
        case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
1080
                bitSize := v.typ.size * 8
1081
                trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1082
                return x != trunc
1083
        }
1084
        panic(&ValueError{"reflect.Value.OverflowUint", k})
1085
}
1086
 
1087
// Pointer returns v's value as a uintptr.
1088
// It returns uintptr instead of unsafe.Pointer so that
1089
// code using reflect cannot obtain unsafe.Pointers
1090
// without importing the unsafe package explicitly.
1091
// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
1092
func (v Value) Pointer() uintptr {
1093
        k := v.kind()
1094
        switch k {
1095
        case Chan, Func, Map, Ptr, UnsafePointer:
1096
                if k == Func && v.flag&flagMethod != 0 {
1097
                        panic("reflect.Value.Pointer of method Value")
1098
                }
1099
                p := v.val
1100
                if v.flag&flagIndir != 0 {
1101
                        p = *(*unsafe.Pointer)(p)
1102
                }
1103
                return uintptr(p)
1104
        case Slice:
1105
                return (*SliceHeader)(v.val).Data
1106
        }
1107
        panic(&ValueError{"reflect.Value.Pointer", k})
1108
}
1109
 
1110
// Recv receives and returns a value from the channel v.
1111
// It panics if v's Kind is not Chan.
1112
// The receive blocks until a value is ready.
1113
// The boolean value ok is true if the value x corresponds to a send
1114
// on the channel, false if it is a zero value received because the channel is closed.
1115
func (v Value) Recv() (x Value, ok bool) {
1116
        v.mustBe(Chan)
1117
        v.mustBeExported()
1118
        return v.recv(false)
1119
}
1120
 
1121
// internal recv, possibly non-blocking (nb).
1122
// v is known to be a channel.
1123
func (v Value) recv(nb bool) (val Value, ok bool) {
1124
        tt := (*chanType)(unsafe.Pointer(v.typ))
1125
        if ChanDir(tt.dir)&RecvDir == 0 {
1126
                panic("recv on send-only channel")
1127
        }
1128
        word, selected, ok := chanrecv(v.typ.runtimeType(), *(*iword)(v.iword()), nb)
1129
        if selected {
1130
                typ := toCommonType(tt.elem)
1131
                fl := flag(typ.Kind()) << flagKindShift
1132
                if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
1133
                        fl |= flagIndir
1134
                }
1135
                val = Value{typ, unsafe.Pointer(word), fl}
1136
        }
1137
        return
1138
}
1139
 
1140
// Send sends x on the channel v.
1141
// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
1142
// As in Go, x's value must be assignable to the channel's element type.
1143
func (v Value) Send(x Value) {
1144
        v.mustBe(Chan)
1145
        v.mustBeExported()
1146
        v.send(x, false)
1147
}
1148
 
1149
// internal send, possibly non-blocking.
1150
// v is known to be a channel.
1151
func (v Value) send(x Value, nb bool) (selected bool) {
1152
        tt := (*chanType)(unsafe.Pointer(v.typ))
1153
        if ChanDir(tt.dir)&SendDir == 0 {
1154
                panic("send on recv-only channel")
1155
        }
1156
        x.mustBeExported()
1157
        x = x.assignTo("reflect.Value.Send", toCommonType(tt.elem), nil)
1158
        return chansend(v.typ.runtimeType(), *(*iword)(v.iword()), x.iword(), nb)
1159
}
1160
 
1161
// Set assigns x to the value v.
1162
// It panics if CanSet returns false.
1163
// As in Go, x's value must be assignable to v's type.
1164
func (v Value) Set(x Value) {
1165
        v.mustBeAssignable()
1166
        x.mustBeExported() // do not let unexported x leak
1167
        var target *interface{}
1168
        if v.kind() == Interface {
1169
                target = (*interface{})(v.val)
1170
        }
1171
        x = x.assignTo("reflect.Set", v.typ, target)
1172
        if x.flag&flagIndir != 0 {
1173
                memmove(v.val, x.val, v.typ.size)
1174
        } else {
1175
                storeIword(v.val, iword(x.val), v.typ.size)
1176
        }
1177
}
1178
 
1179
// SetBool sets v's underlying value.
1180
// It panics if v's Kind is not Bool or if CanSet() is false.
1181
func (v Value) SetBool(x bool) {
1182
        v.mustBeAssignable()
1183
        v.mustBe(Bool)
1184
        *(*bool)(v.val) = x
1185
}
1186
 
1187
// SetBytes sets v's underlying value.
1188
// It panics if v's underlying value is not a slice of bytes.
1189
func (v Value) SetBytes(x []byte) {
1190
        v.mustBeAssignable()
1191
        v.mustBe(Slice)
1192
        if v.typ.Elem().Kind() != Uint8 {
1193
                panic("reflect.Value.SetBytes of non-byte slice")
1194
        }
1195
        *(*[]byte)(v.val) = x
1196
}
1197
 
1198
// SetComplex sets v's underlying value to x.
1199
// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
1200
func (v Value) SetComplex(x complex128) {
1201
        v.mustBeAssignable()
1202
        switch k := v.kind(); k {
1203
        default:
1204
                panic(&ValueError{"reflect.Value.SetComplex", k})
1205
        case Complex64:
1206
                *(*complex64)(v.val) = complex64(x)
1207
        case Complex128:
1208
                *(*complex128)(v.val) = x
1209
        }
1210
}
1211
 
1212
// SetFloat sets v's underlying value to x.
1213
// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
1214
func (v Value) SetFloat(x float64) {
1215
        v.mustBeAssignable()
1216
        switch k := v.kind(); k {
1217
        default:
1218
                panic(&ValueError{"reflect.Value.SetFloat", k})
1219
        case Float32:
1220
                *(*float32)(v.val) = float32(x)
1221
        case Float64:
1222
                *(*float64)(v.val) = x
1223
        }
1224
}
1225
 
1226
// SetInt sets v's underlying value to x.
1227
// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
1228
func (v Value) SetInt(x int64) {
1229
        v.mustBeAssignable()
1230
        switch k := v.kind(); k {
1231
        default:
1232
                panic(&ValueError{"reflect.Value.SetInt", k})
1233
        case Int:
1234
                *(*int)(v.val) = int(x)
1235
        case Int8:
1236
                *(*int8)(v.val) = int8(x)
1237
        case Int16:
1238
                *(*int16)(v.val) = int16(x)
1239
        case Int32:
1240
                *(*int32)(v.val) = int32(x)
1241
        case Int64:
1242
                *(*int64)(v.val) = x
1243
        }
1244
}
1245
 
1246
// SetLen sets v's length to n.
1247
// It panics if v's Kind is not Slice.
1248
func (v Value) SetLen(n int) {
1249
        v.mustBeAssignable()
1250
        v.mustBe(Slice)
1251
        s := (*SliceHeader)(v.val)
1252
        if n < 0 || n > int(s.Cap) {
1253
                panic("reflect: slice length out of range in SetLen")
1254
        }
1255
        s.Len = n
1256
}
1257
 
1258
// SetMapIndex sets the value associated with key in the map v to val.
1259
// It panics if v's Kind is not Map.
1260
// If val is the zero Value, SetMapIndex deletes the key from the map.
1261
// As in Go, key's value must be assignable to the map's key type,
1262
// and val's value must be assignable to the map's value type.
1263
func (v Value) SetMapIndex(key, val Value) {
1264
        v.mustBe(Map)
1265
        v.mustBeExported()
1266
        key.mustBeExported()
1267
        tt := (*mapType)(unsafe.Pointer(v.typ))
1268
        key = key.assignTo("reflect.Value.SetMapIndex", toCommonType(tt.key), nil)
1269
        if val.typ != nil {
1270
                val.mustBeExported()
1271
                val = val.assignTo("reflect.Value.SetMapIndex", toCommonType(tt.elem), nil)
1272
        }
1273
        mapassign(v.typ.runtimeType(), *(*iword)(v.iword()), key.iword(), val.iword(), val.typ != nil)
1274
}
1275
 
1276
// SetUint sets v's underlying value to x.
1277
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
1278
func (v Value) SetUint(x uint64) {
1279
        v.mustBeAssignable()
1280
        switch k := v.kind(); k {
1281
        default:
1282
                panic(&ValueError{"reflect.Value.SetUint", k})
1283
        case Uint:
1284
                *(*uint)(v.val) = uint(x)
1285
        case Uint8:
1286
                *(*uint8)(v.val) = uint8(x)
1287
        case Uint16:
1288
                *(*uint16)(v.val) = uint16(x)
1289
        case Uint32:
1290
                *(*uint32)(v.val) = uint32(x)
1291
        case Uint64:
1292
                *(*uint64)(v.val) = x
1293
        case Uintptr:
1294
                *(*uintptr)(v.val) = uintptr(x)
1295
        }
1296
}
1297
 
1298
// SetPointer sets the unsafe.Pointer value v to x.
1299
// It panics if v's Kind is not UnsafePointer.
1300
func (v Value) SetPointer(x unsafe.Pointer) {
1301
        v.mustBeAssignable()
1302
        v.mustBe(UnsafePointer)
1303
        *(*unsafe.Pointer)(v.val) = x
1304
}
1305
 
1306
// SetString sets v's underlying value to x.
1307
// It panics if v's Kind is not String or if CanSet() is false.
1308
func (v Value) SetString(x string) {
1309
        v.mustBeAssignable()
1310
        v.mustBe(String)
1311
        *(*string)(v.val) = x
1312
}
1313
 
1314
// Slice returns a slice of v.
1315
// It panics if v's Kind is not Array or Slice.
1316
func (v Value) Slice(beg, end int) Value {
1317
        var (
1318
                cap  int
1319
                typ  *sliceType
1320
                base unsafe.Pointer
1321
        )
1322
        switch k := v.kind(); k {
1323
        default:
1324
                panic(&ValueError{"reflect.Value.Slice", k})
1325
        case Array:
1326
                if v.flag&flagAddr == 0 {
1327
                        panic("reflect.Value.Slice: slice of unaddressable array")
1328
                }
1329
                tt := (*arrayType)(unsafe.Pointer(v.typ))
1330
                cap = int(tt.len)
1331
                typ = (*sliceType)(unsafe.Pointer(toCommonType(tt.slice)))
1332
                base = v.val
1333
        case Slice:
1334
                typ = (*sliceType)(unsafe.Pointer(v.typ))
1335
                s := (*SliceHeader)(v.val)
1336
                base = unsafe.Pointer(s.Data)
1337
                cap = s.Cap
1338
 
1339
        }
1340
        if beg < 0 || end < beg || end > cap {
1341
                panic("reflect.Value.Slice: slice index out of bounds")
1342
        }
1343
 
1344
        // Declare slice so that gc can see the base pointer in it.
1345
        var x []byte
1346
 
1347
        // Reinterpret as *SliceHeader to edit.
1348
        s := (*SliceHeader)(unsafe.Pointer(&x))
1349
        s.Data = uintptr(base) + uintptr(beg)*toCommonType(typ.elem).Size()
1350
        s.Len = end - beg
1351
        s.Cap = cap - beg
1352
 
1353
        fl := v.flag&flagRO | flagIndir | flag(Slice)<
1354
        return Value{typ.common(), unsafe.Pointer(&x), fl}
1355
}
1356
 
1357
// String returns the string v's underlying value, as a string.
1358
// String is a special case because of Go's String method convention.
1359
// Unlike the other getters, it does not panic if v's Kind is not String.
1360
// Instead, it returns a string of the form "" where T is v's type.
1361
func (v Value) String() string {
1362
        switch k := v.kind(); k {
1363
        case Invalid:
1364
                return ""
1365
        case String:
1366
                return *(*string)(v.val)
1367
        }
1368
        // If you call String on a reflect.Value of other type, it's better to
1369
        // print something than to panic. Useful in debugging.
1370
        return "<" + v.typ.String() + " Value>"
1371
}
1372
 
1373
// TryRecv attempts to receive a value from the channel v but will not block.
1374
// It panics if v's Kind is not Chan.
1375
// If the receive cannot finish without blocking, x is the zero Value.
1376
// The boolean ok is true if the value x corresponds to a send
1377
// on the channel, false if it is a zero value received because the channel is closed.
1378
func (v Value) TryRecv() (x Value, ok bool) {
1379
        v.mustBe(Chan)
1380
        v.mustBeExported()
1381
        return v.recv(true)
1382
}
1383
 
1384
// TrySend attempts to send x on the channel v but will not block.
1385
// It panics if v's Kind is not Chan.
1386
// It returns true if the value was sent, false otherwise.
1387
// As in Go, x's value must be assignable to the channel's element type.
1388
func (v Value) TrySend(x Value) bool {
1389
        v.mustBe(Chan)
1390
        v.mustBeExported()
1391
        return v.send(x, true)
1392
}
1393
 
1394
// Type returns v's type.
1395
func (v Value) Type() Type {
1396
        f := v.flag
1397
        if f == 0 {
1398
                panic(&ValueError{"reflect.Value.Type", Invalid})
1399
        }
1400
        if f&flagMethod == 0 {
1401
                // Easy case
1402
                return v.typ.toType()
1403
        }
1404
 
1405
        // Method value.
1406
        // v.typ describes the receiver, not the method type.
1407
        i := int(v.flag) >> flagMethodShift
1408
        if v.typ.Kind() == Interface {
1409
                // Method on interface.
1410
                tt := (*interfaceType)(unsafe.Pointer(v.typ))
1411
                if i < 0 || i >= len(tt.methods) {
1412
                        panic("reflect: broken Value")
1413
                }
1414
                m := &tt.methods[i]
1415
                return toCommonType(m.typ).toType()
1416
        }
1417
        // Method on concrete type.
1418
        ut := v.typ.uncommon()
1419
        if ut == nil || i < 0 || i >= len(ut.methods) {
1420
                panic("reflect: broken Value")
1421
        }
1422
        m := &ut.methods[i]
1423
        return toCommonType(m.mtyp).toType()
1424
}
1425
 
1426
// Uint returns v's underlying value, as a uint64.
1427
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
1428
func (v Value) Uint() uint64 {
1429
        k := v.kind()
1430
        var p unsafe.Pointer
1431
        if v.flag&flagIndir != 0 {
1432
                p = v.val
1433
        } else {
1434
                // The escape analysis is good enough that &v.val
1435
                // does not trigger a heap allocation.
1436
                p = unsafe.Pointer(&v.val)
1437
        }
1438
        switch k {
1439
        case Uint:
1440
                return uint64(*(*uint)(p))
1441
        case Uint8:
1442
                return uint64(*(*uint8)(p))
1443
        case Uint16:
1444
                return uint64(*(*uint16)(p))
1445
        case Uint32:
1446
                return uint64(*(*uint32)(p))
1447
        case Uint64:
1448
                return uint64(*(*uint64)(p))
1449
        case Uintptr:
1450
                return uint64(*(*uintptr)(p))
1451
        }
1452
        panic(&ValueError{"reflect.Value.Uint", k})
1453
}
1454
 
1455
// UnsafeAddr returns a pointer to v's data.
1456
// It is for advanced clients that also import the "unsafe" package.
1457
// It panics if v is not addressable.
1458
func (v Value) UnsafeAddr() uintptr {
1459
        if v.typ == nil {
1460
                panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
1461
        }
1462
        if v.flag&flagAddr == 0 {
1463
                panic("reflect.Value.UnsafeAddr of unaddressable value")
1464
        }
1465
        return uintptr(v.val)
1466
}
1467
 
1468
// StringHeader is the runtime representation of a string.
1469
// It cannot be used safely or portably.
1470
type StringHeader struct {
1471
        Data uintptr
1472
        Len  int
1473
}
1474
 
1475
// SliceHeader is the runtime representation of a slice.
1476
// It cannot be used safely or portably.
1477
type SliceHeader struct {
1478
        Data uintptr
1479
        Len  int
1480
        Cap  int
1481
}
1482
 
1483
func typesMustMatch(what string, t1, t2 Type) {
1484
        if t1 != t2 {
1485
                panic(what + ": " + t1.String() + " != " + t2.String())
1486
        }
1487
}
1488
 
1489
// grow grows the slice s so that it can hold extra more values, allocating
1490
// more capacity if needed. It also returns the old and new slice lengths.
1491
func grow(s Value, extra int) (Value, int, int) {
1492
        i0 := s.Len()
1493
        i1 := i0 + extra
1494
        if i1 < i0 {
1495
                panic("reflect.Append: slice overflow")
1496
        }
1497
        m := s.Cap()
1498
        if i1 <= m {
1499
                return s.Slice(0, i1), i0, i1
1500
        }
1501
        if m == 0 {
1502
                m = extra
1503
        } else {
1504
                for m < i1 {
1505
                        if i0 < 1024 {
1506
                                m += m
1507
                        } else {
1508
                                m += m / 4
1509
                        }
1510
                }
1511
        }
1512
        t := MakeSlice(s.Type(), i1, m)
1513
        Copy(t, s)
1514
        return t, i0, i1
1515
}
1516
 
1517
// Append appends the values x to a slice s and returns the resulting slice.
1518
// As in Go, each x's value must be assignable to the slice's element type.
1519
func Append(s Value, x ...Value) Value {
1520
        s.mustBe(Slice)
1521
        s, i0, i1 := grow(s, len(x))
1522
        for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
1523
                s.Index(i).Set(x[j])
1524
        }
1525
        return s
1526
}
1527
 
1528
// AppendSlice appends a slice t to a slice s and returns the resulting slice.
1529
// The slices s and t must have the same element type.
1530
func AppendSlice(s, t Value) Value {
1531
        s.mustBe(Slice)
1532
        t.mustBe(Slice)
1533
        typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
1534
        s, i0, i1 := grow(s, t.Len())
1535
        Copy(s.Slice(i0, i1), t)
1536
        return s
1537
}
1538
 
1539
// Copy copies the contents of src into dst until either
1540
// dst has been filled or src has been exhausted.
1541
// It returns the number of elements copied.
1542
// Dst and src each must have kind Slice or Array, and
1543
// dst and src must have the same element type.
1544
func Copy(dst, src Value) int {
1545
        dk := dst.kind()
1546
        if dk != Array && dk != Slice {
1547
                panic(&ValueError{"reflect.Copy", dk})
1548
        }
1549
        if dk == Array {
1550
                dst.mustBeAssignable()
1551
        }
1552
        dst.mustBeExported()
1553
 
1554
        sk := src.kind()
1555
        if sk != Array && sk != Slice {
1556
                panic(&ValueError{"reflect.Copy", sk})
1557
        }
1558
        src.mustBeExported()
1559
 
1560
        de := dst.typ.Elem()
1561
        se := src.typ.Elem()
1562
        typesMustMatch("reflect.Copy", de, se)
1563
 
1564
        n := dst.Len()
1565
        if sn := src.Len(); n > sn {
1566
                n = sn
1567
        }
1568
 
1569
        // If sk is an in-line array, cannot take its address.
1570
        // Instead, copy element by element.
1571
        if src.flag&flagIndir == 0 {
1572
                for i := 0; i < n; i++ {
1573
                        dst.Index(i).Set(src.Index(i))
1574
                }
1575
                return n
1576
        }
1577
 
1578
        // Copy via memmove.
1579
        var da, sa unsafe.Pointer
1580
        if dk == Array {
1581
                da = dst.val
1582
        } else {
1583
                da = unsafe.Pointer((*SliceHeader)(dst.val).Data)
1584
        }
1585
        if sk == Array {
1586
                sa = src.val
1587
        } else {
1588
                sa = unsafe.Pointer((*SliceHeader)(src.val).Data)
1589
        }
1590
        memmove(da, sa, uintptr(n)*de.Size())
1591
        return n
1592
}
1593
 
1594
/*
1595
 * constructors
1596
 */
1597
 
1598
// MakeSlice creates a new zero-initialized slice value
1599
// for the specified slice type, length, and capacity.
1600
func MakeSlice(typ Type, len, cap int) Value {
1601
        if typ.Kind() != Slice {
1602
                panic("reflect.MakeSlice of non-slice type")
1603
        }
1604
 
1605
        // Declare slice so that gc can see the base pointer in it.
1606
        var x []byte
1607
 
1608
        // Reinterpret as *SliceHeader to edit.
1609
        s := (*SliceHeader)(unsafe.Pointer(&x))
1610
        s.Data = uintptr(unsafe.NewArray(typ.Elem(), cap))
1611
        s.Len = len
1612
        s.Cap = cap
1613
 
1614
        return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<
1615
}
1616
 
1617
// MakeChan creates a new channel with the specified type and buffer size.
1618
func MakeChan(typ Type, buffer int) Value {
1619
        if typ.Kind() != Chan {
1620
                panic("reflect.MakeChan of non-chan type")
1621
        }
1622
        if buffer < 0 {
1623
                panic("reflect.MakeChan: negative buffer size")
1624
        }
1625
        if typ.ChanDir() != BothDir {
1626
                panic("reflect.MakeChan: unidirectional channel type")
1627
        }
1628
        ch := makechan(typ.runtimeType(), uint32(buffer))
1629
        return Value{typ.common(), unsafe.Pointer(ch), flagIndir | (flag(Chan) << flagKindShift)}
1630
}
1631
 
1632
// MakeMap creates a new map of the specified type.
1633
func MakeMap(typ Type) Value {
1634
        if typ.Kind() != Map {
1635
                panic("reflect.MakeMap of non-map type")
1636
        }
1637
        m := makemap(typ.runtimeType())
1638
        return Value{typ.common(), unsafe.Pointer(m), flagIndir | (flag(Map) << flagKindShift)}
1639
}
1640
 
1641
// Indirect returns the value that v points to.
1642
// If v is a nil pointer, Indirect returns a nil Value.
1643
// If v is not a pointer, Indirect returns v.
1644
func Indirect(v Value) Value {
1645
        if v.Kind() != Ptr {
1646
                return v
1647
        }
1648
        return v.Elem()
1649
}
1650
 
1651
// ValueOf returns a new Value initialized to the concrete value
1652
// stored in the interface i.  ValueOf(nil) returns the zero Value.
1653
func ValueOf(i interface{}) Value {
1654
        if i == nil {
1655
                return Value{}
1656
        }
1657
 
1658
        // TODO(rsc): Eliminate this terrible hack.
1659
        // In the call to packValue, eface.typ doesn't escape,
1660
        // and eface.word is an integer.  So it looks like
1661
        // i (= eface) doesn't escape.  But really it does,
1662
        // because eface.word is actually a pointer.
1663
        escapes(i)
1664
 
1665
        // For an interface value with the noAddr bit set,
1666
        // the representation is identical to an empty interface.
1667
        eface := *(*emptyInterface)(unsafe.Pointer(&i))
1668
        typ := toCommonType(eface.typ)
1669
        fl := flag(typ.Kind()) << flagKindShift
1670
        if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
1671
                fl |= flagIndir
1672
        }
1673
        return Value{typ, unsafe.Pointer(eface.word), fl}
1674
}
1675
 
1676
// Zero returns a Value representing a zero value for the specified type.
1677
// The result is different from the zero value of the Value struct,
1678
// which represents no value at all.
1679
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
1680
func Zero(typ Type) Value {
1681
        if typ == nil {
1682
                panic("reflect: Zero(nil)")
1683
        }
1684
        t := typ.common()
1685
        fl := flag(t.Kind()) << flagKindShift
1686
        if t.Kind() == Ptr || t.Kind() == UnsafePointer {
1687
                return Value{t, nil, fl}
1688
        }
1689
        return Value{t, unsafe.New(typ), fl | flagIndir}
1690
}
1691
 
1692
// New returns a Value representing a pointer to a new zero value
1693
// for the specified type.  That is, the returned Value's Type is PtrTo(t).
1694
func New(typ Type) Value {
1695
        if typ == nil {
1696
                panic("reflect: New(nil)")
1697
        }
1698
        ptr := unsafe.New(typ)
1699
        fl := flag(Ptr) << flagKindShift
1700
        return Value{typ.common().ptrTo(), ptr, fl}
1701
}
1702
 
1703
// assignTo returns a value v that can be assigned directly to typ.
1704
// It panics if v is not assignable to typ.
1705
// For a conversion to an interface type, target is a suggested scratch space to use.
1706
func (v Value) assignTo(context string, dst *commonType, target *interface{}) Value {
1707
        if v.flag&flagMethod != 0 {
1708
                panic(context + ": cannot assign method value to type " + dst.String())
1709
        }
1710
 
1711
        switch {
1712
        case directlyAssignable(dst, v.typ):
1713
                // Overwrite type so that they match.
1714
                // Same memory layout, so no harm done.
1715
                v.typ = dst
1716
                fl := v.flag & (flagRO | flagAddr | flagIndir)
1717
                fl |= flag(dst.Kind()) << flagKindShift
1718
                return Value{dst, v.val, fl}
1719
 
1720
        case implements(dst, v.typ):
1721
                if target == nil {
1722
                        target = new(interface{})
1723
                }
1724
                x := valueInterface(v, false)
1725
                if dst.NumMethod() == 0 {
1726
                        *target = x
1727
                } else {
1728
                        ifaceE2I(dst.runtimeType(), x, unsafe.Pointer(target))
1729
                }
1730
                return Value{dst, unsafe.Pointer(target), flagIndir | flag(Interface)<
1731
        }
1732
 
1733
        // Failed.
1734
        panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
1735
}
1736
 
1737
// implemented in ../pkg/runtime
1738
func chancap(ch iword) int32
1739
func chanclose(ch iword)
1740
func chanlen(ch iword) int32
1741
func chanrecv(t *runtime.Type, ch iword, nb bool) (val iword, selected, received bool)
1742
func chansend(t *runtime.Type, ch iword, val iword, nb bool) bool
1743
 
1744
func makechan(typ *runtime.Type, size uint32) (ch iword)
1745
func makemap(t *runtime.Type) (m iword)
1746
func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool)
1747
func mapassign(t *runtime.Type, m iword, key, val iword, ok bool)
1748
func mapiterinit(t *runtime.Type, m iword) *byte
1749
func mapiterkey(it *byte) (key iword, ok bool)
1750
func mapiternext(it *byte)
1751
func maplen(m iword) int32
1752
 
1753
func call(typ *commonType, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer)
1754
func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer)
1755
 
1756
// Dummy annotation marking that the value x escapes,
1757
// for use in cases where the reflect code is so clever that
1758
// the compiler cannot follow.
1759
func escapes(x interface{}) {
1760
        if dummy.b {
1761
                dummy.x = x
1762
        }
1763
}
1764
 
1765
var dummy struct {
1766
        b bool
1767
        x interface{}
1768
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.