LEFT | RIGHT |
(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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 func packValue(flag uint32, typ *runtime.Type, word iword) Value { | 315 func packValue(flag uint32, typ *runtime.Type, word iword) Value { |
316 if typ == nil { | 316 if typ == nil { |
317 panic("packValue") | 317 panic("packValue") |
318 } | 318 } |
319 t := uintptr(unsafe.Pointer(typ)) | 319 t := uintptr(unsafe.Pointer(typ)) |
320 t |= uintptr(flag) | 320 t |= uintptr(flag) |
321 eface := emptyInterface{(*runtime.Type)(unsafe.Pointer(t)), word} | 321 eface := emptyInterface{(*runtime.Type)(unsafe.Pointer(t)), word} |
322 return Value{Internal: *(*interface{})(unsafe.Pointer(&eface))} | 322 return Value{Internal: *(*interface{})(unsafe.Pointer(&eface))} |
323 } | 323 } |
324 | 324 |
| 325 var dummy struct { |
| 326 b bool |
| 327 x interface{} |
| 328 } |
| 329 |
| 330 // Dummy annotation marking that the value x escapes, |
| 331 // for use in cases where the reflect code is so clever that |
| 332 // the compiler cannot follow. |
| 333 func escapes(x interface{}) { |
| 334 if dummy.b { |
| 335 dummy.x = x |
| 336 } |
| 337 } |
| 338 |
325 // valueFromAddr returns a Value using the given type and address. | 339 // valueFromAddr returns a Value using the given type and address. |
326 func valueFromAddr(flag uint32, typ Type, addr unsafe.Pointer) Value { | 340 func valueFromAddr(flag uint32, typ Type, addr unsafe.Pointer) Value { |
| 341 // TODO(rsc): Eliminate this terrible hack. |
| 342 // The escape analysis knows that addr is a pointer |
| 343 // but it doesn't see addr get passed to anything |
| 344 // that keeps it. packValue keeps it, but packValue |
| 345 // takes a uintptr (iword(addr)), and integers (non-pointers) |
| 346 // are assumed not to matter. The escapes function works |
| 347 // because return values always escape (for now). |
| 348 escapes(addr) |
| 349 |
327 if flag&flagAddr != 0 { | 350 if flag&flagAddr != 0 { |
328 // Addressable, so the internal value is | 351 // Addressable, so the internal value is |
329 // an interface containing a pointer to the real value. | 352 // an interface containing a pointer to the real value. |
330 return packValue(flag, PtrTo(typ).runtimeType(), iword(addr)) | 353 return packValue(flag, PtrTo(typ).runtimeType(), iword(addr)) |
331 } | 354 } |
332 | 355 |
333 var w iword | 356 var w iword |
334 if n := typ.Size(); n <= ptrSize { | 357 if n := typ.Size(); n <= ptrSize { |
335 // In line, so the interface word is the actual value. | 358 // In line, so the interface word is the actual value. |
336 w = loadIword(addr, n) | 359 w = loadIword(addr, n) |
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1671 } | 1694 } |
1672 return v.Elem() | 1695 return v.Elem() |
1673 } | 1696 } |
1674 | 1697 |
1675 // ValueOf returns a new Value initialized to the concrete value | 1698 // ValueOf returns a new Value initialized to the concrete value |
1676 // stored in the interface i. ValueOf(nil) returns the zero Value. | 1699 // stored in the interface i. ValueOf(nil) returns the zero Value. |
1677 func ValueOf(i interface{}) Value { | 1700 func ValueOf(i interface{}) Value { |
1678 if i == nil { | 1701 if i == nil { |
1679 return Value{} | 1702 return Value{} |
1680 } | 1703 } |
| 1704 |
| 1705 // TODO(rsc): Eliminate this terrible hack. |
| 1706 // In the call to packValue, eface.typ doesn't escape, |
| 1707 // and eface.word is an integer. So it looks like |
| 1708 // i (= eface) doesn't escape. But really it does, |
| 1709 // because eface.word is actually a pointer. |
| 1710 escapes(i) |
| 1711 |
1681 // For an interface value with the noAddr bit set, | 1712 // For an interface value with the noAddr bit set, |
1682 // the representation is identical to an empty interface. | 1713 // the representation is identical to an empty interface. |
1683 eface := *(*emptyInterface)(unsafe.Pointer(&i)) | 1714 eface := *(*emptyInterface)(unsafe.Pointer(&i)) |
1684 return packValue(0, eface.typ, eface.word) | 1715 return packValue(0, eface.typ, eface.word) |
1685 } | 1716 } |
1686 | 1717 |
1687 // Zero returns a Value representing a zero value for the specified type. | 1718 // Zero returns a Value representing a zero value for the specified type. |
1688 // The result is different from the zero value of the Value struct, | 1719 // The result is different from the zero value of the Value struct, |
1689 // which represents no value at all. | 1720 // which represents no value at all. |
1690 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. | 1721 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 func makemap(t *runtime.Type) iword | 1783 func makemap(t *runtime.Type) iword |
1753 func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool) | 1784 func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool) |
1754 func mapassign(t *runtime.Type, m iword, key, val iword, ok bool) | 1785 func mapassign(t *runtime.Type, m iword, key, val iword, ok bool) |
1755 func mapiterinit(t *runtime.Type, m iword) *byte | 1786 func mapiterinit(t *runtime.Type, m iword) *byte |
1756 func mapiterkey(it *byte) (key iword, ok bool) | 1787 func mapiterkey(it *byte) (key iword, ok bool) |
1757 func mapiternext(it *byte) | 1788 func mapiternext(it *byte) |
1758 func maplen(m iword) int32 | 1789 func maplen(m iword) int32 |
1759 | 1790 |
1760 func call(fn, arg unsafe.Pointer, n uint32) | 1791 func call(fn, arg unsafe.Pointer, n uint32) |
1761 func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer) | 1792 func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer) |
LEFT | RIGHT |