summaryrefslogtreecommitdiff
path: root/src/cmd/gc/walk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/walk.c')
-rw-r--r--src/cmd/gc/walk.c214
1 files changed, 105 insertions, 109 deletions
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 7c17794a5..b2bea4f62 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -592,7 +592,7 @@ loop:
}
// convert dynamic to static generated by ONEW
- if(isptrarray(t) && isptrdarray(l->type))
+ if(issarray(t) && isdarray(l->type))
goto ret;
// structure literal
@@ -1882,8 +1882,8 @@ ascompat(Type *t1, Type *t2)
if(ismethod(t1))
return 1;
- if(isptrdarray(t1))
- if(isptrarray(t2))
+ if(isdarray(t1))
+ if(issarray(t2))
return 1;
return 0;
@@ -1992,45 +1992,69 @@ newcompat(Node *n)
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*
@@ -2119,10 +2143,8 @@ stringop(Node *n, int top)
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;
@@ -2557,24 +2579,20 @@ shape:
}
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;
}
@@ -2583,7 +2601,7 @@ Node*
arrayop(Node *n, int top)
{
Node *r, *a;
- Type *t;
+ Type *t, *tl;
Node *on;
Iter save;
@@ -2592,8 +2610,30 @@ arrayop(Node *n, int top)
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
@@ -2624,41 +2664,12 @@ arrayop(Node *n, int top)
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
@@ -2674,44 +2685,29 @@ arrayop(Node *n, int top)
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;
@@ -2899,7 +2895,7 @@ convas(Node *n)
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));