~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/cmd/gc/closure.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-08-03 17:04:59 UTC
  • mfrom: (14.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20110803170459-wzd99m3567y80ila
Tags: 1:59-1
* Imported Upstream version 59
* Refresh patches to a new release
* Fix FTBFS on ARM (Closes: #634270)
* Update version.bash to work with Debian packaging and not hg
  repository

Show diffs side-by-side

added added

removed removed

Lines of Context:
116
116
        }
117
117
}
118
118
 
119
 
Node*
120
 
walkclosure(Node *func, NodeList **init)
 
119
static Node*
 
120
makeclosure(Node *func, NodeList **init, int nowrap)
121
121
{
122
 
        int narg;
123
 
        Node *xtype, *v, *addr, *xfunc, *call, *clos;
124
 
        NodeList *l, *in;
 
122
        Node *xtype, *v, *addr, *xfunc;
 
123
        NodeList *l;
125
124
        static int closgen;
126
125
        char *p;
127
126
 
133
132
 
134
133
        // each closure variable has a corresponding
135
134
        // address parameter.
136
 
        narg = 0;
137
135
        for(l=func->cvars; l; l=l->next) {
138
136
                v = l->n;
139
137
                if(v->op == 0)
146
144
                addr->class = PPARAM;
147
145
                addr->addable = 1;
148
146
                addr->ullman = 1;
149
 
                narg++;
150
147
 
151
148
                v->heapaddr = addr;
152
149
 
154
151
        }
155
152
 
156
153
        // then a dummy arg where the closure's caller pc sits
157
 
        xtype->list = list(xtype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 
154
        if (!nowrap)
 
155
                xtype->list = list(xtype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
158
156
 
159
157
        // then the function arguments
160
158
        xtype->list = concat(xtype->list, func->list);
176
174
        typecheck(&xfunc, Etop);
177
175
        closures = list(closures, xfunc);
178
176
 
 
177
        return xfunc;
 
178
}
 
179
 
 
180
Node*
 
181
walkclosure(Node *func, NodeList **init)
 
182
{
 
183
        int narg;
 
184
        Node *xtype, *xfunc, *call, *clos;
 
185
        NodeList *l, *in;
 
186
 
 
187
        /*
 
188
         * wrap body in external function
 
189
         * with extra closure parameters.
 
190
         */
 
191
 
 
192
        // create the function
 
193
        xfunc = makeclosure(func, init, 0);
 
194
        xtype = xfunc->nname->ntype;
 
195
 
179
196
        // prepare call of sys.closure that turns external func into func literal value.
180
197
        clos = syslook("closure", 1);
181
198
        clos->type = T;
182
199
        clos->ntype = nod(OTFUNC, N, N);
183
200
        in = list1(nod(ODCLFIELD, N, typenod(types[TINT])));    // siz
184
201
        in = list(in, nod(ODCLFIELD, N, xtype));
 
202
        narg = 0;
185
203
        for(l=func->cvars; l; l=l->next) {
186
204
                if(l->n->op == 0)
187
205
                        continue;
 
206
                narg++;
188
207
                in = list(in, nod(ODCLFIELD, N, l->n->heapaddr->ntype));
189
208
        }
190
209
        clos->ntype->list = in;
211
230
void
212
231
walkcallclosure(Node *n, NodeList **init)
213
232
{
214
 
        Node *z;
215
 
        NodeList *ll, *cargs;
216
 
 
217
 
        walkexpr(&n->left, init);
218
 
        cargs = n->left    // FUNC runtime.closure
219
 
                ->list     // arguments
220
 
                ->next     // skip first
221
 
                ->next;    // skip second
222
 
 
223
 
        n->left = n->left  // FUNC runtime.closure
224
 
                ->list     // arguments
225
 
                ->next     // skip first
226
 
                ->n        // AS (to indreg) 
227
 
                ->right;   // argument  == the generated function 
228
 
 
229
 
        // New arg list for n. First the closure-args, stolen from
230
 
        // runtime.closure's 3rd and following,
231
 
        ll = nil;
232
 
        for (; cargs; cargs = cargs->next)
233
 
                ll = list(ll, cargs->n->right);  // cargs->n is the OAS(INDREG, arg)
234
 
 
235
 
        // then an extra zero, to fill the dummy return pointer slot,
236
 
        z = nod(OXXX, N, N);
237
 
        nodconst(z, types[TUINTPTR], 0);
238
 
        z->typecheck = 1;
239
 
        ll = list(ll, z);
240
 
 
241
 
        // and finally the original parameter list.
242
 
        n->list = concat(ll, n->list);
 
233
        if (n->op != OCALLFUNC || n->left->op != OCLOSURE) {
 
234
                dump("walkcallclosure", n);
 
235
                fatal("abuse of walkcallclosure");
 
236
        }
 
237
 
 
238
        // New arg list for n. First the closure-args
 
239
        // and then the original parameter list.
 
240
        n->list = concat(n->left->enter, n->list);
 
241
        n->left = makeclosure(n->left, init, 1)->nname;
 
242
        dowidth(n->left->type);
 
243
        n->type = getoutargx(n->left->type);
 
244
        // for a single valued function, pull the field type out of the struct
 
245
        if (n->type && n->type->type && !n->type->type->down)
 
246
                n->type = n->type->type->type;
243
247
}