OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |