deferproc = sysfunc("deferproc");
deferreturn = sysfunc("deferreturn");
throwindex = sysfunc("throwindex");
+ throwslice = sysfunc("throwslice");
throwreturn = sysfunc("throwreturn");
}
static int
regcmp(Node *ra, Node *rb)
{
- return ra->xoffset - rb->xoffset;
+ return ra->local - rb->local;
}
void
cgen(l->n->right, reg+i);
} else
reg[i] = *l->n->right;
- reg[i].xoffset = l->n->left->xoffset;
+ if(reg[i].local != 0)
+ yyerror("local used");
+ reg[i].local = l->n->left->xoffset;
l = l->next;
}
- qsort(reg, n, sizeof(*reg), regcmp);
+ qsort((void*)reg, n, sizeof(*reg), regcmp);
for(i=0; i<n; i++)
- reg[i].xoffset = 0;
+ reg[i].local = 0;
}
void
if(smallintconst(nr)) {
cr = mpgetfix(nr->val.u.xval);
if(cl > cr)
- ginscall(throwindex, 0);
+ ginscall(throwslice, 0);
return;
}
gins(optoas(OCMP, types[TUINT32]), nl, nr);
p1 = gbranch(optoas(op, types[TUINT32]), T);
- ginscall(throwindex, 0);
+ ginscall(throwslice, 0);
patch(p1, pc);
}
if(n->op != OCALLFUNC)
goto no;
- if(n->left->op != ONAME)
+ if(!n->left->addable)
goto no;
if(!res->addable)
goto no;
// if(lb[2] > hb[3]) goto throw
cmpandthrow(nodes+2, nodes+3);
-
// len = hb[3] - lb[2] (destroys hb)
n2 = *res;
n2.xoffset += Array_nel;
} else {
regalloc(&n1, types[TUINT32], nodes+3);
gmove(nodes+3, &n1);
- gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+ if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
}
} else {
regalloc(&n1, types[TUINT32], nodes+1);
gmove(nodes+1, &n1);
- gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+ if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
}
if(smallintconst(nodes+2) && smallintconst(nodes+4)) {
v = mpgetfix((nodes+2)->val.u.xval) *
mpgetfix((nodes+4)->val.u.xval);
- nodconst(&n1, types[tptr], v);
- gins(optoas(OADD, types[tptr]), &n1, nodes+0);
+ if(v != 0) {
+ nodconst(&n1, types[tptr], v);
+ gins(optoas(OADD, types[tptr]), &n1, nodes+0);
+ }
} else {
regalloc(&n1, types[tptr], nodes+2);
gmove(nodes+2, &n1);
return 1;
sliceslice:
-goto no;
getargs(n->list, nodes, 4);
+ if(!(nodes+0)->addable) {
+ for(i=0; i<4; i++) {
+ if((nodes+i)->op == OREGISTER)
+ regfree(nodes+i);
+ }
+ goto no;
+ }
+
+ // if(hb[2] > old.cap[0]) goto throw;
+ n2 = *(nodes+0);
+ n2.xoffset += Array_cap;
+ cmpandthrow(nodes+2, &n2);
- // if(hb > old.cap) goto throw;
- // if(lb > hb) goto throw;
- // ret.len = hb-lb;
- // ret.cap = old.cap - lb;
- // ret.array = old.array + lb*width;
+ // if(lb[1] > hb[2]) goto throw;
+ cmpandthrow(nodes+1, nodes+2);
+
+ // ret.len = hb[2]-lb[1]; (destroys hb[2])
+ n2 = *res;
+ n2.xoffset += Array_nel;
+
+ if(smallintconst(nodes+2) && smallintconst(nodes+1)) {
+ v = mpgetfix((nodes+2)->val.u.xval) -
+ mpgetfix((nodes+1)->val.u.xval);
+ nodconst(&n1, types[TUINT32], v);
+ gins(optoas(OAS, types[TUINT32]), &n1, &n2);
+ } else {
+ regalloc(&n1, types[TUINT32], nodes+2);
+ gmove(nodes+2, &n1);
+ if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+ gins(optoas(OAS, types[TUINT32]), &n1, &n2);
+ regfree(&n1);
+ }
+
+ // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
+ n2 = *(nodes+0);
+ n2.xoffset += Array_cap;
+
+ regalloc(&n1, types[TUINT32], nodes+2);
+ gins(optoas(OAS, types[TUINT32]), &n2, &n1);
+ if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+
+ n2 = *res;
+ n2.xoffset += Array_cap;
+ gins(optoas(OAS, types[TUINT32]), &n1, &n2);
+ regfree(&n1);
+
+ // ret.array = old.array[0]+lb[1]*width[3]; (uses lb)
+ n2 = *(nodes+0);
+ n2.xoffset += Array_array;
+
+ regalloc(&n1, types[tptr], nodes+1);
+ if(smallintconst(nodes+1) && smallintconst(nodes+3)) {
+ gins(optoas(OAS, types[TUINT32]), &n2, &n1);
+ v = mpgetfix((nodes+1)->val.u.xval) *
+ mpgetfix((nodes+3)->val.u.xval);
+ if(v != 0) {
+ nodconst(&n2, types[tptr], v);
+ gins(optoas(OADD, types[tptr]), &n2, &n1);
+ }
+ } else {
+ gmove(nodes+1, &n1);
+ if(!smallintconst(nodes+3) || mpgetfix((nodes+3)->val.u.xval) != 1)
+ gins(optoas(OMUL, types[tptr]), nodes+3, &n1);
+ gins(optoas(OADD, types[tptr]), &n2, &n1);
+ }
+
+ n2 = *res;
+ n2.xoffset += Array_array;
+ gins(optoas(OAS, types[tptr]), &n1, &n2);
+ regfree(&n1);
for(i=0; i<4; i++) {
if((nodes+i)->op == OREGISTER)
--- /dev/null
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var bx []byte
+var by []byte;
+var fx []float
+var fy []float;
+var lb,hb int
+var t int
+
+func
+main()
+{
+
+ // width 1 (byte)
+ lb = 0; hb = 10;
+ by = bx[lb:hb]; tstb();
+ by = bx[lb:10]; tstb();
+ by = bx[0:hb]; tstb();
+ by = bx[0:10]; tstb();
+
+ lb = 2; hb = 10;
+ by = bx[lb:hb]; tstb();
+ by = bx[lb:10]; tstb();
+ by = bx[2:hb]; tstb();
+ by = bx[2:10]; tstb();
+
+ lb = 0; hb = 8;
+ by = bx[lb:hb]; tstb();
+ by = bx[lb:8]; tstb();
+ by = bx[0:hb]; tstb();
+ by = bx[0:8]; tstb();
+
+ lb = 2; hb = 8;
+ by = bx[lb:hb]; tstb();
+ by = bx[lb:8]; tstb();
+ by = bx[2:hb]; tstb();
+ by = bx[2:8]; tstb();
+
+ // width 4 (float)
+ lb = 0; hb = 10;
+ fy = fx[lb:hb]; tstf();
+ fy = fx[lb:10]; tstf();
+ fy = fx[0:hb]; tstf();
+ fy = fx[0:10]; tstf();
+
+ lb = 2; hb = 10;
+ fy = fx[lb:hb]; tstf();
+ fy = fx[lb:10]; tstf();
+ fy = fx[2:hb]; tstf();
+ fy = fx[2:10]; tstf();
+
+ lb = 0; hb = 8;
+ fy = fx[lb:hb]; tstf();
+ fy = fx[lb:8]; tstf();
+ fy = fx[0:hb]; tstf();
+ fy = fx[0:8]; tstf();
+
+ lb = 2; hb = 8;
+ fy = fx[lb:hb]; tstf();
+ fy = fx[lb:8]; tstf();
+ fy = fx[2:hb]; tstf();
+ fy = fx[2:8]; tstf();
+}
+
+func
+tstb()
+{
+ t++;
+ if len(by) != hb-lb {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "len=", len(by), "hb-lb=", hb-lb);
+ }
+ if cap(by) != len(bx)-lb {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "cap=", cap(by), "len(bx)-lb=", len(bx)-lb);
+ }
+ for i:=lb; i<hb; i++ {
+ if bx[i] != by[i-lb] {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "bx[", i, "]=", bx[i],
+ "by[", i-lb, "]=", by[i-lb]);
+ }
+ }
+ by = nil;
+}
+
+func
+tstf()
+{
+ t++;
+ if len(fy) != hb-lb {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "len=", len(fy), "hb-lb=", hb-lb);
+ }
+ if cap(fy) != len(fx)-lb {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "cap=", cap(fy), "len(fx)-lb=", len(fx)-lb);
+ }
+ for i:=lb; i<hb; i++ {
+ if fx[i] != fy[i-lb] {
+ panicln("t=", t, "lb=", lb, "hb=", hb,
+ "fx[", i, "]=", fx[i],
+ "fy[", i-lb, "]=", fy[i-lb]);
+ }
+ }
+ fy = nil;
+}
+
+func
+init()
+{
+ bx = make([]byte, 10);
+ for i:=0; i<len(bx); i++ {
+ bx[i] = byte(i+20);
+ }
+ by = nil;
+
+ fx = make([]float, 10);
+ for i:=0; i<len(fx); i++ {
+ fx[i] = float(i+20);
+ }
+ fy = nil;
+}