Created
November 30, 2014 07:11
-
-
Save moriyoshi/c0e2b2f9be6883e33251 to your computer and use it in GitHub Desktop.
indexoperatoroverload.patch.diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r ffe33f1f1f17 src/cmd/gc/esc.c | |
--- a/src/cmd/gc/esc.c Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/esc.c Sun Nov 30 15:58:50 2014 +0900 | |
@@ -756,6 +756,12 @@ | |
escassign(e, &e->theSink, dst->right); | |
dst = &e->theSink; | |
break; | |
+ case OINDEXINTER: | |
+ // lose track of key and value | |
+ esc(e, dst->left, dst); | |
+ esc(e, dst->right, dst); | |
+ dst = &e->theSink; | |
+ break; | |
} | |
lno = setlineno(src); | |
@@ -1223,6 +1229,7 @@ | |
// fall through | |
case ODOTPTR: | |
case OINDEXMAP: | |
+ case OINDEXINTER: | |
case OIND: | |
newlevel = level; | |
if(level > MinLevel) | |
diff -r ffe33f1f1f17 src/cmd/gc/go.h | |
--- a/src/cmd/gc/go.h Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/go.h Sun Nov 30 15:58:50 2014 +0900 | |
@@ -505,6 +505,7 @@ | |
OIND, // *p | |
OINDEX, // a[i] | |
OINDEXMAP, // m[s] | |
+ OINDEXINTER, // m[s] where m is an opaque receiver | |
OKEY, // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc. | |
OPARAM, // The on-stack copy of a parameter or return value that escapes. | |
OLEN, // len | |
diff -r ffe33f1f1f17 src/cmd/gc/order.c | |
--- a/src/cmd/gc/order.c Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/order.c Sun Nov 30 15:58:50 2014 +0900 | |
@@ -169,6 +169,7 @@ | |
case OINDEX: | |
case OINDEXMAP: | |
+ case OINDEXINTER: | |
if(isfixedarray(n->left->type)) | |
l = ordersafeexpr(n->left, order); | |
else | |
@@ -455,7 +456,7 @@ | |
case OAS: | |
order->out = list(order->out, n); | |
// We call writebarrierfat only for values > 4 pointers long. See walk.c. | |
- if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) { | |
+ if(n->left->op != OINDEXINTER && (n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) { | |
m = n->left; | |
n->left = ordertemp(m->type, order, 0); | |
a = nod(OAS, m, n->left); | |
diff -r ffe33f1f1f17 src/cmd/gc/subr.c | |
--- a/src/cmd/gc/subr.c Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/subr.c Sun Nov 30 15:58:50 2014 +0900 | |
@@ -2051,6 +2051,7 @@ | |
case OINDEX: | |
case OINDEXMAP: | |
+ case OINDEXINTER: | |
l = safeexpr(n->left, init); | |
r = safeexpr(n->right, init); | |
if(l == n->left && r == n->right) | |
diff -r ffe33f1f1f17 src/cmd/gc/typecheck.c | |
--- a/src/cmd/gc/typecheck.c Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/typecheck.c Sun Nov 30 15:58:50 2014 +0900 | |
@@ -916,6 +916,14 @@ | |
n->type = t->type; | |
n->op = OINDEXMAP; | |
break; | |
+ | |
+ case TPTR32: | |
+ case TPTR64: | |
+ case TSTRUCT: | |
+ case TINTER: | |
+ n->etype = 0; | |
+ n->op = OINDEXINTER; | |
+ break; | |
} | |
goto ret; | |
@@ -2798,7 +2806,7 @@ | |
{ | |
if(islvalue(n)) | |
return; | |
- if(n->op == OINDEXMAP) { | |
+ if(n->op == OINDEXMAP || n->op == OINDEXINTER) { | |
n->etype = 1; | |
return; | |
} | |
@@ -2885,7 +2893,7 @@ | |
// Recognize slices being updated in place, for better code generation later. | |
// Don't rewrite if using race detector, to avoid needing to teach race detector | |
// about this optimization. | |
- if(n->left && n->left->op != OINDEXMAP && n->right && !flag_race) { | |
+ if(n->left && n->left->op != OINDEXMAP && n->left->op != OINDEXINTER && n->right && !flag_race) { | |
switch(n->right->op) { | |
case OSLICE: | |
case OSLICE3: | |
@@ -2958,13 +2966,18 @@ | |
r = n->rlist->n; | |
// m[i] = x, ok | |
- if(cl == 1 && cr == 2 && l->op == OINDEXMAP) { | |
+ if(cl == 1 && cr == 2 && (l->op == OINDEXMAP || l->op == OINDEXINTER)) { | |
if(l->type == T) | |
goto out; | |
yyerror("assignment count mismatch: %d = %d (use delete)", cl, cr); | |
goto out; | |
} | |
+ if(cl == 2 && cr == 1 && r->op == OINDEXINTER) { | |
+ // We need to assert this later | |
+ goto out; | |
+ } | |
+ | |
// x,y,z = f() | |
if(cr == 1) { | |
if(r->type == T) | |
@@ -3420,7 +3433,7 @@ | |
defaultlit(&n, types[TINT]); | |
return 0; | |
default: | |
- break; | |
+ break; | |
} | |
} | |
diff -r ffe33f1f1f17 src/cmd/gc/walk.c | |
--- a/src/cmd/gc/walk.c Tue Nov 25 15:41:33 2014 +1100 | |
+++ b/src/cmd/gc/walk.c Sun Nov 30 15:58:50 2014 +0900 | |
@@ -362,6 +362,53 @@ | |
} | |
} | |
+ | |
+static | |
+void | |
+walkindexinter(Node **np, int as2, NodeList **init) | |
+{ | |
+ Node *nn, *nr; | |
+ nr = nod(ONAME, N, N); | |
+ nr->sym = lookup("__getindex"); | |
+ nn = nod(OCALL, nod(ODOT, (*np)->left, N), N); | |
+ nn->left->right = nr; | |
+ nn->list = list1((*np)->right); | |
+ if(!as2) { | |
+ Node *ntr, *nt1, *nt2, *nif, *nas; | |
+ Type *t, *t2; | |
+ Iter s; | |
+ NodeList *l; | |
+ typecheck(&nn, Etop); | |
+ if(nn->type->etype != TSTRUCT || nn->type->funarg == 0 || structcount(nn->type) != 2) { | |
+ yyerror("assignment count mismatch"); | |
+ return; | |
+ } | |
+ t = structfirst(&s, &nn->type); | |
+ t2 = structnext(&s); | |
+ if(t2->type->etype != TBOOL) { | |
+ yyerror("function does not return a boolean value as the second value (%T)", t2); | |
+ return; | |
+ } | |
+ ntr = temp(t->type); | |
+ nt1 = temp(t->type); | |
+ nt2 = temp(types[TBOOL]); | |
+ nas = nod(OAS2, N, N); | |
+ nas->list = list(list1(nt1), nt2); | |
+ nas->rlist = list1(nn); | |
+ nif = nod(OIF, N, N); | |
+ nif->ntest = nt2; | |
+ nif->ninit = list1(nas); | |
+ nif->nbody = list1(nod(OAS, ntr, nt1)); | |
+ nif->nelse = list1(nod(OAS, ntr, N)); | |
+ l = list1(nif); | |
+ typechecklist(l, Etop); | |
+ walkstmtlist(l); | |
+ *init = concat(*init, l); | |
+ nn = ntr; | |
+ } | |
+ *np = nn; | |
+} | |
+ | |
void | |
walkexpr(Node **np, NodeList **init) | |
{ | |
@@ -607,6 +654,19 @@ | |
*init = concat(*init, n->ninit); | |
n->ninit = nil; | |
+ if(n->left->op == OINDEXINTER) { | |
+ Node *nn, *nr; | |
+ nr = nod(ONAME, N, N); | |
+ nr->sym = lookup("__setindex"); | |
+ nn = nod(OCALL, nod(ODOT, n->left->left, N), N); | |
+ nn->left->right = nr; | |
+ nn->list = list(list1(n->left->right), n->right); | |
+ typecheck(&nn, Etop); | |
+ walkexpr(&nn, init); | |
+ n = nn; | |
+ goto ret; | |
+ } | |
+ | |
walkexpr(&n->left, init); | |
n->left = safeexpr(n->left, init); | |
@@ -644,14 +704,23 @@ | |
case OAS2: | |
*init = concat(*init, n->ninit); | |
n->ninit = nil; | |
- walkexprlistsafe(n->list, init); | |
- walkexprlistsafe(n->rlist, init); | |
- ll = ascompatee(OAS, n->list, n->rlist, init); | |
- ll = reorder3(ll); | |
- for(lr = ll; lr != nil; lr = lr->next) | |
- lr->n = applywritebarrier(lr->n, init); | |
- n = liststmt(ll); | |
- goto ret; | |
+ if(n->rlist->n->op == OINDEXINTER) { | |
+ walkindexinter(&n->rlist->n, 1, init); | |
+ n->typecheck = 0; | |
+ typecheck(&n, Etop); | |
+ if(n->op != OAS2FUNC) | |
+ goto ret; | |
+ // fall-through | |
+ } else { | |
+ walkexprlistsafe(n->list, init); | |
+ walkexprlistsafe(n->rlist, init); | |
+ ll = ascompatee(OAS, n->list, n->rlist, init); | |
+ ll = reorder3(ll); | |
+ for(lr = ll; lr != nil; lr = lr->next) | |
+ lr->n = applywritebarrier(lr->n, init); | |
+ n = liststmt(ll); | |
+ goto ret; | |
+ } | |
case OAS2FUNC: | |
// a,b,... = fn() | |
@@ -1124,6 +1193,14 @@ | |
zerosize = t->type->width; | |
goto ret; | |
+ case OINDEXINTER: | |
+ if(n->etype == 1) | |
+ goto ret; | |
+ walkindexinter(&n, 0, init); | |
+ typecheck(&n, Erv); | |
+ walkexpr(&n, init); | |
+ goto ret; | |
+ | |
case ORECV: | |
fatal("walkexpr ORECV"); // should see inside OAS only | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment