aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-12-04 20:40:21 -0800
committerRuss Cox <rsc@golang.org>2009-12-04 20:40:21 -0800
commit6f14cada11411c6fff924c0ab8d8bbd430c3ae61 (patch)
treec8e6e32e253a0e15b8ae3dfa73c9e91be08cda19
parent7c4aeec8686466674450ccb591621329978c48e3 (diff)
downloadgo-6f14cada11411c6fff924c0ab8d8bbd430c3ae61.tar.gz
go-6f14cada11411c6fff924c0ab8d8bbd430c3ae61.zip
gc: walk pointer in range on slice/array
R=ken2 https://golang.org/cl/166071
-rw-r--r--src/cmd/gc/range.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index 4147e8e6c9..2794504d2c 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -90,6 +90,7 @@ walkrange(Node *n)
{
Node *ohv1, *hv1, *hv2; // hidden (old) val 1, 2
Node *ha, *hit; // hidden aggregate, iterator
+ Node *hn, *hp; // hidden len, pointer
Node *a, *v1, *v2; // not hidden aggregate, val 1, 2
Node *fn, *tmp;
NodeList *body, *init;
@@ -122,16 +123,32 @@ walkrange(Node *n)
case TARRAY:
hv1 = nod(OXXX, N, n);
tempname(hv1, types[TINT]);
+ hn = nod(OXXX, N, N);
+ tempname(hn, types[TINT]);
+ hp = nil;
init = list(init, nod(OAS, hv1, N));
- n->ntest = nod(OLT, hv1, nod(OLEN, ha, N));
+ init = list(init, nod(OAS, hn, nod(OLEN, ha, N)));
+ if(v2) {
+ hp = nod(OXXX, N, N);
+ tempname(hp, ptrto(a->type->type));
+ tmp = nod(OINDEX, ha, nodintconst(0));
+ tmp->etype = 1; // no bounds check
+ init = list(init, nod(OAS, hp, nod(OADDR, tmp, N)));
+ }
+
+ n->ntest = nod(OLT, hv1, hn);
n->nincr = nod(OASOP, hv1, nodintconst(1));
n->nincr->etype = OADD;
body = list1(nod(OAS, v1, hv1));
if(v2) {
- tmp = nod(OINDEX, ha, hv1);
- tmp->etype = 1; // no bounds check
- body = list(body, nod(OAS, v2, tmp));
+ body = list(body, nod(OAS, v2, nod(OIND, hp, N)));
+ tmp = nod(OADD, hp, nodintconst(t->type->width));
+ tmp->type = hp->type;
+ tmp->typecheck = 1;
+ tmp->right->type = types[tptr];
+ tmp->right->typecheck = 1;
+ body = list(body, nod(OAS, hp, tmp));
}
break;