mirror of
https://github.com/golang/go
synced 2024-11-21 18:14:42 -07:00
gc: typecheck the whole tree before walking. preparation for some escape-analysis related changes.
R=rsc CC=golang-dev https://golang.org/cl/4528116
This commit is contained in:
parent
ef2d5f68d0
commit
e59aa8ea4a
@ -15,16 +15,17 @@ HFILES=\
|
|||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
../5l/enam.$O\
|
../5l/enam.$O\
|
||||||
list.$O\
|
|
||||||
galign.$O\
|
|
||||||
gobj.$O\
|
|
||||||
ggen.$O\
|
|
||||||
gsubr.$O\
|
|
||||||
cgen.$O\
|
cgen.$O\
|
||||||
cgen64.$O\
|
cgen64.$O\
|
||||||
cplx.$O\
|
cplx.$O\
|
||||||
reg.$O\
|
galign.$O\
|
||||||
|
ggen.$O\
|
||||||
|
gobj.$O\
|
||||||
|
gsubr.$O\
|
||||||
|
list.$O\
|
||||||
peep.$O\
|
peep.$O\
|
||||||
|
pgen.$O\
|
||||||
|
reg.$O\
|
||||||
|
|
||||||
LIB=\
|
LIB=\
|
||||||
../gc/gc.a\
|
../gc/gc.a\
|
||||||
|
@ -7,107 +7,9 @@
|
|||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "opt.h"
|
||||||
|
|
||||||
static Prog *pret;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(Node *fn)
|
defframe(Prog *ptxt)
|
||||||
{
|
{
|
||||||
Plist *pl;
|
|
||||||
Node nod1;
|
|
||||||
Prog *ptxt;
|
|
||||||
int32 lno;
|
|
||||||
Type *t;
|
|
||||||
Iter save;
|
|
||||||
|
|
||||||
if(newproc == N) {
|
|
||||||
newproc = sysfunc("newproc");
|
|
||||||
deferproc = sysfunc("deferproc");
|
|
||||||
deferreturn = sysfunc("deferreturn");
|
|
||||||
panicindex = sysfunc("panicindex");
|
|
||||||
panicslice = sysfunc("panicslice");
|
|
||||||
throwreturn = sysfunc("throwreturn");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fn->nbody == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// set up domain for labels
|
|
||||||
clearlabels();
|
|
||||||
|
|
||||||
lno = setlineno(fn);
|
|
||||||
|
|
||||||
curfn = fn;
|
|
||||||
dowidth(curfn->type);
|
|
||||||
|
|
||||||
if(curfn->type->outnamed) {
|
|
||||||
// add clearing of the output parameters
|
|
||||||
t = structfirst(&save, getoutarg(curfn->type));
|
|
||||||
while(t != T) {
|
|
||||||
if(t->nname != N)
|
|
||||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
|
||||||
t = structnext(&save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hasdefer = 0;
|
|
||||||
walk(curfn);
|
|
||||||
if(nerrors != 0 || isblank(curfn->nname))
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
allocparams();
|
|
||||||
|
|
||||||
continpc = P;
|
|
||||||
breakpc = P;
|
|
||||||
|
|
||||||
pl = newplist();
|
|
||||||
pl->name = curfn->nname;
|
|
||||||
|
|
||||||
setlineno(curfn);
|
|
||||||
|
|
||||||
nodconst(&nod1, types[TINT32], 0);
|
|
||||||
ptxt = gins(ATEXT, curfn->nname, &nod1);
|
|
||||||
afunclit(&ptxt->from);
|
|
||||||
|
|
||||||
ginit();
|
|
||||||
genlist(curfn->enter);
|
|
||||||
|
|
||||||
pret = nil;
|
|
||||||
if(hasdefer || curfn->exit) {
|
|
||||||
Prog *p1;
|
|
||||||
|
|
||||||
p1 = gjmp(nil);
|
|
||||||
pret = gjmp(nil);
|
|
||||||
patch(p1, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
genlist(curfn->nbody);
|
|
||||||
gclean();
|
|
||||||
checklabels();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
if(curfn->type->outtuple != 0)
|
|
||||||
ginscall(throwreturn, 0);
|
|
||||||
|
|
||||||
if(pret)
|
|
||||||
patch(pret, pc);
|
|
||||||
ginit();
|
|
||||||
if(hasdefer)
|
|
||||||
ginscall(deferreturn, 0);
|
|
||||||
if(curfn->exit)
|
|
||||||
genlist(curfn->exit);
|
|
||||||
gclean();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
if(curfn->endlineno)
|
|
||||||
lineno = curfn->endlineno;
|
|
||||||
pc->as = ARET; // overwrite AEND
|
|
||||||
pc->lineno = lineno;
|
|
||||||
|
|
||||||
if(!debug['N'] || debug['R'] || debug['P']) {
|
|
||||||
regopt(ptxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill in argument size
|
// fill in argument size
|
||||||
ptxt->to.type = D_CONST2;
|
ptxt->to.type = D_CONST2;
|
||||||
ptxt->reg = 0; // flags
|
ptxt->reg = 0; // flags
|
||||||
@ -118,12 +20,6 @@ compile(Node *fn)
|
|||||||
maxstksize = stksize;
|
maxstksize = stksize;
|
||||||
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
|
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
|
||||||
maxstksize = 0;
|
maxstksize = 0;
|
||||||
|
|
||||||
if(debug['f'])
|
|
||||||
frame(0);
|
|
||||||
|
|
||||||
ret:
|
|
||||||
lineno = lno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -197,7 +93,7 @@ ginscall(Node *f, int proc)
|
|||||||
nodconst(&con, types[TINT32], 0);
|
nodconst(&con, types[TINT32], 0);
|
||||||
p = gins(ACMP, &con, N);
|
p = gins(ACMP, &con, N);
|
||||||
p->reg = 0;
|
p->reg = 0;
|
||||||
patch(gbranch(ABNE, T), pret);
|
patch(gbranch(ABNE, T), retpc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -401,7 +297,7 @@ cgen_ret(Node *n)
|
|||||||
{
|
{
|
||||||
genlist(n->list); // copy out args
|
genlist(n->list); // copy out args
|
||||||
if(hasdefer || curfn->exit)
|
if(hasdefer || curfn->exit)
|
||||||
gjmp(pret);
|
gjmp(retpc);
|
||||||
else
|
else
|
||||||
gins(ARET, N, N);
|
gins(ARET, N, N);
|
||||||
}
|
}
|
||||||
|
@ -14,16 +14,17 @@ HFILES=\
|
|||||||
opt.h\
|
opt.h\
|
||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
list.$O\
|
../6l/enam.$O\
|
||||||
gobj.$O\
|
|
||||||
galign.$O\
|
|
||||||
ggen.$O\
|
|
||||||
cgen.$O\
|
cgen.$O\
|
||||||
cplx.$O\
|
cplx.$O\
|
||||||
|
galign.$O\
|
||||||
|
ggen.$O\
|
||||||
|
gobj.$O\
|
||||||
gsubr.$O\
|
gsubr.$O\
|
||||||
|
list.$O\
|
||||||
peep.$O\
|
peep.$O\
|
||||||
|
pgen.$O\
|
||||||
reg.$O\
|
reg.$O\
|
||||||
../6l/enam.$O\
|
|
||||||
|
|
||||||
LIB=\
|
LIB=\
|
||||||
../gc/gc.a\
|
../gc/gc.a\
|
||||||
|
@ -7,121 +7,18 @@
|
|||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "opt.h"
|
||||||
|
|
||||||
static Prog *pret;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(Node *fn)
|
defframe(Prog *ptxt)
|
||||||
{
|
{
|
||||||
Plist *pl;
|
|
||||||
Node nod1;
|
|
||||||
Prog *ptxt;
|
|
||||||
int32 lno;
|
|
||||||
Type *t;
|
|
||||||
Iter save;
|
|
||||||
|
|
||||||
if(newproc == N) {
|
|
||||||
newproc = sysfunc("newproc");
|
|
||||||
deferproc = sysfunc("deferproc");
|
|
||||||
deferreturn = sysfunc("deferreturn");
|
|
||||||
panicindex = sysfunc("panicindex");
|
|
||||||
panicslice = sysfunc("panicslice");
|
|
||||||
throwreturn = sysfunc("throwreturn");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fn->nbody == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// set up domain for labels
|
|
||||||
clearlabels();
|
|
||||||
|
|
||||||
lno = setlineno(fn);
|
|
||||||
|
|
||||||
curfn = fn;
|
|
||||||
dowidth(curfn->type);
|
|
||||||
|
|
||||||
if(curfn->type->outnamed) {
|
|
||||||
// add clearing of the output parameters
|
|
||||||
t = structfirst(&save, getoutarg(curfn->type));
|
|
||||||
while(t != T) {
|
|
||||||
if(t->nname != N)
|
|
||||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
|
||||||
t = structnext(&save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hasdefer = 0;
|
|
||||||
walk(curfn);
|
|
||||||
if(nerrors != 0 || isblank(curfn->nname))
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
allocparams();
|
|
||||||
|
|
||||||
continpc = P;
|
|
||||||
breakpc = P;
|
|
||||||
|
|
||||||
pl = newplist();
|
|
||||||
pl->name = curfn->nname;
|
|
||||||
|
|
||||||
setlineno(curfn);
|
|
||||||
|
|
||||||
nodconst(&nod1, types[TINT32], 0);
|
|
||||||
ptxt = gins(ATEXT, curfn->nname, &nod1);
|
|
||||||
afunclit(&ptxt->from);
|
|
||||||
|
|
||||||
ginit();
|
|
||||||
genlist(curfn->enter);
|
|
||||||
|
|
||||||
pret = nil;
|
|
||||||
if(hasdefer || curfn->exit) {
|
|
||||||
Prog *p1;
|
|
||||||
|
|
||||||
p1 = gjmp(nil);
|
|
||||||
pret = gjmp(nil);
|
|
||||||
patch(p1, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
genlist(curfn->nbody);
|
|
||||||
gclean();
|
|
||||||
checklabels();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
if(curfn->endlineno)
|
|
||||||
lineno = curfn->endlineno;
|
|
||||||
|
|
||||||
if(curfn->type->outtuple != 0)
|
|
||||||
ginscall(throwreturn, 0);
|
|
||||||
|
|
||||||
if(pret)
|
|
||||||
patch(pret, pc);
|
|
||||||
ginit();
|
|
||||||
if(hasdefer)
|
|
||||||
ginscall(deferreturn, 0);
|
|
||||||
if(curfn->exit)
|
|
||||||
genlist(curfn->exit);
|
|
||||||
gclean();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
pc->as = ARET; // overwrite AEND
|
|
||||||
pc->lineno = lineno;
|
|
||||||
|
|
||||||
if(!debug['N'] || debug['R'] || debug['P']) {
|
|
||||||
regopt(ptxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill in argument size
|
// fill in argument size
|
||||||
ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
|
ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
|
||||||
|
|
||||||
// fill in final stack size
|
// fill in final stack size
|
||||||
ptxt->to.offset <<= 32;
|
ptxt->to.offset <<= 32;
|
||||||
ptxt->to.offset |= rnd(stksize+maxarg, widthptr);
|
ptxt->to.offset |= rnd(stksize+maxarg, widthptr);
|
||||||
|
|
||||||
if(debug['f'])
|
|
||||||
frame(0);
|
|
||||||
|
|
||||||
ret:
|
|
||||||
lineno = lno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generate:
|
* generate:
|
||||||
* call f
|
* call f
|
||||||
@ -163,7 +60,7 @@ ginscall(Node *f, int proc)
|
|||||||
if(proc == 2) {
|
if(proc == 2) {
|
||||||
nodreg(®, types[TINT64], D_AX);
|
nodreg(®, types[TINT64], D_AX);
|
||||||
gins(ATESTQ, ®, ®);
|
gins(ATESTQ, ®, ®);
|
||||||
patch(gbranch(AJNE, T), pret);
|
patch(gbranch(AJNE, T), retpc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -355,7 +252,7 @@ cgen_ret(Node *n)
|
|||||||
{
|
{
|
||||||
genlist(n->list); // copy out args
|
genlist(n->list); // copy out args
|
||||||
if(hasdefer || curfn->exit)
|
if(hasdefer || curfn->exit)
|
||||||
gjmp(pret);
|
gjmp(retpc);
|
||||||
else
|
else
|
||||||
gins(ARET, N, N);
|
gins(ARET, N, N);
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,16 @@ HFILES=\
|
|||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
../8l/enam.$O\
|
../8l/enam.$O\
|
||||||
list.$O\
|
|
||||||
galign.$O\
|
|
||||||
gobj.$O\
|
|
||||||
ggen.$O\
|
|
||||||
gsubr.$O\
|
|
||||||
cgen.$O\
|
cgen.$O\
|
||||||
cgen64.$O\
|
cgen64.$O\
|
||||||
cplx.$O\
|
cplx.$O\
|
||||||
|
galign.$O\
|
||||||
|
ggen.$O\
|
||||||
|
gobj.$O\
|
||||||
|
gsubr.$O\
|
||||||
|
list.$O\
|
||||||
peep.$O\
|
peep.$O\
|
||||||
|
pgen.$O\
|
||||||
reg.$O\
|
reg.$O\
|
||||||
|
|
||||||
LIB=\
|
LIB=\
|
||||||
|
@ -7,106 +7,9 @@
|
|||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "opt.h"
|
||||||
|
|
||||||
static Prog *pret;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(Node *fn)
|
defframe(Prog *ptxt)
|
||||||
{
|
{
|
||||||
Plist *pl;
|
|
||||||
Node nod1;
|
|
||||||
Prog *ptxt;
|
|
||||||
int32 lno;
|
|
||||||
Type *t;
|
|
||||||
Iter save;
|
|
||||||
|
|
||||||
if(newproc == N) {
|
|
||||||
newproc = sysfunc("newproc");
|
|
||||||
deferproc = sysfunc("deferproc");
|
|
||||||
deferreturn = sysfunc("deferreturn");
|
|
||||||
panicindex = sysfunc("panicindex");
|
|
||||||
panicslice = sysfunc("panicslice");
|
|
||||||
throwreturn = sysfunc("throwreturn");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fn->nbody == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// set up domain for labels
|
|
||||||
clearlabels();
|
|
||||||
|
|
||||||
lno = setlineno(fn);
|
|
||||||
|
|
||||||
curfn = fn;
|
|
||||||
dowidth(curfn->type);
|
|
||||||
|
|
||||||
if(curfn->type->outnamed) {
|
|
||||||
// add clearing of the output parameters
|
|
||||||
t = structfirst(&save, getoutarg(curfn->type));
|
|
||||||
while(t != T) {
|
|
||||||
if(t->nname != N)
|
|
||||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
|
||||||
t = structnext(&save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hasdefer = 0;
|
|
||||||
walk(curfn);
|
|
||||||
if(nerrors != 0 || isblank(curfn->nname))
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
allocparams();
|
|
||||||
|
|
||||||
continpc = P;
|
|
||||||
breakpc = P;
|
|
||||||
|
|
||||||
pl = newplist();
|
|
||||||
pl->name = curfn->nname;
|
|
||||||
|
|
||||||
setlineno(curfn);
|
|
||||||
|
|
||||||
nodconst(&nod1, types[TINT32], 0);
|
|
||||||
ptxt = gins(ATEXT, curfn->nname, &nod1);
|
|
||||||
afunclit(&ptxt->from);
|
|
||||||
|
|
||||||
ginit();
|
|
||||||
genlist(curfn->enter);
|
|
||||||
|
|
||||||
pret = nil;
|
|
||||||
if(hasdefer || curfn->exit) {
|
|
||||||
Prog *p1;
|
|
||||||
|
|
||||||
p1 = gjmp(nil);
|
|
||||||
pret = gjmp(nil);
|
|
||||||
patch(p1, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
genlist(curfn->nbody);
|
|
||||||
gclean();
|
|
||||||
checklabels();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
if(curfn->endlineno)
|
|
||||||
lineno = curfn->endlineno;
|
|
||||||
|
|
||||||
if(curfn->type->outtuple != 0)
|
|
||||||
ginscall(throwreturn, 0);
|
|
||||||
|
|
||||||
if(pret)
|
|
||||||
patch(pret, pc);
|
|
||||||
ginit();
|
|
||||||
if(hasdefer)
|
|
||||||
ginscall(deferreturn, 0);
|
|
||||||
if(curfn->exit)
|
|
||||||
genlist(curfn->exit);
|
|
||||||
gclean();
|
|
||||||
if(nerrors != 0)
|
|
||||||
goto ret;
|
|
||||||
pc->as = ARET; // overwrite AEND
|
|
||||||
pc->lineno = lineno;
|
|
||||||
|
|
||||||
if(!debug['N'] || debug['R'] || debug['P']) {
|
|
||||||
regopt(ptxt);
|
|
||||||
}
|
|
||||||
// fill in argument size
|
// fill in argument size
|
||||||
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
|
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
|
||||||
|
|
||||||
@ -115,12 +18,6 @@ compile(Node *fn)
|
|||||||
maxstksize = stksize;
|
maxstksize = stksize;
|
||||||
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
|
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
|
||||||
maxstksize = 0;
|
maxstksize = 0;
|
||||||
|
|
||||||
if(debug['f'])
|
|
||||||
frame(0);
|
|
||||||
|
|
||||||
ret:
|
|
||||||
lineno = lno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -200,7 +97,7 @@ ginscall(Node *f, int proc)
|
|||||||
if(proc == 2) {
|
if(proc == 2) {
|
||||||
nodreg(®, types[TINT64], D_AX);
|
nodreg(®, types[TINT64], D_AX);
|
||||||
gins(ATESTL, ®, ®);
|
gins(ATESTL, ®, ®);
|
||||||
patch(gbranch(AJNE, T), pret);
|
patch(gbranch(AJNE, T), retpc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -391,8 +288,8 @@ void
|
|||||||
cgen_ret(Node *n)
|
cgen_ret(Node *n)
|
||||||
{
|
{
|
||||||
genlist(n->list); // copy out args
|
genlist(n->list); // copy out args
|
||||||
if(pret)
|
if(retpc)
|
||||||
gjmp(pret);
|
gjmp(retpc);
|
||||||
else
|
else
|
||||||
gins(ARET, N, N);
|
gins(ARET, N, N);
|
||||||
}
|
}
|
||||||
|
@ -1251,9 +1251,6 @@ funccompile(Node *n, int isclosure)
|
|||||||
|
|
||||||
if(curfn)
|
if(curfn)
|
||||||
fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
|
fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
|
||||||
curfn = n;
|
|
||||||
typechecklist(n->nbody, Etop);
|
|
||||||
curfn = nil;
|
|
||||||
|
|
||||||
stksize = 0;
|
stksize = 0;
|
||||||
dclcontext = PAUTO;
|
dclcontext = PAUTO;
|
||||||
|
@ -1213,6 +1213,7 @@ EXTERN Prog* continpc;
|
|||||||
EXTERN Prog* breakpc;
|
EXTERN Prog* breakpc;
|
||||||
EXTERN Prog* pc;
|
EXTERN Prog* pc;
|
||||||
EXTERN Prog* firstpc;
|
EXTERN Prog* firstpc;
|
||||||
|
EXTERN Prog* retpc;
|
||||||
|
|
||||||
EXTERN Node* nodfp;
|
EXTERN Node* nodfp;
|
||||||
|
|
||||||
@ -1226,6 +1227,7 @@ void cgen_callinter(Node *n, Node *res, int proc);
|
|||||||
void cgen_ret(Node *n);
|
void cgen_ret(Node *n);
|
||||||
void clearfat(Node *n);
|
void clearfat(Node *n);
|
||||||
void compile(Node*);
|
void compile(Node*);
|
||||||
|
void defframe(Prog*);
|
||||||
int dgostringptr(Sym*, int off, char *str);
|
int dgostringptr(Sym*, int off, char *str);
|
||||||
int dgostrlitptr(Sym*, int off, Strlit*);
|
int dgostrlitptr(Sym*, int off, Strlit*);
|
||||||
int dstringptr(Sym *s, int off, char *str);
|
int dstringptr(Sym *s, int off, char *str);
|
||||||
|
@ -182,11 +182,14 @@ fninit(NodeList *n)
|
|||||||
// (11)
|
// (11)
|
||||||
a = nod(ORETURN, N, N);
|
a = nod(ORETURN, N, N);
|
||||||
r = list(r, a);
|
r = list(r, a);
|
||||||
|
|
||||||
exportsym(fn->nname);
|
exportsym(fn->nname);
|
||||||
|
|
||||||
fn->nbody = r;
|
fn->nbody = r;
|
||||||
funcbody(fn);
|
funcbody(fn);
|
||||||
|
|
||||||
|
curfn = fn;
|
||||||
typecheck(&fn, Etop);
|
typecheck(&fn, Etop);
|
||||||
|
typechecklist(r, Etop);
|
||||||
|
curfn = nil;
|
||||||
funccompile(fn, 0);
|
funccompile(fn, 0);
|
||||||
}
|
}
|
||||||
|
@ -235,13 +235,14 @@ main(int argc, char *argv[])
|
|||||||
if(debug['f'])
|
if(debug['f'])
|
||||||
frame(1);
|
frame(1);
|
||||||
|
|
||||||
// Process top-level declarations in three phases.
|
// Process top-level declarations in four phases.
|
||||||
// Phase 1: const, type, and names and types of funcs.
|
// Phase 1: const, type, and names and types of funcs.
|
||||||
// This will gather all the information about types
|
// This will gather all the information about types
|
||||||
// and methods but doesn't depend on any of it.
|
// and methods but doesn't depend on any of it.
|
||||||
// Phase 2: Variable assignments.
|
// Phase 2: Variable assignments.
|
||||||
// To check interface assignments, depends on phase 1.
|
// To check interface assignments, depends on phase 1.
|
||||||
// Phase 3: Function bodies.
|
// Phase 3: Type check function bodies.
|
||||||
|
// Phase 4: Compile function bodies.
|
||||||
defercheckwidth();
|
defercheckwidth();
|
||||||
for(l=xtop; l; l=l->next)
|
for(l=xtop; l; l=l->next)
|
||||||
if(l->n->op != ODCL && l->n->op != OAS)
|
if(l->n->op != ODCL && l->n->op != OAS)
|
||||||
@ -251,17 +252,28 @@ main(int argc, char *argv[])
|
|||||||
typecheck(&l->n, Etop);
|
typecheck(&l->n, Etop);
|
||||||
resumetypecopy();
|
resumetypecopy();
|
||||||
resumecheckwidth();
|
resumecheckwidth();
|
||||||
|
|
||||||
|
for(l=xtop; l; l=l->next)
|
||||||
|
if(l->n->op == ODCLFUNC) {
|
||||||
|
curfn = l->n;
|
||||||
|
typechecklist(l->n->nbody, Etop);
|
||||||
|
}
|
||||||
|
curfn = nil;
|
||||||
|
|
||||||
for(l=xtop; l; l=l->next)
|
for(l=xtop; l; l=l->next)
|
||||||
if(l->n->op == ODCLFUNC)
|
if(l->n->op == ODCLFUNC)
|
||||||
funccompile(l->n, 0);
|
funccompile(l->n, 0);
|
||||||
|
|
||||||
if(nerrors == 0)
|
if(nerrors == 0)
|
||||||
fninit(xtop);
|
fninit(xtop);
|
||||||
|
|
||||||
while(closures) {
|
while(closures) {
|
||||||
l = closures;
|
l = closures;
|
||||||
closures = nil;
|
closures = nil;
|
||||||
for(; l; l=l->next)
|
for(; l; l=l->next)
|
||||||
funccompile(l->n, 1);
|
funccompile(l->n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dclchecks();
|
dclchecks();
|
||||||
|
|
||||||
if(nerrors)
|
if(nerrors)
|
||||||
|
119
src/cmd/gc/pgen.c
Normal file
119
src/cmd/gc/pgen.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#define EXTERN
|
||||||
|
#include "gg.h"
|
||||||
|
#include "opt.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
compile(Node *fn)
|
||||||
|
{
|
||||||
|
Plist *pl;
|
||||||
|
Node nod1, *n;
|
||||||
|
Prog *ptxt;
|
||||||
|
int32 lno;
|
||||||
|
Type *t;
|
||||||
|
Iter save;
|
||||||
|
|
||||||
|
if(newproc == N) {
|
||||||
|
newproc = sysfunc("newproc");
|
||||||
|
deferproc = sysfunc("deferproc");
|
||||||
|
deferreturn = sysfunc("deferreturn");
|
||||||
|
panicindex = sysfunc("panicindex");
|
||||||
|
panicslice = sysfunc("panicslice");
|
||||||
|
throwreturn = sysfunc("throwreturn");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fn->nbody == nil)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// set up domain for labels
|
||||||
|
clearlabels();
|
||||||
|
|
||||||
|
lno = setlineno(fn);
|
||||||
|
|
||||||
|
curfn = fn;
|
||||||
|
dowidth(curfn->type);
|
||||||
|
|
||||||
|
if(curfn->type->outnamed) {
|
||||||
|
// add clearing of the output parameters
|
||||||
|
t = structfirst(&save, getoutarg(curfn->type));
|
||||||
|
while(t != T) {
|
||||||
|
if(t->nname != N) {
|
||||||
|
n = nod(OAS, t->nname, N);
|
||||||
|
typecheck(&n, Etop);
|
||||||
|
curfn->nbody = concat(list1(n), curfn->nbody);
|
||||||
|
}
|
||||||
|
t = structnext(&save);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasdefer = 0;
|
||||||
|
walk(curfn);
|
||||||
|
if(nerrors != 0 || isblank(curfn->nname))
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
allocparams();
|
||||||
|
|
||||||
|
continpc = P;
|
||||||
|
breakpc = P;
|
||||||
|
|
||||||
|
pl = newplist();
|
||||||
|
pl->name = curfn->nname;
|
||||||
|
|
||||||
|
setlineno(curfn);
|
||||||
|
|
||||||
|
nodconst(&nod1, types[TINT32], 0);
|
||||||
|
ptxt = gins(ATEXT, curfn->nname, &nod1);
|
||||||
|
afunclit(&ptxt->from);
|
||||||
|
|
||||||
|
ginit();
|
||||||
|
genlist(curfn->enter);
|
||||||
|
|
||||||
|
retpc = nil;
|
||||||
|
if(hasdefer || curfn->exit) {
|
||||||
|
Prog *p1;
|
||||||
|
|
||||||
|
p1 = gjmp(nil);
|
||||||
|
retpc = gjmp(nil);
|
||||||
|
patch(p1, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
genlist(curfn->nbody);
|
||||||
|
gclean();
|
||||||
|
checklabels();
|
||||||
|
if(nerrors != 0)
|
||||||
|
goto ret;
|
||||||
|
if(curfn->endlineno)
|
||||||
|
lineno = curfn->endlineno;
|
||||||
|
|
||||||
|
if(curfn->type->outtuple != 0)
|
||||||
|
ginscall(throwreturn, 0);
|
||||||
|
|
||||||
|
if(retpc)
|
||||||
|
patch(retpc, pc);
|
||||||
|
ginit();
|
||||||
|
if(hasdefer)
|
||||||
|
ginscall(deferreturn, 0);
|
||||||
|
if(curfn->exit)
|
||||||
|
genlist(curfn->exit);
|
||||||
|
gclean();
|
||||||
|
if(nerrors != 0)
|
||||||
|
goto ret;
|
||||||
|
pc->as = ARET; // overwrite AEND
|
||||||
|
pc->lineno = lineno;
|
||||||
|
|
||||||
|
if(!debug['N'] || debug['R'] || debug['P']) {
|
||||||
|
regopt(ptxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
defframe(ptxt);
|
||||||
|
|
||||||
|
if(debug['f'])
|
||||||
|
frame(0);
|
||||||
|
|
||||||
|
ret:
|
||||||
|
lineno = lno;
|
||||||
|
}
|
@ -3170,7 +3170,10 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
|
|||||||
dumplist("genwrapper body", fn->nbody);
|
dumplist("genwrapper body", fn->nbody);
|
||||||
|
|
||||||
funcbody(fn);
|
funcbody(fn);
|
||||||
|
curfn = fn;
|
||||||
typecheck(&fn, Etop);
|
typecheck(&fn, Etop);
|
||||||
|
typechecklist(fn->nbody, Etop);
|
||||||
|
curfn = nil;
|
||||||
funccompile(fn, 0);
|
funccompile(fn, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ walk(Node *fn)
|
|||||||
int lno;
|
int lno;
|
||||||
|
|
||||||
curfn = fn;
|
curfn = fn;
|
||||||
|
|
||||||
if(debug['W']) {
|
if(debug['W']) {
|
||||||
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
|
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
|
||||||
dumplist(s, curfn->nbody);
|
dumplist(s, curfn->nbody);
|
||||||
@ -73,7 +74,7 @@ walk(Node *fn)
|
|||||||
if(curfn->type->outtuple)
|
if(curfn->type->outtuple)
|
||||||
if(walkret(curfn->nbody))
|
if(walkret(curfn->nbody))
|
||||||
yyerror("function ends without a return statement");
|
yyerror("function ends without a return statement");
|
||||||
typechecklist(curfn->nbody, Etop);
|
|
||||||
lno = lineno;
|
lno = lineno;
|
||||||
for(l=fn->dcl; l; l=l->next) {
|
for(l=fn->dcl; l; l=l->next) {
|
||||||
n = l->n;
|
n = l->n;
|
||||||
@ -468,8 +469,10 @@ walkstmt(Node **np)
|
|||||||
case OPANIC:
|
case OPANIC:
|
||||||
case OEMPTY:
|
case OEMPTY:
|
||||||
case ORECOVER:
|
case ORECOVER:
|
||||||
if(n->typecheck == 0)
|
if(n->typecheck == 0) {
|
||||||
|
dump("missing typecheck:", n);
|
||||||
fatal("missing typecheck");
|
fatal("missing typecheck");
|
||||||
|
}
|
||||||
init = n->ninit;
|
init = n->ninit;
|
||||||
n->ninit = nil;
|
n->ninit = nil;
|
||||||
walkexpr(&n, &init);
|
walkexpr(&n, &init);
|
||||||
|
Loading…
Reference in New Issue
Block a user