1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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;
}
|