LEFT | RIGHT |
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 1603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 } else { | 1614 } else { |
1615 sa = unsafe.Pointer((*SliceHeader)(src.val).Data) | 1615 sa = unsafe.Pointer((*SliceHeader)(src.val).Data) |
1616 } | 1616 } |
1617 memmove(da, sa, uintptr(n)*de.Size()) | 1617 memmove(da, sa, uintptr(n)*de.Size()) |
1618 return n | 1618 return n |
1619 } | 1619 } |
1620 | 1620 |
1621 // A runtimeSelect is a single case passed to rselect. | 1621 // A runtimeSelect is a single case passed to rselect. |
1622 // This must match ../runtime/chan.c:/runtimeSelect | 1622 // This must match ../runtime/chan.c:/runtimeSelect |
1623 type runtimeSelect struct { | 1623 type runtimeSelect struct { |
1624 » dir uintptr // 0, SendDir, or RecvDir | 1624 » dir uintptr // 0, SendDir, or RecvDir |
1625 » typ *chanType // channel type | 1625 » typ *runtimeType // channel type |
1626 » ch iword // interface word for channel | 1626 » ch iword // interface word for channel |
1627 » val iword // interface word for value (for SendDir) | 1627 » val iword // interface word for value (for SendDir) |
1628 } | 1628 } |
1629 | 1629 |
1630 // rselect runs a select. It returns the index of the chosen case, | 1630 // rselect runs a select. It returns the index of the chosen case, |
1631 // and if the case was a receive, the interface word of the received | 1631 // and if the case was a receive, the interface word of the received |
1632 // value and the conventional OK bool to indicate whether the receive | 1632 // value and the conventional OK bool to indicate whether the receive |
1633 // corresponds to a sent value. | 1633 // corresponds to a sent value. |
1634 func rselect([]runtimeSelect) (chosen int, recv iword, recvOK bool) | 1634 func rselect([]runtimeSelect) (chosen int, recv iword, recvOK bool) |
1635 | 1635 |
1636 // A SelectDir describes the communication direction of a select case. | 1636 // A SelectDir describes the communication direction of a select case. |
1637 type SelectDir int | 1637 type SelectDir int |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 } | 1697 } |
1698 if c.Send.IsValid() { | 1698 if c.Send.IsValid() { |
1699 panic("reflect.Select: default case has Send val
ue") | 1699 panic("reflect.Select: default case has Send val
ue") |
1700 } | 1700 } |
1701 | 1701 |
1702 case SelectSend: | 1702 case SelectSend: |
1703 ch := c.Chan | 1703 ch := c.Chan |
1704 if !ch.IsValid() { | 1704 if !ch.IsValid() { |
1705 break | 1705 break |
1706 } | 1706 } |
| 1707 ch.mustBe(Chan) |
1707 ch.mustBeExported() | 1708 ch.mustBeExported() |
1708 tt := (*chanType)(unsafe.Pointer(ch.typ)) | 1709 tt := (*chanType)(unsafe.Pointer(ch.typ)) |
1709 if ChanDir(tt.dir)&SendDir == 0 { | 1710 if ChanDir(tt.dir)&SendDir == 0 { |
1710 panic("reflect.Select: SendDir case using recv-o
nly channel") | 1711 panic("reflect.Select: SendDir case using recv-o
nly channel") |
1711 } | 1712 } |
1712 rc.ch = ch.iword() | 1713 rc.ch = ch.iword() |
1713 » » » rc.typ = tt | 1714 » » » rc.typ = tt.runtimeType() |
1714 v := c.Send | 1715 v := c.Send |
1715 if !v.IsValid() { | 1716 if !v.IsValid() { |
1716 panic("reflect.Select: SendDir case missing Send
value") | 1717 panic("reflect.Select: SendDir case missing Send
value") |
1717 } | 1718 } |
1718 v.mustBeExported() | 1719 v.mustBeExported() |
1719 v = v.assignTo("reflect.Select", toCommonType(tt.elem),
nil) | 1720 v = v.assignTo("reflect.Select", toCommonType(tt.elem),
nil) |
1720 rc.val = v.iword() | 1721 rc.val = v.iword() |
1721 | 1722 |
1722 case SelectRecv: | 1723 case SelectRecv: |
1723 if c.Send.IsValid() { | 1724 if c.Send.IsValid() { |
1724 panic("reflect.Select: RecvDir case has Send val
ue") | 1725 panic("reflect.Select: RecvDir case has Send val
ue") |
1725 } | 1726 } |
1726 ch := c.Chan | 1727 ch := c.Chan |
1727 if !ch.IsValid() { | 1728 if !ch.IsValid() { |
1728 break | 1729 break |
1729 } | 1730 } |
| 1731 ch.mustBe(Chan) |
1730 ch.mustBeExported() | 1732 ch.mustBeExported() |
1731 tt := (*chanType)(unsafe.Pointer(ch.typ)) | 1733 tt := (*chanType)(unsafe.Pointer(ch.typ)) |
1732 » » » rc.typ = tt | 1734 » » » rc.typ = tt.runtimeType() |
1733 if ChanDir(tt.dir)&RecvDir == 0 { | 1735 if ChanDir(tt.dir)&RecvDir == 0 { |
1734 panic("reflect.Select: RecvDir case using send-o
nly channel") | 1736 panic("reflect.Select: RecvDir case using send-o
nly channel") |
1735 } | 1737 } |
1736 rc.ch = ch.iword() | 1738 rc.ch = ch.iword() |
1737 } | 1739 } |
1738 } | 1740 } |
1739 | 1741 |
1740 chosen, word, recvOK := rselect(runcases) | 1742 chosen, word, recvOK := rselect(runcases) |
1741 if runcases[chosen].dir == uintptr(SelectRecv) { | 1743 if runcases[chosen].dir == uintptr(SelectRecv) { |
1742 » » typ := toCommonType(runcases[chosen].typ.elem) | 1744 » » tt := (*chanType)(unsafe.Pointer(toCommonType(runcases[chosen].t
yp))) |
| 1745 » » typ := toCommonType(tt.elem) |
1743 fl := flag(typ.Kind()) << flagKindShift | 1746 fl := flag(typ.Kind()) << flagKindShift |
1744 if typ.size > ptrSize { | 1747 if typ.size > ptrSize { |
1745 fl |= flagIndir | 1748 fl |= flagIndir |
1746 } | 1749 } |
1747 recv = Value{typ, unsafe.Pointer(word), fl} | 1750 recv = Value{typ, unsafe.Pointer(word), fl} |
1748 } | 1751 } |
1749 return chosen, recv, recvOK | 1752 return chosen, recv, recvOK |
1750 } | 1753 } |
1751 | 1754 |
1752 /* | 1755 /* |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 func escapes(x interface{}) { | 1941 func escapes(x interface{}) { |
1939 if dummy.b { | 1942 if dummy.b { |
1940 dummy.x = x | 1943 dummy.x = x |
1941 } | 1944 } |
1942 } | 1945 } |
1943 | 1946 |
1944 var dummy struct { | 1947 var dummy struct { |
1945 b bool | 1948 b bool |
1946 x interface{} | 1949 x interface{} |
1947 } | 1950 } |
LEFT | RIGHT |