diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index 5838ddef22b..4d6e11279df 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 4df9b790ad1..553abfa605e 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 a46e76af318..19b44f90996 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 9152bfb1abb..428e7055197 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 @@ -1683,23 +1659,6 @@ bad: return S; } -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) { diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 99dd118e2bb..e7a95d26999 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -164,6 +164,33 @@ indir(Node *nl, Node *nr) *nl = *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) { @@ -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;