Commit e48c0fb5 authored by Russ Cox's avatar Russ Cox

5g, 6g, 8g: generate code for string index

instead of calling function.

R=ken2
CC=golang-dev
https://golang.org/cl/2762041
parent 705c0382
...@@ -558,9 +558,11 @@ agen(Node *n, Node *res) ...@@ -558,9 +558,11 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex. p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
if(nr->addable) { if(nr->addable) {
agenr(nl, &n3, res); if(!isconst(nr, CTINT))
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
...@@ -572,13 +574,16 @@ agen(Node *n, Node *res) ...@@ -572,13 +574,16 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
regalloc(&n3, types[tptr], res); if(!isconst(nl, CTSTR)) {
agen(nl, &n3); regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
} else { } else {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp);
nr = &tmp; nr = &tmp;
agenr(nl, &n3, res); if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1); gins(optoas(OAS, tmp.type), &tmp, &n1);
} }
...@@ -592,9 +597,10 @@ agen(Node *n, Node *res) ...@@ -592,9 +597,10 @@ agen(Node *n, Node *res)
// constant index // constant index
if(isconst(nr, CTINT)) { if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index");
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
...@@ -638,7 +644,10 @@ agen(Node *n, Node *res) ...@@ -638,7 +644,10 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) { if(!debug['B'] && !n->etype) {
// check bounds // check bounds
regalloc(&n4, types[TUINT32], N); regalloc(&n4, types[TUINT32], N);
if(isslice(nl->type)) { if(isconst(nl, CTSTR)) {
nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
gmove(&n1, &n4);
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -656,8 +665,13 @@ agen(Node *n, Node *res) ...@@ -656,8 +665,13 @@ agen(Node *n, Node *res)
ginscall(panicindex, 0); ginscall(panicindex, 0);
patch(p1, pc); patch(p1, pc);
} }
if(isslice(nl->type)) { if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(AMOVW, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST;
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -795,12 +809,8 @@ igen(Node *n, Node *a, Node *res) ...@@ -795,12 +809,8 @@ igen(Node *n, Node *a, Node *res)
void void
agenr(Node *n, Node *a, Node *res) agenr(Node *n, Node *a, Node *res)
{ {
Node n1;
tempname(&n1, types[tptr]);
agen(n, &n1);
regalloc(a, types[tptr], res); regalloc(a, types[tptr], res);
gmove(&n1, a); agen(n, a);
} }
/* /*
......
...@@ -1678,6 +1678,8 @@ sudoaddable(int as, Node *n, Addr *a, int *w) ...@@ -1678,6 +1678,8 @@ sudoaddable(int as, Node *n, Addr *a, int *w)
goto odot; goto odot;
case OINDEX: case OINDEX:
if(n->left->type->etype == TSTRING)
return 0;
cleani += 2; cleani += 2;
reg = &clean[cleani-1]; reg = &clean[cleani-1];
reg1 = &clean[cleani-2]; reg1 = &clean[cleani-2];
......
...@@ -477,8 +477,10 @@ agen(Node *n, Node *res) ...@@ -477,8 +477,10 @@ agen(Node *n, Node *res)
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
} }
regalloc(&n3, types[tptr], res); if(!isconst(nl, CTSTR)) {
agen(nl, &n3); regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
goto index; goto index;
} }
tempname(&tmp, nr->type); tempname(&tmp, nr->type);
...@@ -486,8 +488,10 @@ agen(Node *n, Node *res) ...@@ -486,8 +488,10 @@ agen(Node *n, Node *res)
nr = &tmp; nr = &tmp;
irad: irad:
regalloc(&n3, types[tptr], res); if(!isconst(nl, CTSTR)) {
agen(nl, &n3); regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
...@@ -501,7 +505,7 @@ agen(Node *n, Node *res) ...@@ -501,7 +505,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough // explicit check for nil if array is large enough
// that we might derive too big a pointer. // that we might derive too big a pointer.
if(!isslice(nl->type) && nl->type->width >= unmappedzero) { if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3); regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4); gmove(&n3, &n4);
n4.op = OINDREG; n4.op = OINDREG;
...@@ -516,8 +520,10 @@ agen(Node *n, Node *res) ...@@ -516,8 +520,10 @@ agen(Node *n, Node *res)
// constant index // constant index
if(isconst(nr, CTINT)) { if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index"); // front end should handle
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
...@@ -556,20 +562,21 @@ agen(Node *n, Node *res) ...@@ -556,20 +562,21 @@ agen(Node *n, Node *res)
// check bounds // check bounds
n5.op = OXXX; n5.op = OXXX;
t = types[TUINT32]; t = types[TUINT32];
if(isslice(nl->type)) { if(is64(nr->type))
t = types[TUINT64];
if(isconst(nl, CTSTR)) {
nodconst(&n1, t, nl->val.u.sval->len);
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[TUINT32]; n1.type = types[TUINT32];
n1.xoffset = Array_nel; n1.xoffset = Array_nel;
if(is64(nr->type)) { if(is64(nr->type)) {
t = types[TUINT64];
regalloc(&n5, t, N); regalloc(&n5, t, N);
gmove(&n1, &n5); gmove(&n1, &n5);
n1 = n5; n1 = n5;
} }
} else { } else {
if(is64(nr->type))
t = types[TUINT64];
nodconst(&n1, t, nl->type->bound); nodconst(&n1, t, nl->type->bound);
} }
gins(optoas(OCMP, t), &n2, &n1); gins(optoas(OCMP, t), &n2, &n1);
...@@ -580,7 +587,16 @@ agen(Node *n, Node *res) ...@@ -580,7 +587,16 @@ agen(Node *n, Node *res)
patch(p1, pc); patch(p1, pc);
} }
if(isslice(nl->type)) { if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(ALEAQ, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.scale = 1;
p1->from.index = n2.val.u.reg;
goto indexdone;
}
if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -599,6 +615,7 @@ agen(Node *n, Node *res) ...@@ -599,6 +615,7 @@ agen(Node *n, Node *res)
gmove(&n3, res); gmove(&n3, res);
} }
indexdone:
gmove(&n3, res); gmove(&n3, res);
regfree(&n2); regfree(&n2);
regfree(&n3); regfree(&n3);
......
...@@ -1784,6 +1784,8 @@ sudoaddable(int as, Node *n, Addr *a) ...@@ -1784,6 +1784,8 @@ sudoaddable(int as, Node *n, Addr *a)
goto odot; goto odot;
case OINDEX: case OINDEX:
if(n->left->type->etype == TSTRING)
return 0;
goto oindex; goto oindex;
} }
return 0; return 0;
......
...@@ -230,8 +230,8 @@ cgen(Node *n, Node *res) ...@@ -230,8 +230,8 @@ cgen(Node *n, Node *res)
cgen(nl, res); cgen(nl, res);
break; break;
} }
mgen(nl, &n1, res);
tempname(&n2, n->type); tempname(&n2, n->type);
mgen(nl, &n1, res);
gmove(&n1, &n2); gmove(&n1, &n2);
gmove(&n2, res); gmove(&n2, res);
mfree(&n1); mfree(&n1);
...@@ -518,9 +518,11 @@ agen(Node *n, Node *res) ...@@ -518,9 +518,11 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex. p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
if(nr->addable) { if(nr->addable) {
agenr(nl, &n3, res); if(!isconst(nr, CTINT))
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
...@@ -532,13 +534,16 @@ agen(Node *n, Node *res) ...@@ -532,13 +534,16 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
regalloc(&n3, types[tptr], res); if(!isconst(nl, CTSTR)) {
agen(nl, &n3); regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
} else { } else {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp);
nr = &tmp; nr = &tmp;
agenr(nl, &n3, res); if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1); gins(optoas(OAS, tmp.type), &tmp, &n1);
} }
...@@ -549,7 +554,7 @@ agen(Node *n, Node *res) ...@@ -549,7 +554,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough // explicit check for nil if array is large enough
// that we might derive too big a pointer. // that we might derive too big a pointer.
if(!isslice(nl->type) && nl->type->width >= unmappedzero) { if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3); regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4); gmove(&n3, &n4);
n4.op = OINDREG; n4.op = OINDREG;
...@@ -564,9 +569,10 @@ agen(Node *n, Node *res) ...@@ -564,9 +569,10 @@ agen(Node *n, Node *res)
// constant index // constant index
if(isconst(nr, CTINT)) { if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index");
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
...@@ -600,7 +606,9 @@ agen(Node *n, Node *res) ...@@ -600,7 +606,9 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) { if(!debug['B'] && !n->etype) {
// check bounds // check bounds
if(isslice(nl->type)) { if(isconst(nl, CTSTR))
nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -614,8 +622,17 @@ agen(Node *n, Node *res) ...@@ -614,8 +622,17 @@ agen(Node *n, Node *res)
ginscall(panicindex, 0); ginscall(panicindex, 0);
patch(p1, pc); patch(p1, pc);
} }
if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(ALEAL, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.scale = 1;
p1->from.index = n2.val.u.reg;
goto indexdone;
}
if(isslice(nl->type)) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -635,6 +652,7 @@ agen(Node *n, Node *res) ...@@ -635,6 +652,7 @@ agen(Node *n, Node *res)
gmove(&n3, res); gmove(&n3, res);
} }
indexdone:
gmove(&n3, res); gmove(&n3, res);
regfree(&n2); regfree(&n2);
regfree(&n3); regfree(&n3);
...@@ -710,8 +728,14 @@ igen(Node *n, Node *a, Node *res) ...@@ -710,8 +728,14 @@ igen(Node *n, Node *a, Node *res)
{ {
Node n1; Node n1;
// release register for now, to avoid
// confusing tempname.
if(res != N && res->op == OREGISTER)
reg[res->val.u.reg]--;
tempname(&n1, types[tptr]); tempname(&n1, types[tptr]);
agen(n, &n1); agen(n, &n1);
if(res != N && res->op == OREGISTER)
reg[res->val.u.reg]++;
regalloc(a, types[tptr], res); regalloc(a, types[tptr], res);
gmove(&n1, a); gmove(&n1, a);
a->op = OINDREG; a->op = OINDREG;
......
...@@ -789,6 +789,8 @@ mkvar(Reg *r, Adr *a) ...@@ -789,6 +789,8 @@ mkvar(Reg *r, Adr *a)
// if they overlaps, disable both // if they overlaps, disable both
if(overlap(v->offset, v->width, o, w)) { if(overlap(v->offset, v->width, o, w)) {
if(debug['R'])
print("disable %s\n", v->sym->name);
v->addr = 1; v->addr = 1;
flag = 1; flag = 1;
} }
...@@ -821,7 +823,7 @@ mkvar(Reg *r, Adr *a) ...@@ -821,7 +823,7 @@ mkvar(Reg *r, Adr *a)
v->addr = flag; // funny punning v->addr = flag; // funny punning
if(debug['R']) if(debug['R'])
print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a); print("bit=%2d et=%2d w=%d %S %D flag=%d\n", i, et, w, s, a, v->addr);
ostats.nvar++; ostats.nvar++;
bit = blsh(i); bit = blsh(i);
......
...@@ -24,7 +24,6 @@ char *runtimeimport = ...@@ -24,7 +24,6 @@ char *runtimeimport =
"func \"\".cmpstring (? string, ? string) int\n" "func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n" "func \"\".slicestring (? string, ? int, ? int) string\n"
"func \"\".slicestring1 (? string, ? int) string\n" "func \"\".slicestring1 (? string, ? int) string\n"
"func \"\".indexstring (? string, ? int) uint8\n"
"func \"\".intstring (? int64) string\n" "func \"\".intstring (? int64) string\n"
"func \"\".slicebytetostring (? []uint8) string\n" "func \"\".slicebytetostring (? []uint8) string\n"
"func \"\".sliceinttostring (? []int) string\n" "func \"\".sliceinttostring (? []int) string\n"
......
...@@ -652,7 +652,6 @@ tempname(Node *n, Type *t) ...@@ -652,7 +652,6 @@ tempname(Node *n, Type *t)
snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen);
statuniqgen++; statuniqgen++;
s = lookup(namebuf); s = lookup(namebuf);
memset(n, 0, sizeof(*n)); memset(n, 0, sizeof(*n));
n->op = ONAME; n->op = ONAME;
n->sym = s; n->sym = s;
......
...@@ -369,7 +369,7 @@ enum ...@@ -369,7 +369,7 @@ enum
ODOTTYPE2, ODOTTYPE2,
OEQ, ONE, OLT, OLE, OGE, OGT, OEQ, ONE, OLT, OLE, OGE, OGT,
OIND, OIND,
OINDEX, OINDEXSTR, OINDEXMAP, OINDEX, OINDEXMAP,
OKEY, OPARAM, OKEY, OPARAM,
OLEN, OLEN,
OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
......
...@@ -59,6 +59,9 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -59,6 +59,9 @@ exprfmt(Fmt *f, Node *n, int prec)
case OPRINT: case OPRINT:
case OPRINTN: case OPRINTN:
case OCALL: case OCALL:
case OCALLMETH:
case OCALLINTER:
case OCALLFUNC:
case OCONV: case OCONV:
case OCONVNOP: case OCONVNOP:
case OMAKESLICE: case OMAKESLICE:
...@@ -72,6 +75,8 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -72,6 +75,8 @@ exprfmt(Fmt *f, Node *n, int prec)
case ORECV: case ORECV:
case OCONVIFACE: case OCONVIFACE:
case OTPAREN: case OTPAREN:
case OINDEX:
case OINDEXMAP:
nprec = 7; nprec = 7;
break; break;
...@@ -328,7 +333,6 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -328,7 +333,6 @@ exprfmt(Fmt *f, Node *n, int prec)
case OINDEX: case OINDEX:
case OINDEXMAP: case OINDEXMAP:
case OINDEXSTR:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
fmtprint(f, "["); fmtprint(f, "[");
exprfmt(f, n->right, 0); exprfmt(f, n->right, 0);
......
...@@ -39,7 +39,6 @@ func concatstring() ...@@ -39,7 +39,6 @@ func concatstring()
func cmpstring(string, string) int func cmpstring(string, string) int
func slicestring(string, int, int) string func slicestring(string, int, int) string
func slicestring1(string, int) string func slicestring1(string, int) string
func indexstring(string, int) byte
func intstring(int64) string func intstring(int64) string
func slicebytetostring([]byte) string func slicebytetostring([]byte) string
func sliceinttostring([]int) string func sliceinttostring([]int) string
......
...@@ -614,7 +614,6 @@ reswitch: ...@@ -614,7 +614,6 @@ reswitch:
if(n->right->type != T && !isint[n->right->type->etype]) if(n->right->type != T && !isint[n->right->type->etype])
yyerror("non-integer string index %#N", n->right); yyerror("non-integer string index %#N", n->right);
n->type = types[TUINT8]; n->type = types[TUINT8];
n->op = OINDEXSTR;
break; break;
} }
goto ret; goto ret;
...@@ -2052,6 +2051,8 @@ islvalue(Node *n) ...@@ -2052,6 +2051,8 @@ islvalue(Node *n)
case OINDEX: case OINDEX:
if(isfixedarray(n->left->type)) if(isfixedarray(n->left->type))
return islvalue(n->left); return islvalue(n->left);
if(n->left->type != T && n->left->type->etype == TSTRING)
return 0;
// fall through // fall through
case OIND: case OIND:
case ODOTPTR: case ODOTPTR:
......
...@@ -1033,22 +1033,35 @@ walkexpr(Node **np, NodeList **init) ...@@ -1033,22 +1033,35 @@ walkexpr(Node **np, NodeList **init)
// if range of type cannot exceed static array bound, // if range of type cannot exceed static array bound,
// disable bounds check // disable bounds check
if(!isslice(n->left->type)) if(isfixedarray(n->left->type))
if(n->right->type->width < 4) if(n->right->type->width < 4)
if((1<<(8*n->right->type->width)) <= n->left->type->bound) if((1<<(8*n->right->type->width)) <= n->left->type->bound)
n->etype = 1; n->etype = 1;
if(isconst(n->left, CTSTR))
if(n->right->type->width < 4)
if((1<<(8*n->right->type->width)) <= n->left->val.u.sval->len)
n->etype = 1;
// check for static out of bounds // check for static out of bounds
if(isconst(n->right, CTINT) && !n->etype) { if(isconst(n->right, CTINT) && !n->etype) {
v = mpgetfix(n->right->val.u.xval); v = mpgetfix(n->right->val.u.xval);
len = 1LL<<60; len = 1LL<<60;
t = n->left->type; t = n->left->type;
if(isconst(n->left, CTSTR))
len = n->left->val.u.sval->len;
if(t != T && isptr[t->etype]) if(t != T && isptr[t->etype])
t = t->type; t = t->type;
if(isfixedarray(t)) if(isfixedarray(t))
len = t->bound; len = t->bound;
if(v < 0 || v >= (1LL<<31) || v >= len) if(v < 0 || v >= (1LL<<31) || v >= len)
yyerror("index out of bounds"); yyerror("index out of bounds");
else if(isconst(n->left, CTSTR)) {
// replace "abc"[2] with 'b'.
// delayed until now because "abc"[2] is not
// an ideal constant.
nodconst(n, n->type, n->left->val.u.sval->s[v]);
}
} }
goto ret; goto ret;
...@@ -1252,14 +1265,6 @@ walkexpr(Node **np, NodeList **init) ...@@ -1252,14 +1265,6 @@ walkexpr(Node **np, NodeList **init)
} }
goto ret; goto ret;
case OINDEXSTR:
// TODO(rsc): should be done in back end
// sys_indexstring(s, i)
n = mkcall("indexstring", n->type, init,
conv(n->left, types[TSTRING]),
conv(n->right, types[TINT]));
goto ret;
case OCOPY: case OCOPY:
if(n->right->type->etype == TSTRING) if(n->right->type->etype == TSTRING)
fn = syslook("slicestringcopy", 1); fn = syslook("slicestringcopy", 1);
......
...@@ -200,10 +200,6 @@ func slicestring(si String, lindex int32, hindex int32) (so String) { ...@@ -200,10 +200,6 @@ func slicestring(si String, lindex int32, hindex int32) (so String) {
l = hindex-lindex; l = hindex-lindex;
so.str = si.str + lindex; so.str = si.str + lindex;
so.len = l; so.len = l;
// alternate to create a new string
// so = gostringsize(l);
// mcpy(so.str, si.str+lindex, l);
} }
func slicestring1(si String, lindex int32) (so String) { func slicestring1(si String, lindex int32) (so String) {
...@@ -216,18 +212,6 @@ func slicestring1(si String, lindex int32) (so String) { ...@@ -216,18 +212,6 @@ func slicestring1(si String, lindex int32) (so String) {
l = si.len-lindex; l = si.len-lindex;
so.str = si.str + lindex; so.str = si.str + lindex;
so.len = l; so.len = l;
// alternate to create a new string
// so = gostringsize(l);
// mcpy(so.str, si.str+lindex, l);
}
func indexstring(s String, i int32) (b byte) {
if(i < 0 || i >= s.len) {
·panicindex();
}
b = s.str[i];
} }
func intstring(v int64) (s String) { func intstring(v int64) (s String) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment