2011-06-02 10:48:17 -06:00
|
|
|
// 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.
|
|
|
|
|
2011-06-09 09:44:28 -06:00
|
|
|
#include "gg.h"
|
|
|
|
#include "opt.h"
|
2011-06-02 10:48:17 -06:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|