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

Side by Side Diff: src/pkg/reflect/value.go

Issue 129090043: code review 129090043: cmd/gc, runtime: refactor interface inlining decision i... (Closed)
Patch Set: diff -r 5856eae43c269fc32cdf2cfca0c9412ee4a5969c https://code.google.com/p/go/ Created 9 years, 7 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:
View unified diff | Download patch
« no previous file with comments | « src/pkg/reflect/type.go ('k') | src/pkg/runtime/alg.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // flag holds metadata about the value. 75 // flag holds metadata about the value.
76 // The lowest bits are flag bits: 76 // The lowest bits are flag bits:
77 // - flagRO: obtained via unexported field, so read-only 77 // - flagRO: obtained via unexported field, so read-only
78 // - flagIndir: val holds a pointer to the data 78 // - flagIndir: val holds a pointer to the data
79 // - flagAddr: v.CanAddr is true (implies flagIndir) 79 // - flagAddr: v.CanAddr is true (implies flagIndir)
80 // - flagMethod: v is a method value. 80 // - flagMethod: v is a method value.
81 // The next five bits give the Kind of the value. 81 // The next five bits give the Kind of the value.
82 // This repeats typ.Kind() except for method values. 82 // This repeats typ.Kind() except for method values.
83 // The remaining 23+ bits give a method number for method values. 83 // The remaining 23+ bits give a method number for method values.
84 // If flag.kind() != Func, code can assume that flagMethod is unset. 84 // If flag.kind() != Func, code can assume that flagMethod is unset.
85 » // If typ.size > ptrSize, code can assume that flagIndir is set. 85 » // If !isDirectIface(typ), code can assume that flagIndir is set.
86 flag 86 flag
87 87
88 // A method value represents a curried method invocation 88 // A method value represents a curried method invocation
89 // like r.Read for some receiver r. The typ+val+flag bits describe 89 // like r.Read for some receiver r. The typ+val+flag bits describe
90 // the receiver r, but the flag's Kind bits say Func (methods are 90 // the receiver r, but the flag's Kind bits say Func (methods are
91 // functions), and the top bits of the flag give the method number 91 // functions), and the top bits of the flag give the method number
92 // in r's type's method table. 92 // in r's type's method table.
93 } 93 }
94 94
95 type flag uintptr 95 type flag uintptr
(...skipping 25 matching lines...) Expand all
121 return v.ptr 121 return v.ptr
122 } 122 }
123 123
124 // packEface converts v to the empty interface. 124 // packEface converts v to the empty interface.
125 func packEface(v Value) interface{} { 125 func packEface(v Value) interface{} {
126 t := v.typ 126 t := v.typ
127 var i interface{} 127 var i interface{}
128 e := (*emptyInterface)(unsafe.Pointer(&i)) 128 e := (*emptyInterface)(unsafe.Pointer(&i))
129 // First, fill in the data portion of the interface. 129 // First, fill in the data portion of the interface.
130 switch { 130 switch {
131 » case t.size > ptrSize: 131 » case !isDirectIface(t):
132 » » if v.flag&flagIndir == 0 {
133 » » » panic("bad indir")
134 » » }
132 // Value is indirect, and so is the interface we're making. 135 // Value is indirect, and so is the interface we're making.
133 ptr := v.ptr 136 ptr := v.ptr
134 if v.flag&flagAddr != 0 { 137 if v.flag&flagAddr != 0 {
135 // TODO: pass safe boolean from valueInterface so 138 // TODO: pass safe boolean from valueInterface so
136 // we don't need to copy if safe==true? 139 // we don't need to copy if safe==true?
137 c := unsafe_New(t) 140 c := unsafe_New(t)
138 memmove(c, ptr, t.size) 141 memmove(c, ptr, t.size)
139 ptr = c 142 ptr = c
140 } 143 }
141 e.word = iword(ptr) 144 e.word = iword(ptr)
(...skipping 23 matching lines...) Expand all
165 168
166 // unpackEface converts the empty interface i to a Value. 169 // unpackEface converts the empty interface i to a Value.
167 func unpackEface(i interface{}) Value { 170 func unpackEface(i interface{}) Value {
168 e := (*emptyInterface)(unsafe.Pointer(&i)) 171 e := (*emptyInterface)(unsafe.Pointer(&i))
169 // NOTE: don't read e.word until we know whether it is really a pointer or not. 172 // NOTE: don't read e.word until we know whether it is really a pointer or not.
170 t := e.typ 173 t := e.typ
171 if t == nil { 174 if t == nil {
172 return Value{} 175 return Value{}
173 } 176 }
174 f := flag(t.Kind()) << flagKindShift 177 f := flag(t.Kind()) << flagKindShift
175 » if t.size > ptrSize { 178 » if !isDirectIface(t) {
176 return Value{t, unsafe.Pointer(e.word), 0, f | flagIndir} 179 return Value{t, unsafe.Pointer(e.word), 0, f | flagIndir}
177 } 180 }
178 if t.pointers() { 181 if t.pointers() {
179 return Value{t, unsafe.Pointer(e.word), 0, f} 182 return Value{t, unsafe.Pointer(e.word), 0, f}
180 } 183 }
181 return Value{t, nil, uintptr(e.word), f} 184 return Value{t, nil, uintptr(e.word), f}
182 } 185 }
183 186
184 // A ValueError occurs when a Value method is invoked on 187 // A ValueError occurs when a Value method is invoked on
185 // a Value that does not support it. Such cases are documented 188 // a Value that does not support it. Such cases are documented
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 603
601 // Copy argument frame into Values. 604 // Copy argument frame into Values.
602 ptr := frame 605 ptr := frame
603 off := uintptr(0) 606 off := uintptr(0)
604 in := make([]Value, 0, len(ftyp.in)) 607 in := make([]Value, 0, len(ftyp.in))
605 for _, arg := range ftyp.in { 608 for _, arg := range ftyp.in {
606 typ := arg 609 typ := arg
607 off += -off & uintptr(typ.align-1) 610 off += -off & uintptr(typ.align-1)
608 addr := unsafe.Pointer(uintptr(ptr) + off) 611 addr := unsafe.Pointer(uintptr(ptr) + off)
609 v := Value{typ, nil, 0, flag(typ.Kind()) << flagKindShift} 612 v := Value{typ, nil, 0, flag(typ.Kind()) << flagKindShift}
610 » » if typ.size > ptrSize { 613 » » if !isDirectIface(typ) {
611 » » » // value does not fit in word. 614 » » » // value cannot be inlined in interface data.
612 // Must make a copy, because f might keep a reference to it, 615 // Must make a copy, because f might keep a reference to it,
613 // and we cannot let f keep a reference to the stack fra me 616 // and we cannot let f keep a reference to the stack fra me
614 // after this function returns, not even a read-only ref erence. 617 // after this function returns, not even a read-only ref erence.
615 v.ptr = unsafe_New(typ) 618 v.ptr = unsafe_New(typ)
616 memmove(v.ptr, addr, typ.size) 619 memmove(v.ptr, addr, typ.size)
617 v.flag |= flagIndir 620 v.flag |= flagIndir
618 } else if typ.pointers() { 621 } else if typ.pointers() {
619 v.ptr = *(*unsafe.Pointer)(addr) 622 v.ptr = *(*unsafe.Pointer)(addr)
620 } else { 623 } else {
621 v.scalar = loadScalar(addr, typ.size) 624 v.scalar = loadScalar(addr, typ.size)
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 // encode that receiver at the start of the argument list. 710 // encode that receiver at the start of the argument list.
708 // Reflect uses the "interface" calling convention for 711 // Reflect uses the "interface" calling convention for
709 // methods, which always uses one word to record the receiver. 712 // methods, which always uses one word to record the receiver.
710 func storeRcvr(v Value, p unsafe.Pointer) { 713 func storeRcvr(v Value, p unsafe.Pointer) {
711 t := v.typ 714 t := v.typ
712 if t.Kind() == Interface { 715 if t.Kind() == Interface {
713 // the interface data word becomes the receiver word 716 // the interface data word becomes the receiver word
714 iface := (*nonEmptyInterface)(v.ptr) 717 iface := (*nonEmptyInterface)(v.ptr)
715 *(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word) 718 *(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
716 } else if v.flag&flagIndir != 0 { 719 } else if v.flag&flagIndir != 0 {
717 » » if t.size > ptrSize { 720 » » if !isDirectIface(t) {
718 *(*unsafe.Pointer)(p) = v.ptr 721 *(*unsafe.Pointer)(p) = v.ptr
719 } else if t.pointers() { 722 } else if t.pointers() {
720 *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr) 723 *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
721 } else { 724 } else {
722 *(*uintptr)(p) = loadScalar(v.ptr, t.size) 725 *(*uintptr)(p) = loadScalar(v.ptr, t.size)
723 } 726 }
724 } else if t.pointers() { 727 } else if t.pointers() {
725 *(*unsafe.Pointer)(p) = v.ptr 728 *(*unsafe.Pointer)(p) = v.ptr
726 } else { 729 } else {
727 *(*uintptr)(p) = v.scalar 730 *(*uintptr)(p) = v.scalar
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 offset := uintptr(i) * typ.size 983 offset := uintptr(i) * typ.size
981 984
982 var val unsafe.Pointer 985 var val unsafe.Pointer
983 var scalar uintptr 986 var scalar uintptr
984 switch { 987 switch {
985 case fl&flagIndir != 0: 988 case fl&flagIndir != 0:
986 // Indirect. Just bump pointer. 989 // Indirect. Just bump pointer.
987 val = unsafe.Pointer(uintptr(v.ptr) + offset) 990 val = unsafe.Pointer(uintptr(v.ptr) + offset)
988 case typ.pointers(): 991 case typ.pointers():
989 if offset != 0 { 992 if offset != 0 {
990 » » » » panic("can't Index(i) with i!=0 on ptrLike value ") 993 » » » » // This is an array stored inline in an interfac e value.
994 » » » » // And the array element type has pointers.
995 » » » » // Since the inline storage space is only a sing le word,
996 » » » » // this implies we must be holding an array of l ength 1
997 » » » » // with an element type that is a single pointer .
998 » » » » // If the offset is not 0, something has gone wr ong.
999 » » » » panic("reflect: internal error: unexpected array index")
991 } 1000 }
992 val = v.ptr 1001 val = v.ptr
993 case bigEndian: 1002 case bigEndian:
994 // Direct. Discard leading bytes. 1003 // Direct. Discard leading bytes.
995 scalar = v.scalar << (offset * 8) 1004 scalar = v.scalar << (offset * 8)
996 default: 1005 default:
997 // Direct. Discard leading bytes. 1006 // Direct. Discard leading bytes.
998 scalar = v.scalar >> (offset * 8) 1007 scalar = v.scalar >> (offset * 8)
999 } 1008 }
1000 return Value{typ, val, scalar, fl} 1009 return Value{typ, val, scalar, fl}
1001 1010
1002 case Slice: 1011 case Slice:
1003 // Element flag same as Elem of Ptr. 1012 // Element flag same as Elem of Ptr.
1004 // Addressable, indirect, possibly read-only. 1013 // Addressable, indirect, possibly read-only.
1005 fl := flagAddr | flagIndir | v.flag&flagRO 1014 fl := flagAddr | flagIndir | v.flag&flagRO
1006 s := (*sliceHeader)(v.ptr) 1015 s := (*sliceHeader)(v.ptr)
1007 if i < 0 || i >= s.Len { 1016 if i < 0 || i >= s.Len {
1008 panic("reflect: slice index out of range") 1017 panic("reflect: slice index out of range")
1009 } 1018 }
1010 tt := (*sliceType)(unsafe.Pointer(v.typ)) 1019 tt := (*sliceType)(unsafe.Pointer(v.typ))
1011 typ := tt.elem 1020 typ := tt.elem
1012 fl |= flag(typ.Kind()) << flagKindShift 1021 fl |= flag(typ.Kind()) << flagKindShift
1013 val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size) 1022 val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size)
1014 return Value{typ, val, 0, fl} 1023 return Value{typ, val, 0, fl}
1015 1024
1016 case String: 1025 case String:
1017 » » fl := v.flag&flagRO | flag(Uint8<<flagKindShift) 1026 » » fl := v.flag&flagRO | flag(Uint8<<flagKindShift) | flagIndir
1018 s := (*stringHeader)(v.ptr) 1027 s := (*stringHeader)(v.ptr)
1019 if i < 0 || i >= s.Len { 1028 if i < 0 || i >= s.Len {
1020 panic("reflect: string index out of range") 1029 panic("reflect: string index out of range")
1021 } 1030 }
1022 » » b := uintptr(0) 1031 » » p := unsafe.Pointer(uintptr(s.Data) + uintptr(i))
1023 » » *(*byte)(unsafe.Pointer(&b)) = *(*byte)(unsafe.Pointer(uintptr(s .Data) + uintptr(i))) 1032 » » return Value{uint8Type, p, 0, fl}
1024 » » return Value{uint8Type, nil, b, fl}
1025 } 1033 }
1026 panic(&ValueError{"reflect.Value.Index", k}) 1034 panic(&ValueError{"reflect.Value.Index", k})
1027 } 1035 }
1028 1036
1029 // Int returns v's underlying value, as an int64. 1037 // Int returns v's underlying value, as an int64.
1030 // It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64. 1038 // It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
1031 func (v Value) Int() int64 { 1039 func (v Value) Int() int64 {
1032 k := v.kind() 1040 k := v.kind()
1033 var p unsafe.Pointer 1041 var p unsafe.Pointer
1034 if v.flag&flagIndir != 0 { 1042 if v.flag&flagIndir != 0 {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 } else { 1210 } else {
1203 k = unsafe.Pointer(&key.scalar) 1211 k = unsafe.Pointer(&key.scalar)
1204 } 1212 }
1205 e := mapaccess(v.typ, v.pointer(), k) 1213 e := mapaccess(v.typ, v.pointer(), k)
1206 if e == nil { 1214 if e == nil {
1207 return Value{} 1215 return Value{}
1208 } 1216 }
1209 typ := tt.elem 1217 typ := tt.elem
1210 fl := (v.flag | key.flag) & flagRO 1218 fl := (v.flag | key.flag) & flagRO
1211 fl |= flag(typ.Kind()) << flagKindShift 1219 fl |= flag(typ.Kind()) << flagKindShift
1212 » if typ.size > ptrSize { 1220 » if !isDirectIface(typ) {
1213 // Copy result so future changes to the map 1221 // Copy result so future changes to the map
1214 // won't change the underlying value. 1222 // won't change the underlying value.
1215 c := unsafe_New(typ) 1223 c := unsafe_New(typ)
1216 memmove(c, e, typ.size) 1224 memmove(c, e, typ.size)
1217 return Value{typ, c, 0, fl | flagIndir} 1225 return Value{typ, c, 0, fl | flagIndir}
1218 } else if typ.pointers() { 1226 } else if typ.pointers() {
1219 return Value{typ, *(*unsafe.Pointer)(e), 0, fl} 1227 return Value{typ, *(*unsafe.Pointer)(e), 0, fl}
1220 } else { 1228 } else {
1221 return Value{typ, nil, loadScalar(e, typ.size), fl} 1229 return Value{typ, nil, loadScalar(e, typ.size), fl}
1222 } 1230 }
(...skipping 19 matching lines...) Expand all
1242 a := make([]Value, mlen) 1250 a := make([]Value, mlen)
1243 var i int 1251 var i int
1244 for i = 0; i < len(a); i++ { 1252 for i = 0; i < len(a); i++ {
1245 key := mapiterkey(it) 1253 key := mapiterkey(it)
1246 if key == nil { 1254 if key == nil {
1247 // Someone deleted an entry from the map since we 1255 // Someone deleted an entry from the map since we
1248 // called maplen above. It's a data race, but nothing 1256 // called maplen above. It's a data race, but nothing
1249 // we can do about it. 1257 // we can do about it.
1250 break 1258 break
1251 } 1259 }
1252 » » if keyType.size > ptrSize { 1260 » » if !isDirectIface(keyType) {
1253 // Copy result so future changes to the map 1261 // Copy result so future changes to the map
1254 // won't change the underlying value. 1262 // won't change the underlying value.
1255 c := unsafe_New(keyType) 1263 c := unsafe_New(keyType)
1256 memmove(c, key, keyType.size) 1264 memmove(c, key, keyType.size)
1257 a[i] = Value{keyType, c, 0, fl | flagIndir} 1265 a[i] = Value{keyType, c, 0, fl | flagIndir}
1258 } else if keyType.pointers() { 1266 } else if keyType.pointers() {
1259 a[i] = Value{keyType, *(*unsafe.Pointer)(key), 0, fl} 1267 a[i] = Value{keyType, *(*unsafe.Pointer)(key), 0, fl}
1260 } else { 1268 } else {
1261 a[i] = Value{keyType, nil, loadScalar(key, keyType.size) , fl} 1269 a[i] = Value{keyType, nil, loadScalar(key, keyType.size) , fl}
1262 } 1270 }
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 // internal recv, possibly non-blocking (nb). 1449 // internal recv, possibly non-blocking (nb).
1442 // v is known to be a channel. 1450 // v is known to be a channel.
1443 func (v Value) recv(nb bool) (val Value, ok bool) { 1451 func (v Value) recv(nb bool) (val Value, ok bool) {
1444 tt := (*chanType)(unsafe.Pointer(v.typ)) 1452 tt := (*chanType)(unsafe.Pointer(v.typ))
1445 if ChanDir(tt.dir)&RecvDir == 0 { 1453 if ChanDir(tt.dir)&RecvDir == 0 {
1446 panic("reflect: recv on send-only channel") 1454 panic("reflect: recv on send-only channel")
1447 } 1455 }
1448 t := tt.elem 1456 t := tt.elem
1449 val = Value{t, nil, 0, flag(t.Kind()) << flagKindShift} 1457 val = Value{t, nil, 0, flag(t.Kind()) << flagKindShift}
1450 var p unsafe.Pointer 1458 var p unsafe.Pointer
1451 » if t.size > ptrSize { 1459 » if !isDirectIface(t) {
1452 p = unsafe_New(t) 1460 p = unsafe_New(t)
1453 val.ptr = p 1461 val.ptr = p
1454 val.flag |= flagIndir 1462 val.flag |= flagIndir
1455 } else if t.pointers() { 1463 } else if t.pointers() {
1456 p = unsafe.Pointer(&val.ptr) 1464 p = unsafe.Pointer(&val.ptr)
1457 } else { 1465 } else {
1458 p = unsafe.Pointer(&val.scalar) 1466 p = unsafe.Pointer(&val.scalar)
1459 } 1467 }
1460 selected, ok := chanrecv(v.typ, v.pointer(), nb, p) 1468 selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
1461 if !selected { 1469 if !selected {
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 rc.val = unsafe_New(tt.elem) 2191 rc.val = unsafe_New(tt.elem)
2184 } 2192 }
2185 } 2193 }
2186 2194
2187 chosen, recvOK = rselect(runcases) 2195 chosen, recvOK = rselect(runcases)
2188 if runcases[chosen].dir == uintptr(SelectRecv) { 2196 if runcases[chosen].dir == uintptr(SelectRecv) {
2189 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ)) 2197 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
2190 t := tt.elem 2198 t := tt.elem
2191 p := runcases[chosen].val 2199 p := runcases[chosen].val
2192 fl := flag(t.Kind()) << flagKindShift 2200 fl := flag(t.Kind()) << flagKindShift
2193 » » if t.size > ptrSize { 2201 » » if !isDirectIface(t) {
2194 recv = Value{t, p, 0, fl | flagIndir} 2202 recv = Value{t, p, 0, fl | flagIndir}
2195 } else if t.pointers() { 2203 } else if t.pointers() {
2196 recv = Value{t, *(*unsafe.Pointer)(p), 0, fl} 2204 recv = Value{t, *(*unsafe.Pointer)(p), 0, fl}
2197 } else { 2205 } else {
2198 recv = Value{t, nil, loadScalar(p, t.size), fl} 2206 recv = Value{t, nil, loadScalar(p, t.size), fl}
2199 } 2207 }
2200 } 2208 }
2201 return chosen, recv, recvOK 2209 return chosen, recv, recvOK
2202 } 2210 }
2203 2211
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 // The result is different from the zero value of the Value struct, 2292 // The result is different from the zero value of the Value struct,
2285 // which represents no value at all. 2293 // which represents no value at all.
2286 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. 2294 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
2287 // The returned value is neither addressable nor settable. 2295 // The returned value is neither addressable nor settable.
2288 func Zero(typ Type) Value { 2296 func Zero(typ Type) Value {
2289 if typ == nil { 2297 if typ == nil {
2290 panic("reflect: Zero(nil)") 2298 panic("reflect: Zero(nil)")
2291 } 2299 }
2292 t := typ.common() 2300 t := typ.common()
2293 fl := flag(t.Kind()) << flagKindShift 2301 fl := flag(t.Kind()) << flagKindShift
2294 » if t.size <= ptrSize { 2302 » if isDirectIface(t) {
2295 return Value{t, nil, 0, fl} 2303 return Value{t, nil, 0, fl}
2296 } 2304 }
2297 return Value{t, unsafe_New(typ.(*rtype)), 0, fl | flagIndir} 2305 return Value{t, unsafe_New(typ.(*rtype)), 0, fl | flagIndir}
2298 } 2306 }
2299 2307
2300 // New returns a Value representing a pointer to a new zero value 2308 // New returns a Value representing a pointer to a new zero value
2301 // for the specified type. That is, the returned Value's Type is PtrTo(typ). 2309 // for the specified type. That is, the returned Value's Type is PtrTo(typ).
2302 func New(typ Type) Value { 2310 func New(typ Type) Value {
2303 if typ == nil { 2311 if typ == nil {
2304 panic("reflect: New(nil)") 2312 panic("reflect: New(nil)")
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2443 return cvtT2I 2451 return cvtT2I
2444 } 2452 }
2445 2453
2446 return nil 2454 return nil
2447 } 2455 }
2448 2456
2449 // makeInt returns a Value of type t equal to bits (possibly truncated), 2457 // makeInt returns a Value of type t equal to bits (possibly truncated),
2450 // where t is a signed or unsigned int type. 2458 // where t is a signed or unsigned int type.
2451 func makeInt(f flag, bits uint64, t Type) Value { 2459 func makeInt(f flag, bits uint64, t Type) Value {
2452 typ := t.common() 2460 typ := t.common()
2453 » if typ.size > ptrSize { 2461 » if !isDirectIface(typ) {
2454 » » // Assume ptrSize >= 4, so this must be uint64.
2455 ptr := unsafe_New(typ) 2462 ptr := unsafe_New(typ)
2456 » » *(*uint64)(unsafe.Pointer(ptr)) = bits 2463 » » switch typ.size {
2464 » » case 1:
2465 » » » *(*uint8)(unsafe.Pointer(ptr)) = uint8(bits)
2466 » » case 2:
2467 » » » *(*uint16)(unsafe.Pointer(ptr)) = uint16(bits)
2468 » » case 4:
2469 » » » *(*uint32)(unsafe.Pointer(ptr)) = uint32(bits)
2470 » » case 8:
2471 » » » *(*uint64)(unsafe.Pointer(ptr)) = bits
2472 » » }
2457 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift} 2473 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift}
2458 } 2474 }
2459 var s uintptr 2475 var s uintptr
2460 switch typ.size { 2476 switch typ.size {
2461 case 1: 2477 case 1:
2462 *(*uint8)(unsafe.Pointer(&s)) = uint8(bits) 2478 *(*uint8)(unsafe.Pointer(&s)) = uint8(bits)
2463 case 2: 2479 case 2:
2464 *(*uint16)(unsafe.Pointer(&s)) = uint16(bits) 2480 *(*uint16)(unsafe.Pointer(&s)) = uint16(bits)
2465 case 4: 2481 case 4:
2466 *(*uint32)(unsafe.Pointer(&s)) = uint32(bits) 2482 *(*uint32)(unsafe.Pointer(&s)) = uint32(bits)
2467 case 8: 2483 case 8:
2468 *(*uint64)(unsafe.Pointer(&s)) = uint64(bits) 2484 *(*uint64)(unsafe.Pointer(&s)) = uint64(bits)
2469 } 2485 }
2470 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift} 2486 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
2471 } 2487 }
2472 2488
2473 // makeFloat returns a Value of type t equal to v (possibly truncated to float32 ), 2489 // makeFloat returns a Value of type t equal to v (possibly truncated to float32 ),
2474 // where t is a float32 or float64 type. 2490 // where t is a float32 or float64 type.
2475 func makeFloat(f flag, v float64, t Type) Value { 2491 func makeFloat(f flag, v float64, t Type) Value {
2476 typ := t.common() 2492 typ := t.common()
2477 » if typ.size > ptrSize { 2493 » if !isDirectIface(typ) {
2478 » » // Assume ptrSize >= 4, so this must be float64.
2479 ptr := unsafe_New(typ) 2494 ptr := unsafe_New(typ)
2480 » » *(*float64)(unsafe.Pointer(ptr)) = v 2495 » » switch typ.size {
2496 » » case 4:
2497 » » » *(*float32)(unsafe.Pointer(ptr)) = float32(v)
2498 » » case 8:
2499 » » » *(*float64)(unsafe.Pointer(ptr)) = v
2500 » » }
2481 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift} 2501 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift}
2482 } 2502 }
2483 2503
2484 var s uintptr 2504 var s uintptr
2485 switch typ.size { 2505 switch typ.size {
2486 case 4: 2506 case 4:
2487 *(*float32)(unsafe.Pointer(&s)) = float32(v) 2507 *(*float32)(unsafe.Pointer(&s)) = float32(v)
2488 case 8: 2508 case 8:
2489 *(*float64)(unsafe.Pointer(&s)) = v 2509 *(*float64)(unsafe.Pointer(&s)) = v
2490 } 2510 }
2491 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift} 2511 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
2492 } 2512 }
2493 2513
2494 // makeComplex returns a Value of type t equal to v (possibly truncated to compl ex64), 2514 // makeComplex returns a Value of type t equal to v (possibly truncated to compl ex64),
2495 // where t is a complex64 or complex128 type. 2515 // where t is a complex64 or complex128 type.
2496 func makeComplex(f flag, v complex128, t Type) Value { 2516 func makeComplex(f flag, v complex128, t Type) Value {
2497 typ := t.common() 2517 typ := t.common()
2498 » if typ.size > ptrSize { 2518 » if !isDirectIface(typ) {
2499 ptr := unsafe_New(typ) 2519 ptr := unsafe_New(typ)
2500 switch typ.size { 2520 switch typ.size {
2501 case 8: 2521 case 8:
2502 *(*complex64)(unsafe.Pointer(ptr)) = complex64(v) 2522 *(*complex64)(unsafe.Pointer(ptr)) = complex64(v)
2503 case 16: 2523 case 16:
2504 *(*complex128)(unsafe.Pointer(ptr)) = v 2524 *(*complex128)(unsafe.Pointer(ptr)) = v
2505 } 2525 }
2506 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift} 2526 return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flag KindShift}
2507 } 2527 }
2508 2528
2509 // Assume ptrSize <= 8 so this must be complex64.
2510 var s uintptr 2529 var s uintptr
2511 » *(*complex64)(unsafe.Pointer(&s)) = complex64(v) 2530 » switch typ.size {
2531 » case 8:
2532 » » *(*complex64)(unsafe.Pointer(&s)) = complex64(v)
2533 » case 16:
2534 » » *(*complex128)(unsafe.Pointer(&s)) = v
2535 » }
2512 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift} 2536 return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
2513 } 2537 }
2514 2538
2515 func makeString(f flag, v string, t Type) Value { 2539 func makeString(f flag, v string, t Type) Value {
2516 ret := New(t).Elem() 2540 ret := New(t).Elem()
2517 ret.SetString(v) 2541 ret.SetString(v)
2518 ret.flag = ret.flag&^flagAddr | f 2542 ret.flag = ret.flag&^flagAddr | f
2519 return ret 2543 return ret
2520 } 2544 }
2521 2545
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 func escapes(x interface{}) { 2699 func escapes(x interface{}) {
2676 if dummy.b { 2700 if dummy.b {
2677 dummy.x = x 2701 dummy.x = x
2678 } 2702 }
2679 } 2703 }
2680 2704
2681 var dummy struct { 2705 var dummy struct {
2682 b bool 2706 b bool
2683 x interface{} 2707 x interface{}
2684 } 2708 }
OLDNEW
« no previous file with comments | « src/pkg/reflect/type.go ('k') | src/pkg/runtime/alg.go » ('j') | no next file with comments »

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