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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 *(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w)) | 200 *(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w)) |
201 case 7: | 201 case 7: |
202 *(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w)) | 202 *(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w)) |
203 case 8: | 203 case 8: |
204 *(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w)) | 204 *(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w)) |
205 } | 205 } |
206 } | 206 } |
207 | 207 |
208 // emptyInterface is the header for an interface{} value. | 208 // emptyInterface is the header for an interface{} value. |
209 type emptyInterface struct { | 209 type emptyInterface struct { |
210 » typ *runtime.Type | 210 » typ *runtimeType |
211 word iword | 211 word iword |
212 } | 212 } |
213 | 213 |
214 // nonEmptyInterface is the header for a interface value with methods. | 214 // nonEmptyInterface is the header for a interface value with methods. |
215 type nonEmptyInterface struct { | 215 type nonEmptyInterface struct { |
216 // see ../runtime/iface.c:/Itab | 216 // see ../runtime/iface.c:/Itab |
217 itab *struct { | 217 itab *struct { |
218 » » ityp *runtime.Type // static interface type | 218 » » ityp *runtimeType // static interface type |
219 » » typ *runtime.Type // dynamic concrete type | 219 » » typ *runtimeType // dynamic concrete type |
220 link unsafe.Pointer | 220 link unsafe.Pointer |
221 bad int32 | 221 bad int32 |
222 unused int32 | 222 unused int32 |
223 fun [100000]unsafe.Pointer // method table | 223 fun [100000]unsafe.Pointer // method table |
224 } | 224 } |
225 word iword | 225 word iword |
226 } | 226 } |
227 | 227 |
228 // mustBe panics if f's kind is not expected. | 228 // mustBe panics if f's kind is not expected. |
229 // Making this a method on flag instead of on Value | 229 // Making this a method on flag instead of on Value |
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 sa = unsafe.Pointer((*SliceHeader)(src.val).Data) | 1599 sa = unsafe.Pointer((*SliceHeader)(src.val).Data) |
1600 } | 1600 } |
1601 memmove(da, sa, uintptr(n)*de.Size()) | 1601 memmove(da, sa, uintptr(n)*de.Size()) |
1602 return n | 1602 return n |
1603 } | 1603 } |
1604 | 1604 |
1605 /* | 1605 /* |
1606 * constructors | 1606 * constructors |
1607 */ | 1607 */ |
1608 | 1608 |
| 1609 // implemented in package runtime |
| 1610 func unsafe_New(Type) unsafe.Pointer |
| 1611 func unsafe_NewArray(Type, int) unsafe.Pointer |
| 1612 |
1609 // MakeSlice creates a new zero-initialized slice value | 1613 // MakeSlice creates a new zero-initialized slice value |
1610 // for the specified slice type, length, and capacity. | 1614 // for the specified slice type, length, and capacity. |
1611 func MakeSlice(typ Type, len, cap int) Value { | 1615 func MakeSlice(typ Type, len, cap int) Value { |
1612 if typ.Kind() != Slice { | 1616 if typ.Kind() != Slice { |
1613 panic("reflect.MakeSlice of non-slice type") | 1617 panic("reflect.MakeSlice of non-slice type") |
1614 } | 1618 } |
1615 | 1619 |
1616 // Declare slice so that gc can see the base pointer in it. | 1620 // Declare slice so that gc can see the base pointer in it. |
1617 var x []byte | 1621 var x []byte |
1618 | 1622 |
1619 // Reinterpret as *SliceHeader to edit. | 1623 // Reinterpret as *SliceHeader to edit. |
1620 s := (*SliceHeader)(unsafe.Pointer(&x)) | 1624 s := (*SliceHeader)(unsafe.Pointer(&x)) |
1621 » s.Data = uintptr(unsafe.NewArray(typ.Elem(), cap)) | 1625 » s.Data = uintptr(unsafe_NewArray(typ.Elem(), cap)) |
1622 s.Len = len | 1626 s.Len = len |
1623 s.Cap = cap | 1627 s.Cap = cap |
1624 | 1628 |
1625 return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<<
flagKindShift} | 1629 return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<<
flagKindShift} |
1626 } | 1630 } |
1627 | 1631 |
1628 // MakeChan creates a new channel with the specified type and buffer size. | 1632 // MakeChan creates a new channel with the specified type and buffer size. |
1629 func MakeChan(typ Type, buffer int) Value { | 1633 func MakeChan(typ Type, buffer int) Value { |
1630 if typ.Kind() != Chan { | 1634 if typ.Kind() != Chan { |
1631 panic("reflect.MakeChan of non-chan type") | 1635 panic("reflect.MakeChan of non-chan type") |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. | 1694 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. |
1691 func Zero(typ Type) Value { | 1695 func Zero(typ Type) Value { |
1692 if typ == nil { | 1696 if typ == nil { |
1693 panic("reflect: Zero(nil)") | 1697 panic("reflect: Zero(nil)") |
1694 } | 1698 } |
1695 t := typ.common() | 1699 t := typ.common() |
1696 fl := flag(t.Kind()) << flagKindShift | 1700 fl := flag(t.Kind()) << flagKindShift |
1697 if t.size <= ptrSize { | 1701 if t.size <= ptrSize { |
1698 return Value{t, nil, fl} | 1702 return Value{t, nil, fl} |
1699 } | 1703 } |
1700 » return Value{t, unsafe.New(typ), fl | flagIndir} | 1704 » return Value{t, unsafe_New(typ), fl | flagIndir} |
1701 } | 1705 } |
1702 | 1706 |
1703 // New returns a Value representing a pointer to a new zero value | 1707 // New returns a Value representing a pointer to a new zero value |
1704 // for the specified type. That is, the returned Value's Type is PtrTo(t). | 1708 // for the specified type. That is, the returned Value's Type is PtrTo(t). |
1705 func New(typ Type) Value { | 1709 func New(typ Type) Value { |
1706 if typ == nil { | 1710 if typ == nil { |
1707 panic("reflect: New(nil)") | 1711 panic("reflect: New(nil)") |
1708 } | 1712 } |
1709 » ptr := unsafe.New(typ) | 1713 » ptr := unsafe_New(typ) |
1710 fl := flag(Ptr) << flagKindShift | 1714 fl := flag(Ptr) << flagKindShift |
1711 return Value{typ.common().ptrTo(), ptr, fl} | 1715 return Value{typ.common().ptrTo(), ptr, fl} |
1712 } | 1716 } |
1713 | 1717 |
| 1718 // NewAt returns a Value representing a pointer to a value of the |
| 1719 // specified type, using p as that pointer. |
| 1720 func NewAt(typ Type, p unsafe.Pointer) Value { |
| 1721 fl := flag(Ptr) << flagKindShift |
| 1722 return Value{typ.common().ptrTo(), p, fl} |
| 1723 } |
| 1724 |
1714 // assignTo returns a value v that can be assigned directly to typ. | 1725 // assignTo returns a value v that can be assigned directly to typ. |
1715 // It panics if v is not assignable to typ. | 1726 // It panics if v is not assignable to typ. |
1716 // For a conversion to an interface type, target is a suggested scratch space to
use. | 1727 // For a conversion to an interface type, target is a suggested scratch space to
use. |
1717 func (v Value) assignTo(context string, dst *commonType, target *interface{}) Va
lue { | 1728 func (v Value) assignTo(context string, dst *commonType, target *interface{}) Va
lue { |
1718 if v.flag&flagMethod != 0 { | 1729 if v.flag&flagMethod != 0 { |
1719 panic(context + ": cannot assign method value to type " + dst.St
ring()) | 1730 panic(context + ": cannot assign method value to type " + dst.St
ring()) |
1720 } | 1731 } |
1721 | 1732 |
1722 switch { | 1733 switch { |
1723 case directlyAssignable(dst, v.typ): | 1734 case directlyAssignable(dst, v.typ): |
(...skipping 18 matching lines...) Expand all Loading... |
1742 } | 1753 } |
1743 | 1754 |
1744 // Failed. | 1755 // Failed. |
1745 panic(context + ": value of type " + v.typ.String() + " is not assignabl
e to type " + dst.String()) | 1756 panic(context + ": value of type " + v.typ.String() + " is not assignabl
e to type " + dst.String()) |
1746 } | 1757 } |
1747 | 1758 |
1748 // implemented in ../pkg/runtime | 1759 // implemented in ../pkg/runtime |
1749 func chancap(ch iword) int32 | 1760 func chancap(ch iword) int32 |
1750 func chanclose(ch iword) | 1761 func chanclose(ch iword) |
1751 func chanlen(ch iword) int32 | 1762 func chanlen(ch iword) int32 |
1752 func chanrecv(t *runtime.Type, ch iword, nb bool) (val iword, selected, received
bool) | 1763 func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received
bool) |
1753 func chansend(t *runtime.Type, ch iword, val iword, nb bool) bool | 1764 func chansend(t *runtimeType, ch iword, val iword, nb bool) bool |
1754 | 1765 |
1755 func makechan(typ *runtime.Type, size uint32) (ch iword) | 1766 func makechan(typ *runtimeType, size uint32) (ch iword) |
1756 func makemap(t *runtime.Type) (m iword) | 1767 func makemap(t *runtimeType) (m iword) |
1757 func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool) | 1768 func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool) |
1758 func mapassign(t *runtime.Type, m iword, key, val iword, ok bool) | 1769 func mapassign(t *runtimeType, m iword, key, val iword, ok bool) |
1759 func mapiterinit(t *runtime.Type, m iword) *byte | 1770 func mapiterinit(t *runtimeType, m iword) *byte |
1760 func mapiterkey(it *byte) (key iword, ok bool) | 1771 func mapiterkey(it *byte) (key iword, ok bool) |
1761 func mapiternext(it *byte) | 1772 func mapiternext(it *byte) |
1762 func maplen(m iword) int32 | 1773 func maplen(m iword) int32 |
1763 | 1774 |
1764 func call(fn, arg unsafe.Pointer, n uint32) | 1775 func call(fn, arg unsafe.Pointer, n uint32) |
1765 func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer) | 1776 func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer) |
1766 | 1777 |
1767 // Dummy annotation marking that the value x escapes, | 1778 // Dummy annotation marking that the value x escapes, |
1768 // for use in cases where the reflect code is so clever that | 1779 // for use in cases where the reflect code is so clever that |
1769 // the compiler cannot follow. | 1780 // the compiler cannot follow. |
1770 func escapes(x interface{}) { | 1781 func escapes(x interface{}) { |
1771 if dummy.b { | 1782 if dummy.b { |
1772 dummy.x = x | 1783 dummy.x = x |
1773 } | 1784 } |
1774 } | 1785 } |
1775 | 1786 |
1776 var dummy struct { | 1787 var dummy struct { |
1777 b bool | 1788 b bool |
1778 x interface{} | 1789 x interface{} |
1779 } | 1790 } |
OLD | NEW |