/src/moddable/xs/sources/xsScope.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2016-2017 Moddable Tech, Inc. |
3 | | * |
4 | | * This file is part of the Moddable SDK Runtime. |
5 | | * |
6 | | * The Moddable SDK Runtime is free software: you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation, either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * The Moddable SDK Runtime is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>. |
18 | | * |
19 | | * This file incorporates work covered by the following copyright and |
20 | | * permission notice: |
21 | | * |
22 | | * Copyright (C) 2010-2016 Marvell International Ltd. |
23 | | * Copyright (C) 2002-2010 Kinoma, Inc. |
24 | | * |
25 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
26 | | * you may not use this file except in compliance with the License. |
27 | | * You may obtain a copy of the License at |
28 | | * |
29 | | * http://www.apache.org/licenses/LICENSE-2.0 |
30 | | * |
31 | | * Unless required by applicable law or agreed to in writing, software |
32 | | * distributed under the License is distributed on an "AS IS" BASIS, |
33 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
34 | | * See the License for the specific language governing permissions and |
35 | | * limitations under the License. |
36 | | */ |
37 | | |
38 | | #include "xsScript.h" |
39 | | |
40 | | #define mxBindHoistPart\ |
41 | | txParser* parser;\ |
42 | | txScope* scope |
43 | | |
44 | | typedef struct sxExportlink txExportLink; |
45 | | |
46 | | typedef struct { |
47 | | mxBindHoistPart; |
48 | | txInteger scopeLevel; |
49 | | txInteger scopeMaximum; |
50 | | txClassNode* classNode; |
51 | | } txBinder; |
52 | | |
53 | | typedef struct { |
54 | | mxBindHoistPart; |
55 | | txScope* functionScope; |
56 | | txScope* bodyScope; |
57 | | txNode* environmentNode; |
58 | | txExportLink* firstExportLink; |
59 | | txClassNode* classNode; |
60 | | } txHoister; |
61 | | |
62 | | struct sxExportlink { |
63 | | txExportLink* next; |
64 | | txSymbol* symbol; |
65 | | }; |
66 | | |
67 | | static void fxHoisterAddExportLink(txHoister* self, txSpecifierNode* specifier); |
68 | | static void fxBinderPopVariables(txBinder* self, txInteger count); |
69 | | static void fxBinderPushVariables(txBinder* self, txInteger count); |
70 | | static txScope* fxScopeNew(txHoister* hoister, txNode* node, txToken token); |
71 | | static void fxScopeAddDeclareNode(txScope* self, txDeclareNode* node); |
72 | | static void fxScopeAddDefineNode(txScope* self, txDefineNode* node); |
73 | | static void fxScopeArrow(txScope* self); |
74 | | static void fxScopeBindDefineNodes(txScope* self, void* param); |
75 | | static void fxScopeBinding(txScope* self, txBinder* binder); |
76 | | static void fxScopeBound(txScope* self, txBinder* binder); |
77 | | static void fxScopeEval(txScope* self); |
78 | | static txDeclareNode* fxScopeGetDeclareNode(txScope* self, txSymbol* symbol); |
79 | | static void fxScopeHoisted(txScope* self, txHoister* hoister); |
80 | | static void fxScopeLookup(txScope* self, txAccessNode* access, txBoolean closureFlag); |
81 | | |
82 | | static void fxNodeDispatchBind(void* it, void* param); |
83 | | static void fxNodeDispatchHoist(void* it, void* param); |
84 | | static void fxFunctionNodeRename(void* it, txSymbol* symbol); |
85 | | |
86 | | void fxParserBind(txParser* parser) |
87 | 557k | { |
88 | 557k | txBinder binder; |
89 | 557k | c_memset(&binder, 0, sizeof(txBinder)); |
90 | 557k | binder.parser = parser; |
91 | 557k | if (parser->errorCount == 0) { |
92 | 171k | mxTryParser(parser) { |
93 | 171k | fxNodeDispatchBind(parser->root, &binder); |
94 | 171k | } |
95 | 171k | mxCatchParser(parser) { |
96 | 537 | } |
97 | 171k | } |
98 | 557k | } |
99 | | |
100 | | void fxParserHoist(txParser* parser) |
101 | 557k | { |
102 | 557k | txHoister hoister; |
103 | 557k | c_memset(&hoister, 0, sizeof(txHoister)); |
104 | 557k | hoister.parser = parser; |
105 | 557k | if (parser->errorCount == 0) { |
106 | 171k | mxTryParser(parser) { |
107 | 171k | fxNodeDispatchHoist(parser->root, &hoister); |
108 | 171k | } |
109 | 171k | mxCatchParser(parser) { |
110 | 163 | } |
111 | 171k | } |
112 | 557k | } |
113 | | |
114 | | void fxHoisterAddExportLink(txHoister* self, txSpecifierNode* specifier) |
115 | 437 | { |
116 | 437 | txExportLink* link = self->firstExportLink; |
117 | 437 | txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol; |
118 | 437 | if (symbol) { |
119 | 883 | while (link) { |
120 | 453 | if (link->symbol == symbol) { |
121 | 3 | fxReportParserError(self->parser, specifier->line, "duplicate export %s", symbol->string); |
122 | 3 | return; |
123 | 3 | } |
124 | 450 | link = link->next; |
125 | 450 | } |
126 | 430 | link = fxNewParserChunk(self->parser, sizeof(txExportLink)); |
127 | 430 | link->next = self->firstExportLink; |
128 | 430 | link->symbol = symbol; |
129 | 430 | self->firstExportLink = link; |
130 | 430 | } |
131 | 437 | } |
132 | | |
133 | | void fxBinderPopVariables(txBinder* self, txInteger count) |
134 | 820k | { |
135 | 820k | self->scopeLevel -= count; |
136 | 820k | } |
137 | | |
138 | | void fxBinderPushVariables(txBinder* self, txInteger count) |
139 | 820k | { |
140 | 820k | self->scopeLevel += count; |
141 | 820k | if (self->scopeMaximum < self->scopeLevel) |
142 | 297k | self->scopeMaximum = self->scopeLevel; |
143 | 820k | } |
144 | | |
145 | | txScope* fxScopeNew(txHoister* hoister, txNode* node, txToken token) |
146 | 423k | { |
147 | 423k | txScope* scope = fxNewParserChunkClear(hoister->parser, sizeof(txScope)); |
148 | 423k | scope->parser = hoister->parser; |
149 | 423k | scope->scope = hoister->scope; |
150 | 423k | scope->token = token; |
151 | 423k | scope->flags = node->flags & mxStrictFlag; |
152 | 423k | scope->node = node; |
153 | 423k | hoister->scope = scope; |
154 | 423k | return scope; |
155 | 423k | } |
156 | | |
157 | | void fxScopeAddDeclareNode(txScope* self, txDeclareNode* node) |
158 | 274k | { |
159 | 274k | self->declareNodeCount++; |
160 | 274k | if (self->token == XS_TOKEN_EVAL) { |
161 | 12.8k | if (self->lastDeclareNode) |
162 | 2.56k | node->nextDeclareNode = self->firstDeclareNode; |
163 | 10.2k | else |
164 | 10.2k | self->lastDeclareNode = node; |
165 | 12.8k | self->firstDeclareNode = node; |
166 | 12.8k | } |
167 | 261k | else { |
168 | 261k | if (self->lastDeclareNode) |
169 | 113k | self->lastDeclareNode->nextDeclareNode = node; |
170 | 148k | else |
171 | 148k | self->firstDeclareNode = node; |
172 | 261k | self->lastDeclareNode = node; |
173 | 261k | } |
174 | 274k | if (node->description->token == XS_TOKEN_USING) { |
175 | 4.10k | txDeclareNode* node = fxDeclareNodeNew(self->parser, XS_TOKEN_CONST, C_NULL); |
176 | 4.10k | node->flags |= mxDeclareNodeDisposableFlag; |
177 | 4.10k | fxScopeAddDeclareNode(self, node); |
178 | 4.10k | self->disposableNodeCount++; |
179 | 4.10k | } |
180 | 274k | } |
181 | | |
182 | | void fxScopeAddDefineNode(txScope* self, txDefineNode* node) |
183 | 46.0k | { |
184 | 46.0k | self->defineNodeCount++; |
185 | 46.0k | if (self->lastDefineNode) |
186 | 702 | self->lastDefineNode->nextDefineNode = node; |
187 | 45.3k | else |
188 | 45.3k | self->firstDefineNode = node; |
189 | 46.0k | self->lastDefineNode = node; |
190 | 46.0k | } |
191 | | |
192 | | void fxScopeArrow(txScope* self) |
193 | 8.30k | { |
194 | 8.30k | if (self->token == XS_TOKEN_EVAL) { |
195 | 2.40k | } |
196 | 5.90k | else if (self->token == XS_TOKEN_FUNCTION) { |
197 | 2.66k | if (self->node->flags & mxArrowFlag) { |
198 | 136 | self->node->flags |= mxDefaultFlag; |
199 | 136 | if (self->scope) |
200 | 136 | fxScopeArrow(self->scope); |
201 | 136 | } |
202 | 2.66k | } |
203 | 3.24k | else if (self->token == XS_TOKEN_PROGRAM) { |
204 | 352 | } |
205 | 2.88k | else if (self->scope) { |
206 | 2.88k | fxScopeArrow(self->scope); |
207 | 2.88k | } |
208 | 8.30k | } |
209 | | |
210 | | void fxScopeBindDefineNodes(txScope* self, void* param) |
211 | 399k | { |
212 | 399k | txDefineNode* node = self->firstDefineNode; |
213 | 445k | while (node) { |
214 | 46.0k | fxNodeDispatchBind(node, param); |
215 | 46.0k | node = node->nextDefineNode; |
216 | 46.0k | } |
217 | 399k | } |
218 | | |
219 | | void fxScopeBinding(txScope* self, txBinder* binder) |
220 | 423k | { |
221 | 423k | self->scope = binder->scope; |
222 | 423k | binder->scope = self; |
223 | 423k | fxBinderPushVariables(binder, self->declareNodeCount); |
224 | 423k | } |
225 | | |
226 | | void fxScopeBound(txScope* self, txBinder* binder) |
227 | 422k | { |
228 | 422k | if (self->flags & mxEvalFlag) { |
229 | 36.5k | txDeclareNode* node = self->firstDeclareNode; |
230 | 89.4k | while (node) { |
231 | 52.9k | node->flags |= mxDeclareNodeClosureFlag; |
232 | 52.9k | node = node->nextDeclareNode; |
233 | 52.9k | } |
234 | 36.5k | } |
235 | 422k | if (self->token == XS_TOKEN_MODULE) { |
236 | 2.48k | txDeclareNode* node = self->firstDeclareNode; |
237 | 3.01k | while (node) { |
238 | 534 | if (!(node->flags & mxDeclareNodeDisposableFlag)) |
239 | 534 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
240 | 534 | node = node->nextDeclareNode; |
241 | 534 | } |
242 | 2.48k | } |
243 | 420k | else if (self->token == XS_TOKEN_PROGRAM) { |
244 | 64.3k | txDeclareNode* node = self->firstDeclareNode; |
245 | 91.3k | while (node) { |
246 | 26.9k | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
247 | 26.9k | node = node->nextDeclareNode; |
248 | 26.9k | } |
249 | 64.3k | } |
250 | 422k | binder->scopeLevel += self->closureNodeCount; |
251 | 422k | binder->scopeMaximum += self->closureNodeCount; |
252 | 422k | fxBinderPopVariables(binder, self->declareNodeCount); |
253 | 422k | binder->scope = self->scope; |
254 | 422k | } |
255 | | |
256 | | void fxScopeEval(txScope* self) |
257 | 8.85k | { |
258 | 220k | while (self) { |
259 | 212k | self->flags |= mxEvalFlag; |
260 | 212k | self = self->scope; |
261 | 212k | } |
262 | 8.85k | } |
263 | | |
264 | | txDeclareNode* fxScopeGetDeclareNode(txScope* self, txSymbol* symbol) |
265 | 2.27M | { |
266 | 2.27M | txDeclareNode* node = self->firstDeclareNode; |
267 | 19.3M | while (node) { |
268 | 17.4M | if (node->symbol == symbol) |
269 | 336k | return node; |
270 | 17.0M | node = node->nextDeclareNode; |
271 | 17.0M | } |
272 | 1.93M | return NULL; |
273 | 2.27M | } |
274 | | |
275 | | void fxScopeHoisted(txScope* self, txHoister* hoister) |
276 | 423k | { |
277 | 423k | if (self->token == XS_TOKEN_BLOCK) { |
278 | 152k | txDeclareNode** address = &self->firstDeclareNode; |
279 | 152k | txDeclareNode* node; |
280 | 152k | txDeclareNode* last = C_NULL; |
281 | 269k | while ((node = *address)) { |
282 | 117k | if (node->description->token == XS_NO_TOKEN) { |
283 | 30.7k | self->declareNodeCount--; |
284 | 30.7k | *address = node->nextDeclareNode; |
285 | 30.7k | } |
286 | 87.1k | else { |
287 | 87.1k | address = &node->nextDeclareNode; |
288 | 87.1k | last = node; |
289 | 87.1k | } |
290 | 117k | } |
291 | 152k | self->lastDeclareNode = last; |
292 | 152k | } |
293 | 271k | else if (self->token == XS_TOKEN_PROGRAM) { |
294 | 64.4k | txDeclareNode* node = self->firstDeclareNode; |
295 | 91.3k | while (node) { |
296 | 26.9k | if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR)) |
297 | 21.0k | self->declareNodeCount--; |
298 | 26.9k | node = node->nextDeclareNode; |
299 | 26.9k | } |
300 | 64.4k | } |
301 | 206k | else if (self->token == XS_TOKEN_EVAL) { |
302 | 104k | if (!(self->flags & mxStrictFlag)) { |
303 | 103k | txDeclareNode* node = self->firstDeclareNode; |
304 | 115k | while (node) { |
305 | 11.6k | if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR)) |
306 | 5.53k | self->declareNodeCount--; |
307 | 11.6k | node = node->nextDeclareNode; |
308 | 11.6k | } |
309 | 103k | } |
310 | 104k | } |
311 | 423k | hoister->scope = self->scope; |
312 | 423k | } |
313 | | |
314 | | void fxScopeLookup(txScope* self, txAccessNode* access, txBoolean closureFlag) |
315 | 2.03M | { |
316 | 2.03M | txDeclareNode* declaration; |
317 | 2.03M | if (self->token == XS_TOKEN_EVAL) { |
318 | 159k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
319 | 159k | if (declaration) { |
320 | 14.1k | if ((!(self->flags & mxStrictFlag)) && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) { |
321 | 6.61k | declaration = C_NULL; |
322 | 6.61k | } |
323 | 7.56k | else if (closureFlag) |
324 | 408 | declaration->flags |= mxDeclareNodeClosureFlag; |
325 | 14.1k | } |
326 | 144k | else if ((self->flags & mxStrictFlag) && (access->description->token == XS_TOKEN_PRIVATE_MEMBER)) { |
327 | 0 | declaration = fxDeclareNodeNew(self->parser, XS_TOKEN_PRIVATE, access->symbol); |
328 | 0 | declaration->flags |= mxDeclareNodeClosureFlag; |
329 | 0 | declaration->line = access->line; |
330 | 0 | fxScopeAddDeclareNode(self, declaration); |
331 | 0 | self->closureNodeCount++; |
332 | 0 | } |
333 | 159k | access->declaration = declaration; |
334 | 159k | } |
335 | 1.87M | else if (self->token == XS_TOKEN_FUNCTION) { |
336 | 613k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
337 | 613k | if (declaration) { |
338 | 81.2k | if (closureFlag) |
339 | 2.55k | declaration->flags |= mxDeclareNodeClosureFlag; |
340 | 81.2k | access->declaration = declaration; |
341 | 81.2k | } |
342 | 532k | else if ((self->node->flags & mxEvalFlag) && !(self->node->flags & mxStrictFlag)) { |
343 | | // eval can create variables that override closures |
344 | 3.44k | access->declaration = C_NULL; |
345 | 3.44k | } |
346 | 528k | else if (self->scope) { |
347 | 528k | fxScopeLookup(self->scope, access, 1); |
348 | 528k | if (access->declaration) { |
349 | 44.4k | txDeclareNode* closureNode = fxDeclareNodeNew(self->parser, XS_NO_TOKEN, access->symbol); |
350 | 44.4k | closureNode->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
351 | 44.4k | closureNode->line = access->declaration->line; |
352 | 44.4k | closureNode->declaration = access->declaration; |
353 | 44.4k | fxScopeAddDeclareNode(self, closureNode); |
354 | 44.4k | self->closureNodeCount++; |
355 | 44.4k | access->declaration = closureNode; |
356 | 44.4k | } |
357 | 528k | } |
358 | 613k | } |
359 | 1.26M | else if (self->token == XS_TOKEN_PROGRAM) { |
360 | 397k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
361 | 397k | if (declaration && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) { |
362 | 91.5k | declaration = C_NULL; |
363 | 91.5k | } |
364 | 397k | access->declaration = declaration; |
365 | 397k | } |
366 | 863k | else if (self->token == XS_TOKEN_WITH) { |
367 | | // with object can have properties that override variables |
368 | 8.77k | access->declaration = C_NULL; |
369 | 8.77k | } |
370 | 854k | else { |
371 | 854k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
372 | 854k | if (declaration) { |
373 | 81.7k | if (closureFlag) |
374 | 38.5k | declaration->flags |= mxDeclareNodeClosureFlag; |
375 | 81.7k | access->declaration = declaration; |
376 | 81.7k | } |
377 | 772k | else if (self->scope) { |
378 | 767k | fxScopeLookup(self->scope, access, closureFlag); |
379 | 767k | } |
380 | 5.21k | else { |
381 | 5.21k | access->declaration = C_NULL; |
382 | 5.21k | access->symbol->usage |= 2; |
383 | 5.21k | } |
384 | 854k | } |
385 | 2.03M | } |
386 | | |
387 | | void fxNodeHoist(void* it, void* param) |
388 | 2.82M | { |
389 | 2.82M | txNode* node = it; |
390 | 2.82M | (*node->description->dispatch->distribute)(node, fxNodeDispatchHoist, param); |
391 | 2.82M | } |
392 | | |
393 | | void fxNodeDispatchHoist(void* it, void* param) |
394 | 4.82M | { |
395 | 4.82M | txNode* node = it; |
396 | 4.82M | fxCheckParserStack(((txHoister*)param)->parser, node->line); |
397 | 4.82M | (*node->description->dispatch->hoist)(it, param); |
398 | 4.82M | } |
399 | | |
400 | | void fxBlockNodeHoist(void* it, void* param) |
401 | 6.45k | { |
402 | 6.45k | txBlockNode* self = it; |
403 | 6.45k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
404 | 6.45k | fxNodeDispatchHoist(self->statement, param); |
405 | 6.45k | fxScopeHoisted(self->scope, param); |
406 | 6.45k | } |
407 | | |
408 | | void fxBodyNodeHoist(void* it, void* param) |
409 | 96.5k | { |
410 | 96.5k | txBlockNode* self = it; |
411 | 96.5k | txHoister* hoister = param; |
412 | 96.5k | txNode* environmentNode = hoister->environmentNode; |
413 | 96.5k | hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
414 | 96.5k | hoister->environmentNode = it; |
415 | 96.5k | fxNodeDispatchHoist(self->statement, param); |
416 | 96.5k | hoister->environmentNode = environmentNode; |
417 | 96.5k | fxScopeHoisted(self->scope, param); |
418 | 96.5k | } |
419 | | |
420 | | void fxCallNodeHoist(void* it, void* param) |
421 | 111k | { |
422 | 111k | txCallNewNode* self = it; |
423 | 111k | txHoister* hoister = param; |
424 | 111k | txParser* parser = hoister->parser; |
425 | 111k | if (self->reference->description->token == XS_TOKEN_ACCESS) { |
426 | 21.3k | txAccessNode* access = (txAccessNode*)self->reference; |
427 | 21.3k | if (access->symbol == parser->evalSymbol) { |
428 | 5.47k | fxScopeEval(hoister->scope); |
429 | 5.47k | hoister->functionScope->node->flags |= mxArgumentsFlag | mxEvalFlag; |
430 | 5.47k | hoister->environmentNode->flags |= mxEvalFlag; |
431 | 5.47k | self->params->flags |= mxEvalParametersFlag; |
432 | 5.47k | } |
433 | 21.3k | } |
434 | 111k | fxNodeDispatchHoist(self->reference, param); |
435 | 111k | fxNodeDispatchHoist(self->params, param); |
436 | 111k | } |
437 | | |
438 | | void fxCatchNodeHoist(void* it, void* param) |
439 | 1.80k | { |
440 | 1.80k | txCatchNode* self = it; |
441 | 1.80k | txHoister* hoister = param; |
442 | 1.80k | txDeclareNode* node; |
443 | 1.80k | if (self->parameter) { |
444 | 1.75k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
445 | 1.75k | fxNodeDispatchHoist(self->parameter, param); |
446 | 1.75k | self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
447 | 1.75k | fxNodeDispatchHoist(self->statement, param); |
448 | 1.75k | fxScopeHoisted(self->statementScope, param); |
449 | 1.75k | fxScopeHoisted(self->scope, param); |
450 | 1.75k | node = self->statementScope->firstDeclareNode; |
451 | 1.79k | while (node) { |
452 | 44 | if (fxScopeGetDeclareNode(self->scope, node->symbol)) |
453 | 1 | fxReportParserError(hoister->parser, node->line, "duplicate variable %s", node->symbol->string); |
454 | 44 | node = node->nextDeclareNode; |
455 | 44 | } |
456 | 1.75k | } |
457 | 58 | else { |
458 | 58 | self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
459 | 58 | fxNodeDispatchHoist(self->statement, param); |
460 | 58 | fxScopeHoisted(self->statementScope, param); |
461 | 58 | } |
462 | 1.80k | } |
463 | | |
464 | | void fxClassNodeHoist(void* it, void* param) |
465 | 9.47k | { |
466 | 9.47k | txClassNode* self = it; |
467 | 9.47k | txHoister* hoister = param; |
468 | 9.47k | txClassNode* former = hoister->classNode; |
469 | 9.47k | txNode* item = self->items->first; |
470 | 9.47k | if (self->symbol) { |
471 | 9.26k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol); |
472 | 9.26k | node->flags |= mxDeclareNodeClosureFlag; |
473 | 9.26k | self->symbolScope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK); |
474 | 9.26k | fxScopeAddDeclareNode(self->symbolScope, node); |
475 | 9.26k | } |
476 | 9.47k | if (self->heritage) |
477 | 295 | fxNodeDispatchHoist(self->heritage, param); |
478 | 9.47k | self->scope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK); |
479 | 47.8k | while (item) { |
480 | 38.4k | if (item->description->token == XS_TOKEN_PROPERTY) { |
481 | 13.2k | } |
482 | 25.1k | else if (item->description->token == XS_TOKEN_PROPERTY_AT) { |
483 | 16.3k | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) { |
484 | 69 | } |
485 | 16.2k | else { |
486 | 16.2k | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
487 | 16.2k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
488 | 16.2k | symbol->ID = -1; |
489 | 16.2k | node->flags |= mxDeclareNodeClosureFlag; |
490 | 16.2k | fxScopeAddDeclareNode(self->scope, node); |
491 | 16.2k | ((txPropertyAtNode*)item)->atAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
492 | 16.2k | } |
493 | 16.3k | } |
494 | 8.83k | else { |
495 | 8.83k | txSymbol* symbol = ((txPrivatePropertyNode*)item)->symbol; |
496 | 8.83k | txDeclareNode* node = fxScopeGetDeclareNode(self->scope, symbol); |
497 | 8.83k | if (node) { |
498 | 100 | txUnsigned flags = (node->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)) ^ (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)); |
499 | 100 | if ((flags != (mxGetterFlag | mxSetterFlag))) |
500 | 100 | fxReportParserError(hoister->parser, item->line, "duplicate %s", symbol->string); |
501 | 100 | } |
502 | 8.83k | node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
503 | 8.83k | node->flags |= mxDeclareNodeClosureFlag | (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)); |
504 | 8.83k | fxScopeAddDeclareNode(self->scope, node); |
505 | 8.83k | ((txPrivatePropertyNode*)item)->symbolAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
506 | 8.83k | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) { |
507 | 4.14k | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
508 | 4.14k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
509 | 4.14k | symbol->ID = -1; |
510 | 4.14k | node->flags |= mxDeclareNodeClosureFlag; |
511 | 4.14k | fxScopeAddDeclareNode(self->scope, node); |
512 | 4.14k | ((txPrivatePropertyNode*)item)->valueAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
513 | 4.14k | } |
514 | 8.83k | } |
515 | 38.4k | item = item->next; |
516 | 38.4k | } |
517 | 9.47k | if (self->instanceInit) { |
518 | 8.40k | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
519 | 8.40k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
520 | 8.40k | symbol->ID = -1; |
521 | 8.40k | node->flags |= mxDeclareNodeClosureFlag; |
522 | 8.40k | fxScopeAddDeclareNode(self->scope, node); |
523 | 8.40k | self->instanceInitAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
524 | 8.40k | } |
525 | 9.47k | hoister->classNode = self; |
526 | 9.47k | fxNodeDispatchHoist(self->constructor, param); |
527 | 9.47k | fxNodeListDistribute(self->items, fxNodeDispatchHoist, param); |
528 | 9.47k | if (self->constructorInit) |
529 | 86 | fxNodeDispatchHoist(self->constructorInit, param); |
530 | 9.47k | if (self->instanceInit) |
531 | 8.39k | fxNodeDispatchHoist(self->instanceInit, param); |
532 | 9.47k | hoister->classNode = former; |
533 | 9.47k | fxScopeHoisted(self->scope, param); |
534 | 9.47k | if (self->symbol) |
535 | 9.15k | fxScopeHoisted(self->symbolScope, param); |
536 | 9.47k | } |
537 | | |
538 | | void fxCoalesceExpressionNodeHoist(void* it, void* param) |
539 | 347 | { |
540 | 347 | txBinaryExpressionNode* self = it; |
541 | 347 | txHoister* hoister = param; |
542 | 347 | txToken leftToken = self->left->description->token; |
543 | 347 | txToken rightToken = self->right->description->token; |
544 | 347 | if ((leftToken == XS_TOKEN_AND) || (rightToken == XS_TOKEN_AND)) |
545 | 1 | fxReportParserError(hoister->parser, self->line, "missing () around &&"); |
546 | 346 | else if ((leftToken == XS_TOKEN_OR) || (rightToken == XS_TOKEN_OR)) |
547 | 9 | fxReportParserError(hoister->parser, self->line, "missing () around ||"); |
548 | 347 | fxNodeDispatchHoist(self->left, param); |
549 | 347 | fxNodeDispatchHoist(self->right, param); |
550 | 347 | } |
551 | | |
552 | | void fxDeclareNodeHoist(void* it, void* param) |
553 | 110k | { |
554 | 110k | txDeclareNode* self = it; |
555 | 110k | txHoister* hoister = param; |
556 | 110k | txDeclareNode* node; |
557 | 110k | txScope* scope; |
558 | 110k | if (self->description->token == XS_TOKEN_ARG) { |
559 | 21.0k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
560 | 21.0k | if (node) { |
561 | 39 | if ((node->description->token == XS_TOKEN_ARG) && (hoister->functionScope->node->flags & (mxArrowFlag | mxAsyncFlag | mxMethodFlag | mxNotSimpleParametersFlag | mxStrictFlag))) |
562 | 5 | fxReportParserError(hoister->parser, self->line, "duplicate argument %s", self->symbol->string); |
563 | 39 | } |
564 | 20.9k | else { |
565 | 20.9k | fxScopeAddDeclareNode(hoister->functionScope, self); |
566 | 20.9k | } |
567 | 21.0k | } |
568 | 89.3k | else if ((self->description->token == XS_TOKEN_CONST) || (self->description->token == XS_TOKEN_LET) || (self->description->token == XS_TOKEN_USING)) { |
569 | 26.8k | node = fxScopeGetDeclareNode(hoister->scope, self->symbol); |
570 | 26.8k | if (!node && (hoister->scope == hoister->bodyScope)) { |
571 | 21.7k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
572 | 21.7k | if (node && (node->description->token != XS_TOKEN_ARG)) |
573 | 25 | node = C_NULL; |
574 | 21.7k | } |
575 | 26.8k | if (node) |
576 | 37 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
577 | 26.7k | else |
578 | 26.7k | fxScopeAddDeclareNode(hoister->scope, self); |
579 | 26.8k | } |
580 | 62.5k | else { |
581 | 62.5k | scope = hoister->scope; |
582 | 62.5k | node = C_NULL; |
583 | 98.2k | while (scope != hoister->bodyScope) { |
584 | 35.7k | node = fxScopeGetDeclareNode(scope, self->symbol); |
585 | 35.7k | if (node) { |
586 | 9.12k | if ((node->description->token == XS_TOKEN_CONST) || (node->description->token == XS_TOKEN_LET) || (node->description->token == XS_TOKEN_USING) || (node->description->token == XS_TOKEN_DEFINE)) |
587 | 1 | break; |
588 | 9.12k | node = C_NULL; |
589 | 9.12k | } |
590 | 35.7k | scope = scope->scope; |
591 | 35.7k | } |
592 | 62.5k | if (!node) { |
593 | 62.5k | node = fxScopeGetDeclareNode(scope, self->symbol); |
594 | 62.5k | if (node) { |
595 | 23.5k | if ((node->description->token != XS_TOKEN_CONST) && (node->description->token != XS_TOKEN_LET) && (node->description->token != XS_TOKEN_USING)) |
596 | 23.5k | node = C_NULL; |
597 | 23.5k | } |
598 | 62.5k | } |
599 | 62.5k | if (node) |
600 | 3 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
601 | 62.5k | else { |
602 | 62.5k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
603 | 62.5k | if (!node || ((node->description->token != XS_TOKEN_ARG) && (node->description->token != XS_TOKEN_VAR))) |
604 | 48.1k | fxScopeAddDeclareNode(hoister->bodyScope, self); |
605 | 62.5k | scope = hoister->scope; |
606 | 98.2k | while (scope != hoister->bodyScope) { |
607 | 35.6k | fxScopeAddDeclareNode(scope, fxDeclareNodeNew(hoister->parser, XS_NO_TOKEN, self->symbol)); |
608 | 35.6k | scope = scope->scope; |
609 | 35.6k | } |
610 | 62.5k | } |
611 | 62.5k | } |
612 | 110k | } |
613 | | |
614 | | void fxDefineNodeHoist(void* it, void* param) |
615 | 2.29k | { |
616 | 2.29k | txDefineNode* self = it; |
617 | 2.29k | txHoister* hoister = param; |
618 | 2.29k | txDeclareNode* node; |
619 | 2.29k | if (self->flags & mxStrictFlag) { |
620 | 0 | if ((self->symbol == hoister->parser->argumentsSymbol) || (self->symbol == hoister->parser->evalSymbol) || (self->symbol == hoister->parser->yieldSymbol)) |
621 | 0 | fxReportParserError(hoister->parser, self->line, "invalid definition %s", self->symbol->string); |
622 | 0 | } |
623 | 2.29k | if ((hoister->scope == hoister->bodyScope) && (hoister->scope->token != XS_TOKEN_MODULE)) { |
624 | 2.12k | node = fxScopeGetDeclareNode(hoister->bodyScope, self->symbol); |
625 | 2.12k | if (node) { |
626 | 262 | if ((node->description->token == XS_TOKEN_CONST) || (node->description->token == XS_TOKEN_LET)) |
627 | 2 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
628 | 262 | } |
629 | 1.86k | else { |
630 | 1.86k | if (hoister->functionScope != hoister->bodyScope) |
631 | 307 | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
632 | 1.86k | if (!node) |
633 | 1.86k | fxScopeAddDeclareNode(hoister->bodyScope, (txDeclareNode*)self); |
634 | 1.86k | } |
635 | 2.12k | fxScopeAddDefineNode(hoister->bodyScope, self); |
636 | 2.12k | } |
637 | 163 | else { |
638 | 163 | node = fxScopeGetDeclareNode(hoister->scope, self->symbol); |
639 | 163 | if (node) |
640 | 1 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
641 | 162 | else |
642 | 162 | fxScopeAddDeclareNode(hoister->scope, (txDeclareNode*)self); |
643 | 163 | fxScopeAddDefineNode(hoister->scope, self); |
644 | 163 | } |
645 | 2.29k | ((txFunctionNode*)(self->initializer))->symbol = C_NULL; |
646 | 2.29k | fxNodeDispatchHoist(self->initializer, param); |
647 | 2.29k | ((txFunctionNode*)(self->initializer))->symbol = self->symbol; |
648 | 2.29k | } |
649 | | |
650 | | void fxExportNodeHoist(void* it, void* param) |
651 | 440 | { |
652 | 440 | txExportNode* self = it; |
653 | 440 | txHoister* hoister = param; |
654 | 440 | if (self->from) { |
655 | 42 | if (self->specifiers && self->specifiers->length) { |
656 | 37 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
657 | 74 | while (specifier) { |
658 | 37 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
659 | 37 | specifier->from = self->from; |
660 | 37 | specifier->with = self->with; |
661 | 37 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
662 | 37 | node->line = self->line; |
663 | 37 | node->importSpecifier = specifier; |
664 | 37 | node->firstExportSpecifier = specifier; |
665 | 37 | fxScopeAddDeclareNode(hoister->scope, node); |
666 | 37 | specifier = (txSpecifierNode*)specifier->next; |
667 | 37 | } |
668 | 37 | } |
669 | 5 | else { |
670 | 5 | txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER); |
671 | 5 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
672 | 5 | specifier->from = self->from; |
673 | 5 | specifier->with = self->with; |
674 | 5 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
675 | 5 | node->line = self->line; |
676 | 5 | node->importSpecifier = specifier; |
677 | 5 | node->firstExportSpecifier = C_NULL; |
678 | 5 | fxScopeAddDeclareNode(hoister->scope, node); |
679 | 5 | } |
680 | 42 | } |
681 | 440 | if (self->specifiers && self->specifiers->length) { |
682 | 435 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
683 | 872 | while (specifier) { |
684 | 437 | fxHoisterAddExportLink(hoister, specifier); |
685 | 437 | fxNodeDispatchHoist(specifier, param); |
686 | 437 | specifier = (txSpecifierNode*)specifier->next; |
687 | 437 | } |
688 | 435 | } |
689 | 440 | } |
690 | | |
691 | | void fxForNodeHoist(void* it, void* param) |
692 | 9.38k | { |
693 | 9.38k | txForNode* self = it; |
694 | 9.38k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
695 | 9.38k | if (self->initialization) |
696 | 9.30k | fxNodeDispatchHoist(self->initialization, param); |
697 | 9.38k | if (self->expression) |
698 | 9.27k | fxNodeDispatchHoist(self->expression, param); |
699 | 9.38k | if (self->iteration) |
700 | 9.26k | fxNodeDispatchHoist(self->iteration, param); |
701 | 9.38k | fxNodeDispatchHoist(self->statement, param); |
702 | 9.38k | fxScopeHoisted(self->scope, param); |
703 | 9.38k | } |
704 | | |
705 | | void fxForInForOfNodeHoist(void* it, void* param) |
706 | 16.8k | { |
707 | 16.8k | txForInForOfNode* self = it; |
708 | 16.8k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
709 | 16.8k | fxNodeDispatchHoist(self->reference, param); |
710 | 16.8k | fxNodeDispatchHoist(self->expression, param); |
711 | 16.8k | fxNodeDispatchHoist(self->statement, param); |
712 | 16.8k | fxScopeHoisted(self->scope, param); |
713 | 16.8k | } |
714 | | |
715 | | void fxFunctionNodeHoist(void* it, void* param) |
716 | 96.5k | { |
717 | 96.5k | txFunctionNode* self = it; |
718 | 96.5k | txHoister* hoister = param; |
719 | 96.5k | txScope* functionScope = hoister->functionScope; |
720 | 96.5k | txScope* bodyScope = hoister->bodyScope; |
721 | 96.5k | hoister->functionScope = self->scope = fxScopeNew(param, it, XS_TOKEN_FUNCTION); |
722 | 96.5k | hoister->bodyScope = C_NULL; |
723 | 96.5k | if (self->symbol) { |
724 | 43.7k | txDefineNode* node = fxDefineNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol); |
725 | 43.7k | node->initializer = fxValueNodeNew(hoister->parser, XS_TOKEN_CURRENT); |
726 | 43.7k | fxScopeAddDeclareNode(hoister->functionScope, (txDeclareNode*)node); |
727 | 43.7k | fxScopeAddDefineNode(hoister->functionScope, node); |
728 | 43.7k | } |
729 | 96.5k | fxNodeDispatchHoist(self->params, param); |
730 | 96.5k | if ((self->flags & (mxArgumentsFlag | mxEvalFlag)) && !(self->flags & mxArrowFlag)) { |
731 | 1.29k | txDeclareNode* declaration = fxDeclareNodeNew(hoister->parser, XS_TOKEN_VAR, hoister->parser->argumentsSymbol); |
732 | 1.29k | fxScopeAddDeclareNode(hoister->functionScope, declaration); |
733 | 1.29k | } |
734 | 96.5k | fxNodeDispatchHoist(self->body, param); |
735 | 96.5k | fxScopeHoisted(self->scope, param); |
736 | 96.5k | hoister->bodyScope = bodyScope; |
737 | 96.5k | hoister->functionScope = functionScope; |
738 | 96.5k | } |
739 | | |
740 | | txHostNode* fxHostNodeClone(txParser* parser, txHostNode* self) |
741 | 0 | { |
742 | 0 | txHostNode* node = fxNewParserChunkClear(parser, sizeof(txHostNode)); |
743 | 0 | c_memcpy(node, self, sizeof(txHostNode)); |
744 | 0 | return node; |
745 | 0 | } |
746 | | |
747 | | void fxHostNodeHoist(void* it, void* param) |
748 | 0 | { |
749 | 0 | txHostNode* self = it; |
750 | 0 | txHoister* hoister = param; |
751 | 0 | txScope* scope = hoister->bodyScope; |
752 | 0 | self->hostIndex = -1; |
753 | 0 | if ((scope->token != XS_TOKEN_MODULE) && (scope->token != XS_TOKEN_PROGRAM)) { |
754 | 0 | txParser* parser = hoister->parser; |
755 | 0 | while ((scope->token != XS_TOKEN_MODULE) && (scope->token != XS_TOKEN_PROGRAM)) |
756 | 0 | scope = scope->scope; |
757 | 0 | snprintf(parser->buffer, parser->bufferSize, "@%s", self->at->value); |
758 | 0 | txSymbol* symbol = fxNewParserSymbol(parser, parser->buffer); |
759 | 0 | if (!fxScopeGetDeclareNode(scope, symbol)) { |
760 | 0 | txDefineNode* definition = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol); |
761 | 0 | definition->initializer = (txNode*)fxHostNodeClone(parser, self); |
762 | 0 | fxScopeAddDeclareNode(scope, (txDeclareNode*)definition); |
763 | 0 | fxScopeAddDefineNode(scope, definition); |
764 | 0 | } |
765 | 0 | txAccessNode* access = it; |
766 | 0 | access->description = &gxTokenDescriptions[XS_TOKEN_ACCESS]; |
767 | 0 | access->symbol = symbol; |
768 | 0 | access->initializer = C_NULL; |
769 | 0 | access->declaration = C_NULL; |
770 | 0 | } |
771 | 0 | } |
772 | | |
773 | | void fxImportNodeHoist(void* it, void* param) |
774 | 119 | { |
775 | 119 | txImportNode* self = it; |
776 | 119 | txHoister* hoister = param; |
777 | 119 | if (self->specifiers && self->specifiers->length) { |
778 | 103 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
779 | 206 | while (specifier) { |
780 | 103 | txDeclareNode* node; |
781 | 103 | txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol; |
782 | 103 | if (self->flags & mxStrictFlag) { |
783 | 103 | if ((symbol == hoister->parser->argumentsSymbol) || (symbol == hoister->parser->evalSymbol)) |
784 | 0 | fxReportParserError(hoister->parser, self->line, "invalid import %s", symbol->string); |
785 | 103 | } |
786 | 103 | node = fxScopeGetDeclareNode(hoister->scope, symbol); |
787 | 103 | if (node) |
788 | 1 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", symbol->string); |
789 | 102 | else { |
790 | 102 | specifier->declaration = node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, symbol); |
791 | 102 | specifier->from = self->from; |
792 | 102 | specifier->with = self->with; |
793 | 102 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
794 | 102 | node->line = self->line; |
795 | 102 | node->importSpecifier = specifier; |
796 | 102 | fxScopeAddDeclareNode(hoister->scope, node); |
797 | 102 | } |
798 | 103 | specifier = (txSpecifierNode*)specifier->next; |
799 | 103 | } |
800 | 103 | } |
801 | 16 | else { |
802 | 16 | txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER); |
803 | 16 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
804 | 16 | specifier->from = self->from; |
805 | 16 | specifier->with = self->with; |
806 | 16 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
807 | 16 | node->line = self->line; |
808 | 16 | node->importSpecifier = specifier; |
809 | 16 | fxScopeAddDeclareNode(hoister->scope, node); |
810 | 16 | } |
811 | 119 | } |
812 | | |
813 | | void fxModuleNodeHoist(void* it, void* param) |
814 | 2.49k | { |
815 | 2.49k | txModuleNode* self = it; |
816 | 2.49k | txHoister* hoister = param; |
817 | 2.49k | hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_MODULE); // @@ |
818 | 2.49k | hoister->environmentNode = it; |
819 | 2.49k | fxNodeDispatchHoist(self->body, param); |
820 | 2.49k | hoister->environmentNode = C_NULL; |
821 | 2.49k | fxScopeHoisted(self->scope, param); |
822 | 2.49k | } |
823 | | |
824 | | void fxParamsBindingNodeHoist(void* it, void* param) |
825 | 96.5k | { |
826 | 96.5k | txParamsNode* self = it; |
827 | 96.5k | txNode* item = self->items->first; |
828 | 117k | while (item) { |
829 | 20.8k | fxNodeDispatchHoist(item, param); |
830 | 20.8k | item = item->next; |
831 | 20.8k | } |
832 | 96.5k | } |
833 | | |
834 | | void fxProgramNodeHoist(void* it, void* param) |
835 | 169k | { |
836 | 169k | txProgramNode* self = it; |
837 | 169k | txHoister* hoister = param; |
838 | 169k | hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, (hoister->parser->flags & mxEvalFlag) ? XS_TOKEN_EVAL : XS_TOKEN_PROGRAM); |
839 | 169k | hoister->environmentNode = it; |
840 | 169k | fxNodeDispatchHoist(self->body, param); |
841 | 169k | hoister->environmentNode = C_NULL; |
842 | 169k | self->variableCount = hoister->functionScope->declareNodeCount; |
843 | 169k | fxScopeHoisted(self->scope, param); |
844 | 169k | } |
845 | | |
846 | | void fxStatementNodeHoist(void* it, void* param) |
847 | 465k | { |
848 | 465k | txStatementNode* self = it; |
849 | 465k | fxNodeDispatchHoist(self->expression, param); |
850 | 465k | } |
851 | | |
852 | | void fxPropertyNodeHoist(void* it, void* param) |
853 | 64.2k | { |
854 | 64.2k | txPropertyNode* self = it; |
855 | 64.2k | if (self->value) { |
856 | 51.6k | if (self->value->description->token == XS_TOKEN_HOST) |
857 | 0 | ((txHostNode*)(self->value))->symbol = self->symbol; |
858 | 51.6k | fxNodeDispatchHoist(self->value, param); |
859 | 51.6k | } |
860 | 64.2k | } |
861 | | |
862 | | void fxStringNodeHoist(void* it, void* param) |
863 | 733k | { |
864 | 733k | txStringNode* self = it; |
865 | 733k | txHoister* hoister = param; |
866 | 733k | if ((self->flags & mxStringLegacyFlag) && (hoister->scope->flags & mxStrictFlag)) |
867 | 102 | self->flags |= mxStringErrorFlag; |
868 | 733k | } |
869 | | |
870 | | void fxSwitchNodeHoist(void* it, void* param) |
871 | 827 | { |
872 | 827 | txSwitchNode* self = it; |
873 | 827 | fxNodeDispatchHoist(self->expression, param); |
874 | 827 | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
875 | 827 | fxNodeListDistribute(self->items, fxNodeDispatchHoist, param); |
876 | 827 | fxScopeHoisted(self->scope, param); |
877 | 827 | } |
878 | | |
879 | | void fxWithNodeHoist(void* it, void* param) |
880 | 3.37k | { |
881 | 3.37k | txWithNode* self = it; |
882 | 3.37k | txHoister* hoister = param; |
883 | 3.37k | fxNodeDispatchHoist(self->expression, param); |
884 | 3.37k | self->scope = fxScopeNew(param, it, XS_TOKEN_WITH); |
885 | 3.37k | fxScopeEval(hoister->scope); |
886 | 3.37k | fxNodeDispatchHoist(self->statement, param); |
887 | 3.37k | fxScopeHoisted(self->scope, param); |
888 | 3.37k | } |
889 | | |
890 | | void fxNodeDispatchBind(void* it, void* param) |
891 | 4.51M | { |
892 | 4.51M | txNode* node = it; |
893 | 4.51M | fxCheckParserStack(((txBinder*)param)->parser, node->line); |
894 | 4.51M | (*node->description->dispatch->bind)(it, param); |
895 | 4.51M | } |
896 | | |
897 | | void fxNodeBind(void* it, void* param) |
898 | 2.66M | { |
899 | 2.66M | txNode* node = it; |
900 | 2.66M | (*node->description->dispatch->distribute)(node, fxNodeDispatchBind, param); |
901 | 2.66M | } |
902 | | |
903 | | void fxAccessNodeBind(void* it, void* param) |
904 | 537k | { |
905 | 537k | txAccessNode* self = it; |
906 | 537k | txBinder* binder = param; |
907 | 537k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
908 | 537k | } |
909 | | |
910 | | void fxArrayNodeBind(void* it, void* param) |
911 | 48.4k | { |
912 | 48.4k | txArrayNode* self = it; |
913 | 48.4k | fxBinderPushVariables(param, 1); |
914 | 48.4k | if (self->flags & mxSpreadFlag) { |
915 | 532 | fxBinderPushVariables(param, 2); |
916 | 532 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
917 | 532 | fxBinderPopVariables(param, 2); |
918 | 532 | } |
919 | 47.9k | else |
920 | 47.9k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
921 | 48.4k | fxBinderPopVariables(param, 1); |
922 | 48.4k | } |
923 | | |
924 | | void fxArrayBindingNodeBind(void* it, void* param) |
925 | 22.6k | { |
926 | 22.6k | txArrayBindingNode* self = it; |
927 | 22.6k | fxBinderPushVariables(param, 6); |
928 | 22.6k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
929 | 22.6k | fxBinderPopVariables(param, 6); |
930 | 22.6k | } |
931 | | |
932 | | void fxAssignNodeBind(void* it, void* param) |
933 | 31.5k | { |
934 | 31.5k | txAssignNode* self = it; |
935 | 31.5k | txToken token = self->reference->description->token; |
936 | 31.5k | fxNodeDispatchBind(self->reference, param); |
937 | 31.5k | if ((token == XS_TOKEN_ACCESS) || (token == XS_TOKEN_ARG) || (token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_USING) || (token == XS_TOKEN_VAR)) |
938 | 24.1k | fxFunctionNodeRename(self->value, ((txAccessNode*)self->reference)->symbol); |
939 | 31.5k | fxNodeDispatchBind(self->value, param); |
940 | 31.5k | } |
941 | | |
942 | | void fxBindingNodeBind(void* it, void* param) |
943 | 43.5k | { |
944 | 43.5k | txBindingNode* self = it; |
945 | 43.5k | txToken token = self->target->description->token; |
946 | 43.5k | fxNodeDispatchBind(self->target, param); |
947 | 43.5k | if ((token == XS_TOKEN_ACCESS) || (token == XS_TOKEN_ARG) || (token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_USING) || (token == XS_TOKEN_VAR)) |
948 | 43.3k | fxFunctionNodeRename(self->initializer, ((txAccessNode*)self->target)->symbol); |
949 | 43.5k | fxNodeDispatchBind(self->initializer, param); |
950 | 43.5k | } |
951 | | |
952 | | void fxBlockNodeBind(void* it, void* param) |
953 | 102k | { |
954 | 102k | txBlockNode* self = it; |
955 | 102k | fxScopeBinding(self->scope, param); |
956 | 102k | fxScopeBindDefineNodes(self->scope, param); |
957 | 102k | if (self->scope->disposableNodeCount) |
958 | 4.07k | fxBinderPushVariables(param, 2); |
959 | 102k | fxNodeDispatchBind(self->statement, param); |
960 | 102k | if (self->scope->disposableNodeCount) |
961 | 4.07k | fxBinderPopVariables(param, 2); |
962 | 102k | fxScopeBound(self->scope, param); |
963 | 102k | } |
964 | | |
965 | | void fxCatchNodeBind(void* it, void* param) |
966 | 1.80k | { |
967 | 1.80k | txCatchNode* self = it; |
968 | 1.80k | if (self->parameter) { |
969 | 1.74k | fxScopeBinding(self->scope, param); |
970 | 1.74k | fxNodeDispatchBind(self->parameter, param); |
971 | 1.74k | fxScopeBinding(self->statementScope, param); |
972 | 1.74k | fxScopeBindDefineNodes(self->statementScope, param); |
973 | 1.74k | if (self->statementScope->disposableNodeCount) |
974 | 0 | fxBinderPushVariables(param, 2); |
975 | 1.74k | fxNodeDispatchBind(self->statement, param); |
976 | 1.74k | if (self->statementScope->disposableNodeCount) |
977 | 0 | fxBinderPushVariables(param, 2); |
978 | 1.74k | fxScopeBound(self->statementScope, param); |
979 | 1.74k | fxScopeBound(self->scope, param); |
980 | 1.74k | } |
981 | 58 | else { |
982 | 58 | fxScopeBinding(self->statementScope, param); |
983 | 58 | fxScopeBindDefineNodes(self->statementScope, param); |
984 | 58 | if (self->statementScope->disposableNodeCount) |
985 | 0 | fxBinderPushVariables(param, 2); |
986 | 58 | fxNodeDispatchBind(self->statement, param); |
987 | 58 | if (self->statementScope->disposableNodeCount) |
988 | 0 | fxBinderPushVariables(param, 2); |
989 | 58 | fxScopeBound(self->statementScope, param); |
990 | 58 | } |
991 | 1.80k | } |
992 | | |
993 | | void fxClassNodeBind(void* it, void* param) |
994 | 9.33k | { |
995 | 9.33k | txClassNode* self = it; |
996 | 9.33k | txBinder* binder = param; |
997 | 9.33k | txClassNode* former = binder->classNode; |
998 | 9.33k | fxBinderPushVariables(param, 2); |
999 | 9.33k | if (self->symbol) |
1000 | 9.12k | fxScopeBinding(self->symbolScope, param); |
1001 | 9.33k | if (self->heritage) |
1002 | 294 | fxNodeDispatchBind(self->heritage, param); |
1003 | 9.33k | fxScopeBinding(self->scope, param); |
1004 | 9.33k | binder->classNode = self; |
1005 | 9.33k | fxNodeDispatchBind(self->constructor, param); |
1006 | 9.33k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1007 | 9.33k | if (self->constructorInit) |
1008 | 85 | fxNodeDispatchBind(self->constructorInit, param); |
1009 | 9.33k | if (self->instanceInit) |
1010 | 8.37k | fxNodeDispatchBind(self->instanceInit, param); |
1011 | 9.33k | binder->classNode = former; |
1012 | 9.33k | fxScopeBound(self->scope, param); |
1013 | 9.33k | if (self->symbol) |
1014 | 9.12k | fxScopeBound(self->symbolScope, param); |
1015 | 9.33k | fxBinderPopVariables(param, 2); |
1016 | 9.33k | } |
1017 | | |
1018 | | void fxDeclareNodeBind(void* it, void* param) |
1019 | 153k | { |
1020 | 153k | txBindingNode* self = it; |
1021 | 153k | txBinder* binder = param; |
1022 | 153k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1023 | 153k | } |
1024 | | |
1025 | | void fxDefineNodeBind(void* it, void* param) |
1026 | 4.53k | { |
1027 | 4.53k | txDefineNode* self = it; |
1028 | 4.53k | txBinder* binder = param; |
1029 | 4.53k | if (self->flags & mxDefineNodeBoundFlag) |
1030 | 2.26k | return; |
1031 | 2.27k | self->flags |= mxDefineNodeBoundFlag; |
1032 | 2.27k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1033 | 2.27k | fxNodeDispatchBind(self->initializer, param); |
1034 | 2.27k | } |
1035 | | |
1036 | | void fxDelegateNodeBind(void* it, void* param) |
1037 | 35 | { |
1038 | 35 | txStatementNode* self = it; |
1039 | 35 | fxBinderPushVariables(param, 5); |
1040 | 35 | fxNodeDispatchBind(self->expression, param); |
1041 | 35 | fxBinderPopVariables(param, 5); |
1042 | 35 | } |
1043 | | |
1044 | | void fxExportNodeBind(void* it, void* param) |
1045 | 415 | { |
1046 | 415 | txExportNode* self = it; |
1047 | 415 | txBinder* binder = param; |
1048 | 415 | if (self->from) |
1049 | 27 | return; |
1050 | 388 | if (self->specifiers) { |
1051 | 388 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
1052 | 777 | while (specifier) { |
1053 | 389 | txAccessNode* node = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, specifier->symbol); |
1054 | 389 | fxScopeLookup(binder->scope, node, 0); |
1055 | 389 | if (node->declaration) { |
1056 | 388 | specifier->declaration = node->declaration; |
1057 | 388 | specifier->declaration->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
1058 | 388 | specifier->nextSpecifier = specifier->declaration->firstExportSpecifier; |
1059 | 388 | specifier->declaration->firstExportSpecifier = specifier; |
1060 | 388 | } |
1061 | 1 | else |
1062 | 1 | fxReportParserError(binder->parser, specifier->line, "unknown variable %s", specifier->symbol->string); |
1063 | 389 | specifier = (txSpecifierNode*)specifier->next; |
1064 | 389 | } |
1065 | 388 | } |
1066 | 388 | } |
1067 | | |
1068 | | void fxFieldNodeBind(void* it, void* param) |
1069 | 37.2k | { |
1070 | 37.2k | txFieldNode* self = it; |
1071 | 37.2k | txBinder* binder = param; |
1072 | 37.2k | txNode* item = self->item; |
1073 | 37.2k | if (item->description->token == XS_TOKEN_PROPERTY_AT) |
1074 | 16.1k | fxScopeLookup(binder->scope, ((txPropertyAtNode*)item)->atAccess, 0); |
1075 | 21.1k | else if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) { |
1076 | 8.59k | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) |
1077 | 4.13k | fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->valueAccess, 0); |
1078 | 8.59k | fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->symbolAccess, 0); |
1079 | 8.59k | } |
1080 | 37.2k | if (self->value) |
1081 | 33.0k | fxNodeDispatchBind(self->value, param); |
1082 | 37.2k | } |
1083 | | |
1084 | | void fxForNodeBind(void* it, void* param) |
1085 | 9.37k | { |
1086 | 9.37k | txForNode* self = it; |
1087 | 9.37k | fxScopeBinding(self->scope, param); |
1088 | 9.37k | fxScopeBindDefineNodes(self->scope, param); |
1089 | 9.37k | if (self->scope->disposableNodeCount) |
1090 | 0 | fxBinderPushVariables(param, 2); |
1091 | 9.37k | if (self->initialization) |
1092 | 9.29k | fxNodeDispatchBind(self->initialization, param); |
1093 | 9.37k | if (self->expression) |
1094 | 9.26k | fxNodeDispatchBind(self->expression, param); |
1095 | 9.37k | if (self->iteration) |
1096 | 9.25k | fxNodeDispatchBind(self->iteration, param); |
1097 | 9.37k | fxNodeDispatchBind(self->statement, param); |
1098 | 9.37k | if (self->scope->disposableNodeCount) |
1099 | 0 | fxBinderPopVariables(param, 2); |
1100 | 9.37k | fxScopeBound(self->scope, param); |
1101 | 9.37k | } |
1102 | | |
1103 | | void fxForInForOfNodeBind(void* it, void* param) |
1104 | 16.8k | { |
1105 | 16.8k | txForInForOfNode* self = it; |
1106 | 16.8k | fxBinderPushVariables(param, 6); |
1107 | 16.8k | fxScopeBinding(self->scope, param); |
1108 | 16.8k | fxScopeBindDefineNodes(self->scope, param); |
1109 | 16.8k | fxNodeDispatchBind(self->reference, param); |
1110 | 16.8k | fxNodeDispatchBind(self->expression, param); |
1111 | 16.8k | fxNodeDispatchBind(self->statement, param); |
1112 | 16.8k | fxScopeBound(self->scope, param); |
1113 | 16.8k | fxBinderPopVariables(param, 6); |
1114 | 16.8k | } |
1115 | | |
1116 | | void fxFunctionNodeBind(void* it, void* param) |
1117 | 96.4k | { |
1118 | 96.4k | txFunctionNode* self = it; |
1119 | 96.4k | txBinder* binder = param; |
1120 | 96.4k | txInteger scopeLevel = binder->scopeLevel; |
1121 | 96.4k | txInteger scopeMaximum = binder->scopeMaximum; |
1122 | 96.4k | scopeLevel = binder->scopeLevel; |
1123 | 96.4k | scopeMaximum = binder->scopeMaximum; |
1124 | 96.4k | binder->scopeLevel = 0; |
1125 | 96.4k | binder->scopeMaximum = 0; |
1126 | 96.4k | fxScopeBinding(self->scope, param); |
1127 | 96.4k | fxNodeDispatchBind(self->params, param); |
1128 | 96.4k | if (self->flags & mxBaseFlag) { |
1129 | 9.03k | if (binder->classNode->instanceInitAccess) { |
1130 | 8.35k | fxScopeLookup(binder->scope, binder->classNode->instanceInitAccess, 0); |
1131 | 8.35k | } |
1132 | 9.03k | } |
1133 | 96.4k | fxScopeBindDefineNodes(self->scope, param); |
1134 | 96.4k | fxNodeDispatchBind(self->body, param); |
1135 | 96.4k | fxScopeBound(self->scope, param); |
1136 | 96.4k | self->scopeCount = binder->scopeMaximum; |
1137 | 96.4k | binder->scopeMaximum = scopeMaximum; |
1138 | 96.4k | binder->scopeLevel = scopeLevel; |
1139 | 96.4k | } |
1140 | | |
1141 | | void fxFunctionNodeRename(void* it, txSymbol* symbol) |
1142 | 67.5k | { |
1143 | 67.5k | txNode* self = it; |
1144 | 67.5k | txToken token = self->description->token; |
1145 | 67.5k | if (token == XS_TOKEN_EXPRESSIONS) { |
1146 | 184 | self = ((txExpressionsNode*)self)->items->first; |
1147 | 184 | if (self->next) |
1148 | 13 | return; |
1149 | 171 | token = self->description->token; |
1150 | 171 | } |
1151 | 67.4k | if (token == XS_TOKEN_CLASS) { |
1152 | 5.16k | txClassNode* node = (txClassNode*)self; |
1153 | 5.16k | if (!node->symbol) |
1154 | 13 | ((txFunctionNode*)(node->constructor))->symbol = symbol; |
1155 | 5.16k | } |
1156 | 62.3k | else if ((token == XS_TOKEN_FUNCTION) || (token == XS_TOKEN_GENERATOR) || (token == XS_TOKEN_HOST)) { |
1157 | 3.72k | txFunctionNode* node = (txFunctionNode*)self; |
1158 | 3.72k | if (!node->symbol) |
1159 | 3.67k | node->symbol = symbol; |
1160 | 3.72k | } |
1161 | 67.4k | } |
1162 | | |
1163 | | void fxHostNodeBind(void* it, void* param) |
1164 | 0 | { |
1165 | 0 | } |
1166 | | |
1167 | | void fxModuleNodeBind(void* it, void* param) |
1168 | 2.48k | { |
1169 | 2.48k | txModuleNode* self = it; |
1170 | 2.48k | txBinder* binder = param; |
1171 | 2.48k | fxScopeBinding(self->scope, param); |
1172 | 2.48k | fxScopeBindDefineNodes(self->scope, param); |
1173 | 2.48k | fxNodeDispatchBind(self->body, param); |
1174 | 2.48k | fxScopeBound(self->scope, param); |
1175 | 2.48k | self->scopeCount = binder->scopeMaximum; |
1176 | 2.48k | } |
1177 | | |
1178 | | void fxObjectNodeBind(void* it, void* param) |
1179 | 29.4k | { |
1180 | 29.4k | txObjectNode* self = it; |
1181 | 29.4k | txNode* item = self->items->first; |
1182 | 29.4k | fxBinderPushVariables(param, 1); |
1183 | 89.1k | while (item) { |
1184 | 59.7k | txNode* value; |
1185 | 59.7k | if (item->description->token == XS_TOKEN_SPREAD) { |
1186 | 281 | } |
1187 | 59.4k | else { |
1188 | 59.4k | if (item->description->token == XS_TOKEN_PROPERTY) { |
1189 | 51.0k | value = ((txPropertyNode*)item)->value; |
1190 | 51.0k | } |
1191 | 8.42k | else { |
1192 | 8.42k | value = ((txPropertyAtNode*)item)->value; |
1193 | 8.42k | } |
1194 | 59.4k | if ((value->description->token == XS_TOKEN_FUNCTION) || (value->description->token == XS_TOKEN_GENERATOR) || (value->description->token == XS_TOKEN_HOST)) { |
1195 | 2.73k | txFunctionNode* node = (txFunctionNode*)value; |
1196 | 2.73k | node->flags |= item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag); |
1197 | 2.73k | } |
1198 | 56.7k | else if (value->description->token == XS_TOKEN_CLASS) { |
1199 | | // txFunctionNode* node = (txFunctionNode*)(((txClassNode*)value)->constructor); |
1200 | 2 | } |
1201 | 59.4k | } |
1202 | 59.7k | fxNodeDispatchBind(item, param); |
1203 | 59.7k | item = item->next; |
1204 | 59.7k | } |
1205 | 29.4k | fxBinderPopVariables(param, 1); |
1206 | 29.4k | } |
1207 | | |
1208 | | void fxObjectBindingNodeBind(void* it, void* param) |
1209 | 406 | { |
1210 | 406 | txObjectBindingNode* self = it; |
1211 | 406 | fxBinderPushVariables(param, 2); |
1212 | 406 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1213 | 406 | fxBinderPopVariables(param, 2); |
1214 | 406 | } |
1215 | | |
1216 | | void fxParamsNodeBind(void* it, void* param) |
1217 | 128k | { |
1218 | 128k | txParamsNode* self = it; |
1219 | 128k | if (self->flags & mxSpreadFlag) { |
1220 | 386 | fxBinderPushVariables(param, 1); |
1221 | 386 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1222 | 386 | fxBinderPopVariables(param, 1); |
1223 | 386 | } |
1224 | 127k | else |
1225 | 127k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1226 | 128k | } |
1227 | | |
1228 | | void fxParamsBindingNodeBind(void* it, void* param) |
1229 | 96.4k | { |
1230 | 96.4k | txParamsBindingNode* self = it; |
1231 | 96.4k | txBinder* binder = param; |
1232 | 96.4k | txScope* functionScope = binder->scope; |
1233 | 96.4k | txFunctionNode* functionNode = (txFunctionNode*)(functionScope->node); |
1234 | 96.4k | txInteger count = self->items->length; |
1235 | 96.4k | if (functionNode->flags & mxGetterFlag) { |
1236 | 406 | if (count != 0) |
1237 | 1 | fxReportParserError(binder->parser, self->line, "invalid getter arguments"); |
1238 | 406 | } |
1239 | 96.0k | else if (functionNode->flags & mxSetterFlag) { |
1240 | 118 | if ((count != 1) || (self->items->first->description->token == XS_TOKEN_REST_BINDING)) |
1241 | 1 | fxReportParserError(binder->parser, self->line, "invalid setter arguments"); |
1242 | 118 | } |
1243 | 95.9k | else { |
1244 | 95.9k | if (count > 255) |
1245 | 0 | fxReportParserError(binder->parser, self->line, "too many arguments"); |
1246 | 95.9k | } |
1247 | 96.4k | if (functionNode->flags & mxArgumentsFlag) { |
1248 | 6.62k | txNode* item; |
1249 | 6.62k | self->declaration = fxScopeGetDeclareNode(functionScope, binder->parser->argumentsSymbol); |
1250 | 6.62k | if (functionNode->flags & mxStrictFlag) |
1251 | 3.93k | goto bail; |
1252 | 2.69k | item = self->items->first; |
1253 | 3.64k | while (item) { |
1254 | 960 | if (item->description->token != XS_TOKEN_ARG) |
1255 | 14 | goto bail; |
1256 | 946 | item = item->next; |
1257 | 946 | } |
1258 | 2.68k | item = self->items->first; |
1259 | 3.62k | while (item) { |
1260 | 941 | ((txDeclareNode*)item)->flags |= mxDeclareNodeClosureFlag; |
1261 | 941 | item = item->next; |
1262 | 941 | } |
1263 | 2.68k | self->mapped = 1; |
1264 | 2.68k | } |
1265 | 96.4k | bail: |
1266 | 96.4k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1267 | 96.4k | } |
1268 | | |
1269 | | void fxPostfixExpressionNodeBind(void* it, void* param) |
1270 | 12.3k | { |
1271 | 12.3k | txPostfixExpressionNode* self = it; |
1272 | 12.3k | fxNodeDispatchBind(self->left, param); |
1273 | 12.3k | fxBinderPushVariables(param, 1); |
1274 | 12.3k | fxBinderPopVariables(param, 1); |
1275 | 12.3k | } |
1276 | | |
1277 | | void fxPrivateMemberNodeBind(void* it, void* param) |
1278 | 5.31k | { |
1279 | 5.31k | txBinder* binder = param; |
1280 | 5.31k | txPrivateMemberNode* self = it; |
1281 | 5.31k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1282 | 5.31k | if (!self->declaration) |
1283 | 534 | fxReportParserError(binder->parser, self->line, "invalid private identifier"); |
1284 | 5.31k | fxNodeDispatchBind(self->reference, param); |
1285 | 5.31k | } |
1286 | | |
1287 | | void fxProgramNodeBind(void* it, void* param) |
1288 | 168k | { |
1289 | 168k | txProgramNode* self = it; |
1290 | 168k | txBinder* binder = param; |
1291 | 168k | fxScopeBinding(self->scope, param); |
1292 | 168k | fxScopeBindDefineNodes(self->scope, param); |
1293 | 168k | fxNodeDispatchBind(self->body, param); |
1294 | 168k | fxScopeBound(self->scope, param); |
1295 | 168k | self->scopeCount = binder->scopeMaximum; |
1296 | 168k | } |
1297 | | |
1298 | | void fxSpreadNodeBind(void* it, void* param) |
1299 | 1.54k | { |
1300 | 1.54k | txSpreadNode* self = it; |
1301 | 1.54k | fxBinderPushVariables(param, 1); |
1302 | 1.54k | fxNodeDispatchBind(self->expression, param); |
1303 | 1.54k | fxBinderPopVariables(param, 1); |
1304 | 1.54k | } |
1305 | | |
1306 | | void fxSuperNodeBind(void* it, void* param) |
1307 | 285 | { |
1308 | 285 | txSuperNode* self = it; |
1309 | 285 | txBinder* binder = param; |
1310 | 285 | fxScopeArrow(binder->scope); |
1311 | 285 | fxNodeDispatchBind(self->params, param); |
1312 | 285 | if (binder->classNode->instanceInitAccess) { |
1313 | 18 | self->instanceInitAccess = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, binder->classNode->instanceInitAccess->symbol); |
1314 | 18 | fxScopeLookup(binder->scope, self->instanceInitAccess, 0); |
1315 | 18 | } |
1316 | 285 | } |
1317 | | |
1318 | | void fxSwitchNodeBind(void* it, void* param) |
1319 | 825 | { |
1320 | 825 | txSwitchNode* self = it; |
1321 | 825 | fxNodeDispatchBind(self->expression, param); |
1322 | 825 | fxScopeBinding(self->scope, param); |
1323 | 825 | fxScopeBindDefineNodes(self->scope, param); |
1324 | 825 | if (self->scope->disposableNodeCount) |
1325 | 0 | fxBinderPushVariables(param, 2); |
1326 | 825 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1327 | 825 | if (self->scope->disposableNodeCount) |
1328 | 0 | fxBinderPopVariables(param, 2); |
1329 | 825 | fxScopeBound(self->scope, param); |
1330 | 825 | } |
1331 | | |
1332 | | void fxTargetNodeBind(void* it, void* param) |
1333 | 4 | { |
1334 | 4 | txBinder* binder = param; |
1335 | 4 | fxScopeArrow(binder->scope); |
1336 | 4 | } |
1337 | | |
1338 | | void fxTemplateNodeBind(void* it, void* param) |
1339 | 280k | { |
1340 | 280k | txTemplateNode* self = it; |
1341 | 280k | if (self->reference) { |
1342 | 249k | fxBinderPushVariables(param, 2); |
1343 | 249k | fxNodeDispatchBind(self->reference, param); |
1344 | 249k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1345 | 249k | fxBinderPopVariables(param, 2); |
1346 | 249k | } |
1347 | 31.2k | else { |
1348 | 31.2k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1349 | 31.2k | } |
1350 | 280k | } |
1351 | | |
1352 | | void fxThisNodeBind(void* it, void* param) |
1353 | 4.99k | { |
1354 | 4.99k | txBinder* binder = param; |
1355 | 4.99k | fxScopeArrow(binder->scope); |
1356 | 4.99k | } |
1357 | | |
1358 | | void fxTryNodeBind(void* it, void* param) |
1359 | 1.82k | { |
1360 | 1.82k | txTryNode* self = it; |
1361 | 1.82k | fxBinderPushVariables(param, 3); |
1362 | 1.82k | fxNodeDispatchBind(self->tryBlock, param); |
1363 | 1.82k | if (self->catchBlock) |
1364 | 1.80k | fxNodeDispatchBind(self->catchBlock, param); |
1365 | 1.82k | if (self->finallyBlock) |
1366 | 30 | fxNodeDispatchBind(self->finallyBlock, param); |
1367 | 1.82k | fxBinderPopVariables(param, 3); |
1368 | 1.82k | } |
1369 | | |
1370 | | void fxWithNodeBind(void* it, void* param) |
1371 | 3.37k | { |
1372 | 3.37k | txWithNode* self = it; |
1373 | 3.37k | fxNodeDispatchBind(self->expression, param); |
1374 | 3.37k | fxScopeBinding(self->scope, param); |
1375 | 3.37k | fxNodeDispatchBind(self->statement, param); |
1376 | 3.37k | fxScopeBound(self->scope, param); |
1377 | 3.37k | } |
1378 | | |
1379 | | |
1380 | | |