w = wptr;
break;
case TARRAY:
+ if(t->type == T)
+ break;
dowidth(t->type);
- if(t->bound >= 0 && t->type != T)
+ w = sizeof(Array);
+ if(t->bound >= 0)
w = t->bound * t->type->width;
break;
}
regalloc(&n1, nl->type, res);
cgen(nl, &n1);
- if(isptrarray(n->type) && isptrdarray(nl->type)) {
+ if(isptrsarray(n->type) && isptrdarray(nl->type)) {
// convert dynamic array to static array
n2 = n1;
n2.op = OINDREG;
n2.type = types[tptr];
gins(AMOVQ, &n2, &n1);
}
- if(isptrdarray(n->type) && isptrarray(nl->type)) {
+ if(isptrdarray(n->type) && isptrsarray(nl->type)) {
// conver static array to dynamic 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);
}
gmove(&n1, res);
regfree(&n1);
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);
break;
regfree(&n1);
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);
break;
if(v < 0)
yyerror("out of bounds on array");
else
- if(isptrarray(nl->type)) {
+ if(isptrsarray(nl->type)) {
if(v >= nl->type->type->bound)
yyerror("out of bounds on array");
} else
n1.xoffset = offsetof(Array, nel);
} else {
nodconst(&n1, types[TUINT64], nl->type->bound);
- if(isptrarray(nl->type))
+ if(isptrsarray(nl->type))
nodconst(&n1, types[TUINT64], nl->type->type->bound);
}
gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
int32 c, q, odst, osrc;
if(debug['g']) {
- dump("\nsgen-res", ns);
- dump("sgen-r", n);
+ print("\nsgen w=%d\n", w);
+ dump("r", n);
+ dump("res", ns);
}
if(w == 0)
return;
// offset on the stack
osrc = stkof(n);
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(&nodr, types[tptr], D_SI);
fatal("stotype: oops %N\n", n);
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 TMAP:
case TSTRING:
struct Array
{ // must not move anything
uchar array[8]; // pointer to data
- uint32 nel; // number of elements
- uint32 cap; // allocated number of elements
- uchar b; // actual array - may not be contig
+ uchar nel[4]; // number of elements
+ uchar cap[4]; // allocated number of elements
};
/*
Type* aindex(Node*, Type*);
int isnil(Node*);
int isptrto(Type*, int);
-int isptrarray(Type*);
+int isptrsarray(Type*);
int isptrdarray(Type*);
+int issarray(Type*);
+int isdarray(Type*);
int isinter(Type*);
int isnilinter(Type*);
int isddd(Type*);
| LNEW '(' type ')'
{
$$ = nod(ONEW, N, N);
- $$->type = ptrto($3);
+ $$->type = $3;
}
| LNEW '(' type ',' expr_list ')'
{
$$ = nod(ONEW, $5, N);
- $$->type = ptrto($3);
+ $$->type = $3;
}
| LCONVERT '(' type ',' keyexpr_list ')'
{
r = typ(TARRAY);
r->type = t;
r->bound = bound;
+ dowidth(r);
return r;
}
}
int
-isptrarray(Type *t)
+isptrsarray(Type *t)
{
if(isptrto(t, TARRAY))
if(t->type->bound >= 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
isselect(Node *n)
{
export func indexstring(string, int) byte;
export func intstring(int64) 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 ifaceI2T(sigt *byte, iface any) (ret any);
export func selectdefault(sel *byte) (selected bool);
export func selectgo(sel *byte);
-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 arrayslices(old *any, nel int, lb int, hb int, width int) (ary *[]any);
-export func arrays2d(old *any, nel 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 arrayslices(old *any, nel int, lb int, hb int, width int) (ary []any);
+export func arrays2d(old *any, nel int) (ary []any);
export func gosched();
export func goexit();
"export func sys.indexstring (? string, ? int) (? uint8)\n"
"export func sys.intstring (? int64) (? 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.ifaceI2T (sigt *uint8, iface any) (ret any)\n"
"export func sys.ifaceI2T2 (sigt *uint8, iface any) (ret any, ok 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.selectgo (sel *uint8)\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.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.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.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.gosched ()\n"
"export func sys.goexit ()\n"
"export func sys.readfile (? string) (? string, ? bool)\n"
}
// convert dynamic to static generated by ONEW
- if(isptrarray(t) && isptrdarray(l->type))
+ if(issarray(t) && isdarray(l->type))
goto ret;
// structure literal
if(ismethod(t1))
return 1;
- if(isptrdarray(t1))
- if(isptrarray(t2))
+ if(isdarray(t1))
+ if(issarray(t2))
return 1;
return 0;
Type *t;
t = n->type;
- if(t == T || !isptr[t->etype] || t->type == T)
- fatal("newcompat: type should be pointer %lT", t);
+ if(t == 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) {
- case TFUNC:
- yyerror("cannot make new %T", t);
- break;
+ default:
+ goto bad;
+
+ 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:
+ n->type = ptrto(n->type);
r = mapop(n, Erv);
- return r;
+ break;
case TCHAN:
+ n->type = ptrto(n->type);
r = chanop(n, Erv);
- return r;
+ break;
case TARRAY:
r = arrayop(n, Erv);
- return r;
+ break;
}
- 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 = nod(OCONV, r, N);
- r->type = n->type;
-
+ret:
return r;
+
+bad:
+ fatal("cannot make new %T", t);
+ return n;
}
Node*
break;
case OARRAY:
- // arraystring(*[]byte) string;
+ // arraystring([]byte) string;
r = n->left;
- if(!isptr[r->type->etype])
- r = nod(OADDR, r, N);
on = syslook("arraystring", 0);
r = nod(OCALL, on, r);
break;
}
Type*
-fixarray(Type *tm)
+fixarray(Type *t)
{
- Type *t;
- t = tm->type;
if(t == T)
goto bad;
if(t->etype != TARRAY)
goto bad;
if(t->type == T)
goto bad;
-
- dowidth(t->type);
-
+ dowidth(t);
return t;
bad:
- yyerror("not an array: %lT", tm);
+ yyerror("not an array: %lT", t);
return T;
}
arrayop(Node *n, int top)
{
Node *r, *a;
- Type *t;
+ Type *t, *tl;
Node *on;
Iter save;
default:
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:
- // newarray(nel int, max int, width int) (ary *[]any)
+ // newarray(nel int, max int, width int) (ary []any)
t = fixarray(n->type);
a = nodintconst(t->type->width); // width
r = nod(OCALL, on, r);
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;
- 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:
- if(isptrarray(n->left->type))
- goto slicestatic;
+ // arrayslices(old any, nel int, lb int, hb int, width int) (ary []any)
+ // 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);
a = nodintconst(t->type->width); // width
a->type = types[TINT];
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);
-
- a = nodintconst(t->type->width); // width
- a = nod(OCONV, a, N);
- a->type = types[TINT];
- r = a;
-
- a = nod(OCONV, n->right->right, N); // hb
- a->type = types[TINT];
- r = list(a, r);
-
- a = nod(OCONV, n->right->left, N); // lb
- a->type = types[TINT];
- r = list(a, r);
-
- a = nodintconst(t->bound); // nel
- a = nod(OCONV, a, N);
- a->type = types[TINT];
- r = list(a, r);
-
- a = n->left; // old
- r = list(a, r);
-
- on = syslook("arrayslices", 1);
- argtype(on, t); // any-1
- argtype(on, t->type); // any-2
+ if(t->bound >= 0) {
+ // static slice
+ a = nodintconst(t->bound); // nel
+ a = nod(OCONV, a, N);
+ a->type = types[TINT];
+ r = list(a, r);
+
+ a = nod(OADDR, n->left, N); // old
+ r = list(a, r);
+
+ on = syslook("arrayslices", 1);
+ argtype(on, t); // any-1
+ argtype(on, t->type); // any-2
+ } else {
+ // dynamic slice
+ 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;
goto out;
}
- if(isptrdarray(lt) && isptrarray(rt)) {
+ if(isdarray(lt) && issarray(rt)) {
if(!eqtype(lt->type->type, rt->type->type, 0))
goto bad;
indir(n, arrayop(n, Etop));
static int32 debug = 0;
-// newarray(nel uint32, cap uint32, width uint32) (ary *[]any);
+// newarray(nel int, cap int, width int) (ary []any);
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;
if(cap < nel)
cap = nel;
size = cap*width;
- d = mal(sizeof(*d) - sizeof(d->b) + size);
- d->nel = nel;
- d->cap = cap;
- d->array = d->b;
+ ret.nel = nel;
+ ret.cap = cap;
+ ret.array = mal(size);
- ret = d;
FLUSH(&ret);
if(debug) {
prints("; width=");
sys·printint(width);
prints("; ret=");
- sys·printarray(ret);
+ sys·printarray(&ret);
prints("\n");
}
}
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
-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) {
- prints("sys·arrayslices: old=");
- sys·printpointer(old);
+ prints("sys·arraysliced: old=");
+ sys·printarray(&old);
prints("; lb=");
sys·printint(lb);
prints("; hb=");
prints("\n");
prints("oldarray: nel=");
- sys·printint(old->nel);
+ sys·printint(old.nel);
prints("; cap=");
- sys·printint(old->cap);
+ sys·printint(old.cap);
prints("\n");
}
- throwslice(lb, hb, old->cap);
+ throwslice(lb, hb, old.cap);
}
// new array is inside old array
- d = mal(sizeof(*d) - sizeof(d->b));
- d->nel = hb-lb;
- d->cap = old->cap - lb;
- d->array = old->array + lb*width;
+ ret.nel = hb-lb;
+ ret.cap = old.cap - lb;
+ ret.array = old.array + lb*width;
- ret = d;
FLUSH(&ret);
if(debug) {
- prints("sys·arrayslices: old=");
- sys·printarray(old);
+ prints("sys·arraysliced: old=");
+ sys·printarray(&old);
prints("; lb=");
sys·printint(lb);
prints("; hb=");
prints("; width=");
sys·printint(width);
prints("; ret=");
- sys·printarray(ret);
+ sys·printarray(&ret);
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
-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(debug) {
}
// new array is inside old array
- d = mal(sizeof(*d) - sizeof(d->b));
- d->nel = hb-lb;
- d->cap = nel-lb;
- d->array = old + lb*width;
+ ret.nel = hb-lb;
+ ret.cap = nel-lb;
+ ret.array = old + lb*width;
- ret = d;
FLUSH(&ret);
if(debug) {
prints("; width=");
sys·printint(width);
prints("; ret=");
- sys·printarray(ret);
+ sys·printarray(&ret);
prints("\n");
}
}
-// arrays2d(old *any, nel uint32) (ary *[]any)
+// arrays2d(old *any, nel int) (ary []any)
void
-sys·arrays2d(byte* old, uint32 nel, Array* ret)
+sys·arrays2d(byte* old, uint32 nel, Array ret)
{
- Array *d;
// new dope to old array
- d = mal(sizeof(*d) - sizeof(d->b));
- d->nel = nel;
- d->cap = nel;
- d->array = old;
+ ret.nel = nel;
+ ret.cap = nel;
+ ret.array = old;
- ret = d;
FLUSH(&ret);
if(debug) {
prints("sys·arrays2d: old=");
sys·printpointer(old);
prints("; ret=");
- sys·printarray(ret);
+ sys·printarray(&ret);
prints("\n");
}
}
{
prints("[");
sys·printint(a->nel);
- prints(",");
+ prints("/");
sys·printint(a->cap);
prints("]");
sys·printpointer(a->array);
byte* array; // actual data
uint32 nel; // number of elements
uint32 cap; // allocated number of elements
- byte b[8]; // actual array - may not be contig
};
struct Gobuf
{
package main
export func
-setpd(a *[]int)
+setpd(a []int)
{
// print("setpd a=", a, " len=", len(a), " cap=", cap(a), "\n");
for i:=0; i<len(a); i++ {
}
export func
-sumpd(a *[]int) int
+sumpd(a []int) int
{
// print("sumpd a=", a, " len=", len(a), " cap=", cap(a), "\n");
t := 0;
{
var a [80]int;
- setpd(&a);
- res(sumpd(&a), 0, 80);
+ setpd(a);
+ res(sumpd(a), 0, 80);
}
// generate bounds error with ptr dynamic
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
struct
}
func
-mkchan(c,n int) *[]*Chan
+mkchan(c,n int) []*Chan
{
ca := new([]*Chan, n);
for i:=0; i<n; i++ {
{
nproc++; // total goroutines running
for {
- for r:=rand.nrand(10); r>=0; r-- {
+ for r:=nrand(10); r>=0; r-- {
sys.gosched();
}
c.sc <- c.sv;
nproc++; // total goroutines running
for {
- for r:=rand.nrand(10); r>=0; r-- {
+ for r:=nrand(10); r>=0; r-- {
sys.gosched();
}
v = <-c.rc;
if s3.sc != nil { a++ }
for {
- for r:=rand.nrand(5); r>=0; r-- {
+ for r:=nrand(5); r>=0; r-- {
sys.gosched();
}
const size = 16;
var a [size]byte;
-var p *[]byte;
+var p []byte;
var m *map[int]byte;
func