Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(992)

Delta Between Two Patch Sets: src/pkg/reflect/value.go

Issue 6572043: code review 6572043: reflect: add ArrayOf, ChanOf, MapOf, SliceOf (Closed)
Left Patch Set: Created 11 years, 6 months ago
Right Patch Set: diff -r 6e9d872ffc66 https://code.google.com/p/go/ Created 11 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/reflect/type.go ('k') | src/pkg/runtime/iface.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package reflect 5 package reflect
6 6
7 import ( 7 import (
8 "math" 8 "math"
9 "runtime" 9 "runtime"
10 "strconv" 10 "strconv"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 // Its IsValid method returns false, its Kind method returns Invalid, 53 // Its IsValid method returns false, its Kind method returns Invalid,
54 // its String method returns "<invalid Value>", and all other methods panic. 54 // its String method returns "<invalid Value>", and all other methods panic.
55 // Most functions and methods never return an invalid value. 55 // Most functions and methods never return an invalid value.
56 // If one does, its documentation states the conditions explicitly. 56 // If one does, its documentation states the conditions explicitly.
57 // 57 //
58 // A Value can be used concurrently by multiple goroutines provided that 58 // A Value can be used concurrently by multiple goroutines provided that
59 // the underlying Go value can be used concurrently for the equivalent 59 // the underlying Go value can be used concurrently for the equivalent
60 // direct operations. 60 // direct operations.
61 type Value struct { 61 type Value struct {
62 // typ holds the type of the value represented by a Value. 62 // typ holds the type of the value represented by a Value.
63 » typ *commonType 63 » typ *rtype
64 64
65 // val holds the 1-word representation of the value. 65 // val holds the 1-word representation of the value.
66 // If flag's flagIndir bit is set, then val is a pointer to the data. 66 // If flag's flagIndir bit is set, then val is a pointer to the data.
67 // Otherwise val is a word holding the actual data. 67 // Otherwise val is a word holding the actual data.
68 // When the data is smaller than a word, it begins at 68 // When the data is smaller than a word, it begins at
69 // the first byte (in the memory address sense) of val. 69 // the first byte (in the memory address sense) of val.
70 // We use unsafe.Pointer so that the garbage collector 70 // We use unsafe.Pointer so that the garbage collector
71 // knows that val could be a pointer. 71 // knows that val could be a pointer.
72 val unsafe.Pointer 72 val unsafe.Pointer
73 73
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 *(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w)) 204 *(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w))
205 case 7: 205 case 7:
206 *(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w)) 206 *(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w))
207 case 8: 207 case 8:
208 *(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w)) 208 *(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w))
209 } 209 }
210 } 210 }
211 211
212 // emptyInterface is the header for an interface{} value. 212 // emptyInterface is the header for an interface{} value.
213 type emptyInterface struct { 213 type emptyInterface struct {
214 » typ *runtimeType 214 » typ *rtype
215 word iword 215 word iword
216 } 216 }
217 217
218 // nonEmptyInterface is the header for a interface value with methods. 218 // nonEmptyInterface is the header for a interface value with methods.
219 type nonEmptyInterface struct { 219 type nonEmptyInterface struct {
220 // see ../runtime/iface.c:/Itab 220 // see ../runtime/iface.c:/Itab
221 itab *struct { 221 itab *struct {
222 » » ityp *runtimeType // static interface type 222 » » ityp *rtype // static interface type
223 » » typ *runtimeType // dynamic concrete type 223 » » typ *rtype // dynamic concrete type
224 link unsafe.Pointer 224 link unsafe.Pointer
225 bad int32 225 bad int32
226 unused int32 226 unused int32
227 fun [100000]unsafe.Pointer // method table 227 fun [100000]unsafe.Pointer // method table
228 } 228 }
229 word iword 229 word iword
230 } 230 }
231 231
232 // mustBe panics if f's kind is not expected. 232 // mustBe panics if f's kind is not expected.
233 // Making this a method on flag instead of on Value 233 // Making this a method on flag instead of on Value
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 i := int(v.flag) >> flagMethodShift 369 i := int(v.flag) >> flagMethodShift
370 if v.typ.Kind() == Interface { 370 if v.typ.Kind() == Interface {
371 tt := (*interfaceType)(unsafe.Pointer(v.typ)) 371 tt := (*interfaceType)(unsafe.Pointer(v.typ))
372 if i < 0 || i >= len(tt.methods) { 372 if i < 0 || i >= len(tt.methods) {
373 panic("reflect: broken Value") 373 panic("reflect: broken Value")
374 } 374 }
375 m := &tt.methods[i] 375 m := &tt.methods[i]
376 if m.pkgPath != nil { 376 if m.pkgPath != nil {
377 panic(method + " of unexported method") 377 panic(method + " of unexported method")
378 } 378 }
379 » » » t = toCommonType(m.typ) 379 » » » t = m.typ
380 iface := (*nonEmptyInterface)(v.val) 380 iface := (*nonEmptyInterface)(v.val)
381 if iface.itab == nil { 381 if iface.itab == nil {
382 panic(method + " of method on nil interface valu e") 382 panic(method + " of method on nil interface valu e")
383 } 383 }
384 fn = iface.itab.fun[i] 384 fn = iface.itab.fun[i]
385 rcvr = iface.word 385 rcvr = iface.word
386 } else { 386 } else {
387 ut := v.typ.uncommon() 387 ut := v.typ.uncommon()
388 if ut == nil || i < 0 || i >= len(ut.methods) { 388 if ut == nil || i < 0 || i >= len(ut.methods) {
389 panic("reflect: broken Value") 389 panic("reflect: broken Value")
390 } 390 }
391 m := &ut.methods[i] 391 m := &ut.methods[i]
392 if m.pkgPath != nil { 392 if m.pkgPath != nil {
393 panic(method + " of unexported method") 393 panic(method + " of unexported method")
394 } 394 }
395 fn = m.ifn 395 fn = m.ifn
396 » » » t = toCommonType(m.mtyp) 396 » » » t = m.mtyp
397 rcvr = v.iword() 397 rcvr = v.iword()
398 } 398 }
399 } else if v.flag&flagIndir != 0 { 399 } else if v.flag&flagIndir != 0 {
400 fn = *(*unsafe.Pointer)(v.val) 400 fn = *(*unsafe.Pointer)(v.val)
401 } else { 401 } else {
402 fn = v.val 402 fn = v.val
403 } 403 }
404 404
405 if fn == nil { 405 if fn == nil {
406 panic("reflect.Value.Call: call of nil function") 406 panic("reflect.Value.Call: call of nil function")
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 args := make([]unsafe.Pointer, size/ptrSize) 506 args := make([]unsafe.Pointer, size/ptrSize)
507 ptr := uintptr(unsafe.Pointer(&args[0])) 507 ptr := uintptr(unsafe.Pointer(&args[0]))
508 off := uintptr(0) 508 off := uintptr(0)
509 if v.flag&flagMethod != 0 { 509 if v.flag&flagMethod != 0 {
510 // Hard-wired first argument. 510 // Hard-wired first argument.
511 *(*iword)(unsafe.Pointer(ptr)) = rcvr 511 *(*iword)(unsafe.Pointer(ptr)) = rcvr
512 off = ptrSize 512 off = ptrSize
513 } 513 }
514 for i, v := range in { 514 for i, v := range in {
515 v.mustBeExported() 515 v.mustBeExported()
516 » » targ := t.In(i).(*commonType) 516 » » targ := t.In(i).(*rtype)
517 a := uintptr(targ.align) 517 a := uintptr(targ.align)
518 off = (off + a - 1) &^ (a - 1) 518 off = (off + a - 1) &^ (a - 1)
519 n := targ.size 519 n := targ.size
520 addr := unsafe.Pointer(ptr + off) 520 addr := unsafe.Pointer(ptr + off)
521 v = v.assignTo("reflect.Value.Call", targ, (*interface{})(addr)) 521 v = v.assignTo("reflect.Value.Call", targ, (*interface{})(addr))
522 if v.flag&flagIndir == 0 { 522 if v.flag&flagIndir == 0 {
523 storeIword(addr, iword(v.val), n) 523 storeIword(addr, iword(v.val), n)
524 } else { 524 } else {
525 memmove(addr, v.val, n) 525 memmove(addr, v.val, n)
526 } 526 }
(...skipping 27 matching lines...) Expand all
554 // callReflect converts a call of a function with a concrete argument 554 // callReflect converts a call of a function with a concrete argument
555 // frame into a call using Values. 555 // frame into a call using Values.
556 // It is in this file so that it can be next to the call method above. 556 // It is in this file so that it can be next to the call method above.
557 // The remainder of the MakeFunc implementation is in makefunc.go. 557 // The remainder of the MakeFunc implementation is in makefunc.go.
558 func callReflect(ftyp *funcType, f func([]Value) []Value, frame unsafe.Pointer) { 558 func callReflect(ftyp *funcType, f func([]Value) []Value, frame unsafe.Pointer) {
559 // Copy argument frame into Values. 559 // Copy argument frame into Values.
560 ptr := frame 560 ptr := frame
561 off := uintptr(0) 561 off := uintptr(0)
562 in := make([]Value, 0, len(ftyp.in)) 562 in := make([]Value, 0, len(ftyp.in))
563 for _, arg := range ftyp.in { 563 for _, arg := range ftyp.in {
564 » » typ := toCommonType(arg) 564 » » typ := arg
565 off += -off & uintptr(typ.align-1) 565 off += -off & uintptr(typ.align-1)
566 v := Value{typ, nil, flag(typ.Kind()) << flagKindShift} 566 v := Value{typ, nil, flag(typ.Kind()) << flagKindShift}
567 if typ.size <= ptrSize { 567 if typ.size <= ptrSize {
568 // value fits in word. 568 // value fits in word.
569 v.val = unsafe.Pointer(loadIword(unsafe.Pointer(uintptr( ptr)+off), typ.size)) 569 v.val = unsafe.Pointer(loadIword(unsafe.Pointer(uintptr( ptr)+off), typ.size))
570 } else { 570 } else {
571 // value does not fit in word. 571 // value does not fit in word.
572 // Must make a copy, because f might keep a reference to it, 572 // Must make a copy, because f might keep a reference to it,
573 // and we cannot let f keep a reference to the stack fra me 573 // and we cannot let f keep a reference to the stack fra me
574 // after this function returns, not even a read-only ref erence. 574 // after this function returns, not even a read-only ref erence.
575 v.val = unsafe_New(typ) 575 v.val = unsafe_New(typ)
576 memmove(v.val, unsafe.Pointer(uintptr(ptr)+off), typ.siz e) 576 memmove(v.val, unsafe.Pointer(uintptr(ptr)+off), typ.siz e)
577 v.flag |= flagIndir 577 v.flag |= flagIndir
578 } 578 }
579 in = append(in, v) 579 in = append(in, v)
580 off += typ.size 580 off += typ.size
581 } 581 }
582 582
583 // Call underlying function. 583 // Call underlying function.
584 out := f(in) 584 out := f(in)
585 if len(out) != len(ftyp.out) { 585 if len(out) != len(ftyp.out) {
586 panic("reflect: wrong return count from function created by Make Func") 586 panic("reflect: wrong return count from function created by Make Func")
587 } 587 }
588 588
589 // Copy results back into argument frame. 589 // Copy results back into argument frame.
590 if len(ftyp.out) > 0 { 590 if len(ftyp.out) > 0 {
591 off += -off & (ptrSize - 1) 591 off += -off & (ptrSize - 1)
592 for i, arg := range ftyp.out { 592 for i, arg := range ftyp.out {
593 » » » typ := toCommonType(arg) 593 » » » typ := arg
594 v := out[i] 594 v := out[i]
595 if v.typ != typ { 595 if v.typ != typ {
596 panic("reflect: function created by MakeFunc usi ng " + funcName(f) + 596 panic("reflect: function created by MakeFunc usi ng " + funcName(f) +
597 " returned wrong type: have " + 597 " returned wrong type: have " +
598 out[i].typ.String() + " for " + typ.Stri ng()) 598 out[i].typ.String() + " for " + typ.Stri ng())
599 } 599 }
600 if v.flag&flagRO != 0 { 600 if v.flag&flagRO != 0 {
601 panic("reflect: function created by MakeFunc usi ng " + funcName(f) + 601 panic("reflect: function created by MakeFunc usi ng " + funcName(f) +
602 " returned value obtained from unexporte d field") 602 " returned value obtained from unexporte d field")
603 } 603 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 666
667 // Elem returns the value that the interface v contains 667 // Elem returns the value that the interface v contains
668 // or that the pointer v points to. 668 // or that the pointer v points to.
669 // It panics if v's Kind is not Interface or Ptr. 669 // It panics if v's Kind is not Interface or Ptr.
670 // It returns the zero Value if v is nil. 670 // It returns the zero Value if v is nil.
671 func (v Value) Elem() Value { 671 func (v Value) Elem() Value {
672 k := v.kind() 672 k := v.kind()
673 switch k { 673 switch k {
674 case Interface: 674 case Interface:
675 var ( 675 var (
676 » » » typ *commonType 676 » » » typ *rtype
677 val unsafe.Pointer 677 val unsafe.Pointer
678 ) 678 )
679 if v.typ.NumMethod() == 0 { 679 if v.typ.NumMethod() == 0 {
680 eface := (*emptyInterface)(v.val) 680 eface := (*emptyInterface)(v.val)
681 if eface.typ == nil { 681 if eface.typ == nil {
682 // nil interface value 682 // nil interface value
683 return Value{} 683 return Value{}
684 } 684 }
685 » » » typ = toCommonType(eface.typ) 685 » » » typ = eface.typ
686 val = unsafe.Pointer(eface.word) 686 val = unsafe.Pointer(eface.word)
687 } else { 687 } else {
688 iface := (*nonEmptyInterface)(v.val) 688 iface := (*nonEmptyInterface)(v.val)
689 if iface.itab == nil { 689 if iface.itab == nil {
690 // nil interface value 690 // nil interface value
691 return Value{} 691 return Value{}
692 } 692 }
693 » » » typ = toCommonType(iface.itab.typ) 693 » » » typ = iface.itab.typ
694 val = unsafe.Pointer(iface.word) 694 val = unsafe.Pointer(iface.word)
695 } 695 }
696 fl := v.flag & flagRO 696 fl := v.flag & flagRO
697 fl |= flag(typ.Kind()) << flagKindShift 697 fl |= flag(typ.Kind()) << flagKindShift
698 if typ.size > ptrSize { 698 if typ.size > ptrSize {
699 fl |= flagIndir 699 fl |= flagIndir
700 } 700 }
701 return Value{typ, val, fl} 701 return Value{typ, val, fl}
702 702
703 case Ptr: 703 case Ptr:
704 val := v.val 704 val := v.val
705 if v.flag&flagIndir != 0 { 705 if v.flag&flagIndir != 0 {
706 val = *(*unsafe.Pointer)(val) 706 val = *(*unsafe.Pointer)(val)
707 } 707 }
708 // The returned value's address is v's value. 708 // The returned value's address is v's value.
709 if val == nil { 709 if val == nil {
710 return Value{} 710 return Value{}
711 } 711 }
712 tt := (*ptrType)(unsafe.Pointer(v.typ)) 712 tt := (*ptrType)(unsafe.Pointer(v.typ))
713 » » typ := toCommonType(tt.elem) 713 » » typ := tt.elem
714 fl := v.flag&flagRO | flagIndir | flagAddr 714 fl := v.flag&flagRO | flagIndir | flagAddr
715 fl |= flag(typ.Kind() << flagKindShift) 715 fl |= flag(typ.Kind() << flagKindShift)
716 return Value{typ, val, fl} 716 return Value{typ, val, fl}
717 } 717 }
718 panic(&ValueError{"reflect.Value.Elem", k}) 718 panic(&ValueError{"reflect.Value.Elem", k})
719 } 719 }
720 720
721 // Field returns the i'th field of the struct v. 721 // Field returns the i'th field of the struct v.
722 // It panics if v's Kind is not Struct or i is out of range. 722 // It panics if v's Kind is not Struct or i is out of range.
723 func (v Value) Field(i int) Value { 723 func (v Value) Field(i int) Value {
724 v.mustBe(Struct) 724 v.mustBe(Struct)
725 tt := (*structType)(unsafe.Pointer(v.typ)) 725 tt := (*structType)(unsafe.Pointer(v.typ))
726 if i < 0 || i >= len(tt.fields) { 726 if i < 0 || i >= len(tt.fields) {
727 panic("reflect: Field index out of range") 727 panic("reflect: Field index out of range")
728 } 728 }
729 field := &tt.fields[i] 729 field := &tt.fields[i]
730 » typ := toCommonType(field.typ) 730 » typ := field.typ
731 731
732 // Inherit permission bits from v. 732 // Inherit permission bits from v.
733 fl := v.flag & (flagRO | flagIndir | flagAddr) 733 fl := v.flag & (flagRO | flagIndir | flagAddr)
734 // Using an unexported field forces flagRO. 734 // Using an unexported field forces flagRO.
735 if field.pkgPath != nil { 735 if field.pkgPath != nil {
736 fl |= flagRO 736 fl |= flagRO
737 } 737 }
738 fl |= flag(typ.Kind()) << flagKindShift 738 fl |= flag(typ.Kind()) << flagKindShift
739 739
740 var val unsafe.Pointer 740 var val unsafe.Pointer
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 return float64(*(*float32)(unsafe.Pointer(&v.val))) 803 return float64(*(*float32)(unsafe.Pointer(&v.val)))
804 case Float64: 804 case Float64:
805 if v.flag&flagIndir != 0 { 805 if v.flag&flagIndir != 0 {
806 return *(*float64)(v.val) 806 return *(*float64)(v.val)
807 } 807 }
808 return *(*float64)(unsafe.Pointer(&v.val)) 808 return *(*float64)(unsafe.Pointer(&v.val))
809 } 809 }
810 panic(&ValueError{"reflect.Value.Float", k}) 810 panic(&ValueError{"reflect.Value.Float", k})
811 } 811 }
812 812
813 var uint8Type = TypeOf(uint8(0)).(*commonType) 813 var uint8Type = TypeOf(uint8(0)).(*rtype)
814 814
815 // Index returns v's i'th element. 815 // Index returns v's i'th element.
816 // It panics if v's Kind is not Array, Slice, or String or i is out of range. 816 // It panics if v's Kind is not Array, Slice, or String or i is out of range.
817 func (v Value) Index(i int) Value { 817 func (v Value) Index(i int) Value {
818 k := v.kind() 818 k := v.kind()
819 switch k { 819 switch k {
820 case Array: 820 case Array:
821 tt := (*arrayType)(unsafe.Pointer(v.typ)) 821 tt := (*arrayType)(unsafe.Pointer(v.typ))
822 if i < 0 || i > int(tt.len) { 822 if i < 0 || i > int(tt.len) {
823 panic("reflect: array index out of range") 823 panic("reflect: array index out of range")
824 } 824 }
825 » » typ := toCommonType(tt.elem) 825 » » typ := tt.elem
826 fl := v.flag & (flagRO | flagIndir | flagAddr) // bits same as o verall array 826 fl := v.flag & (flagRO | flagIndir | flagAddr) // bits same as o verall array
827 fl |= flag(typ.Kind()) << flagKindShift 827 fl |= flag(typ.Kind()) << flagKindShift
828 offset := uintptr(i) * typ.size 828 offset := uintptr(i) * typ.size
829 829
830 var val unsafe.Pointer 830 var val unsafe.Pointer
831 switch { 831 switch {
832 case fl&flagIndir != 0: 832 case fl&flagIndir != 0:
833 // Indirect. Just bump pointer. 833 // Indirect. Just bump pointer.
834 val = unsafe.Pointer(uintptr(v.val) + offset) 834 val = unsafe.Pointer(uintptr(v.val) + offset)
835 case bigEndian: 835 case bigEndian:
836 // Direct. Discard leading bytes. 836 // Direct. Discard leading bytes.
837 val = unsafe.Pointer(uintptr(v.val) << (offset * 8)) 837 val = unsafe.Pointer(uintptr(v.val) << (offset * 8))
838 default: 838 default:
839 // Direct. Discard leading bytes. 839 // Direct. Discard leading bytes.
840 val = unsafe.Pointer(uintptr(v.val) >> (offset * 8)) 840 val = unsafe.Pointer(uintptr(v.val) >> (offset * 8))
841 } 841 }
842 return Value{typ, val, fl} 842 return Value{typ, val, fl}
843 843
844 case Slice: 844 case Slice:
845 // Element flag same as Elem of Ptr. 845 // Element flag same as Elem of Ptr.
846 // Addressable, indirect, possibly read-only. 846 // Addressable, indirect, possibly read-only.
847 fl := flagAddr | flagIndir | v.flag&flagRO 847 fl := flagAddr | flagIndir | v.flag&flagRO
848 s := (*SliceHeader)(v.val) 848 s := (*SliceHeader)(v.val)
849 if i < 0 || i >= s.Len { 849 if i < 0 || i >= s.Len {
850 panic("reflect: slice index out of range") 850 panic("reflect: slice index out of range")
851 } 851 }
852 tt := (*sliceType)(unsafe.Pointer(v.typ)) 852 tt := (*sliceType)(unsafe.Pointer(v.typ))
853 » » typ := toCommonType(tt.elem) 853 » » typ := tt.elem
854 fl |= flag(typ.Kind()) << flagKindShift 854 fl |= flag(typ.Kind()) << flagKindShift
855 val := unsafe.Pointer(s.Data + uintptr(i)*typ.size) 855 val := unsafe.Pointer(s.Data + uintptr(i)*typ.size)
856 return Value{typ, val, fl} 856 return Value{typ, val, fl}
857 857
858 case String: 858 case String:
859 fl := v.flag&flagRO | flag(Uint8<<flagKindShift) 859 fl := v.flag&flagRO | flag(Uint8<<flagKindShift)
860 s := (*StringHeader)(v.val) 860 s := (*StringHeader)(v.val)
861 if i < 0 || i >= s.Len { 861 if i < 0 || i >= s.Len {
862 panic("reflect: string index out of range") 862 panic("reflect: string index out of range")
863 } 863 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 if v.NumMethod() == 0 { 937 if v.NumMethod() == 0 {
938 return *(*interface{})(v.val) 938 return *(*interface{})(v.val)
939 } 939 }
940 return *(*interface { 940 return *(*interface {
941 M() 941 M()
942 })(v.val) 942 })(v.val)
943 } 943 }
944 944
945 // Non-interface value. 945 // Non-interface value.
946 var eface emptyInterface 946 var eface emptyInterface
947 » eface.typ = v.typ.runtimeType() 947 » eface.typ = v.typ
948 eface.word = v.iword() 948 eface.word = v.iword()
949 949
950 if v.flag&flagIndir != 0 && v.typ.size > ptrSize { 950 if v.flag&flagIndir != 0 && v.typ.size > ptrSize {
951 // eface.word is a pointer to the actual data, 951 // eface.word is a pointer to the actual data,
952 // which might be changed. We need to return 952 // which might be changed. We need to return
953 // a pointer to unchanging data, so make a copy. 953 // a pointer to unchanging data, so make a copy.
954 ptr := unsafe_New(v.typ) 954 ptr := unsafe_New(v.typ)
955 memmove(ptr, unsafe.Pointer(eface.word), v.typ.size) 955 memmove(ptr, unsafe.Pointer(eface.word), v.typ.size)
956 eface.word = iword(ptr) 956 eface.word = iword(ptr)
957 } 957 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 v.mustBe(Map) 1038 v.mustBe(Map)
1039 tt := (*mapType)(unsafe.Pointer(v.typ)) 1039 tt := (*mapType)(unsafe.Pointer(v.typ))
1040 1040
1041 // Do not require key to be exported, so that DeepEqual 1041 // Do not require key to be exported, so that DeepEqual
1042 // and other programs can use all the keys returned by 1042 // and other programs can use all the keys returned by
1043 // MapKeys as arguments to MapIndex. If either the map 1043 // MapKeys as arguments to MapIndex. If either the map
1044 // or the key is unexported, though, the result will be 1044 // or the key is unexported, though, the result will be
1045 // considered unexported. This is consistent with the 1045 // considered unexported. This is consistent with the
1046 // behavior for structs, which allow read but not write 1046 // behavior for structs, which allow read but not write
1047 // of unexported fields. 1047 // of unexported fields.
1048 » key = key.assignTo("reflect.Value.MapIndex", toCommonType(tt.key), nil) 1048 » key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
1049 1049
1050 » word, ok := mapaccess(v.typ.runtimeType(), v.iword(), key.iword()) 1050 » word, ok := mapaccess(v.typ, v.iword(), key.iword())
1051 if !ok { 1051 if !ok {
1052 return Value{} 1052 return Value{}
1053 } 1053 }
1054 » typ := toCommonType(tt.elem) 1054 » typ := tt.elem
1055 fl := (v.flag | key.flag) & flagRO 1055 fl := (v.flag | key.flag) & flagRO
1056 if typ.size > ptrSize { 1056 if typ.size > ptrSize {
1057 fl |= flagIndir 1057 fl |= flagIndir
1058 } 1058 }
1059 fl |= flag(typ.Kind()) << flagKindShift 1059 fl |= flag(typ.Kind()) << flagKindShift
1060 return Value{typ, unsafe.Pointer(word), fl} 1060 return Value{typ, unsafe.Pointer(word), fl}
1061 } 1061 }
1062 1062
1063 // MapKeys returns a slice containing all the keys present in the map, 1063 // MapKeys returns a slice containing all the keys present in the map,
1064 // in unspecified order. 1064 // in unspecified order.
1065 // It panics if v's Kind is not Map. 1065 // It panics if v's Kind is not Map.
1066 // It returns an empty slice if v represents a nil map. 1066 // It returns an empty slice if v represents a nil map.
1067 func (v Value) MapKeys() []Value { 1067 func (v Value) MapKeys() []Value {
1068 v.mustBe(Map) 1068 v.mustBe(Map)
1069 tt := (*mapType)(unsafe.Pointer(v.typ)) 1069 tt := (*mapType)(unsafe.Pointer(v.typ))
1070 » keyType := toCommonType(tt.key) 1070 » keyType := tt.key
1071 1071
1072 fl := v.flag & flagRO 1072 fl := v.flag & flagRO
1073 fl |= flag(keyType.Kind()) << flagKindShift 1073 fl |= flag(keyType.Kind()) << flagKindShift
1074 if keyType.size > ptrSize { 1074 if keyType.size > ptrSize {
1075 fl |= flagIndir 1075 fl |= flagIndir
1076 } 1076 }
1077 1077
1078 m := v.iword() 1078 m := v.iword()
1079 mlen := int(0) 1079 mlen := int(0)
1080 if m != nil { 1080 if m != nil {
1081 mlen = maplen(m) 1081 mlen = maplen(m)
1082 } 1082 }
1083 » it := mapiterinit(v.typ.runtimeType(), m) 1083 » it := mapiterinit(v.typ, m)
1084 a := make([]Value, mlen) 1084 a := make([]Value, mlen)
1085 var i int 1085 var i int
1086 for i = 0; i < len(a); i++ { 1086 for i = 0; i < len(a); i++ {
1087 keyWord, ok := mapiterkey(it) 1087 keyWord, ok := mapiterkey(it)
1088 if !ok { 1088 if !ok {
1089 break 1089 break
1090 } 1090 }
1091 a[i] = Value{keyType, unsafe.Pointer(keyWord), fl} 1091 a[i] = Value{keyType, unsafe.Pointer(keyWord), fl}
1092 mapiternext(it) 1092 mapiternext(it)
1093 } 1093 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 return v.recv(false) 1242 return v.recv(false)
1243 } 1243 }
1244 1244
1245 // internal recv, possibly non-blocking (nb). 1245 // internal recv, possibly non-blocking (nb).
1246 // v is known to be a channel. 1246 // v is known to be a channel.
1247 func (v Value) recv(nb bool) (val Value, ok bool) { 1247 func (v Value) recv(nb bool) (val Value, ok bool) {
1248 tt := (*chanType)(unsafe.Pointer(v.typ)) 1248 tt := (*chanType)(unsafe.Pointer(v.typ))
1249 if ChanDir(tt.dir)&RecvDir == 0 { 1249 if ChanDir(tt.dir)&RecvDir == 0 {
1250 panic("recv on send-only channel") 1250 panic("recv on send-only channel")
1251 } 1251 }
1252 » word, selected, ok := chanrecv(v.typ.runtimeType(), v.iword(), nb) 1252 » word, selected, ok := chanrecv(v.typ, v.iword(), nb)
1253 if selected { 1253 if selected {
1254 » » typ := toCommonType(tt.elem) 1254 » » typ := tt.elem
1255 fl := flag(typ.Kind()) << flagKindShift 1255 fl := flag(typ.Kind()) << flagKindShift
1256 if typ.size > ptrSize { 1256 if typ.size > ptrSize {
1257 fl |= flagIndir 1257 fl |= flagIndir
1258 } 1258 }
1259 val = Value{typ, unsafe.Pointer(word), fl} 1259 val = Value{typ, unsafe.Pointer(word), fl}
1260 } 1260 }
1261 return 1261 return
1262 } 1262 }
1263 1263
1264 // Send sends x on the channel v. 1264 // Send sends x on the channel v.
1265 // It panics if v's kind is not Chan or if x's type is not the same type as v's element type. 1265 // It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
1266 // As in Go, x's value must be assignable to the channel's element type. 1266 // As in Go, x's value must be assignable to the channel's element type.
1267 func (v Value) Send(x Value) { 1267 func (v Value) Send(x Value) {
1268 v.mustBe(Chan) 1268 v.mustBe(Chan)
1269 v.mustBeExported() 1269 v.mustBeExported()
1270 v.send(x, false) 1270 v.send(x, false)
1271 } 1271 }
1272 1272
1273 // internal send, possibly non-blocking. 1273 // internal send, possibly non-blocking.
1274 // v is known to be a channel. 1274 // v is known to be a channel.
1275 func (v Value) send(x Value, nb bool) (selected bool) { 1275 func (v Value) send(x Value, nb bool) (selected bool) {
1276 tt := (*chanType)(unsafe.Pointer(v.typ)) 1276 tt := (*chanType)(unsafe.Pointer(v.typ))
1277 if ChanDir(tt.dir)&SendDir == 0 { 1277 if ChanDir(tt.dir)&SendDir == 0 {
1278 panic("send on recv-only channel") 1278 panic("send on recv-only channel")
1279 } 1279 }
1280 x.mustBeExported() 1280 x.mustBeExported()
1281 » x = x.assignTo("reflect.Value.Send", toCommonType(tt.elem), nil) 1281 » x = x.assignTo("reflect.Value.Send", tt.elem, nil)
1282 » return chansend(v.typ.runtimeType(), v.iword(), x.iword(), nb) 1282 » return chansend(v.typ, v.iword(), x.iword(), nb)
1283 } 1283 }
1284 1284
1285 // Set assigns x to the value v. 1285 // Set assigns x to the value v.
1286 // It panics if CanSet returns false. 1286 // It panics if CanSet returns false.
1287 // As in Go, x's value must be assignable to v's type. 1287 // As in Go, x's value must be assignable to v's type.
1288 func (v Value) Set(x Value) { 1288 func (v Value) Set(x Value) {
1289 v.mustBeAssignable() 1289 v.mustBeAssignable()
1290 x.mustBeExported() // do not let unexported x leak 1290 x.mustBeExported() // do not let unexported x leak
1291 var target *interface{} 1291 var target *interface{}
1292 if v.kind() == Interface { 1292 if v.kind() == Interface {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 // SetMapIndex sets the value associated with key in the map v to val. 1394 // SetMapIndex sets the value associated with key in the map v to val.
1395 // It panics if v's Kind is not Map. 1395 // It panics if v's Kind is not Map.
1396 // If val is the zero Value, SetMapIndex deletes the key from the map. 1396 // If val is the zero Value, SetMapIndex deletes the key from the map.
1397 // As in Go, key's value must be assignable to the map's key type, 1397 // As in Go, key's value must be assignable to the map's key type,
1398 // and val's value must be assignable to the map's value type. 1398 // and val's value must be assignable to the map's value type.
1399 func (v Value) SetMapIndex(key, val Value) { 1399 func (v Value) SetMapIndex(key, val Value) {
1400 v.mustBe(Map) 1400 v.mustBe(Map)
1401 v.mustBeExported() 1401 v.mustBeExported()
1402 key.mustBeExported() 1402 key.mustBeExported()
1403 tt := (*mapType)(unsafe.Pointer(v.typ)) 1403 tt := (*mapType)(unsafe.Pointer(v.typ))
1404 » key = key.assignTo("reflect.Value.SetMapIndex", toCommonType(tt.key), ni l) 1404 » key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
1405 if val.typ != nil { 1405 if val.typ != nil {
1406 val.mustBeExported() 1406 val.mustBeExported()
1407 » » val = val.assignTo("reflect.Value.SetMapIndex", toCommonType(tt. elem), nil) 1407 » » val = val.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
1408 » } 1408 » }
1409 » mapassign(v.typ.runtimeType(), v.iword(), key.iword(), val.iword(), val. typ != nil) 1409 » mapassign(v.typ, v.iword(), key.iword(), val.iword(), val.typ != nil)
1410 } 1410 }
1411 1411
1412 // SetUint sets v's underlying value to x. 1412 // SetUint sets v's underlying value to x.
1413 // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false. 1413 // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
1414 func (v Value) SetUint(x uint64) { 1414 func (v Value) SetUint(x uint64) {
1415 v.mustBeAssignable() 1415 v.mustBeAssignable()
1416 switch k := v.kind(); k { 1416 switch k := v.kind(); k {
1417 default: 1417 default:
1418 panic(&ValueError{"reflect.Value.SetUint", k}) 1418 panic(&ValueError{"reflect.Value.SetUint", k})
1419 case Uint: 1419 case Uint:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 switch k := v.kind(); k { 1458 switch k := v.kind(); k {
1459 default: 1459 default:
1460 panic(&ValueError{"reflect.Value.Slice", k}) 1460 panic(&ValueError{"reflect.Value.Slice", k})
1461 1461
1462 case Array: 1462 case Array:
1463 if v.flag&flagAddr == 0 { 1463 if v.flag&flagAddr == 0 {
1464 panic("reflect.Value.Slice: slice of unaddressable array ") 1464 panic("reflect.Value.Slice: slice of unaddressable array ")
1465 } 1465 }
1466 tt := (*arrayType)(unsafe.Pointer(v.typ)) 1466 tt := (*arrayType)(unsafe.Pointer(v.typ))
1467 cap = int(tt.len) 1467 cap = int(tt.len)
1468 » » typ = (*sliceType)(unsafe.Pointer(toCommonType(tt.slice))) 1468 » » typ = (*sliceType)(unsafe.Pointer(tt.slice))
1469 base = v.val 1469 base = v.val
1470 1470
1471 case Slice: 1471 case Slice:
1472 typ = (*sliceType)(unsafe.Pointer(v.typ)) 1472 typ = (*sliceType)(unsafe.Pointer(v.typ))
1473 s := (*SliceHeader)(v.val) 1473 s := (*SliceHeader)(v.val)
1474 base = unsafe.Pointer(s.Data) 1474 base = unsafe.Pointer(s.Data)
1475 cap = s.Cap 1475 cap = s.Cap
1476 1476
1477 case String: 1477 case String:
1478 s := (*StringHeader)(v.val) 1478 s := (*StringHeader)(v.val)
1479 if beg < 0 || end < beg || end > s.Len { 1479 if beg < 0 || end < beg || end > s.Len {
1480 panic("reflect.Value.Slice: string slice index out of bo unds") 1480 panic("reflect.Value.Slice: string slice index out of bo unds")
1481 } 1481 }
1482 var x string 1482 var x string
1483 val := (*StringHeader)(unsafe.Pointer(&x)) 1483 val := (*StringHeader)(unsafe.Pointer(&x))
1484 val.Data = s.Data + uintptr(beg) 1484 val.Data = s.Data + uintptr(beg)
1485 val.Len = end - beg 1485 val.Len = end - beg
1486 return Value{v.typ, unsafe.Pointer(&x), v.flag} 1486 return Value{v.typ, unsafe.Pointer(&x), v.flag}
1487 } 1487 }
1488 1488
1489 if beg < 0 || end < beg || end > cap { 1489 if beg < 0 || end < beg || end > cap {
1490 panic("reflect.Value.Slice: slice index out of bounds") 1490 panic("reflect.Value.Slice: slice index out of bounds")
1491 } 1491 }
1492 1492
1493 // Declare slice so that gc can see the base pointer in it. 1493 // Declare slice so that gc can see the base pointer in it.
1494 var x []byte 1494 var x []byte
1495 1495
1496 // Reinterpret as *SliceHeader to edit. 1496 // Reinterpret as *SliceHeader to edit.
1497 s := (*SliceHeader)(unsafe.Pointer(&x)) 1497 s := (*SliceHeader)(unsafe.Pointer(&x))
1498 » s.Data = uintptr(base) + uintptr(beg)*toCommonType(typ.elem).Size() 1498 » s.Data = uintptr(base) + uintptr(beg)*typ.elem.Size()
1499 s.Len = end - beg 1499 s.Len = end - beg
1500 s.Cap = cap - beg 1500 s.Cap = cap - beg
1501 1501
1502 fl := v.flag&flagRO | flagIndir | flag(Slice)<<flagKindShift 1502 fl := v.flag&flagRO | flagIndir | flag(Slice)<<flagKindShift
1503 return Value{typ.common(), unsafe.Pointer(&x), fl} 1503 return Value{typ.common(), unsafe.Pointer(&x), fl}
1504 } 1504 }
1505 1505
1506 // String returns the string v's underlying value, as a string. 1506 // String returns the string v's underlying value, as a string.
1507 // String is a special case because of Go's String method convention. 1507 // String is a special case because of Go's String method convention.
1508 // Unlike the other getters, it does not panic if v's Kind is not String. 1508 // Unlike the other getters, it does not panic if v's Kind is not String.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 // Method value. 1554 // Method value.
1555 // v.typ describes the receiver, not the method type. 1555 // v.typ describes the receiver, not the method type.
1556 i := int(v.flag) >> flagMethodShift 1556 i := int(v.flag) >> flagMethodShift
1557 if v.typ.Kind() == Interface { 1557 if v.typ.Kind() == Interface {
1558 // Method on interface. 1558 // Method on interface.
1559 tt := (*interfaceType)(unsafe.Pointer(v.typ)) 1559 tt := (*interfaceType)(unsafe.Pointer(v.typ))
1560 if i < 0 || i >= len(tt.methods) { 1560 if i < 0 || i >= len(tt.methods) {
1561 panic("reflect: broken Value") 1561 panic("reflect: broken Value")
1562 } 1562 }
1563 m := &tt.methods[i] 1563 m := &tt.methods[i]
1564 » » return toCommonType(m.typ) 1564 » » return m.typ
1565 } 1565 }
1566 // Method on concrete type. 1566 // Method on concrete type.
1567 ut := v.typ.uncommon() 1567 ut := v.typ.uncommon()
1568 if ut == nil || i < 0 || i >= len(ut.methods) { 1568 if ut == nil || i < 0 || i >= len(ut.methods) {
1569 panic("reflect: broken Value") 1569 panic("reflect: broken Value")
1570 } 1570 }
1571 m := &ut.methods[i] 1571 m := &ut.methods[i]
1572 » return toCommonType(m.mtyp) 1572 » return m.mtyp
1573 } 1573 }
1574 1574
1575 // Uint returns v's underlying value, as a uint64. 1575 // Uint returns v's underlying value, as a uint64.
1576 // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64. 1576 // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
1577 func (v Value) Uint() uint64 { 1577 func (v Value) Uint() uint64 {
1578 k := v.kind() 1578 k := v.kind()
1579 var p unsafe.Pointer 1579 var p unsafe.Pointer
1580 if v.flag&flagIndir != 0 { 1580 if v.flag&flagIndir != 0 {
1581 p = v.val 1581 p = v.val
1582 } else { 1582 } else {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 } else { 1736 } else {
1737 sa = unsafe.Pointer((*SliceHeader)(src.val).Data) 1737 sa = unsafe.Pointer((*SliceHeader)(src.val).Data)
1738 } 1738 }
1739 memmove(da, sa, uintptr(n)*de.Size()) 1739 memmove(da, sa, uintptr(n)*de.Size())
1740 return n 1740 return n
1741 } 1741 }
1742 1742
1743 // A runtimeSelect is a single case passed to rselect. 1743 // A runtimeSelect is a single case passed to rselect.
1744 // This must match ../runtime/chan.c:/runtimeSelect 1744 // This must match ../runtime/chan.c:/runtimeSelect
1745 type runtimeSelect struct { 1745 type runtimeSelect struct {
1746 » dir uintptr // 0, SendDir, or RecvDir 1746 » dir uintptr // 0, SendDir, or RecvDir
1747 » typ *runtimeType // channel type 1747 » typ *rtype // channel type
1748 » ch iword // interface word for channel 1748 » ch iword // interface word for channel
1749 » val iword // interface word for value (for SendDir) 1749 » val iword // interface word for value (for SendDir)
1750 } 1750 }
1751 1751
1752 // rselect runs a select. It returns the index of the chosen case, 1752 // rselect runs a select. It returns the index of the chosen case,
1753 // and if the case was a receive, the interface word of the received 1753 // and if the case was a receive, the interface word of the received
1754 // value and the conventional OK bool to indicate whether the receive 1754 // value and the conventional OK bool to indicate whether the receive
1755 // corresponds to a sent value. 1755 // corresponds to a sent value.
1756 func rselect([]runtimeSelect) (chosen int, recv iword, recvOK bool) 1756 func rselect([]runtimeSelect) (chosen int, recv iword, recvOK bool)
1757 1757
1758 // A SelectDir describes the communication direction of a select case. 1758 // A SelectDir describes the communication direction of a select case.
1759 type SelectDir int 1759 type SelectDir int
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 if !ch.IsValid() { 1826 if !ch.IsValid() {
1827 break 1827 break
1828 } 1828 }
1829 ch.mustBe(Chan) 1829 ch.mustBe(Chan)
1830 ch.mustBeExported() 1830 ch.mustBeExported()
1831 tt := (*chanType)(unsafe.Pointer(ch.typ)) 1831 tt := (*chanType)(unsafe.Pointer(ch.typ))
1832 if ChanDir(tt.dir)&SendDir == 0 { 1832 if ChanDir(tt.dir)&SendDir == 0 {
1833 panic("reflect.Select: SendDir case using recv-o nly channel") 1833 panic("reflect.Select: SendDir case using recv-o nly channel")
1834 } 1834 }
1835 rc.ch = ch.iword() 1835 rc.ch = ch.iword()
1836 » » » rc.typ = tt.runtimeType() 1836 » » » rc.typ = &tt.rtype
1837 v := c.Send 1837 v := c.Send
1838 if !v.IsValid() { 1838 if !v.IsValid() {
1839 panic("reflect.Select: SendDir case missing Send value") 1839 panic("reflect.Select: SendDir case missing Send value")
1840 } 1840 }
1841 v.mustBeExported() 1841 v.mustBeExported()
1842 » » » v = v.assignTo("reflect.Select", toCommonType(tt.elem), nil) 1842 » » » v = v.assignTo("reflect.Select", tt.elem, nil)
1843 rc.val = v.iword() 1843 rc.val = v.iword()
1844 1844
1845 case SelectRecv: 1845 case SelectRecv:
1846 if c.Send.IsValid() { 1846 if c.Send.IsValid() {
1847 panic("reflect.Select: RecvDir case has Send val ue") 1847 panic("reflect.Select: RecvDir case has Send val ue")
1848 } 1848 }
1849 ch := c.Chan 1849 ch := c.Chan
1850 if !ch.IsValid() { 1850 if !ch.IsValid() {
1851 break 1851 break
1852 } 1852 }
1853 ch.mustBe(Chan) 1853 ch.mustBe(Chan)
1854 ch.mustBeExported() 1854 ch.mustBeExported()
1855 tt := (*chanType)(unsafe.Pointer(ch.typ)) 1855 tt := (*chanType)(unsafe.Pointer(ch.typ))
1856 » » » rc.typ = tt.runtimeType() 1856 » » » rc.typ = &tt.rtype
1857 if ChanDir(tt.dir)&RecvDir == 0 { 1857 if ChanDir(tt.dir)&RecvDir == 0 {
1858 panic("reflect.Select: RecvDir case using send-o nly channel") 1858 panic("reflect.Select: RecvDir case using send-o nly channel")
1859 } 1859 }
1860 rc.ch = ch.iword() 1860 rc.ch = ch.iword()
1861 } 1861 }
1862 } 1862 }
1863 1863
1864 chosen, word, recvOK := rselect(runcases) 1864 chosen, word, recvOK := rselect(runcases)
1865 if runcases[chosen].dir == uintptr(SelectRecv) { 1865 if runcases[chosen].dir == uintptr(SelectRecv) {
1866 » » tt := (*chanType)(unsafe.Pointer(toCommonType(runcases[chosen].t yp))) 1866 » » tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
1867 » » typ := toCommonType(tt.elem) 1867 » » typ := tt.elem
1868 fl := flag(typ.Kind()) << flagKindShift 1868 fl := flag(typ.Kind()) << flagKindShift
1869 if typ.size > ptrSize { 1869 if typ.size > ptrSize {
1870 fl |= flagIndir 1870 fl |= flagIndir
1871 } 1871 }
1872 recv = Value{typ, unsafe.Pointer(word), fl} 1872 recv = Value{typ, unsafe.Pointer(word), fl}
1873 } 1873 }
1874 return chosen, recv, recvOK 1874 return chosen, recv, recvOK
1875 } 1875 }
1876 1876
1877 /* 1877 /*
1878 * constructors 1878 * constructors
1879 */ 1879 */
1880 1880
1881 // implemented in package runtime 1881 // implemented in package runtime
1882 func unsafe_New(Type) unsafe.Pointer 1882 func unsafe_New(*rtype) unsafe.Pointer
1883 func unsafe_NewArray(Type, int) unsafe.Pointer 1883 func unsafe_NewArray(*rtype, int) unsafe.Pointer
1884 1884
1885 // MakeSlice creates a new zero-initialized slice value 1885 // MakeSlice creates a new zero-initialized slice value
1886 // for the specified slice type, length, and capacity. 1886 // for the specified slice type, length, and capacity.
1887 func MakeSlice(typ Type, len, cap int) Value { 1887 func MakeSlice(typ Type, len, cap int) Value {
1888 if typ.Kind() != Slice { 1888 if typ.Kind() != Slice {
1889 panic("reflect.MakeSlice of non-slice type") 1889 panic("reflect.MakeSlice of non-slice type")
1890 } 1890 }
1891 if len < 0 { 1891 if len < 0 {
1892 panic("reflect.MakeSlice: negative len") 1892 panic("reflect.MakeSlice: negative len")
1893 } 1893 }
1894 if cap < 0 { 1894 if cap < 0 {
1895 panic("reflect.MakeSlice: negative cap") 1895 panic("reflect.MakeSlice: negative cap")
1896 } 1896 }
1897 if len > cap { 1897 if len > cap {
1898 panic("reflect.MakeSlice: len > cap") 1898 panic("reflect.MakeSlice: len > cap")
1899 } 1899 }
1900 1900
1901 // Declare slice so that gc can see the base pointer in it. 1901 // Declare slice so that gc can see the base pointer in it.
1902 var x []byte 1902 var x []byte
1903 1903
1904 // Reinterpret as *SliceHeader to edit. 1904 // Reinterpret as *SliceHeader to edit.
1905 s := (*SliceHeader)(unsafe.Pointer(&x)) 1905 s := (*SliceHeader)(unsafe.Pointer(&x))
1906 » s.Data = uintptr(unsafe_NewArray(typ.Elem(), cap)) 1906 » s.Data = uintptr(unsafe_NewArray(typ.Elem().(*rtype), cap))
1907 s.Len = len 1907 s.Len = len
1908 s.Cap = cap 1908 s.Cap = cap
1909 1909
1910 return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<< flagKindShift} 1910 return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<< flagKindShift}
1911 } 1911 }
1912 1912
1913 // MakeChan creates a new channel with the specified type and buffer size. 1913 // MakeChan creates a new channel with the specified type and buffer size.
1914 func MakeChan(typ Type, buffer int) Value { 1914 func MakeChan(typ Type, buffer int) Value {
1915 if typ.Kind() != Chan { 1915 if typ.Kind() != Chan {
1916 panic("reflect.MakeChan of non-chan type") 1916 panic("reflect.MakeChan of non-chan type")
1917 } 1917 }
1918 if buffer < 0 { 1918 if buffer < 0 {
1919 panic("reflect.MakeChan: negative buffer size") 1919 panic("reflect.MakeChan: negative buffer size")
1920 } 1920 }
1921 if typ.ChanDir() != BothDir { 1921 if typ.ChanDir() != BothDir {
1922 panic("reflect.MakeChan: unidirectional channel type") 1922 panic("reflect.MakeChan: unidirectional channel type")
1923 } 1923 }
1924 » ch := makechan(typ.runtimeType(), uint64(buffer)) 1924 » ch := makechan(typ.(*rtype), uint64(buffer))
1925 return Value{typ.common(), unsafe.Pointer(ch), flag(Chan) << flagKindShi ft} 1925 return Value{typ.common(), unsafe.Pointer(ch), flag(Chan) << flagKindShi ft}
1926 } 1926 }
1927 1927
1928 // MakeMap creates a new map of the specified type. 1928 // MakeMap creates a new map of the specified type.
1929 func MakeMap(typ Type) Value { 1929 func MakeMap(typ Type) Value {
1930 if typ.Kind() != Map { 1930 if typ.Kind() != Map {
1931 panic("reflect.MakeMap of non-map type") 1931 panic("reflect.MakeMap of non-map type")
1932 } 1932 }
1933 » m := makemap(typ.runtimeType()) 1933 » m := makemap(typ.(*rtype))
1934 return Value{typ.common(), unsafe.Pointer(m), flag(Map) << flagKindShift } 1934 return Value{typ.common(), unsafe.Pointer(m), flag(Map) << flagKindShift }
1935 } 1935 }
1936 1936
1937 // Indirect returns the value that v points to. 1937 // Indirect returns the value that v points to.
1938 // If v is a nil pointer, Indirect returns a zero Value. 1938 // If v is a nil pointer, Indirect returns a zero Value.
1939 // If v is not a pointer, Indirect returns v. 1939 // If v is not a pointer, Indirect returns v.
1940 func Indirect(v Value) Value { 1940 func Indirect(v Value) Value {
1941 if v.Kind() != Ptr { 1941 if v.Kind() != Ptr {
1942 return v 1942 return v
1943 } 1943 }
(...skipping 10 matching lines...) Expand all
1954 // TODO(rsc): Eliminate this terrible hack. 1954 // TODO(rsc): Eliminate this terrible hack.
1955 // In the call to packValue, eface.typ doesn't escape, 1955 // In the call to packValue, eface.typ doesn't escape,
1956 // and eface.word is an integer. So it looks like 1956 // and eface.word is an integer. So it looks like
1957 // i (= eface) doesn't escape. But really it does, 1957 // i (= eface) doesn't escape. But really it does,
1958 // because eface.word is actually a pointer. 1958 // because eface.word is actually a pointer.
1959 escapes(i) 1959 escapes(i)
1960 1960
1961 // For an interface value with the noAddr bit set, 1961 // For an interface value with the noAddr bit set,
1962 // the representation is identical to an empty interface. 1962 // the representation is identical to an empty interface.
1963 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1963 eface := *(*emptyInterface)(unsafe.Pointer(&i))
1964 » typ := toCommonType(eface.typ) 1964 » typ := eface.typ
1965 fl := flag(typ.Kind()) << flagKindShift 1965 fl := flag(typ.Kind()) << flagKindShift
1966 if typ.size > ptrSize { 1966 if typ.size > ptrSize {
1967 fl |= flagIndir 1967 fl |= flagIndir
1968 } 1968 }
1969 return Value{typ, unsafe.Pointer(eface.word), fl} 1969 return Value{typ, unsafe.Pointer(eface.word), fl}
1970 } 1970 }
1971 1971
1972 // Zero returns a Value representing the zero value for the specified type. 1972 // Zero returns a Value representing the zero value for the specified type.
1973 // The result is different from the zero value of the Value struct, 1973 // The result is different from the zero value of the Value struct,
1974 // which represents no value at all. 1974 // which represents no value at all.
1975 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. 1975 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
1976 // The returned value is neither addressable nor settable. 1976 // The returned value is neither addressable nor settable.
1977 func Zero(typ Type) Value { 1977 func Zero(typ Type) Value {
1978 if typ == nil { 1978 if typ == nil {
1979 panic("reflect: Zero(nil)") 1979 panic("reflect: Zero(nil)")
1980 } 1980 }
1981 t := typ.common() 1981 t := typ.common()
1982 fl := flag(t.Kind()) << flagKindShift 1982 fl := flag(t.Kind()) << flagKindShift
1983 if t.size <= ptrSize { 1983 if t.size <= ptrSize {
1984 return Value{t, nil, fl} 1984 return Value{t, nil, fl}
1985 } 1985 }
1986 » return Value{t, unsafe_New(typ), fl | flagIndir} 1986 » return Value{t, unsafe_New(typ.(*rtype)), fl | flagIndir}
1987 } 1987 }
1988 1988
1989 // New returns a Value representing a pointer to a new zero value 1989 // New returns a Value representing a pointer to a new zero value
1990 // for the specified type. That is, the returned Value's Type is PtrTo(t). 1990 // for the specified type. That is, the returned Value's Type is PtrTo(t).
1991 func New(typ Type) Value { 1991 func New(typ Type) Value {
1992 if typ == nil { 1992 if typ == nil {
1993 panic("reflect: New(nil)") 1993 panic("reflect: New(nil)")
1994 } 1994 }
1995 » ptr := unsafe_New(typ) 1995 » ptr := unsafe_New(typ.(*rtype))
1996 fl := flag(Ptr) << flagKindShift 1996 fl := flag(Ptr) << flagKindShift
1997 return Value{typ.common().ptrTo(), ptr, fl} 1997 return Value{typ.common().ptrTo(), ptr, fl}
1998 } 1998 }
1999 1999
2000 // NewAt returns a Value representing a pointer to a value of the 2000 // NewAt returns a Value representing a pointer to a value of the
2001 // specified type, using p as that pointer. 2001 // specified type, using p as that pointer.
2002 func NewAt(typ Type, p unsafe.Pointer) Value { 2002 func NewAt(typ Type, p unsafe.Pointer) Value {
2003 fl := flag(Ptr) << flagKindShift 2003 fl := flag(Ptr) << flagKindShift
2004 return Value{typ.common().ptrTo(), p, fl} 2004 return Value{typ.common().ptrTo(), p, fl}
2005 } 2005 }
2006 2006
2007 // assignTo returns a value v that can be assigned directly to typ. 2007 // assignTo returns a value v that can be assigned directly to typ.
2008 // It panics if v is not assignable to typ. 2008 // It panics if v is not assignable to typ.
2009 // For a conversion to an interface type, target is a suggested scratch space to use. 2009 // For a conversion to an interface type, target is a suggested scratch space to use.
2010 func (v Value) assignTo(context string, dst *commonType, target *interface{}) Va lue { 2010 func (v Value) assignTo(context string, dst *rtype, target *interface{}) Value {
2011 if v.flag&flagMethod != 0 { 2011 if v.flag&flagMethod != 0 {
2012 panic(context + ": cannot assign method value to type " + dst.St ring()) 2012 panic(context + ": cannot assign method value to type " + dst.St ring())
2013 } 2013 }
2014 2014
2015 switch { 2015 switch {
2016 case directlyAssignable(dst, v.typ): 2016 case directlyAssignable(dst, v.typ):
2017 // Overwrite type so that they match. 2017 // Overwrite type so that they match.
2018 // Same memory layout, so no harm done. 2018 // Same memory layout, so no harm done.
2019 v.typ = dst 2019 v.typ = dst
2020 fl := v.flag & (flagRO | flagAddr | flagIndir) 2020 fl := v.flag & (flagRO | flagAddr | flagIndir)
2021 fl |= flag(dst.Kind()) << flagKindShift 2021 fl |= flag(dst.Kind()) << flagKindShift
2022 return Value{dst, v.val, fl} 2022 return Value{dst, v.val, fl}
2023 2023
2024 case implements(dst, v.typ): 2024 case implements(dst, v.typ):
2025 if target == nil { 2025 if target == nil {
2026 target = new(interface{}) 2026 target = new(interface{})
2027 } 2027 }
2028 x := valueInterface(v, false) 2028 x := valueInterface(v, false)
2029 if dst.NumMethod() == 0 { 2029 if dst.NumMethod() == 0 {
2030 *target = x 2030 *target = x
2031 } else { 2031 } else {
2032 » » » ifaceE2I(dst.runtimeType(), x, unsafe.Pointer(target)) 2032 » » » ifaceE2I(dst, x, unsafe.Pointer(target))
2033 } 2033 }
2034 return Value{dst, unsafe.Pointer(target), flagIndir | flag(Inter face)<<flagKindShift} 2034 return Value{dst, unsafe.Pointer(target), flagIndir | flag(Inter face)<<flagKindShift}
2035 } 2035 }
2036 2036
2037 // Failed. 2037 // Failed.
2038 panic(context + ": value of type " + v.typ.String() + " is not assignabl e to type " + dst.String()) 2038 panic(context + ": value of type " + v.typ.String() + " is not assignabl e to type " + dst.String())
2039 } 2039 }
2040 2040
2041 // Convert returns the value v converted to type t. 2041 // Convert returns the value v converted to type t.
2042 // If the usual Go conversion rules do not allow conversion 2042 // If the usual Go conversion rules do not allow conversion
2043 // of the value v to type t, Convert panics. 2043 // of the value v to type t, Convert panics.
2044 func (v Value) Convert(t Type) Value { 2044 func (v Value) Convert(t Type) Value {
2045 if v.flag&flagMethod != 0 { 2045 if v.flag&flagMethod != 0 {
2046 panic("reflect.Value.Convert: cannot convert method values") 2046 panic("reflect.Value.Convert: cannot convert method values")
2047 } 2047 }
2048 op := convertOp(t.common(), v.typ) 2048 op := convertOp(t.common(), v.typ)
2049 if op == nil { 2049 if op == nil {
2050 panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String()) 2050 panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
2051 } 2051 }
2052 return op(v, t) 2052 return op(v, t)
2053 } 2053 }
2054 2054
2055 // convertOp returns the function to convert a value of type src 2055 // convertOp returns the function to convert a value of type src
2056 // to a value of type dst. If the conversion is illegal, convertOp returns nil. 2056 // to a value of type dst. If the conversion is illegal, convertOp returns nil.
2057 func convertOp(dst, src *commonType) func(Value, Type) Value { 2057 func convertOp(dst, src *rtype) func(Value, Type) Value {
2058 switch src.Kind() { 2058 switch src.Kind() {
2059 case Int, Int8, Int16, Int32, Int64: 2059 case Int, Int8, Int16, Int32, Int64:
2060 switch dst.Kind() { 2060 switch dst.Kind() {
2061 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32 , Uint64, Uintptr: 2061 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32 , Uint64, Uintptr:
2062 return cvtInt 2062 return cvtInt
2063 case Float32, Float64: 2063 case Float32, Float64:
2064 return cvtIntFloat 2064 return cvtIntFloat
2065 case String: 2065 case String:
2066 return cvtIntString 2066 return cvtIntString
2067 } 2067 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 2134
2135 return nil 2135 return nil
2136 } 2136 }
2137 2137
2138 // makeInt returns a Value of type t equal to bits (possibly truncated), 2138 // makeInt returns a Value of type t equal to bits (possibly truncated),
2139 // where t is a signed or unsigned int type. 2139 // where t is a signed or unsigned int type.
2140 func makeInt(f flag, bits uint64, t Type) Value { 2140 func makeInt(f flag, bits uint64, t Type) Value {
2141 typ := t.common() 2141 typ := t.common()
2142 if typ.size > ptrSize { 2142 if typ.size > ptrSize {
2143 // Assume ptrSize >= 4, so this must be uint64. 2143 // Assume ptrSize >= 4, so this must be uint64.
2144 » » ptr := unsafe_New(t) 2144 » » ptr := unsafe_New(typ)
2145 *(*uint64)(unsafe.Pointer(ptr)) = bits 2145 *(*uint64)(unsafe.Pointer(ptr)) = bits
2146 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift} 2146 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift}
2147 } 2147 }
2148 var w iword 2148 var w iword
2149 switch typ.size { 2149 switch typ.size {
2150 case 1: 2150 case 1:
2151 *(*uint8)(unsafe.Pointer(&w)) = uint8(bits) 2151 *(*uint8)(unsafe.Pointer(&w)) = uint8(bits)
2152 case 2: 2152 case 2:
2153 *(*uint16)(unsafe.Pointer(&w)) = uint16(bits) 2153 *(*uint16)(unsafe.Pointer(&w)) = uint16(bits)
2154 case 4: 2154 case 4:
2155 *(*uint32)(unsafe.Pointer(&w)) = uint32(bits) 2155 *(*uint32)(unsafe.Pointer(&w)) = uint32(bits)
2156 case 8: 2156 case 8:
2157 *(*uint64)(unsafe.Pointer(&w)) = uint64(bits) 2157 *(*uint64)(unsafe.Pointer(&w)) = uint64(bits)
2158 } 2158 }
2159 return Value{typ, unsafe.Pointer(w), f | flag(typ.Kind())<<flagKindShift } 2159 return Value{typ, unsafe.Pointer(w), f | flag(typ.Kind())<<flagKindShift }
2160 } 2160 }
2161 2161
2162 // makeFloat returns a Value of type t equal to v (possibly truncated to float32 ), 2162 // makeFloat returns a Value of type t equal to v (possibly truncated to float32 ),
2163 // where t is a float32 or float64 type. 2163 // where t is a float32 or float64 type.
2164 func makeFloat(f flag, v float64, t Type) Value { 2164 func makeFloat(f flag, v float64, t Type) Value {
2165 typ := t.common() 2165 typ := t.common()
2166 if typ.size > ptrSize { 2166 if typ.size > ptrSize {
2167 // Assume ptrSize >= 4, so this must be float64. 2167 // Assume ptrSize >= 4, so this must be float64.
2168 » » ptr := unsafe_New(t) 2168 » » ptr := unsafe_New(typ)
2169 *(*float64)(unsafe.Pointer(ptr)) = v 2169 *(*float64)(unsafe.Pointer(ptr)) = v
2170 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift} 2170 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift}
2171 } 2171 }
2172 2172
2173 var w iword 2173 var w iword
2174 switch typ.size { 2174 switch typ.size {
2175 case 4: 2175 case 4:
2176 *(*float32)(unsafe.Pointer(&w)) = float32(v) 2176 *(*float32)(unsafe.Pointer(&w)) = float32(v)
2177 case 8: 2177 case 8:
2178 *(*float64)(unsafe.Pointer(&w)) = v 2178 *(*float64)(unsafe.Pointer(&w)) = v
2179 } 2179 }
2180 return Value{typ, unsafe.Pointer(w), f | flag(typ.Kind())<<flagKindShift } 2180 return Value{typ, unsafe.Pointer(w), f | flag(typ.Kind())<<flagKindShift }
2181 } 2181 }
2182 2182
2183 // makeComplex returns a Value of type t equal to v (possibly truncated to compl ex64), 2183 // makeComplex returns a Value of type t equal to v (possibly truncated to compl ex64),
2184 // where t is a complex64 or complex128 type. 2184 // where t is a complex64 or complex128 type.
2185 func makeComplex(f flag, v complex128, t Type) Value { 2185 func makeComplex(f flag, v complex128, t Type) Value {
2186 typ := t.common() 2186 typ := t.common()
2187 if typ.size > ptrSize { 2187 if typ.size > ptrSize {
2188 » » ptr := unsafe_New(t) 2188 » » ptr := unsafe_New(typ)
2189 switch typ.size { 2189 switch typ.size {
2190 case 8: 2190 case 8:
2191 *(*complex64)(unsafe.Pointer(ptr)) = complex64(v) 2191 *(*complex64)(unsafe.Pointer(ptr)) = complex64(v)
2192 case 16: 2192 case 16:
2193 *(*complex128)(unsafe.Pointer(ptr)) = v 2193 *(*complex128)(unsafe.Pointer(ptr)) = v
2194 } 2194 }
2195 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift} 2195 return Value{typ, ptr, f | flag(typ.Kind())<<flagKindShift}
2196 } 2196 }
2197 2197
2198 // Assume ptrSize <= 8 so this must be complex64. 2198 // Assume ptrSize <= 8 so this must be complex64.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2312 return Value{t, val, v.flag&flagRO | f} 2312 return Value{t, val, v.flag&flagRO | f}
2313 } 2313 }
2314 2314
2315 // convertOp: concrete -> interface 2315 // convertOp: concrete -> interface
2316 func cvtT2I(v Value, typ Type) Value { 2316 func cvtT2I(v Value, typ Type) Value {
2317 target := new(interface{}) 2317 target := new(interface{})
2318 x := valueInterface(v, false) 2318 x := valueInterface(v, false)
2319 if typ.NumMethod() == 0 { 2319 if typ.NumMethod() == 0 {
2320 *target = x 2320 *target = x
2321 } else { 2321 } else {
2322 » » ifaceE2I(typ.runtimeType(), x, unsafe.Pointer(target)) 2322 » » ifaceE2I(typ.(*rtype), x, unsafe.Pointer(target))
2323 } 2323 }
2324 return Value{typ.common(), unsafe.Pointer(target), v.flag&flagRO | flagI ndir | flag(Interface)<<flagKindShift} 2324 return Value{typ.common(), unsafe.Pointer(target), v.flag&flagRO | flagI ndir | flag(Interface)<<flagKindShift}
2325 } 2325 }
2326 2326
2327 // convertOp: interface -> interface 2327 // convertOp: interface -> interface
2328 func cvtI2I(v Value, typ Type) Value { 2328 func cvtI2I(v Value, typ Type) Value {
2329 if v.IsNil() { 2329 if v.IsNil() {
2330 ret := Zero(typ) 2330 ret := Zero(typ)
2331 ret.flag |= v.flag & flagRO 2331 ret.flag |= v.flag & flagRO
2332 return ret 2332 return ret
2333 } 2333 }
2334 return cvtT2I(v.Elem(), typ) 2334 return cvtT2I(v.Elem(), typ)
2335 } 2335 }
2336 2336
2337 // implemented in ../pkg/runtime 2337 // implemented in ../pkg/runtime
2338 func chancap(ch iword) int 2338 func chancap(ch iword) int
2339 func chanclose(ch iword) 2339 func chanclose(ch iword)
2340 func chanlen(ch iword) int 2340 func chanlen(ch iword) int
2341 func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received bool) 2341 func chanrecv(t *rtype, ch iword, nb bool) (val iword, selected, received bool)
2342 func chansend(t *runtimeType, ch iword, val iword, nb bool) bool 2342 func chansend(t *rtype, ch iword, val iword, nb bool) bool
2343 2343
2344 func makechan(typ *runtimeType, size uint64) (ch iword) 2344 func makechan(typ *rtype, size uint64) (ch iword)
2345 func makemap(t *runtimeType) (m iword) 2345 func makemap(t *rtype) (m iword)
2346 func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool) 2346 func mapaccess(t *rtype, m iword, key iword) (val iword, ok bool)
2347 func mapassign(t *runtimeType, m iword, key, val iword, ok bool) 2347 func mapassign(t *rtype, m iword, key, val iword, ok bool)
2348 func mapiterinit(t *runtimeType, m iword) *byte 2348 func mapiterinit(t *rtype, m iword) *byte
2349 func mapiterkey(it *byte) (key iword, ok bool) 2349 func mapiterkey(it *byte) (key iword, ok bool)
2350 func mapiternext(it *byte) 2350 func mapiternext(it *byte)
2351 func maplen(m iword) int 2351 func maplen(m iword) int
2352 2352
2353 func call(fn, arg unsafe.Pointer, n uint32) 2353 func call(fn, arg unsafe.Pointer, n uint32)
2354 func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer) 2354 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
2355 2355
2356 // Dummy annotation marking that the value x escapes, 2356 // Dummy annotation marking that the value x escapes,
2357 // for use in cases where the reflect code is so clever that 2357 // for use in cases where the reflect code is so clever that
2358 // the compiler cannot follow. 2358 // the compiler cannot follow.
2359 func escapes(x interface{}) { 2359 func escapes(x interface{}) {
2360 if dummy.b { 2360 if dummy.b {
2361 dummy.x = x 2361 dummy.x = x
2362 } 2362 }
2363 } 2363 }
2364 2364
2365 var dummy struct { 2365 var dummy struct {
2366 b bool 2366 b bool
2367 x interface{} 2367 x interface{}
2368 } 2368 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b