summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/6g/cgen.c95
-rw-r--r--src/cmd/6g/gsubr.c1
-rw-r--r--src/cmd/gc/go.h9
-rw-r--r--src/cmd/gc/subr.c51
-rw-r--r--src/cmd/gc/walk.c119
5 files changed, 71 insertions, 204 deletions
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index 5838ddef2..4d6e11279 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -189,27 +189,12 @@ cgen(Node *n, Node *res)
}
regalloc(&n1, nl->type, res);
cgen(nl, &n1);
- if(isptrsarray(n->type) && isptrdarray(nl->type)) {
- // convert dynamic array to static array
- n2 = n1;
- n2.op = OINDREG;
- n2.xoffset = Array_array;
- n2.type = types[tptr];
- gins(AMOVQ, &n2, &n1);
- }
- if(isptrdarray(n->type) && isptrsarray(nl->type)) {
- // conver static array to dynamic array
- // it is assumed that the dope is just before the array
- nodconst(&n2, types[tptr], sizeof_Array);
- gins(ASUBQ, &n2, &n1);
- }
gmove(&n1, res);
regfree(&n1);
break;
case ODOT:
case ODOTPTR:
- case OINDEXPTR:
case OINDEX:
case OIND:
igen(n, &n1, res);
@@ -218,7 +203,9 @@ cgen(Node *n, Node *res)
break;
case OLEN:
- if(istype(nl->type, TSTRING)) {
+ if(istype(nl->type, TSTRING) || istype(nl->type, TMAP)) {
+ // both string and map have len in the first 32-bit word.
+ // a zero pointer means zero length
regalloc(&n1, types[tptr], res);
cgen(nl, &n1);
@@ -237,26 +224,7 @@ cgen(Node *n, Node *res)
regfree(&n1);
break;
}
- if(istype(nl->type, TMAP)) {
- regalloc(&n1, types[tptr], res);
- cgen(nl, &n1);
- n1.op = OINDREG;
- n1.type = types[TINT32];
- gmove(&n1, res);
- regfree(&n1);
- break;
- }
- if(isptrdarray(nl->type)) {
- regalloc(&n1, types[tptr], res);
- cgen(nl, &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT32];
- n1.xoffset = Array_nel;
- gmove(&n1, res);
- regfree(&n1);
- break;
- }
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
regalloc(&n1, types[tptr], res);
agen(nl, &n1);
n1.op = OINDREG;
@@ -270,17 +238,7 @@ cgen(Node *n, Node *res)
break;
case OCAP:
- if(isptrdarray(nl->type)) {
- regalloc(&n1, types[tptr], res);
- cgen(nl, &n1);
- n1.op = OINDREG;
- n1.type = types[TUINT32];
- n1.xoffset = Array_cap;
- gmove(&n1, res);
- regfree(&n1);
- break;
- }
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
regalloc(&n1, types[tptr], res);
agen(nl, &n1);
n1.op = OINDREG;
@@ -436,32 +394,6 @@ agen(Node *n, Node *res)
cgen_aret(n, res);
break;
- case OINDEXPTR:
- w = n->type->width;
- if(nr->addable)
- goto iprad;
- if(nl->addable) {
- if(whatis(nr) != Wlitint) {
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
- }
- regalloc(&n3, types[tptr], res);
- cgen(nl, &n3);
- goto index;
- }
- cgen(nr, res);
- tempname(&tmp, nr->type);
- gmove(res, &tmp);
-
- iprad:
- regalloc(&n3, types[tptr], res);
- cgen(nl, &n3);
- if(whatis(nr) != Wlitint) {
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
- }
- goto index;
-
case OINDEX:
w = n->type->width;
if(nr->addable)
@@ -499,7 +431,7 @@ agen(Node *n, Node *res)
// constant index
if(whatis(nr) == Wlitint) {
v = mpgetfix(nr->val.u.xval);
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
if(!debug['B']) {
n1 = n3;
@@ -523,10 +455,6 @@ agen(Node *n, Node *res)
if(v < 0)
yyerror("out of bounds on array");
else
- if(isptrsarray(nl->type)) {
- if(v >= nl->type->type->bound)
- yyerror("out of bounds on array");
- } else
if(v >= nl->type->bound)
yyerror("out of bounds on array");
}
@@ -550,23 +478,20 @@ agen(Node *n, Node *res)
if(!debug['B']) {
// check bounds
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
n1.xoffset = Array_nel;
- } else {
+ } else
nodconst(&n1, types[TUINT64], nl->type->bound);
- if(isptrsarray(nl->type))
- nodconst(&n1, types[TUINT64], nl->type->type->bound);
- }
gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
p1 = gbranch(optoas(OLT, types[TUINT32]), T);
gins(ACALL, N, throwindex);
patch(p1, pc);
}
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@@ -776,7 +701,7 @@ bgen(Node *n, int true, Prog *to)
nr = r;
}
- if(isdarray(nl->type)) {
+ if(isslice(nl->type)) {
// only valid to cmp darray to literal nil
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
yyerror("illegal array comparison");
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index 4df9b790a..553abfa60 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -1913,7 +1913,6 @@ sudoaddable(Node *n, Addr *a)
reg1->op = OEMPTY;
goto odot;
- case OINDEXPTR:
case OINDEX:
cleani += 2;
reg = &clean[cleani-1];
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index a46e76af3..19b44f909 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -308,7 +308,7 @@ enum
OADDR,
OIND,
OCALL, OCALLMETH, OCALLINTER,
- OINDEX, OINDEXPTR, OSLICE,
+ OINDEX, OSLICE,
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OLITERAL, OREGISTER, OINDREG,
OCONV, OCOMP, OKEY,
@@ -627,10 +627,8 @@ Type* aindex(Node*, Type*);
int isnil(Node*);
int isptrto(Type*, int);
int istype(Type*, int);
-int isptrsarray(Type*);
-int isptrdarray(Type*);
-int issarray(Type*);
-int isdarray(Type*);
+int isfixedarray(Type*);
+int isslice(Type*);
int isinter(Type*);
int isnilinter(Type*);
int isddd(Type*);
@@ -638,7 +636,6 @@ Type* dclmethod(Type*);
Type* methtype(Type*);
int methconv(Type*);
Sym* signame(Type*);
-int bytearraysz(Type*);
int eqtype(Type*, Type*, int);
void argtype(Node*, Type*);
int eqargs(Type*, Type*);
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 9152bfb1a..428e70551 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -301,7 +301,7 @@ algtype(Type *t)
if(isptr[simtype[t->etype]])
a = APTR; // pointer
else
- if(t->etype == TARRAY && t->bound < 0)
+ if(isslice(t))
a = ASLICE;
else
if(t->etype == TSTRUCT)
@@ -667,7 +667,6 @@ opnames[] =
[OGT] = "GT",
[OIF] = "IF",
[OINDEX] = "INDEX",
- [OINDEXPTR] = "INDEXPTR",
[OIND] = "IND",
[OKEY] = "KEY",
[OLABEL] = "LABEL",
@@ -831,7 +830,6 @@ etnames[] =
[TDDD] = "DDD",
[TFUNC] = "FUNC",
[TARRAY] = "ARRAY",
-// [TDARRAY] = "DARRAY",
[TSTRUCT] = "STRUCT",
[TCHAN] = "CHAN",
[TMAP] = "MAP",
@@ -1436,37 +1434,15 @@ istype(Type *t, int et)
}
int
-isptrsarray(Type *t)
+isfixedarray(Type *t)
{
- if(isptrto(t, TARRAY))
- if(t->type->bound >= 0)
- return 1;
- return 0;
+ return t != T && t->etype == TARRAY && t->bound >= 0;
}
int
-isptrdarray(Type *t)
+isslice(Type *t)
{
- if(isptrto(t, TARRAY))
- if(t->type->bound < 0)
- return 1;
- return 0;
-}
-
-int
-issarray(Type *t)
-{
- if(t != T && t->etype == TARRAY && t->bound >= 0)
- return 1;
- return 0;
-}
-
-int
-isdarray(Type *t)
-{
- if(t != T && t->etype == TARRAY && t->bound < 0)
- return 1;
- return 0;
+ return t != T && t->etype == TARRAY && t->bound < 0;
}
int
@@ -1684,23 +1660,6 @@ bad:
}
int
-bytearraysz(Type *t)
-{
- if(t == T)
- return -2;
- if(isptr[t->etype]) {
- t = t->type;
- if(t == T)
- return -2;
- }
- if(t->etype != TARRAY)
- return -2;
- if(!eqtype(t->type, types[TUINT8], 0))
- return -2;
- return t->bound; // -1 is dyn, >=0 is fixed
-}
-
-int
eqtype(Type *t1, Type *t2, int d)
{
if(d >= 10)
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 99dd118e2..e7a95d269 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -165,6 +165,33 @@ indir(Node *nl, Node *nr)
}
void
+implicitstar(Node **nn)
+{
+ Type *t;
+ Node *n;
+
+ // insert implicit * if needed
+ n = *nn;
+ t = n->type;
+ if(t == T || !isptr[t->etype])
+ return;
+ t = t->type;
+ if(t == T)
+ return;
+ switch(t->etype) {
+ case TMAP:
+ case TSTRING:
+ case TARRAY:
+ break;
+ default:
+ return;
+ }
+ n = nod(OIND, n, N);
+ walktype(n, Elv);
+ *nn = n;
+}
+
+void
walktype(Node *n, int top)
{
Node *r, *l;
@@ -437,7 +464,6 @@ loop:
break;
case OINDEX:
- case OINDEXPTR:
if(cl == 2 && cr == 1) {
// a,b = map[] - mapaccess2
walktype(r->left, Erv);
@@ -496,7 +522,6 @@ loop:
switch(l->op) {
case OINDEX:
- case OINDEXPTR:
if(cl == 1 && cr == 2) {
// map[] = a,b - mapassign2
if(!istype(l->left->type, TMAP))
@@ -581,11 +606,13 @@ loop:
// to string
if(l->type != T)
if(istype(t, TSTRING)) {
- if(isint[l->type->etype]) {
+ et = l->type->etype;
+ if(isint[et]) {
indir(n, stringop(n, top));
goto ret;
}
- if(bytearraysz(l->type) != -2) {
+ if(et == TARRAY)
+ if(istype(l->type->type, TUINT8)) {
n->op = OARRAY;
indir(n, stringop(n, top));
goto ret;
@@ -593,11 +620,11 @@ loop:
}
// convert dynamic to static generated by ONEW/OMAKE
- if(issarray(t) && isdarray(l->type))
+ if(isfixedarray(t) && isslice(l->type))
goto ret;
// convert static array to dynamic array
- if(isdarray(t) && issarray(l->type)) {
+ if(isslice(t) && isfixedarray(l->type)) {
if(eqtype(t->type->type, l->type->type->type, 0)) {
indir(n, arrayop(n, Erv));
goto ret;
@@ -795,10 +822,9 @@ loop:
if(top != Erv)
goto nottop;
walktype(n->left, Erv);
+ implicitstar(&n->left);
evconst(n);
t = n->left->type;
- if(t != T && isptr[t->etype])
- t = t->type;
if(t == T)
goto ret;
switch(t->etype) {
@@ -819,10 +845,9 @@ loop:
if(top != Erv)
goto nottop;
walktype(n->left, Erv);
+ implicitstar(&n->left);
evconst(n);
t = n->left->type;
- if(t != T && isptr[t->etype])
- t = t->type;
if(t == T)
goto ret;
switch(t->etype) {
@@ -837,7 +862,6 @@ loop:
goto ret;
case OINDEX:
- case OINDEXPTR:
if(top == Etop)
goto nottop;
@@ -848,36 +872,29 @@ loop:
goto ret;
defaultlit(n->left);
+ implicitstar(&n->left);
+
t = n->left->type;
if(t == T)
goto ret;
-// BOTCH - convert each index opcode
-// to look like this and get rid of OINDEXPTR
- if(istype(t, TSTRING) || isptrto(t, TSTRING)) {
+ switch(t->etype) {
+ default:
+ goto badt;
+
+ case TSTRING:
// right side must be an int
if(top != Erv)
goto nottop;
if(n->right->type == T) {
convlit(n->right, types[TINT]);
if(n->right->type == T)
- goto ret;
+ break;
}
if(!isint[n->right->type->etype])
goto badt;
indir(n, stringop(n, top));
- goto ret;
- }
-
- // left side is indirect
- if(isptr[t->etype]) {
- t = t->type;
- n->op = OINDEXPTR;
- }
-
- switch(t->etype) {
- default:
- goto badt;
+ break;
case TMAP:
// right side must be map type
@@ -888,7 +905,6 @@ loop:
}
if(!eqtype(n->right->type, t->down, 0))
goto badt;
- n->op = OINDEX;
n->type = t->type;
if(top == Erv)
indir(n, mapop(n, top));
@@ -939,11 +955,10 @@ loop:
if(n->left == N || n->right == N)
goto ret;
convlit(n->left, types[TSTRING]);
+ implicitstar(&n->left);
t = n->left->type;
if(t == T)
goto ret;
- if(isptr[t->etype]) //XXX?
- t = t->type;
if(t->etype == TSTRING) {
indir(n, stringop(n, top));
goto ret;
@@ -1064,7 +1079,7 @@ loop:
case ONE:
if(n->left->type == T)
goto ret;
- if(isdarray(n->left->type)) {
+ if(isslice(n->left->type)) {
t = types[TBOOL];
break;
}
@@ -1912,7 +1927,7 @@ ascompat(Type *dst, Type *src)
if(eqtype(dst, src, 0))
return 1;
- if(isdarray(dst) && issarray(src))
+ if(isslice(dst) && isfixedarray(src))
return 1;
if(isnilinter(dst) || isnilinter(src))
@@ -1973,7 +1988,7 @@ loop:
argtype(on, l->type->type); // any-1
break;
}
- if(isdarray(l->type)) {
+ if(isslice(l->type)) {
on = syslook("printarray", 1);
argtype(on, l->type); // any-1
break;
@@ -2147,15 +2162,9 @@ stringop(Node *n, int top)
case OINDEX:
// sys_indexstring(s, i)
- c = n->left;
- if(istype(c->type->type, TSTRING)) {
- // lhs is string or *string
- c = nod(OIND, c, N);
- c->type = c->left->type->type;
- }
r = nod(OCONV, n->right, N);
r->type = types[TINT];
- r = list(c, r);
+ r = list(n->left, r);
on = syslook("indexstring", 0);
r = nod(OCALL, on, r);
break;
@@ -2284,11 +2293,6 @@ mapop(Node *n, int top)
}
a = n->right; // key
-// if(!isptr[t->down->etype]) {
-// a = nod(OADDR, a, N);
-// a->type = ptrto(t);
-// }
-
r = a;
a = n->left; // map
r = list(a, r);
@@ -2916,12 +2920,6 @@ convas(Node *n)
goto out;
}
- if(n->left->op == OINDEXPTR)
- if(n->left->left->type->etype == TMAP) {
- indir(n, mapop(n, Elv));
- goto out;
- }
-
if(n->left->op == OSEND)
if(n->left->type != T) {
indir(n, chanop(n, Elv));
@@ -2937,7 +2935,7 @@ convas(Node *n)
goto out;
}
- if(isdarray(lt) && issarray(rt)) {
+ if(isslice(lt) && isfixedarray(rt)) {
if(!eqtype(lt->type->type, rt->type->type, 0))
goto bad;
indir(n, arrayop(n, Etop));
@@ -3040,18 +3038,14 @@ multi:
break;
case OINDEX:
- case OINDEXPTR:
// check if rhs is a map index.
- // if so, types are bool,maptype
+ // if so, types are valuetype,bool
if(cl != 2)
goto badt;
walktype(nr->left, Elv);
t = nr->left->type;
- if(t != T && isptr[t->etype])
- t = t->type;
- if(t == T || t->etype != TMAP)
+ if(!istype(t, TMAP))
goto badt;
-
a = old2new(nl->left, t->type);
n = a;
a = old2new(nl->right, types[TBOOL]);
@@ -3110,6 +3104,7 @@ dorange(Node *nn)
if(nn->op != ORANGE)
fatal("dorange not ORANGE");
+ implicitstar(&nn->right);
k = nn->left;
m = nn->right;
local = nn->etype;
@@ -3128,16 +3123,8 @@ dorange(Node *nn)
goto out;
if(t->etype == TARRAY)
goto ary;
- if(isptrto(t, TARRAY)) {
- t = t->type;
- goto ary;
- }
if(t->etype == TMAP)
goto map;
- if(isptrto(t, TMAP)) {
- t = t->type;
- goto map;
- }
yyerror("range must be over map/array");
goto out;