1
0
mirror of https://github.com/golang/go synced 2024-11-22 05:34:39 -07:00

code to assign nil to an interface

without conversions

SVN=114453
This commit is contained in:
Ken Thompson 2008-03-31 19:19:37 -07:00
parent 5918f80f1a
commit e73674b291
6 changed files with 54 additions and 11 deletions

View File

@ -827,19 +827,19 @@ loop:
break; break;
case PAS_SINGLE: // single return val used in expr case PAS_SINGLE: // single return val used in expr
if(nr == N) { if(nr == N || isnil(nr)) {
if(nl->addable) { if(nl->addable) {
gopcodet(PSTOREZ, nl->type, nl); gopcodet(PSTOREZ, nl->type, nl);
break; break;
} }
agen(nl); agen(nl);
gopcodet(PSTOREZIP, nl->type, N); gopcodet(PSTOREZI, nl->type, N);
break; break;
} }
if(nl->addable) { if(nl->addable) {
cgen(nr); cgen(nr);
genconv(nl->type, nr->type); genconv(nl, nr);
gopcodet(PSTORE, nl->type, nl); gopcodet(PSTORE, nl->type, nl);
break; break;
} }
@ -851,7 +851,7 @@ loop:
} }
if(!usesptr(nr)) { if(!usesptr(nr)) {
cgen(nr); cgen(nr);
genconv(nl->type, nr->type); genconv(nl, nr);
agen(nl); agen(nl);
gopcodet(PSTOREI, nr->type, N); gopcodet(PSTOREI, nr->type, N);
break; break;
@ -860,7 +860,7 @@ loop:
r = tempname(ptrto(nl->type)); r = tempname(ptrto(nl->type));
gopcode(PSTORE, PTADDR, r); gopcode(PSTORE, PTADDR, r);
cgen(nr); cgen(nr);
genconv(nl->type, nr->type); genconv(nl, nr);
gopcode(PLOAD, PTADDR, r); gopcode(PLOAD, PTADDR, r);
gopcodet(PSTOREI, nl->type, N); gopcodet(PSTOREI, nl->type, N);
break; break;
@ -964,7 +964,7 @@ cgen_ret(Node *n)
gopcodet(PSTOREI, arg->type, arg); gopcodet(PSTOREI, arg->type, arg);
} else { } else {
cgen(arg); cgen(arg);
genconv(f->type, arg->type); genconv(f, arg);
gopcode(PLOAD, PTADDR, a->nname); gopcode(PLOAD, PTADDR, a->nname);
gopcode(PADDO, PTADDR, f->nname); gopcode(PADDO, PTADDR, f->nname);
gopcodet(PSTOREI, f->type, N); gopcodet(PSTOREI, f->type, N);
@ -1010,7 +1010,7 @@ cgen_call(Node *n, int toss)
gopcodet(PSTOREI, at->type, ae); gopcodet(PSTOREI, at->type, ae);
} else { } else {
cgen(ae); cgen(ae);
genconv(at->type, ae->type); genconv(at, ae);
gopcode(PADDR, PTADDR, sn); gopcode(PADDR, PTADDR, sn);
gopcode(PADDO, PTADDR, at->nname); gopcode(PADDO, PTADDR, at->nname);
gopcodet(PSTOREI, at->type, N); gopcodet(PSTOREI, at->type, N);
@ -1120,9 +1120,13 @@ genprint(Node *n)
int int
needconvert(Node *tl, Node *tr) needconvert(Node *tl, Node *tr)
{ {
if(isinter(tl)) if(isinter(tl)) {
if(isptrto(tr, TSTRUCT) || isinter(tr)) if(isptrto(tr, TSTRUCT))
return 1; return 1;
if(isinter(tr))
return 1;
return 0;
}
if(isptrto(tl, TSTRUCT)) if(isptrto(tl, TSTRUCT))
if(isinter(tr)) if(isinter(tr))
return 1; return 1;
@ -1130,8 +1134,12 @@ needconvert(Node *tl, Node *tr)
} }
void void
genconv(Node *tl, Node *tr) genconv(Node *l, Node *r)
{ {
Node *tl, *tr;
tl = l->type;
tr = r->type;
if(needconvert(tl, tr)) if(needconvert(tl, tr))
gopcode(PCONV, PTNIL, nod(OCONV, tl, tr)); gopcode(PCONV, PTNIL, nod(OCONV, tl, tr));
} }

View File

@ -103,7 +103,7 @@ enum
PLOAD, PLOADI, PLOAD, PLOADI,
PSTORE, PSTOREI, PSTORE, PSTOREI,
PSTOREZ, PSTOREZIP, PSTOREZ, PSTOREZI,
PCONV, PADDR, PADDO, PINDEX, PINDEXZ, PCONV, PADDR, PADDO, PINDEX, PINDEXZ,
PSLICE, PSLICE,

View File

@ -395,6 +395,7 @@ Node* unrev(Node*);
void dodump(Node*, int); void dodump(Node*, int);
void dump(char*, Node*); void dump(char*, Node*);
Node* aindex(Node*, Node*); Node* aindex(Node*, Node*);
int isnil(Node*);
int isptrto(Node*, int); int isptrto(Node*, int);
int isinter(Node*); int isinter(Node*);
int isbytearray(Node*); int isbytearray(Node*);

View File

@ -236,6 +236,7 @@ pnames[] =
[PSTORE] = "STORE", [PSTORE] = "STORE",
[PSTOREI] = "STOREI", [PSTOREI] = "STOREI",
[PSTOREZ] = "STOREZ", [PSTOREZ] = "STOREZ",
[PSTOREZI] = "STOREZI",
[PCONV] = "CONV", [PCONV] = "CONV",
[PADDR] = "ADDR", [PADDR] = "ADDR",
[PADDO] = "ADDO", [PADDO] = "ADDO",

View File

@ -243,6 +243,27 @@ obj1(Prog *p)
} }
break; break;
case PSTOREZI:
switch(p->pt) {
default:
Bprint(bout, "\t*(%Q*)%R = 0;\n", p->pt, PTADDR);
break;
case PTARRAY:
case PTSTRUCT:
Bprint(bout, "\tmemset((%Q*)%R, 0, sizeof((%Q*)%R));\n", p->pt, PTADDR, p->pt, PTADDR);
break;
case PTINTER:
Bprint(bout, "\t((%Q*)%R)->s = 0; ((%Q*)%R)->m = 0;\n", p->pt, PTADDR, p->pt, PTADDR);
break;
case PTSTRING:
Bprint(bout, "\t(%Q*)%R = &nilstring;\n", p->pt, PTADDR);
break;
}
break;
case PCONV: case PCONV:
doconv(p); doconv(p);
break; break;

View File

@ -997,6 +997,18 @@ out:
return fmtstrcpy(fp, buf); return fmtstrcpy(fp, buf);
} }
int
isnil(Node *n)
{
if(n == N)
return 0;
if(n->op != OLITERAL)
return 0;
if(n->val.ctype != CTNIL)
return 0;
return 1;
}
int int
isptrto(Node *t, int et) isptrto(Node *t, int et)
{ {