Commit 4026500d authored by Ken Thompson's avatar Ken Thompson

arrays

R=r
OCL=21564
CL=21564
parent eaa2a364
...@@ -148,8 +148,11 @@ dowidth(Type *t) ...@@ -148,8 +148,11 @@ dowidth(Type *t)
w = wptr; w = wptr;
break; break;
case TARRAY: case TARRAY:
if(t->type == T)
break;
dowidth(t->type); dowidth(t->type);
if(t->bound >= 0 && t->type != T) w = sizeof(Array);
if(t->bound >= 0)
w = t->bound * t->type->width; w = t->bound * t->type->width;
break; break;
......
...@@ -185,7 +185,7 @@ cgen(Node *n, Node *res) ...@@ -185,7 +185,7 @@ cgen(Node *n, Node *res)
} }
regalloc(&n1, nl->type, res); regalloc(&n1, nl->type, res);
cgen(nl, &n1); cgen(nl, &n1);
if(isptrarray(n->type) && isptrdarray(nl->type)) { if(isptrsarray(n->type) && isptrdarray(nl->type)) {
// convert dynamic array to static array // convert dynamic array to static array
n2 = n1; n2 = n1;
n2.op = OINDREG; n2.op = OINDREG;
...@@ -193,10 +193,10 @@ cgen(Node *n, Node *res) ...@@ -193,10 +193,10 @@ cgen(Node *n, Node *res)
n2.type = types[tptr]; n2.type = types[tptr];
gins(AMOVQ, &n2, &n1); gins(AMOVQ, &n2, &n1);
} }
if(isptrdarray(n->type) && isptrarray(nl->type)) { if(isptrdarray(n->type) && isptrsarray(nl->type)) {
// conver static array to dynamic array // conver static array to dynamic array
// it is assumed that the dope is just before the array // it is assumed that the dope is just before the array
nodconst(&n2, types[tptr], offsetof(Array,b)); nodconst(&n2, types[tptr], sizeof(Array));
gins(ASUBQ, &n2, &n1); gins(ASUBQ, &n2, &n1);
} }
gmove(&n1, res); gmove(&n1, res);
...@@ -252,6 +252,16 @@ cgen(Node *n, Node *res) ...@@ -252,6 +252,16 @@ cgen(Node *n, Node *res)
regfree(&n1); regfree(&n1);
break; break;
} }
if(isdarray(nl->type)) {
regalloc(&n1, types[tptr], res);
agen(nl, &n1);
n1.op = OINDREG;
n1.type = types[TUINT32];
n1.xoffset = offsetof(Array,nel);
gmove(&n1, res);
regfree(&n1);
break;
}
fatal("cgen: OLEN: unknown type %lT", nl->type); fatal("cgen: OLEN: unknown type %lT", nl->type);
break; break;
...@@ -266,6 +276,16 @@ cgen(Node *n, Node *res) ...@@ -266,6 +276,16 @@ cgen(Node *n, Node *res)
regfree(&n1); regfree(&n1);
break; break;
} }
if(isdarray(nl->type)) {
regalloc(&n1, types[tptr], res);
agen(nl, &n1);
n1.op = OINDREG;
n1.type = types[TUINT32];
n1.xoffset = offsetof(Array,cap);
gmove(&n1, res);
regfree(&n1);
break;
}
fatal("cgen: OCAP: unknown type %lT", nl->type); fatal("cgen: OCAP: unknown type %lT", nl->type);
break; break;
...@@ -489,7 +509,7 @@ agen(Node *n, Node *res) ...@@ -489,7 +509,7 @@ agen(Node *n, Node *res)
if(v < 0) if(v < 0)
yyerror("out of bounds on array"); yyerror("out of bounds on array");
else else
if(isptrarray(nl->type)) { if(isptrsarray(nl->type)) {
if(v >= nl->type->type->bound) if(v >= nl->type->type->bound)
yyerror("out of bounds on array"); yyerror("out of bounds on array");
} else } else
...@@ -523,7 +543,7 @@ agen(Node *n, Node *res) ...@@ -523,7 +543,7 @@ agen(Node *n, Node *res)
n1.xoffset = offsetof(Array, nel); n1.xoffset = offsetof(Array, nel);
} else { } else {
nodconst(&n1, types[TUINT64], nl->type->bound); nodconst(&n1, types[TUINT64], nl->type->bound);
if(isptrarray(nl->type)) if(isptrsarray(nl->type))
nodconst(&n1, types[TUINT64], nl->type->type->bound); nodconst(&n1, types[TUINT64], nl->type->type->bound);
} }
gins(optoas(OCMP, types[TUINT32]), &n2, &n1); gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
...@@ -815,8 +835,9 @@ sgen(Node *n, Node *ns, int32 w) ...@@ -815,8 +835,9 @@ sgen(Node *n, Node *ns, int32 w)
int32 c, q, odst, osrc; int32 c, q, odst, osrc;
if(debug['g']) { if(debug['g']) {
dump("\nsgen-res", ns); print("\nsgen w=%d\n", w);
dump("sgen-r", n); dump("r", n);
dump("res", ns);
} }
if(w == 0) if(w == 0)
return; return;
...@@ -830,9 +851,6 @@ sgen(Node *n, Node *ns, int32 w) ...@@ -830,9 +851,6 @@ sgen(Node *n, Node *ns, int32 w)
// offset on the stack // offset on the stack
osrc = stkof(n); osrc = stkof(n);
odst = stkof(ns); odst = stkof(ns);
//print("\nnsrc=%N\n", n);
//print("ndst=%N\n", ns);
//print("osrc=%d odst=%d w=%d\n", osrc, odst, w);
nodreg(&nodl, types[tptr], D_DI); nodreg(&nodl, types[tptr], D_DI);
nodreg(&nodr, types[tptr], D_SI); nodreg(&nodr, types[tptr], D_SI);
......
...@@ -484,11 +484,6 @@ loop: ...@@ -484,11 +484,6 @@ loop:
fatal("stotype: oops %N\n", n); fatal("stotype: oops %N\n", n);
switch(n->type->etype) { switch(n->type->etype) {
case TARRAY:
if(n->type->bound < 0)
yyerror("type of a structure field cannot be an open array");
break;
case TCHAN: case TCHAN:
case TMAP: case TMAP:
case TSTRING: case TSTRING:
......
...@@ -69,9 +69,8 @@ typedef struct Array Array; ...@@ -69,9 +69,8 @@ typedef struct Array Array;
struct Array struct Array
{ // must not move anything { // must not move anything
uchar array[8]; // pointer to data uchar array[8]; // pointer to data
uint32 nel; // number of elements uchar nel[4]; // number of elements
uint32 cap; // allocated number of elements uchar cap[4]; // allocated number of elements
uchar b; // actual array - may not be contig
}; };
/* /*
...@@ -637,8 +636,10 @@ void dump(char*, Node*); ...@@ -637,8 +636,10 @@ void dump(char*, Node*);
Type* aindex(Node*, Type*); Type* aindex(Node*, Type*);
int isnil(Node*); int isnil(Node*);
int isptrto(Type*, int); int isptrto(Type*, int);
int isptrarray(Type*); int isptrsarray(Type*);
int isptrdarray(Type*); int isptrdarray(Type*);
int issarray(Type*);
int isdarray(Type*);
int isinter(Type*); int isinter(Type*);
int isnilinter(Type*); int isnilinter(Type*);
int isddd(Type*); int isddd(Type*);
......
...@@ -857,12 +857,12 @@ pexpr: ...@@ -857,12 +857,12 @@ pexpr:
| LNEW '(' type ')' | LNEW '(' type ')'
{ {
$$ = nod(ONEW, N, N); $$ = nod(ONEW, N, N);
$$->type = ptrto($3); $$->type = $3;
} }
| LNEW '(' type ',' expr_list ')' | LNEW '(' type ',' expr_list ')'
{ {
$$ = nod(ONEW, $5, N); $$ = nod(ONEW, $5, N);
$$->type = ptrto($3); $$->type = $3;
} }
| LCONVERT '(' type ',' keyexpr_list ')' | LCONVERT '(' type ',' keyexpr_list ')'
{ {
......
...@@ -440,6 +440,7 @@ aindex(Node *b, Type *t) ...@@ -440,6 +440,7 @@ aindex(Node *b, Type *t)
r = typ(TARRAY); r = typ(TARRAY);
r->type = t; r->type = t;
r->bound = bound; r->bound = bound;
dowidth(r);
return r; return r;
} }
...@@ -1421,7 +1422,7 @@ isptrto(Type *t, int et) ...@@ -1421,7 +1422,7 @@ isptrto(Type *t, int et)
} }
int int
isptrarray(Type *t) isptrsarray(Type *t)
{ {
if(isptrto(t, TARRAY)) if(isptrto(t, TARRAY))
if(t->type->bound >= 0) if(t->type->bound >= 0)
...@@ -1438,6 +1439,22 @@ isptrdarray(Type *t) ...@@ -1438,6 +1439,22 @@ isptrdarray(Type *t)
return 0; 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;
}
int int
isselect(Node *n) isselect(Node *n)
{ {
......
...@@ -26,7 +26,7 @@ export func slicestring(string, int, int) string; ...@@ -26,7 +26,7 @@ export func slicestring(string, int, int) string;
export func indexstring(string, int) byte; export func indexstring(string, int) byte;
export func intstring(int64) string; export func intstring(int64) string;
export func byteastring(*byte, int) string; export func byteastring(*byte, int) string;
export func arraystring(*[]byte) string; export func arraystring([]byte) string;
export func ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any); export func ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
export func ifaceI2T(sigt *byte, iface any) (ret any); export func ifaceI2T(sigt *byte, iface any) (ret any);
...@@ -79,10 +79,10 @@ export func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool); ...@@ -79,10 +79,10 @@ export func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
export func selectdefault(sel *byte) (selected bool); export func selectdefault(sel *byte) (selected bool);
export func selectgo(sel *byte); export func selectgo(sel *byte);
export func newarray(nel int, cap int, width int) (ary *[]any); export func newarray(nel int, cap int, width int) (ary []any);
export func arraysliced(old *[]any, lb int, hb int, width int) (ary *[]any); export func arraysliced(old []any, lb int, hb int, width int) (ary []any);
export func arrayslices(old *any, nel int, lb int, hb int, width int) (ary *[]any); export func arrayslices(old *any, nel int, lb int, hb int, width int) (ary []any);
export func arrays2d(old *any, nel int) (ary *[]any); export func arrays2d(old *any, nel int) (ary []any);
export func gosched(); export func gosched();
export func goexit(); export func goexit();
......
...@@ -19,7 +19,7 @@ char *sysimport = ...@@ -19,7 +19,7 @@ char *sysimport =
"export func sys.indexstring (? string, ? int) (? uint8)\n" "export func sys.indexstring (? string, ? int) (? uint8)\n"
"export func sys.intstring (? int64) (? string)\n" "export func sys.intstring (? int64) (? string)\n"
"export func sys.byteastring (? *uint8, ? int) (? string)\n" "export func sys.byteastring (? *uint8, ? int) (? string)\n"
"export func sys.arraystring (? *[]uint8) (? string)\n" "export func sys.arraystring (? []uint8) (? string)\n"
"export func sys.ifaceT2I (sigi *uint8, sigt *uint8, elem any) (ret any)\n" "export func sys.ifaceT2I (sigi *uint8, sigt *uint8, elem any) (ret any)\n"
"export func sys.ifaceI2T (sigt *uint8, iface any) (ret any)\n" "export func sys.ifaceI2T (sigt *uint8, iface any) (ret any)\n"
"export func sys.ifaceI2T2 (sigt *uint8, iface any) (ret any, ok bool)\n" "export func sys.ifaceI2T2 (sigt *uint8, iface any) (ret any, ok bool)\n"
...@@ -63,10 +63,10 @@ char *sysimport = ...@@ -63,10 +63,10 @@ char *sysimport =
"export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n" "export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n"
"export func sys.selectdefault (sel *uint8) (selected bool)\n" "export func sys.selectdefault (sel *uint8) (selected bool)\n"
"export func sys.selectgo (sel *uint8)\n" "export func sys.selectgo (sel *uint8)\n"
"export func sys.newarray (nel int, cap int, width int) (ary *[]any)\n" "export func sys.newarray (nel int, cap int, width int) (ary []any)\n"
"export func sys.arraysliced (old *[]any, lb int, hb int, width int) (ary *[]any)\n" "export func sys.arraysliced (old []any, lb int, hb int, width int) (ary []any)\n"
"export func sys.arrayslices (old *any, nel int, lb int, hb int, width int) (ary *[]any)\n" "export func sys.arrayslices (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
"export func sys.arrays2d (old *any, nel int) (ary *[]any)\n" "export func sys.arrays2d (old *any, nel int) (ary []any)\n"
"export func sys.gosched ()\n" "export func sys.gosched ()\n"
"export func sys.goexit ()\n" "export func sys.goexit ()\n"
"export func sys.readfile (? string) (? string, ? bool)\n" "export func sys.readfile (? string) (? string, ? bool)\n"
......
...@@ -592,7 +592,7 @@ loop: ...@@ -592,7 +592,7 @@ loop:
} }
// convert dynamic to static generated by ONEW // convert dynamic to static generated by ONEW
if(isptrarray(t) && isptrdarray(l->type)) if(issarray(t) && isdarray(l->type))
goto ret; goto ret;
// structure literal // structure literal
...@@ -1882,8 +1882,8 @@ ascompat(Type *t1, Type *t2) ...@@ -1882,8 +1882,8 @@ ascompat(Type *t1, Type *t2)
if(ismethod(t1)) if(ismethod(t1))
return 1; return 1;
if(isptrdarray(t1)) if(isdarray(t1))
if(isptrarray(t2)) if(issarray(t2))
return 1; return 1;
return 0; return 0;
...@@ -1992,45 +1992,69 @@ newcompat(Node *n) ...@@ -1992,45 +1992,69 @@ newcompat(Node *n)
Type *t; Type *t;
t = n->type; t = n->type;
if(t == T || !isptr[t->etype] || t->type == T) if(t == T)
fatal("newcompat: type should be pointer %lT", t); goto bad;
if(isptr[t->etype]) {
if(t->type == T)
goto bad;
t = t->type;
dowidth(t);
on = syslook("mal", 1);
argtype(on, t);
r = nodintconst(t->width);
r = nod(OCALL, on, r);
walktype(r, Erv);
r->type = n->type;
goto ret;
}
t = t->type;
switch(t->etype) { switch(t->etype) {
case TFUNC: default:
yyerror("cannot make new %T", t); goto bad;
break;
case TSTRUCT:
if(n->left != N)
yyerror("dont know what new(,e) means");
dowidth(t);
on = syslook("mal", 1);
argtype(on, t);
r = nodintconst(t->width);
r = nod(OCALL, on, r);
walktype(r, Erv);
r->type = ptrto(n->type);
return r;
case TMAP: case TMAP:
n->type = ptrto(n->type);
r = mapop(n, Erv); r = mapop(n, Erv);
return r; break;
case TCHAN: case TCHAN:
n->type = ptrto(n->type);
r = chanop(n, Erv); r = chanop(n, Erv);
return r; break;
case TARRAY: case TARRAY:
r = arrayop(n, Erv); r = arrayop(n, Erv);
return r; break;
} }
if(n->left != N) ret:
yyerror("dont know what new(,e) means");
dowidth(t);
on = syslook("mal", 1);
argtype(on, t);
r = nodintconst(t->width);
r = nod(OCALL, on, r);
walktype(r, Erv);
// r = nod(OCONV, r, N);
r->type = n->type;
return r; return r;
bad:
fatal("cannot make new %T", t);
return n;
} }
Node* Node*
...@@ -2119,10 +2143,8 @@ stringop(Node *n, int top) ...@@ -2119,10 +2143,8 @@ stringop(Node *n, int top)
break; break;
case OARRAY: case OARRAY:
// arraystring(*[]byte) string; // arraystring([]byte) string;
r = n->left; r = n->left;
if(!isptr[r->type->etype])
r = nod(OADDR, r, N);
on = syslook("arraystring", 0); on = syslook("arraystring", 0);
r = nod(OCALL, on, r); r = nod(OCALL, on, r);
break; break;
...@@ -2557,24 +2579,20 @@ shape: ...@@ -2557,24 +2579,20 @@ shape:
} }
Type* Type*
fixarray(Type *tm) fixarray(Type *t)
{ {
Type *t;
t = tm->type;
if(t == T) if(t == T)
goto bad; goto bad;
if(t->etype != TARRAY) if(t->etype != TARRAY)
goto bad; goto bad;
if(t->type == T) if(t->type == T)
goto bad; goto bad;
dowidth(t);
dowidth(t->type);
return t; return t;
bad: bad:
yyerror("not an array: %lT", tm); yyerror("not an array: %lT", t);
return T; return T;
} }
...@@ -2583,7 +2601,7 @@ Node* ...@@ -2583,7 +2601,7 @@ Node*
arrayop(Node *n, int top) arrayop(Node *n, int top)
{ {
Node *r, *a; Node *r, *a;
Type *t; Type *t, *tl;
Node *on; Node *on;
Iter save; Iter save;
...@@ -2592,8 +2610,30 @@ arrayop(Node *n, int top) ...@@ -2592,8 +2610,30 @@ arrayop(Node *n, int top)
default: default:
fatal("darrayop: unknown op %O", n->op); fatal("darrayop: unknown op %O", n->op);
case OAS:
// arrays2d(old *any, nel int) (ary []any)
t = fixarray(n->right->type);
tl = fixarray(n->left->type);
a = nodintconst(t->bound); // nel
a = nod(OCONV, a, N);
a->type = types[TINT];
r = a;
a = nod(OADDR, n->right, N); // old
r = list(a, r);
on = syslook("arrays2d", 1);
argtype(on, t); // any-1
argtype(on, tl->type); // any-2
r = nod(OCALL, on, r);
walktype(r, top);
n->right = r;
return n;
case ONEW: case ONEW:
// newarray(nel int, max int, width int) (ary *[]any) // newarray(nel int, max int, width int) (ary []any)
t = fixarray(n->type); t = fixarray(n->type);
a = nodintconst(t->type->width); // width a = nodintconst(t->type->width); // width
...@@ -2624,41 +2664,12 @@ arrayop(Node *n, int top) ...@@ -2624,41 +2664,12 @@ arrayop(Node *n, int top)
r = nod(OCALL, on, r); r = nod(OCALL, on, r);
walktype(r, top); walktype(r, top);
if(t->etype == TARRAY) {
// single case when we can convert a dynamic
// array pointer to a static array pointer
// saves making a sys function to alloc a static
r = nod(OCONV, r, N);
r->type = ptrto(t);
}
break; break;
case OAS:
// arrays2d(old *any, nel int) (ary *[]any)
t = fixarray(n->right->type);
a = nodintconst(t->bound); // nel
a = nod(OCONV, a, N);
a->type = types[TINT];
r = a;
a = n->right; // old
r = list(a, r);
on = syslook("arrays2d", 1);
argtype(on, n->right->type->type); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r);
walktype(r, top);
n->right = r;
return n;
case OSLICE: case OSLICE:
if(isptrarray(n->left->type)) // arrayslices(old any, nel int, lb int, hb int, width int) (ary []any)
goto slicestatic; // arraysliced(old []any, lb int, hb int, width int) (ary []any)
// arrayslices(old *[]any, lb int, hb int, width int) (ary *[]any)
t = fixarray(n->left->type); t = fixarray(n->left->type);
a = nodintconst(t->type->width); // width a = nodintconst(t->type->width); // width
...@@ -2674,44 +2685,29 @@ arrayop(Node *n, int top) ...@@ -2674,44 +2685,29 @@ arrayop(Node *n, int top)
a->type = types[TINT]; a->type = types[TINT];
r = list(a, r); r = list(a, r);
a = n->left; // old
r = list(a, r);
on = syslook("arraysliced", 1);
argtype(on, t->type); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r);
walktype(r, top);
break;
slicestatic:
// arrayslices(old *any, nel int, lb int, hb int, width int) (ary *[]any)
t = fixarray(n->left->type); t = fixarray(n->left->type);
if(t->bound >= 0) {
a = nodintconst(t->type->width); // width // static slice
a = nod(OCONV, a, N); a = nodintconst(t->bound); // nel
a->type = types[TINT]; a = nod(OCONV, a, N);
r = a; a->type = types[TINT];
r = list(a, r);
a = nod(OCONV, n->right->right, N); // hb
a->type = types[TINT]; a = nod(OADDR, n->left, N); // old
r = list(a, r); r = list(a, r);
a = nod(OCONV, n->right->left, N); // lb on = syslook("arrayslices", 1);
a->type = types[TINT]; argtype(on, t); // any-1
r = list(a, r); argtype(on, t->type); // any-2
} else {
a = nodintconst(t->bound); // nel // dynamic slice
a = nod(OCONV, a, N); a = n->left; // old
a->type = types[TINT]; r = list(a, r);
r = list(a, r);
on = syslook("arraysliced", 1);
a = n->left; // old argtype(on, t->type); // any-1
r = list(a, r); argtype(on, t->type); // any-2
}
on = syslook("arrayslices", 1);
argtype(on, t); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r); r = nod(OCALL, on, r);
walktype(r, top); walktype(r, top);
break; break;
...@@ -2899,7 +2895,7 @@ convas(Node *n) ...@@ -2899,7 +2895,7 @@ convas(Node *n)
goto out; goto out;
} }
if(isptrdarray(lt) && isptrarray(rt)) { if(isdarray(lt) && issarray(rt)) {
if(!eqtype(lt->type->type, rt->type->type, 0)) if(!eqtype(lt->type->type, rt->type->type, 0))
goto bad; goto bad;
indir(n, arrayop(n, Etop)); indir(n, arrayop(n, Etop));
......
...@@ -6,23 +6,20 @@ ...@@ -6,23 +6,20 @@
static int32 debug = 0; static int32 debug = 0;
// newarray(nel uint32, cap uint32, width uint32) (ary *[]any); // newarray(nel int, cap int, width int) (ary []any);
void void
sys·newarray(uint32 nel, uint32 cap, uint32 width, Array* ret) sys·newarray(uint32 nel, uint32 cap, uint32 width, Array ret)
{ {
Array *d;
uint64 size; uint64 size;
if(cap < nel) if(cap < nel)
cap = nel; cap = nel;
size = cap*width; size = cap*width;
d = mal(sizeof(*d) - sizeof(d->b) + size); ret.nel = nel;
d->nel = nel; ret.cap = cap;
d->cap = cap; ret.array = mal(size);
d->array = d->b;
ret = d;
FLUSH(&ret); FLUSH(&ret);
if(debug) { if(debug) {
...@@ -33,7 +30,7 @@ sys·newarray(uint32 nel, uint32 cap, uint32 width, Array* ret) ...@@ -33,7 +30,7 @@ sys·newarray(uint32 nel, uint32 cap, uint32 width, Array* ret)
prints("; width="); prints("; width=");
sys·printint(width); sys·printint(width);
prints("; ret="); prints("; ret=");
sys·printarray(ret); sys·printarray(&ret);
prints("\n"); prints("\n");
} }
} }
...@@ -51,16 +48,15 @@ throwslice(uint32 lb, uint32 hb, uint32 n) ...@@ -51,16 +48,15 @@ throwslice(uint32 lb, uint32 hb, uint32 n)
throw("array slice"); throw("array slice");
} }
// arraysliced(old *[]any, lb uint32, hb uint32, width uint32) (ary *[]any); // arraysliced(old []any, lb int, hb int, width int) (ary []any);
void void
sys·arraysliced(Array* old, uint32 lb, uint32 hb, uint32 width, Array* ret) sys·arraysliced(Array old, uint32 lb, uint32 hb, uint32 width, Array ret)
{ {
Array *d;
if(hb > old->cap || lb > hb) { if(hb > old.cap || lb > hb) {
if(debug) { if(debug) {
prints("sys·arrayslices: old="); prints("sys·arraysliced: old=");
sys·printpointer(old); sys·printarray(&old);
prints("; lb="); prints("; lb=");
sys·printint(lb); sys·printint(lb);
prints("; hb="); prints("; hb=");
...@@ -70,26 +66,24 @@ sys·arraysliced(Array* old, uint32 lb, uint32 hb, uint32 width, Array* ret) ...@@ -70,26 +66,24 @@ sys·arraysliced(Array* old, uint32 lb, uint32 hb, uint32 width, Array* ret)
prints("\n"); prints("\n");
prints("oldarray: nel="); prints("oldarray: nel=");
sys·printint(old->nel); sys·printint(old.nel);
prints("; cap="); prints("; cap=");
sys·printint(old->cap); sys·printint(old.cap);
prints("\n"); prints("\n");
} }
throwslice(lb, hb, old->cap); throwslice(lb, hb, old.cap);
} }
// new array is inside old array // new array is inside old array
d = mal(sizeof(*d) - sizeof(d->b)); ret.nel = hb-lb;
d->nel = hb-lb; ret.cap = old.cap - lb;
d->cap = old->cap - lb; ret.array = old.array + lb*width;
d->array = old->array + lb*width;
ret = d;
FLUSH(&ret); FLUSH(&ret);
if(debug) { if(debug) {
prints("sys·arrayslices: old="); prints("sys·arraysliced: old=");
sys·printarray(old); sys·printarray(&old);
prints("; lb="); prints("; lb=");
sys·printint(lb); sys·printint(lb);
prints("; hb="); prints("; hb=");
...@@ -97,16 +91,15 @@ sys·arraysliced(Array* old, uint32 lb, uint32 hb, uint32 width, Array* ret) ...@@ -97,16 +91,15 @@ sys·arraysliced(Array* old, uint32 lb, uint32 hb, uint32 width, Array* ret)
prints("; width="); prints("; width=");
sys·printint(width); sys·printint(width);
prints("; ret="); prints("; ret=");
sys·printarray(ret); sys·printarray(&ret);
prints("\n"); prints("\n");
} }
} }
// arrayslices(old *any, nel uint32, lb uint32, hb uint32, width uint32) (ary *[]any); // arrayslices(old *any, nel int, lb int, hb int, width int) (ary []any);
void void
sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Array* ret) sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Array ret)
{ {
Array *d;
if(hb > nel || lb > hb) { if(hb > nel || lb > hb) {
if(debug) { if(debug) {
...@@ -126,12 +119,10 @@ sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Arra ...@@ -126,12 +119,10 @@ sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Arra
} }
// new array is inside old array // new array is inside old array
d = mal(sizeof(*d) - sizeof(d->b)); ret.nel = hb-lb;
d->nel = hb-lb; ret.cap = nel-lb;
d->cap = nel-lb; ret.array = old + lb*width;
d->array = old + lb*width;
ret = d;
FLUSH(&ret); FLUSH(&ret);
if(debug) { if(debug) {
...@@ -146,31 +137,28 @@ sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Arra ...@@ -146,31 +137,28 @@ sys·arrayslices(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Arra
prints("; width="); prints("; width=");
sys·printint(width); sys·printint(width);
prints("; ret="); prints("; ret=");
sys·printarray(ret); sys·printarray(&ret);
prints("\n"); prints("\n");
} }
} }
// arrays2d(old *any, nel uint32) (ary *[]any) // arrays2d(old *any, nel int) (ary []any)
void void
sys·arrays2d(byte* old, uint32 nel, Array* ret) sys·arrays2d(byte* old, uint32 nel, Array ret)
{ {
Array *d;
// new dope to old array // new dope to old array
d = mal(sizeof(*d) - sizeof(d->b)); ret.nel = nel;
d->nel = nel; ret.cap = nel;
d->cap = nel; ret.array = old;
d->array = old;
ret = d;
FLUSH(&ret); FLUSH(&ret);
if(debug) { if(debug) {
prints("sys·arrays2d: old="); prints("sys·arrays2d: old=");
sys·printpointer(old); sys·printpointer(old);
prints("; ret="); prints("; ret=");
sys·printarray(ret); sys·printarray(&ret);
prints("\n"); prints("\n");
} }
} }
...@@ -180,7 +168,7 @@ sys·printarray(Array *a) ...@@ -180,7 +168,7 @@ sys·printarray(Array *a)
{ {
prints("["); prints("[");
sys·printint(a->nel); sys·printint(a->nel);
prints(","); prints("/");
sys·printint(a->cap); sys·printint(a->cap);
prints("]"); prints("]");
sys·printpointer(a->array); sys·printpointer(a->array);
......
...@@ -115,7 +115,6 @@ struct Array ...@@ -115,7 +115,6 @@ struct Array
byte* array; // actual data byte* array; // actual data
uint32 nel; // number of elements uint32 nel; // number of elements
uint32 cap; // allocated number of elements uint32 cap; // allocated number of elements
byte b[8]; // actual array - may not be contig
}; };
struct Gobuf struct Gobuf
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
package main package main
export func export func
setpd(a *[]int) setpd(a []int)
{ {
// print("setpd a=", a, " len=", len(a), " cap=", cap(a), "\n"); // print("setpd a=", a, " len=", len(a), " cap=", cap(a), "\n");
for i:=0; i<len(a); i++ { for i:=0; i<len(a); i++ {
...@@ -16,7 +16,7 @@ setpd(a *[]int) ...@@ -16,7 +16,7 @@ setpd(a *[]int)
} }
export func export func
sumpd(a *[]int) int sumpd(a []int) int
{ {
// print("sumpd a=", a, " len=", len(a), " cap=", cap(a), "\n"); // print("sumpd a=", a, " len=", len(a), " cap=", cap(a), "\n");
t := 0; t := 0;
...@@ -109,8 +109,8 @@ testpdpf2() ...@@ -109,8 +109,8 @@ testpdpf2()
{ {
var a [80]int; var a [80]int;
setpd(&a); setpd(a);
res(sumpd(&a), 0, 80); res(sumpd(a), 0, 80);
} }
// generate bounds error with ptr dynamic // generate bounds error with ptr dynamic
......
...@@ -6,7 +6,18 @@ ...@@ -6,7 +6,18 @@
package main package main
import rand "rand"
var randx int;
func
nrand(n int) int
{
randx += 10007;
if randx >= 1000000 {
randx -= 1000000;
}
return randx%n;
}
type Chan type Chan
struct struct
...@@ -31,7 +42,7 @@ init() ...@@ -31,7 +42,7 @@ init()
} }
func func
mkchan(c,n int) *[]*Chan mkchan(c,n int) []*Chan
{ {
ca := new([]*Chan, n); ca := new([]*Chan, n);
for i:=0; i<n; i++ { for i:=0; i<n; i++ {
...@@ -76,7 +87,7 @@ send(c *Chan) ...@@ -76,7 +87,7 @@ send(c *Chan)
{ {
nproc++; // total goroutines running nproc++; // total goroutines running
for { for {
for r:=rand.nrand(10); r>=0; r-- { for r:=nrand(10); r>=0; r-- {
sys.gosched(); sys.gosched();
} }
c.sc <- c.sv; c.sc <- c.sv;
...@@ -107,7 +118,7 @@ recv(c *Chan) ...@@ -107,7 +118,7 @@ recv(c *Chan)
nproc++; // total goroutines running nproc++; // total goroutines running
for { for {
for r:=rand.nrand(10); r>=0; r-- { for r:=nrand(10); r>=0; r-- {
sys.gosched(); sys.gosched();
} }
v = <-c.rc; v = <-c.rc;
...@@ -136,7 +147,7 @@ sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) ...@@ -136,7 +147,7 @@ sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan)
if s3.sc != nil { a++ } if s3.sc != nil { a++ }
for { for {
for r:=rand.nrand(5); r>=0; r-- { for r:=nrand(5); r>=0; r-- {
sys.gosched(); sys.gosched();
} }
......
...@@ -9,7 +9,7 @@ package main ...@@ -9,7 +9,7 @@ package main
const size = 16; const size = 16;
var a [size]byte; var a [size]byte;
var p *[]byte; var p []byte;
var m *map[int]byte; var m *map[int]byte;
func func
......
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