o.mapAssign(n)
o.cleanTemp(t)
- // Special: make sure key is addressable if needed,
- // and make sure OINDEXMAP is not copied out.
- case OAS2MAPR:
- t := o.markTemp()
- o.exprList(n.List)
- r := n.Right
- r.Left = o.expr(r.Left, nil)
- r.Right = o.expr(r.Right, nil)
-
- // See similar conversion for OINDEXMAP below.
- _ = mapKeyReplaceStrConv(r.Right)
-
- r.Right = o.mapKeyTemp(r.Left.Type, r.Right)
- o.okAs2(n)
- o.cleanTemp(t)
-
- // Special: avoid copy of func call n.Rlist.First().
+ // Special: avoid copy of func call n.Right
case OAS2FUNC:
t := o.markTemp()
o.exprList(n.List)
o.cleanTemp(t)
// Special: use temporary variables to hold result,
- // so that assertI2Tetc can take address of temporary.
+ // so that runtime can take address of temporary.
// No temporary for blank assignment.
- case OAS2DOTTYPE:
+ //
+ // OAS2MAPR: make sure key is addressable if needed,
+ // and make sure OINDEXMAP is not copied out.
+ case OAS2DOTTYPE, OAS2RECV, OAS2MAPR:
t := o.markTemp()
o.exprList(n.List)
- n.Right.Left = o.expr(n.Right.Left, nil) // i in i.(T)
- o.okAs2(n)
- o.cleanTemp(t)
- // Special: use temporary variables to hold result,
- // so that chanrecv can take address of temporary.
- case OAS2RECV:
- t := o.markTemp()
- o.exprList(n.List)
- n.Right.Left = o.expr(n.Right.Left, nil) // arg to recv
- ch := n.Right.Left.Type
- tmp1 := o.newTemp(ch.Elem(), types.Haspointers(ch.Elem()))
- tmp2 := o.newTemp(types.Types[TBOOL], false)
- o.out = append(o.out, n)
- r := nod(OAS, n.List.First(), tmp1)
- r = typecheck(r, ctxStmt)
- o.mapAssign(r)
- r = okas(n.List.Second(), tmp2)
- r = typecheck(r, ctxStmt)
- o.mapAssign(r)
- n.List.Set2(tmp1, tmp2)
+ switch r := n.Right; r.Op {
+ case ODOTTYPE2, ORECV:
+ r.Left = o.expr(r.Left, nil)
+ case OINDEXMAP:
+ r.Left = o.expr(r.Left, nil)
+ r.Right = o.expr(r.Right, nil)
+ // See similar conversion for OINDEXMAP below.
+ _ = mapKeyReplaceStrConv(r.Right)
+ r.Right = o.mapKeyTemp(r.Left.Type, r.Right)
+ default:
+ Fatalf("order.stmt: %v", r.Op)
+ }
+
+ o.okAs2(n)
o.cleanTemp(t)
// Special: does not save n onto out.
}
// as2 orders OAS2XXXX nodes. It creates temporaries to ensure left-to-right assignment.
-// The caller should order the right-hand side of the assignment before calling orderas2.
+// The caller should order the right-hand side of the assignment before calling order.as2.
// It rewrites,
// a, b, a = ...
// as
o.stmt(as)
}
-// okAs2 orders OAS2 with ok.
+// okAs2 orders OAS2XXX with ok.
// Just like as2, this also adds temporaries to ensure left-to-right assignment.
func (o *Order) okAs2(n *Node) {
var tmp1, tmp2 *Node
n = liststmt(ll)
// x, y = <-c
- // orderstmt made sure x is addressable.
+ // order.stmt made sure x is addressable or blank.
case OAS2RECV:
init.AppendNodes(&n.Ninit)
}
fn := chanfn("chanrecv2", 2, r.Left.Type)
ok := n.List.Second()
- call := mkcall1(fn, ok.Type, init, r.Left, n1)
+ call := mkcall1(fn, types.Types[TBOOL], init, r.Left, n1)
n = nod(OAS, ok, call)
n = typecheck(n, ctxStmt)