diff options
Diffstat (limited to 'src/cmd/gc/walk.c')
-rw-r--r-- | src/cmd/gc/walk.c | 214 |
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)); |