From 88b5c5f0f872e176be8e87b04c612817eeed5844 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Tue, 6 Jan 2009 14:52:26 -0800 Subject: [PATCH] make for slice/map/chan new for pointers R=r OCL=22158 CL=22158 --- src/cmd/gc/go.h | 3 +- src/cmd/gc/go.y | 15 ++++++++-- src/cmd/gc/lex.c | 1 + src/cmd/gc/subr.c | 1 + src/cmd/gc/walk.c | 70 ++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 5499b714a4..a5b103f5ab 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -292,7 +292,7 @@ enum OLIST, OCMP, OPTR, OARRAY, ORANGE, ORETURN, OFOR, OIF, OSWITCH, OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, - OGOTO, OPROC, ONEW, OEMPTY, OSELECT, + OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT, OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF, OOROR, @@ -789,6 +789,7 @@ int ascompat(Type*, Type*); Node* prcompat(Node*, int); Node* nodpanic(int32); Node* newcompat(Node*); +Node* makecompat(Node*); Node* stringop(Node*, int); Type* fixmap(Type*); Node* mapop(Node*, int); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index f6568a365b..275e740bb7 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -18,8 +18,8 @@ %token LPACKAGE LIMPORT LEXPORT %token LMAP LCHAN LINTERFACE LFUNC LSTRUCT %token LCOLAS LFALL LRETURN LDDD -%token LNEW LLEN LCAP LTYPEOF LPANIC LPANICN LPRINT LPRINTN -%token LVAR LTYPE LCONST LCONVERT LSELECT +%token LLEN LCAP LTYPEOF LPANIC LPANICN LPRINT LPRINTN +%token LVAR LTYPE LCONST LCONVERT LSELECT LMAKE LNEW %token LFOR LIF LELSE LSWITCH LCASE LDEFAULT %token LBREAK LCONTINUE LGO LGOTO LRANGE %token LNIL LTRUE LFALSE LIOTA @@ -864,6 +864,16 @@ pexpr: $$ = nod(ONEW, $5, N); $$->type = $3; } +| LMAKE '(' type ')' + { + $$ = nod(OMAKE, N, N); + $$->type = $3; + } +| LMAKE '(' type ',' expr_list ')' + { + $$ = nod(OMAKE, $5, N); + $$->type = $3; + } | latype '(' expr ')' { $$ = nod(OCONV, $3, N); @@ -980,6 +990,7 @@ sym3: | LPRINT | LPRINTN | LNEW +| LMAKE | LBASETYPE | LTYPEOF diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 874265a289..642824a774 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -1064,6 +1064,7 @@ static struct "import", LIMPORT, Txxx, "interface", LINTERFACE, Txxx, "iota", LIOTA, Txxx, + "make", LMAKE, Txxx, "map", LMAP, Txxx, "new", LNEW, Txxx, "len", LLEN, Txxx, diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 9b902838ad..66f9f99b73 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -708,6 +708,7 @@ opnames[] = [OVAR] = "VAR", [OIMPORT] = "IMPORT", [OXOR] = "XOR", + [OMAKE] = "MAKE", [ONEW] = "NEW", [OFALL] = "FALL", [OXFALL] = "XFALL", diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 6e04973009..bea9356efe 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -590,7 +590,7 @@ loop: } } - // convert dynamic to static generated by ONEW + // convert dynamic to static generated by ONEW/OMAKE if(issarray(t) && isdarray(l->type)) goto ret; @@ -979,7 +979,7 @@ loop: nvar = nod(0, N, N); tempname(nvar, t); - nnew = nod(ONEW, N, N); + nnew = nod(OMAKE, N, N); nnew->type = t; nnew = newcompat(nnew); @@ -1017,6 +1017,12 @@ loop: n->type = t->type; goto ret; + case OMAKE: + if(top != Erv) + goto nottop; + indir(n, makecompat(n)); + goto ret; + case ONEW: if(top != Erv) goto nottop; @@ -2014,7 +2020,7 @@ nodpanic(int32 lineno) } Node* -newcompat(Node *n) +makecompat(Node *n) { Node *r, *on; Type *t, *t0; @@ -2026,21 +2032,24 @@ newcompat(Node *n) if(t0->etype == TARRAY) return arrayop(n, Erv); - if(!isptr[t0->etype] || t0->type == T) + if(!isptr[t0->etype]) goto bad; t = t0->type; + if(t == T) + goto bad; + switch(t->etype) { case TSTRING: goto bad; - // the call looks like new(map[int]int) + // the call looks like new(MAP[int]int) // but internally we see new(*MAP[int]int) case TMAP: r = mapop(n, Erv); break; - // the call looks like new(chan int) + // the call looks like new(CHAN int) // but internally we see new(*CHAN int) case TCHAN: r = chanop(n, Erv); @@ -2048,7 +2057,42 @@ newcompat(Node *n) default: if(n->left != N) - yyerror("cannot new(%T, expr)", t0); + yyerror("cannot make(%T, expr)", t0); + dowidth(t); + on = syslook("mal", 1); + argtype(on, t); + r = nodintconst(t->width); + r = nod(OCALL, on, r); + walktype(r, Erv); + break; + } + + return r; + +bad: + yyerror("cannot make(%T)", t0); + return n; +} + +Node* +newcompat(Node *n) +{ + Node *r, *on; + Type *t, *t0; + + t = n->type; + if(t == T) + goto bad; + + switch(t->etype) { + case TSTRING: + case TMAP: + case TCHAN: + goto bad; + + default: + if(n->left != N) + yyerror("cannot new(%T, expr)", t); dowidth(t); on = syslook("mal", 1); argtype(on, t); @@ -2061,7 +2105,7 @@ newcompat(Node *n) return r; bad: - yyerror("cannot new(%T)", t0); + yyerror("cannot new(%T)", t); return n; } @@ -2224,7 +2268,7 @@ mapop(Node *n, int top) default: fatal("mapop: unknown op %O", n->op); - case ONEW: + case OMAKE: if(top != Erv) goto nottop; @@ -2436,7 +2480,7 @@ chanop(Node *n, int top) default: fatal("chanop: unknown op %O", n->op); - case ONEW: + case OMAKE: // newchan(elemsize int, elemalg int, // hint int) (hmap *chan[any-1]); @@ -2642,7 +2686,7 @@ arrayop(Node *n, int top) n->right = r; return n; - case ONEW: + case OMAKE: // newarray(nel int, max int, width int) (ary []any) t = fixarray(n->type); if(t == T) @@ -3523,7 +3567,7 @@ arraylit(Node *n) var = nod(OXXX, N, N); tempname(var, t); - nnew = nod(ONEW, N, N); + nnew = nod(OMAKE, N, N); nnew->type = t; nas = nod(OAS, var, nnew); @@ -3560,7 +3604,7 @@ maplit(Node *n) var = nod(OXXX, N, N); tempname(var, t); - a = nod(ONEW, N, N); + a = nod(OMAKE, N, N); a->type = t; a = nod(OAS, var, a); addtop = list(addtop, a); -- 2.48.1