OFILES=\
../5l/enam.$O\
- list.$O\
- galign.$O\
- gobj.$O\
- ggen.$O\
- gsubr.$O\
cgen.$O\
cgen64.$O\
cplx.$O\
- reg.$O\
+ galign.$O\
+ ggen.$O\
+ gobj.$O\
+ gsubr.$O\
+ list.$O\
peep.$O\
+ pgen.$O\
+ reg.$O\
LIB=\
../gc/gc.a\
#include "gg.h"
#include "opt.h"
-static Prog *pret;
-
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
ptxt->to.type = D_CONST2;
ptxt->reg = 0; // flags
maxstksize = stksize;
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
maxstksize = 0;
-
- if(debug['f'])
- frame(0);
-
-ret:
- lineno = lno;
}
/*
nodconst(&con, types[TINT32], 0);
p = gins(ACMP, &con, N);
p->reg = 0;
- patch(gbranch(ABNE, T), pret);
+ patch(gbranch(ABNE, T), retpc);
}
break;
}
{
genlist(n->list); // copy out args
if(hasdefer || curfn->exit)
- gjmp(pret);
+ gjmp(retpc);
else
gins(ARET, N, N);
}
opt.h\
OFILES=\
- list.$O\
- gobj.$O\
- galign.$O\
- ggen.$O\
+ ../6l/enam.$O\
cgen.$O\
cplx.$O\
+ galign.$O\
+ ggen.$O\
+ gobj.$O\
gsubr.$O\
+ list.$O\
peep.$O\
+ pgen.$O\
reg.$O\
- ../6l/enam.$O\
LIB=\
../gc/gc.a\
#include "gg.h"
#include "opt.h"
-static Prog *pret;
-
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
ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
ptxt->to.offset <<= 32;
ptxt->to.offset |= rnd(stksize+maxarg, widthptr);
-
- if(debug['f'])
- frame(0);
-
-ret:
- lineno = lno;
}
+
/*
* generate:
* call f
if(proc == 2) {
nodreg(®, types[TINT64], D_AX);
gins(ATESTQ, ®, ®);
- patch(gbranch(AJNE, T), pret);
+ patch(gbranch(AJNE, T), retpc);
}
break;
}
{
genlist(n->list); // copy out args
if(hasdefer || curfn->exit)
- gjmp(pret);
+ gjmp(retpc);
else
gins(ARET, N, N);
}
OFILES=\
../8l/enam.$O\
- list.$O\
- galign.$O\
- gobj.$O\
- ggen.$O\
- gsubr.$O\
cgen.$O\
cgen64.$O\
cplx.$O\
+ galign.$O\
+ ggen.$O\
+ gobj.$O\
+ gsubr.$O\
+ list.$O\
peep.$O\
+ pgen.$O\
reg.$O\
LIB=\
#include "gg.h"
#include "opt.h"
-static Prog *pret;
-
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
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
maxstksize = stksize;
ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
maxstksize = 0;
-
- if(debug['f'])
- frame(0);
-
-ret:
- lineno = lno;
}
void
if(proc == 2) {
nodreg(®, types[TINT64], D_AX);
gins(ATESTL, ®, ®);
- patch(gbranch(AJNE, T), pret);
+ patch(gbranch(AJNE, T), retpc);
}
break;
}
cgen_ret(Node *n)
{
genlist(n->list); // copy out args
- if(pret)
- gjmp(pret);
+ if(retpc)
+ gjmp(retpc);
else
gins(ARET, N, N);
}
if(curfn)
fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
- curfn = n;
- typechecklist(n->nbody, Etop);
- curfn = nil;
stksize = 0;
dclcontext = PAUTO;
EXTERN Prog* breakpc;
EXTERN Prog* pc;
EXTERN Prog* firstpc;
+EXTERN Prog* retpc;
EXTERN Node* nodfp;
void cgen_ret(Node *n);
void clearfat(Node *n);
void compile(Node*);
+void defframe(Prog*);
int dgostringptr(Sym*, int off, char *str);
int dgostrlitptr(Sym*, int off, Strlit*);
int dstringptr(Sym *s, int off, char *str);
// (11)
a = nod(ORETURN, N, N);
r = list(r, a);
-
exportsym(fn->nname);
fn->nbody = r;
funcbody(fn);
+
+ curfn = fn;
typecheck(&fn, Etop);
+ typechecklist(r, Etop);
+ curfn = nil;
funccompile(fn, 0);
}
if(debug['f'])
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.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
// Phase 2: Variable assignments.
// To check interface assignments, depends on phase 1.
- // Phase 3: Function bodies.
+ // Phase 3: Type check function bodies.
+ // Phase 4: Compile function bodies.
defercheckwidth();
for(l=xtop; l; l=l->next)
if(l->n->op != ODCL && l->n->op != OAS)
typecheck(&l->n, Etop);
resumetypecopy();
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)
if(l->n->op == ODCLFUNC)
funccompile(l->n, 0);
+
if(nerrors == 0)
fninit(xtop);
+
while(closures) {
l = closures;
closures = nil;
for(; l; l=l->next)
funccompile(l->n, 1);
}
+
dclchecks();
if(nerrors)
--- /dev/null
+// 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;
+}
dumplist("genwrapper body", fn->nbody);
funcbody(fn);
+ curfn = fn;
typecheck(&fn, Etop);
+ typechecklist(fn->nbody, Etop);
+ curfn = nil;
funccompile(fn, 0);
}
int lno;
curfn = fn;
+
if(debug['W']) {
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
dumplist(s, curfn->nbody);
if(curfn->type->outtuple)
if(walkret(curfn->nbody))
yyerror("function ends without a return statement");
- typechecklist(curfn->nbody, Etop);
+
lno = lineno;
for(l=fn->dcl; l; l=l->next) {
n = l->n;
case OPANIC:
case OEMPTY:
case ORECOVER:
- if(n->typecheck == 0)
+ if(n->typecheck == 0) {
+ dump("missing typecheck:", n);
fatal("missing typecheck");
+ }
init = n->ninit;
n->ninit = nil;
walkexpr(&n, &init);