diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:44 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:44 +0200 |
| commit | 9464a0c36318f8a801c07d6874bd0cea40f12504 (patch) | |
| tree | f0178491c19d4f1ebc7b92eede86690998466480 /src/cmd/gc/select.c | |
| parent | ba9fda6068cfadd42db0b152fdca7e8b67aaf77d (diff) | |
| parent | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (diff) | |
| download | golang-9464a0c36318f8a801c07d6874bd0cea40f12504.tar.gz | |
Merge commit 'upstream/60' into debian-sid
Diffstat (limited to 'src/cmd/gc/select.c')
| -rw-r--r-- | src/cmd/gc/select.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c index 91d4ebfd5..909ad3aa4 100644 --- a/src/cmd/gc/select.c +++ b/src/cmd/gc/select.c @@ -108,6 +108,7 @@ walkselect(Node *sel) // optimization: one-case select: single op. if(i == 1) { cas = sel->list->n; + setlineno(cas); l = cas->ninit; if(cas->left != N) { // not default: n = cas->left; @@ -165,6 +166,7 @@ walkselect(Node *sel) // this rewrite is used by both the general code and the next optimization. for(l=sel->list; l; l=l->next) { cas = l->n; + setlineno(cas); n = cas->left; if(n == N) continue; @@ -238,6 +240,7 @@ walkselect(Node *sel) } n = cas->left; + setlineno(n); r = nod(OIF, N, N); r->ninit = cas->ninit; switch(n->op) { @@ -247,9 +250,8 @@ walkselect(Node *sel) case OSEND: // if c != nil && selectnbsend(c, v) { body } else { default body } ch = cheapexpr(n->left, &r->ninit); - r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), - mkcall1(chanfn("selectnbsend", 2, ch->type), - types[TBOOL], &r->ninit, ch, n->right)); + r->ntest = mkcall1(chanfn("selectnbsend", 2, ch->type), + types[TBOOL], &r->ninit, typename(ch->type), ch, n->right); break; case OSELRECV: @@ -257,9 +259,8 @@ walkselect(Node *sel) r = nod(OIF, N, N); r->ninit = cas->ninit; ch = cheapexpr(n->right->left, &r->ninit); - r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), - mkcall1(chanfn("selectnbrecv", 2, ch->type), - types[TBOOL], &r->ninit, n->left, ch)); + r->ntest = mkcall1(chanfn("selectnbrecv", 2, ch->type), + types[TBOOL], &r->ninit, typename(ch->type), n->left, ch); break; case OSELRECV2: @@ -267,9 +268,8 @@ walkselect(Node *sel) r = nod(OIF, N, N); r->ninit = cas->ninit; ch = cheapexpr(n->right->left, &r->ninit); - r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), - mkcall1(chanfn("selectnbrecv2", 2, ch->type), - types[TBOOL], &r->ninit, n->left, n->ntest, ch)); + r->ntest = mkcall1(chanfn("selectnbrecv2", 2, ch->type), + types[TBOOL], &r->ninit, typename(ch->type), n->left, n->ntest, ch); break; } typecheck(&r->ntest, Erv); @@ -283,6 +283,7 @@ walkselect(Node *sel) sel->ninit = nil; // generate sel-struct + setlineno(sel); var = nod(OXXX, N, N); tempname(var, ptrto(types[TUINT8])); r = nod(OAS, var, mkcall("newselect", var->type, nil, nodintconst(sel->xoffset))); @@ -292,6 +293,7 @@ walkselect(Node *sel) // register cases for(l=sel->list; l; l=l->next) { cas = l->n; + setlineno(cas); n = cas->left; r = nod(OIF, N, N); r->nbody = cas->ninit; @@ -309,7 +311,12 @@ walkselect(Node *sel) fatal("select %O", n->op); case OSEND: - // selectsend(sel *byte, hchan *chan any, elem any) (selected bool); + // selectsend(sel *byte, hchan *chan any, elem *any) (selected bool); + n->left = safeexpr(n->left, &r->ninit); + n->right = localexpr(n->right, n->left->type->type, &r->ninit); + n->right = nod(OADDR, n->right, N); + n->right->etype = 1; // pointer does not escape + typecheck(&n->right, Erv); r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL], &init, var, n->left, n->right); break; @@ -333,6 +340,7 @@ walkselect(Node *sel) } // run the select + setlineno(sel); init = list(init, mkcall("selectgo", T, nil, var)); sel->nbody = init; |
