зеркало из https://github.com/CryptoPro/go.git
Родитель
f59ae064ba
Коммит
bf0130cc0f
|
@ -55,6 +55,7 @@ EXTERN Node* newproc;
|
|||
EXTERN Node* deferproc;
|
||||
EXTERN Node* deferreturn;
|
||||
EXTERN Node* throwindex;
|
||||
EXTERN Node* throwslice;
|
||||
EXTERN Node* throwreturn;
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,6 +22,7 @@ compile(Node *fn)
|
|||
deferproc = sysfunc("deferproc");
|
||||
deferreturn = sysfunc("deferreturn");
|
||||
throwindex = sysfunc("throwindex");
|
||||
throwslice = sysfunc("throwslice");
|
||||
throwreturn = sysfunc("throwreturn");
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1177,7 @@ yes:
|
|||
static int
|
||||
regcmp(Node *ra, Node *rb)
|
||||
{
|
||||
return ra->xoffset - rb->xoffset;
|
||||
return ra->local - rb->local;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1192,12 +1193,14 @@ getargs(NodeList *nn, Node *reg, int n)
|
|||
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
|
||||
|
@ -1216,7 +1219,7 @@ cmpandthrow(Node *nl, Node *nr)
|
|||
if(smallintconst(nr)) {
|
||||
cr = mpgetfix(nr->val.u.xval);
|
||||
if(cl > cr)
|
||||
ginscall(throwindex, 0);
|
||||
ginscall(throwslice, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1229,7 +1232,7 @@ cmpandthrow(Node *nl, Node *nr)
|
|||
|
||||
gins(optoas(OCMP, types[TUINT32]), nl, nr);
|
||||
p1 = gbranch(optoas(op, types[TUINT32]), T);
|
||||
ginscall(throwindex, 0);
|
||||
ginscall(throwslice, 0);
|
||||
patch(p1, pc);
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1250,7 @@ cgen_inline(Node *n, Node *res)
|
|||
|
||||
if(n->op != OCALLFUNC)
|
||||
goto no;
|
||||
if(n->left->op != ONAME)
|
||||
if(!n->left->addable)
|
||||
goto no;
|
||||
if(!res->addable)
|
||||
goto no;
|
||||
|
@ -1270,7 +1273,6 @@ slicearray:
|
|||
// 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;
|
||||
|
@ -1283,7 +1285,8 @@ slicearray:
|
|||
} 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);
|
||||
}
|
||||
|
@ -1300,7 +1303,8 @@ slicearray:
|
|||
} 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);
|
||||
}
|
||||
|
@ -1312,8 +1316,10 @@ slicearray:
|
|||
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);
|
||||
|
@ -1331,14 +1337,79 @@ slicearray:
|
|||
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 > 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(hb[2] > old.cap[0]) goto throw;
|
||||
n2 = *(nodes+0);
|
||||
n2.xoffset += Array_cap;
|
||||
cmpandthrow(nodes+2, &n2);
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -1534,6 +1534,7 @@ noreturn(Prog *p)
|
|||
|
||||
if(symlist[0] == S) {
|
||||
symlist[0] = pkglookup("throwindex", "sys");
|
||||
symlist[0] = pkglookup("throwslice", "sys");
|
||||
symlist[1] = pkglookup("panicl", "sys");
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,12 @@ sys·throwindex(void)
|
|||
throw("index out of range");
|
||||
}
|
||||
|
||||
void
|
||||
sys·throwslice(void)
|
||||
{
|
||||
throw("slice out of range");
|
||||
}
|
||||
|
||||
void
|
||||
sys·throwreturn(void)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
// $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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче