mirror of
https://github.com/golang/go
synced 2024-11-19 02:24:41 -07:00
5g, 6g, 8g: generate code for string index
instead of calling function. R=ken2 CC=golang-dev https://golang.org/cl/2762041
This commit is contained in:
parent
705c0382e8
commit
e48c0fb562
@ -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)
|
|||||||
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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
// 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
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 =
|
|||||||
"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)
|
|||||||
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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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()
|
|||||||
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:
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
// 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)
|
|||||||
}
|
}
|
||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user