/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 | 415k | { |
88 | 415k | txBinder binder; |
89 | 415k | c_memset(&binder, 0, sizeof(txBinder)); |
90 | 415k | binder.parser = parser; |
91 | 415k | if (parser->errorCount == 0) { |
92 | 151k | mxTryParser(parser) { |
93 | 151k | fxNodeDispatchBind(parser->root, &binder); |
94 | 151k | } |
95 | 151k | mxCatchParser(parser) { |
96 | 510 | } |
97 | 151k | } |
98 | 415k | } |
99 | | |
100 | | void fxParserHoist(txParser* parser) |
101 | 415k | { |
102 | 415k | txHoister hoister; |
103 | 415k | c_memset(&hoister, 0, sizeof(txHoister)); |
104 | 415k | hoister.parser = parser; |
105 | 415k | if (parser->errorCount == 0) { |
106 | 151k | mxTryParser(parser) { |
107 | 151k | fxNodeDispatchHoist(parser->root, &hoister); |
108 | 151k | } |
109 | 151k | mxCatchParser(parser) { |
110 | 118 | } |
111 | 151k | } |
112 | 415k | } |
113 | | |
114 | | void fxHoisterAddExportLink(txHoister* self, txSpecifierNode* specifier) |
115 | 403 | { |
116 | 403 | txExportLink* link = self->firstExportLink; |
117 | 403 | txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol; |
118 | 403 | if (symbol) { |
119 | 842 | while (link) { |
120 | 448 | if (link->symbol == symbol) { |
121 | 2 | fxReportParserError(self->parser, specifier->line, "duplicate export %s", symbol->string); |
122 | 2 | return; |
123 | 2 | } |
124 | 446 | link = link->next; |
125 | 446 | } |
126 | 394 | link = fxNewParserChunk(self->parser, sizeof(txExportLink)); |
127 | 394 | link->next = self->firstExportLink; |
128 | 394 | link->symbol = symbol; |
129 | 394 | self->firstExportLink = link; |
130 | 394 | } |
131 | 403 | } |
132 | | |
133 | | void fxBinderPopVariables(txBinder* self, txInteger count) |
134 | 657k | { |
135 | 657k | self->scopeLevel -= count; |
136 | 657k | } |
137 | | |
138 | | void fxBinderPushVariables(txBinder* self, txInteger count) |
139 | 658k | { |
140 | 658k | self->scopeLevel += count; |
141 | 658k | if (self->scopeMaximum < self->scopeLevel) |
142 | 213k | self->scopeMaximum = self->scopeLevel; |
143 | 658k | } |
144 | | |
145 | | txScope* fxScopeNew(txHoister* hoister, txNode* node, txToken token) |
146 | 355k | { |
147 | 355k | txScope* scope = fxNewParserChunkClear(hoister->parser, sizeof(txScope)); |
148 | 355k | scope->parser = hoister->parser; |
149 | 355k | scope->scope = hoister->scope; |
150 | 355k | scope->token = token; |
151 | 355k | scope->flags = node->flags & mxStrictFlag; |
152 | 355k | scope->node = node; |
153 | 355k | hoister->scope = scope; |
154 | 355k | return scope; |
155 | 355k | } |
156 | | |
157 | | void fxScopeAddDeclareNode(txScope* self, txDeclareNode* node) |
158 | 181k | { |
159 | 181k | self->declareNodeCount++; |
160 | 181k | if (self->token == XS_TOKEN_EVAL) { |
161 | 11.0k | if (self->lastDeclareNode) |
162 | 3.96k | node->nextDeclareNode = self->firstDeclareNode; |
163 | 7.11k | else |
164 | 7.11k | self->lastDeclareNode = node; |
165 | 11.0k | self->firstDeclareNode = node; |
166 | 11.0k | } |
167 | 169k | else { |
168 | 169k | if (self->lastDeclareNode) |
169 | 65.0k | self->lastDeclareNode->nextDeclareNode = node; |
170 | 104k | else |
171 | 104k | self->firstDeclareNode = node; |
172 | 169k | self->lastDeclareNode = node; |
173 | 169k | } |
174 | 181k | if (node->description->token == XS_TOKEN_USING) { |
175 | 76 | txDeclareNode* node = fxDeclareNodeNew(self->parser, XS_TOKEN_CONST, C_NULL); |
176 | 76 | node->flags |= mxDeclareNodeDisposableFlag; |
177 | 76 | fxScopeAddDeclareNode(self, node); |
178 | 76 | self->disposableNodeCount++; |
179 | 76 | } |
180 | 181k | } |
181 | | |
182 | | void fxScopeAddDefineNode(txScope* self, txDefineNode* node) |
183 | 54.3k | { |
184 | 54.3k | self->defineNodeCount++; |
185 | 54.3k | if (self->lastDefineNode) |
186 | 625 | self->lastDefineNode->nextDefineNode = node; |
187 | 53.7k | else |
188 | 53.7k | self->firstDefineNode = node; |
189 | 54.3k | self->lastDefineNode = node; |
190 | 54.3k | } |
191 | | |
192 | | void fxScopeArrow(txScope* self) |
193 | 4.63k | { |
194 | 4.63k | if (self->token == XS_TOKEN_EVAL) { |
195 | 957 | } |
196 | 3.68k | else if (self->token == XS_TOKEN_FUNCTION) { |
197 | 1.64k | if (self->node->flags & mxArrowFlag) { |
198 | 66 | self->node->flags |= mxDefaultFlag; |
199 | 66 | if (self->scope) |
200 | 66 | fxScopeArrow(self->scope); |
201 | 66 | } |
202 | 1.64k | } |
203 | 2.03k | else if (self->token == XS_TOKEN_PROGRAM) { |
204 | 281 | } |
205 | 1.75k | else if (self->scope) { |
206 | 1.75k | fxScopeArrow(self->scope); |
207 | 1.75k | } |
208 | 4.63k | } |
209 | | |
210 | | void fxScopeBindDefineNodes(txScope* self, void* param) |
211 | 345k | { |
212 | 345k | txDefineNode* node = self->firstDefineNode; |
213 | 399k | while (node) { |
214 | 54.2k | fxNodeDispatchBind(node, param); |
215 | 54.2k | node = node->nextDefineNode; |
216 | 54.2k | } |
217 | 345k | } |
218 | | |
219 | | void fxScopeBinding(txScope* self, txBinder* binder) |
220 | 354k | { |
221 | 354k | self->scope = binder->scope; |
222 | 354k | binder->scope = self; |
223 | 354k | fxBinderPushVariables(binder, self->declareNodeCount); |
224 | 354k | } |
225 | | |
226 | | void fxScopeBound(txScope* self, txBinder* binder) |
227 | 353k | { |
228 | 353k | if (self->flags & mxEvalFlag) { |
229 | 19.3k | txDeclareNode* node = self->firstDeclareNode; |
230 | 41.0k | while (node) { |
231 | 21.7k | node->flags |= mxDeclareNodeClosureFlag; |
232 | 21.7k | node = node->nextDeclareNode; |
233 | 21.7k | } |
234 | 19.3k | } |
235 | 353k | if (self->token == XS_TOKEN_MODULE) { |
236 | 222 | txDeclareNode* node = self->firstDeclareNode; |
237 | 727 | while (node) { |
238 | 505 | if (!(node->flags & mxDeclareNodeDisposableFlag)) |
239 | 505 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
240 | 505 | node = node->nextDeclareNode; |
241 | 505 | } |
242 | 222 | } |
243 | 353k | else if (self->token == XS_TOKEN_PROGRAM) { |
244 | 68.6k | txDeclareNode* node = self->firstDeclareNode; |
245 | 92.0k | while (node) { |
246 | 23.3k | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
247 | 23.3k | node = node->nextDeclareNode; |
248 | 23.3k | } |
249 | 68.6k | } |
250 | 353k | binder->scopeLevel += self->closureNodeCount; |
251 | 353k | binder->scopeMaximum += self->closureNodeCount; |
252 | 353k | fxBinderPopVariables(binder, self->declareNodeCount); |
253 | 353k | binder->scope = self->scope; |
254 | 353k | } |
255 | | |
256 | | void fxScopeEval(txScope* self) |
257 | 5.18k | { |
258 | 109k | while (self) { |
259 | 104k | self->flags |= mxEvalFlag; |
260 | 104k | self = self->scope; |
261 | 104k | } |
262 | 5.18k | } |
263 | | |
264 | | txDeclareNode* fxScopeGetDeclareNode(txScope* self, txSymbol* symbol) |
265 | 1.24M | { |
266 | 1.24M | txDeclareNode* node = self->firstDeclareNode; |
267 | 6.83M | while (node) { |
268 | 5.85M | if (node->symbol == symbol) |
269 | 261k | return node; |
270 | 5.59M | node = node->nextDeclareNode; |
271 | 5.59M | } |
272 | 982k | return NULL; |
273 | 1.24M | } |
274 | | |
275 | | void fxScopeHoisted(txScope* self, txHoister* hoister) |
276 | 355k | { |
277 | 355k | if (self->token == XS_TOKEN_BLOCK) { |
278 | 114k | txDeclareNode** address = &self->firstDeclareNode; |
279 | 114k | txDeclareNode* node; |
280 | 114k | txDeclareNode* last = C_NULL; |
281 | 173k | while ((node = *address)) { |
282 | 59.3k | if (node->description->token == XS_NO_TOKEN) { |
283 | 32.7k | self->declareNodeCount--; |
284 | 32.7k | *address = node->nextDeclareNode; |
285 | 32.7k | } |
286 | 26.5k | else { |
287 | 26.5k | address = &node->nextDeclareNode; |
288 | 26.5k | last = node; |
289 | 26.5k | } |
290 | 59.3k | } |
291 | 114k | self->lastDeclareNode = last; |
292 | 114k | } |
293 | 240k | else if (self->token == XS_TOKEN_PROGRAM) { |
294 | 68.7k | txDeclareNode* node = self->firstDeclareNode; |
295 | 92.1k | while (node) { |
296 | 23.4k | if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR)) |
297 | 18.4k | self->declareNodeCount--; |
298 | 23.4k | node = node->nextDeclareNode; |
299 | 23.4k | } |
300 | 68.7k | } |
301 | 172k | else if (self->token == XS_TOKEN_EVAL) { |
302 | 82.8k | if (!(self->flags & mxStrictFlag)) { |
303 | 81.6k | txDeclareNode* node = self->firstDeclareNode; |
304 | 90.3k | while (node) { |
305 | 8.71k | if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR)) |
306 | 4.80k | self->declareNodeCount--; |
307 | 8.71k | node = node->nextDeclareNode; |
308 | 8.71k | } |
309 | 81.6k | } |
310 | 82.8k | } |
311 | 355k | hoister->scope = self->scope; |
312 | 355k | } |
313 | | |
314 | | void fxScopeLookup(txScope* self, txAccessNode* access, txBoolean closureFlag) |
315 | 1.07M | { |
316 | 1.07M | txDeclareNode* declaration; |
317 | 1.07M | if (self->token == XS_TOKEN_EVAL) { |
318 | 99.5k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
319 | 99.5k | if (declaration) { |
320 | 16.4k | if ((!(self->flags & mxStrictFlag)) && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) { |
321 | 6.98k | declaration = C_NULL; |
322 | 6.98k | } |
323 | 9.43k | else if (closureFlag) |
324 | 2.07k | declaration->flags |= mxDeclareNodeClosureFlag; |
325 | 16.4k | } |
326 | 83.1k | 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 | 99.5k | access->declaration = declaration; |
334 | 99.5k | } |
335 | 978k | else if (self->token == XS_TOKEN_FUNCTION) { |
336 | 314k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
337 | 314k | if (declaration) { |
338 | 79.6k | if (closureFlag) |
339 | 2.29k | declaration->flags |= mxDeclareNodeClosureFlag; |
340 | 79.6k | access->declaration = declaration; |
341 | 79.6k | } |
342 | 234k | else if ((self->node->flags & mxEvalFlag) && !(self->node->flags & mxStrictFlag)) { |
343 | | // eval can create variables that override closures |
344 | 3.49k | access->declaration = C_NULL; |
345 | 3.49k | } |
346 | 231k | else if (self->scope) { |
347 | 231k | fxScopeLookup(self->scope, access, 1); |
348 | 231k | if (access->declaration) { |
349 | 14.6k | txDeclareNode* closureNode = fxDeclareNodeNew(self->parser, XS_NO_TOKEN, access->symbol); |
350 | 14.6k | closureNode->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
351 | 14.6k | closureNode->line = access->declaration->line; |
352 | 14.6k | closureNode->declaration = access->declaration; |
353 | 14.6k | fxScopeAddDeclareNode(self, closureNode); |
354 | 14.6k | self->closureNodeCount++; |
355 | 14.6k | access->declaration = closureNode; |
356 | 14.6k | } |
357 | 231k | } |
358 | 314k | } |
359 | 663k | else if (self->token == XS_TOKEN_PROGRAM) { |
360 | 263k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
361 | 263k | if (declaration && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) { |
362 | 78.8k | declaration = C_NULL; |
363 | 78.8k | } |
364 | 263k | access->declaration = declaration; |
365 | 263k | } |
366 | 400k | else if (self->token == XS_TOKEN_WITH) { |
367 | | // with object can have properties that override variables |
368 | 3.91k | access->declaration = C_NULL; |
369 | 3.91k | } |
370 | 396k | else { |
371 | 396k | declaration = fxScopeGetDeclareNode(self, access->symbol); |
372 | 396k | if (declaration) { |
373 | 31.4k | if (closureFlag) |
374 | 7.87k | declaration->flags |= mxDeclareNodeClosureFlag; |
375 | 31.4k | access->declaration = declaration; |
376 | 31.4k | } |
377 | 365k | else if (self->scope) { |
378 | 364k | fxScopeLookup(self->scope, access, closureFlag); |
379 | 364k | } |
380 | 88 | else { |
381 | 88 | access->declaration = C_NULL; |
382 | 88 | access->symbol->usage |= 2; |
383 | 88 | } |
384 | 396k | } |
385 | 1.07M | } |
386 | | |
387 | | void fxNodeHoist(void* it, void* param) |
388 | 2.16M | { |
389 | 2.16M | txNode* node = it; |
390 | 2.16M | (*node->description->dispatch->distribute)(node, fxNodeDispatchHoist, param); |
391 | 2.16M | } |
392 | | |
393 | | void fxNodeDispatchHoist(void* it, void* param) |
394 | 3.76M | { |
395 | 3.76M | txNode* node = it; |
396 | 3.76M | fxCheckParserStack(((txHoister*)param)->parser, node->line); |
397 | 3.76M | (*node->description->dispatch->hoist)(it, param); |
398 | 3.76M | } |
399 | | |
400 | | void fxBlockNodeHoist(void* it, void* param) |
401 | 5.52k | { |
402 | 5.52k | txBlockNode* self = it; |
403 | 5.52k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
404 | 5.52k | fxNodeDispatchHoist(self->statement, param); |
405 | 5.52k | fxScopeHoisted(self->scope, param); |
406 | 5.52k | } |
407 | | |
408 | | void fxBodyNodeHoist(void* it, void* param) |
409 | 86.9k | { |
410 | 86.9k | txBlockNode* self = it; |
411 | 86.9k | txHoister* hoister = param; |
412 | 86.9k | txNode* environmentNode = hoister->environmentNode; |
413 | 86.9k | hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
414 | 86.9k | hoister->environmentNode = it; |
415 | 86.9k | fxNodeDispatchHoist(self->statement, param); |
416 | 86.9k | hoister->environmentNode = environmentNode; |
417 | 86.9k | fxScopeHoisted(self->scope, param); |
418 | 86.9k | } |
419 | | |
420 | | void fxCallNodeHoist(void* it, void* param) |
421 | 103k | { |
422 | 103k | txCallNewNode* self = it; |
423 | 103k | txHoister* hoister = param; |
424 | 103k | txParser* parser = hoister->parser; |
425 | 103k | if (self->reference->description->token == XS_TOKEN_ACCESS) { |
426 | 18.8k | txAccessNode* access = (txAccessNode*)self->reference; |
427 | 18.8k | if (access->symbol == parser->evalSymbol) { |
428 | 3.00k | fxScopeEval(hoister->scope); |
429 | 3.00k | hoister->functionScope->node->flags |= mxArgumentsFlag | mxEvalFlag; |
430 | 3.00k | hoister->environmentNode->flags |= mxEvalFlag; |
431 | 3.00k | self->params->flags |= mxEvalParametersFlag; |
432 | 3.00k | } |
433 | 18.8k | } |
434 | 103k | fxNodeDispatchHoist(self->reference, param); |
435 | 103k | fxNodeDispatchHoist(self->params, param); |
436 | 103k | } |
437 | | |
438 | | void fxCatchNodeHoist(void* it, void* param) |
439 | 1.39k | { |
440 | 1.39k | txCatchNode* self = it; |
441 | 1.39k | txHoister* hoister = param; |
442 | 1.39k | txDeclareNode* node; |
443 | 1.39k | if (self->parameter) { |
444 | 1.32k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
445 | 1.32k | fxNodeDispatchHoist(self->parameter, param); |
446 | 1.32k | self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
447 | 1.32k | fxNodeDispatchHoist(self->statement, param); |
448 | 1.32k | fxScopeHoisted(self->statementScope, param); |
449 | 1.32k | fxScopeHoisted(self->scope, param); |
450 | 1.32k | node = self->statementScope->firstDeclareNode; |
451 | 1.34k | while (node) { |
452 | 22 | if (fxScopeGetDeclareNode(self->scope, node->symbol)) |
453 | 0 | fxReportParserError(hoister->parser, node->line, "duplicate variable %s", node->symbol->string); |
454 | 22 | node = node->nextDeclareNode; |
455 | 22 | } |
456 | 1.32k | } |
457 | 69 | else { |
458 | 69 | self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
459 | 69 | fxNodeDispatchHoist(self->statement, param); |
460 | 69 | fxScopeHoisted(self->statementScope, param); |
461 | 69 | } |
462 | 1.39k | } |
463 | | |
464 | | void fxClassNodeHoist(void* it, void* param) |
465 | 2.82k | { |
466 | 2.82k | txClassNode* self = it; |
467 | 2.82k | txHoister* hoister = param; |
468 | 2.82k | txClassNode* former = hoister->classNode; |
469 | 2.82k | txNode* item = self->items->first; |
470 | 2.82k | if (self->symbol) { |
471 | 2.63k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol); |
472 | 2.63k | node->flags |= mxDeclareNodeClosureFlag; |
473 | 2.63k | self->symbolScope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK); |
474 | 2.63k | fxScopeAddDeclareNode(self->symbolScope, node); |
475 | 2.63k | } |
476 | 2.82k | if (self->heritage) |
477 | 291 | fxNodeDispatchHoist(self->heritage, param); |
478 | 2.82k | self->scope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK); |
479 | 11.9k | while (item) { |
480 | 9.08k | if (item->description->token == XS_TOKEN_PROPERTY) { |
481 | 3.71k | } |
482 | 5.36k | else if (item->description->token == XS_TOKEN_PROPERTY_AT) { |
483 | 4.32k | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) { |
484 | 49 | } |
485 | 4.27k | else { |
486 | 4.27k | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
487 | 4.27k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
488 | 4.27k | symbol->ID = -1; |
489 | 4.27k | node->flags |= mxDeclareNodeClosureFlag; |
490 | 4.27k | fxScopeAddDeclareNode(self->scope, node); |
491 | 4.27k | ((txPropertyAtNode*)item)->atAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
492 | 4.27k | } |
493 | 4.32k | } |
494 | 1.04k | else { |
495 | 1.04k | txSymbol* symbol = ((txPrivatePropertyNode*)item)->symbol; |
496 | 1.04k | txDeclareNode* node = fxScopeGetDeclareNode(self->scope, symbol); |
497 | 1.04k | if (node) { |
498 | 25 | txUnsigned flags = (node->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)) ^ (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)); |
499 | 25 | if ((flags != (mxGetterFlag | mxSetterFlag))) |
500 | 25 | fxReportParserError(hoister->parser, item->line, "duplicate %s", symbol->string); |
501 | 25 | } |
502 | 1.04k | node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
503 | 1.04k | node->flags |= mxDeclareNodeClosureFlag | (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)); |
504 | 1.04k | fxScopeAddDeclareNode(self->scope, node); |
505 | 1.04k | ((txPrivatePropertyNode*)item)->symbolAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
506 | 1.04k | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) { |
507 | 206 | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
508 | 206 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
509 | 206 | symbol->ID = -1; |
510 | 206 | node->flags |= mxDeclareNodeClosureFlag; |
511 | 206 | fxScopeAddDeclareNode(self->scope, node); |
512 | 206 | ((txPrivatePropertyNode*)item)->valueAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
513 | 206 | } |
514 | 1.04k | } |
515 | 9.08k | item = item->next; |
516 | 9.08k | } |
517 | 2.82k | if (self->instanceInit) { |
518 | 1.90k | txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol)); |
519 | 1.90k | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol); |
520 | 1.90k | symbol->ID = -1; |
521 | 1.90k | node->flags |= mxDeclareNodeClosureFlag; |
522 | 1.90k | fxScopeAddDeclareNode(self->scope, node); |
523 | 1.90k | self->instanceInitAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol); |
524 | 1.90k | } |
525 | 2.82k | hoister->classNode = self; |
526 | 2.82k | fxNodeDispatchHoist(self->constructor, param); |
527 | 2.82k | fxNodeListDistribute(self->items, fxNodeDispatchHoist, param); |
528 | 2.82k | if (self->constructorInit) |
529 | 161 | fxNodeDispatchHoist(self->constructorInit, param); |
530 | 2.82k | if (self->instanceInit) |
531 | 1.90k | fxNodeDispatchHoist(self->instanceInit, param); |
532 | 2.82k | hoister->classNode = former; |
533 | 2.82k | fxScopeHoisted(self->scope, param); |
534 | 2.82k | if (self->symbol) |
535 | 2.61k | fxScopeHoisted(self->symbolScope, param); |
536 | 2.82k | } |
537 | | |
538 | | void fxCoalesceExpressionNodeHoist(void* it, void* param) |
539 | 350 | { |
540 | 350 | txBinaryExpressionNode* self = it; |
541 | 350 | txHoister* hoister = param; |
542 | 350 | txToken leftToken = self->left->description->token; |
543 | 350 | txToken rightToken = self->right->description->token; |
544 | 350 | if ((leftToken == XS_TOKEN_AND) || (rightToken == XS_TOKEN_AND)) |
545 | 0 | fxReportParserError(hoister->parser, self->line, "missing () around &&"); |
546 | 350 | else if ((leftToken == XS_TOKEN_OR) || (rightToken == XS_TOKEN_OR)) |
547 | 10 | fxReportParserError(hoister->parser, self->line, "missing () around ||"); |
548 | 350 | fxNodeDispatchHoist(self->left, param); |
549 | 350 | fxNodeDispatchHoist(self->right, param); |
550 | 350 | } |
551 | | |
552 | | void fxDeclareNodeHoist(void* it, void* param) |
553 | 74.3k | { |
554 | 74.3k | txDeclareNode* self = it; |
555 | 74.3k | txHoister* hoister = param; |
556 | 74.3k | txDeclareNode* node; |
557 | 74.3k | txScope* scope; |
558 | 74.3k | if (self->description->token == XS_TOKEN_ARG) { |
559 | 17.4k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
560 | 17.4k | if (node) { |
561 | 101 | if ((node->description->token == XS_TOKEN_ARG) && (hoister->functionScope->node->flags & (mxArrowFlag | mxAsyncFlag | mxMethodFlag | mxNotSimpleParametersFlag | mxStrictFlag))) |
562 | 4 | fxReportParserError(hoister->parser, self->line, "duplicate argument %s", self->symbol->string); |
563 | 101 | } |
564 | 17.3k | else { |
565 | 17.3k | fxScopeAddDeclareNode(hoister->functionScope, self); |
566 | 17.3k | } |
567 | 17.4k | } |
568 | 56.9k | else if ((self->description->token == XS_TOKEN_CONST) || (self->description->token == XS_TOKEN_LET) || (self->description->token == XS_TOKEN_USING)) { |
569 | 20.5k | node = fxScopeGetDeclareNode(hoister->scope, self->symbol); |
570 | 20.5k | if (!node && (hoister->scope == hoister->bodyScope)) { |
571 | 16.5k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
572 | 16.5k | if (node && (node->description->token != XS_TOKEN_ARG)) |
573 | 22 | node = C_NULL; |
574 | 16.5k | } |
575 | 20.5k | if (node) |
576 | 71 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
577 | 20.4k | else |
578 | 20.4k | fxScopeAddDeclareNode(hoister->scope, self); |
579 | 20.5k | } |
580 | 36.4k | else { |
581 | 36.4k | scope = hoister->scope; |
582 | 36.4k | node = C_NULL; |
583 | 71.4k | while (scope != hoister->bodyScope) { |
584 | 35.0k | node = fxScopeGetDeclareNode(scope, self->symbol); |
585 | 35.0k | if (node) { |
586 | 20.7k | 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 | 20.7k | node = C_NULL; |
589 | 20.7k | } |
590 | 35.0k | scope = scope->scope; |
591 | 35.0k | } |
592 | 36.4k | if (!node) { |
593 | 36.4k | node = fxScopeGetDeclareNode(scope, self->symbol); |
594 | 36.4k | if (node) { |
595 | 10.5k | if ((node->description->token != XS_TOKEN_CONST) && (node->description->token != XS_TOKEN_LET) && (node->description->token != XS_TOKEN_USING)) |
596 | 10.5k | node = C_NULL; |
597 | 10.5k | } |
598 | 36.4k | } |
599 | 36.4k | if (node) |
600 | 3 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
601 | 36.4k | else { |
602 | 36.4k | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
603 | 36.4k | if (!node || ((node->description->token != XS_TOKEN_ARG) && (node->description->token != XS_TOKEN_VAR))) |
604 | 28.6k | fxScopeAddDeclareNode(hoister->bodyScope, self); |
605 | 36.4k | scope = hoister->scope; |
606 | 71.4k | while (scope != hoister->bodyScope) { |
607 | 35.0k | fxScopeAddDeclareNode(scope, fxDeclareNodeNew(hoister->parser, XS_NO_TOKEN, self->symbol)); |
608 | 35.0k | scope = scope->scope; |
609 | 35.0k | } |
610 | 36.4k | } |
611 | 36.4k | } |
612 | 74.3k | } |
613 | | |
614 | | void fxDefineNodeHoist(void* it, void* param) |
615 | 3.02k | { |
616 | 3.02k | txDefineNode* self = it; |
617 | 3.02k | txHoister* hoister = param; |
618 | 3.02k | txDeclareNode* node; |
619 | 3.02k | 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 | 3.02k | if ((hoister->scope == hoister->bodyScope) && (hoister->scope->token != XS_TOKEN_MODULE)) { |
624 | 2.97k | node = fxScopeGetDeclareNode(hoister->bodyScope, self->symbol); |
625 | 2.97k | if (node) { |
626 | 270 | 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 | 270 | } |
629 | 2.70k | else { |
630 | 2.70k | if (hoister->functionScope != hoister->bodyScope) |
631 | 280 | node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol); |
632 | 2.70k | if (!node) |
633 | 2.69k | fxScopeAddDeclareNode(hoister->bodyScope, (txDeclareNode*)self); |
634 | 2.70k | } |
635 | 2.97k | fxScopeAddDefineNode(hoister->bodyScope, self); |
636 | 2.97k | } |
637 | 53 | else { |
638 | 53 | node = fxScopeGetDeclareNode(hoister->scope, self->symbol); |
639 | 53 | if (node) |
640 | 1 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string); |
641 | 52 | else |
642 | 52 | fxScopeAddDeclareNode(hoister->scope, (txDeclareNode*)self); |
643 | 53 | fxScopeAddDefineNode(hoister->scope, self); |
644 | 53 | } |
645 | 3.02k | ((txFunctionNode*)(self->initializer))->symbol = C_NULL; |
646 | 3.02k | fxNodeDispatchHoist(self->initializer, param); |
647 | 3.02k | ((txFunctionNode*)(self->initializer))->symbol = self->symbol; |
648 | 3.02k | } |
649 | | |
650 | | void fxExportNodeHoist(void* it, void* param) |
651 | 409 | { |
652 | 409 | txExportNode* self = it; |
653 | 409 | txHoister* hoister = param; |
654 | 409 | if (self->from) { |
655 | 50 | if (self->specifiers && self->specifiers->length) { |
656 | 43 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
657 | 86 | while (specifier) { |
658 | 43 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
659 | 43 | specifier->from = self->from; |
660 | 43 | specifier->with = self->with; |
661 | 43 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
662 | 43 | node->line = self->line; |
663 | 43 | node->importSpecifier = specifier; |
664 | 43 | node->firstExportSpecifier = specifier; |
665 | 43 | fxScopeAddDeclareNode(hoister->scope, node); |
666 | 43 | specifier = (txSpecifierNode*)specifier->next; |
667 | 43 | } |
668 | 43 | } |
669 | 7 | else { |
670 | 7 | txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER); |
671 | 7 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
672 | 7 | specifier->from = self->from; |
673 | 7 | specifier->with = self->with; |
674 | 7 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
675 | 7 | node->line = self->line; |
676 | 7 | node->importSpecifier = specifier; |
677 | 7 | node->firstExportSpecifier = C_NULL; |
678 | 7 | fxScopeAddDeclareNode(hoister->scope, node); |
679 | 7 | } |
680 | 50 | } |
681 | 409 | if (self->specifiers && self->specifiers->length) { |
682 | 402 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
683 | 805 | while (specifier) { |
684 | 403 | fxHoisterAddExportLink(hoister, specifier); |
685 | 403 | fxNodeDispatchHoist(specifier, param); |
686 | 403 | specifier = (txSpecifierNode*)specifier->next; |
687 | 403 | } |
688 | 402 | } |
689 | 409 | } |
690 | | |
691 | | void fxForNodeHoist(void* it, void* param) |
692 | 4.82k | { |
693 | 4.82k | txForNode* self = it; |
694 | 4.82k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
695 | 4.82k | if (self->initialization) |
696 | 4.69k | fxNodeDispatchHoist(self->initialization, param); |
697 | 4.82k | if (self->expression) |
698 | 4.71k | fxNodeDispatchHoist(self->expression, param); |
699 | 4.82k | if (self->iteration) |
700 | 4.70k | fxNodeDispatchHoist(self->iteration, param); |
701 | 4.82k | fxNodeDispatchHoist(self->statement, param); |
702 | 4.82k | fxScopeHoisted(self->scope, param); |
703 | 4.82k | } |
704 | | |
705 | | void fxForInForOfNodeHoist(void* it, void* param) |
706 | 9.00k | { |
707 | 9.00k | txForInForOfNode* self = it; |
708 | 9.00k | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
709 | 9.00k | fxNodeDispatchHoist(self->reference, param); |
710 | 9.00k | fxNodeDispatchHoist(self->expression, param); |
711 | 9.00k | fxNodeDispatchHoist(self->statement, param); |
712 | 9.00k | fxScopeHoisted(self->scope, param); |
713 | 9.00k | } |
714 | | |
715 | | void fxFunctionNodeHoist(void* it, void* param) |
716 | 86.9k | { |
717 | 86.9k | txFunctionNode* self = it; |
718 | 86.9k | txHoister* hoister = param; |
719 | 86.9k | txScope* functionScope = hoister->functionScope; |
720 | 86.9k | txScope* bodyScope = hoister->bodyScope; |
721 | 86.9k | hoister->functionScope = self->scope = fxScopeNew(param, it, XS_TOKEN_FUNCTION); |
722 | 86.9k | hoister->bodyScope = C_NULL; |
723 | 86.9k | if (self->symbol) { |
724 | 51.3k | txDefineNode* node = fxDefineNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol); |
725 | 51.3k | node->initializer = fxValueNodeNew(hoister->parser, XS_TOKEN_CURRENT); |
726 | 51.3k | fxScopeAddDeclareNode(hoister->functionScope, (txDeclareNode*)node); |
727 | 51.3k | fxScopeAddDefineNode(hoister->functionScope, node); |
728 | 51.3k | } |
729 | 86.9k | fxNodeDispatchHoist(self->params, param); |
730 | 86.9k | if ((self->flags & (mxArgumentsFlag | mxEvalFlag)) && !(self->flags & mxArrowFlag)) { |
731 | 573 | txDeclareNode* declaration = fxDeclareNodeNew(hoister->parser, XS_TOKEN_VAR, hoister->parser->argumentsSymbol); |
732 | 573 | fxScopeAddDeclareNode(hoister->functionScope, declaration); |
733 | 573 | } |
734 | 86.9k | fxNodeDispatchHoist(self->body, param); |
735 | 86.9k | fxScopeHoisted(self->scope, param); |
736 | 86.9k | hoister->bodyScope = bodyScope; |
737 | 86.9k | hoister->functionScope = functionScope; |
738 | 86.9k | } |
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 | 122 | { |
775 | 122 | txImportNode* self = it; |
776 | 122 | txHoister* hoister = param; |
777 | 122 | if (self->specifiers && self->specifiers->length) { |
778 | 96 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
779 | 195 | while (specifier) { |
780 | 99 | txDeclareNode* node; |
781 | 99 | txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol; |
782 | 99 | if (self->flags & mxStrictFlag) { |
783 | 99 | if ((symbol == hoister->parser->argumentsSymbol) || (symbol == hoister->parser->evalSymbol)) |
784 | 0 | fxReportParserError(hoister->parser, self->line, "invalid import %s", symbol->string); |
785 | 99 | } |
786 | 99 | node = fxScopeGetDeclareNode(hoister->scope, symbol); |
787 | 99 | if (node) |
788 | 0 | fxReportParserError(hoister->parser, self->line, "duplicate variable %s", symbol->string); |
789 | 99 | else { |
790 | 99 | specifier->declaration = node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, symbol); |
791 | 99 | specifier->from = self->from; |
792 | 99 | specifier->with = self->with; |
793 | 99 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
794 | 99 | node->line = self->line; |
795 | 99 | node->importSpecifier = specifier; |
796 | 99 | fxScopeAddDeclareNode(hoister->scope, node); |
797 | 99 | } |
798 | 99 | specifier = (txSpecifierNode*)specifier->next; |
799 | 99 | } |
800 | 96 | } |
801 | 26 | else { |
802 | 26 | txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER); |
803 | 26 | txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL); |
804 | 26 | specifier->from = self->from; |
805 | 26 | specifier->with = self->with; |
806 | 26 | node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
807 | 26 | node->line = self->line; |
808 | 26 | node->importSpecifier = specifier; |
809 | 26 | fxScopeAddDeclareNode(hoister->scope, node); |
810 | 26 | } |
811 | 122 | } |
812 | | |
813 | | void fxModuleNodeHoist(void* it, void* param) |
814 | 226 | { |
815 | 226 | txModuleNode* self = it; |
816 | 226 | txHoister* hoister = param; |
817 | 226 | hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_MODULE); // @@ |
818 | 226 | hoister->environmentNode = it; |
819 | 226 | fxNodeDispatchHoist(self->body, param); |
820 | 226 | hoister->environmentNode = C_NULL; |
821 | 226 | fxScopeHoisted(self->scope, param); |
822 | 226 | } |
823 | | |
824 | | void fxParamsBindingNodeHoist(void* it, void* param) |
825 | 86.9k | { |
826 | 86.9k | txParamsNode* self = it; |
827 | 86.9k | txNode* item = self->items->first; |
828 | 104k | while (item) { |
829 | 17.3k | fxNodeDispatchHoist(item, param); |
830 | 17.3k | item = item->next; |
831 | 17.3k | } |
832 | 86.9k | } |
833 | | |
834 | | void fxProgramNodeHoist(void* it, void* param) |
835 | 151k | { |
836 | 151k | txProgramNode* self = it; |
837 | 151k | txHoister* hoister = param; |
838 | 151k | hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, (hoister->parser->flags & mxEvalFlag) ? XS_TOKEN_EVAL : XS_TOKEN_PROGRAM); |
839 | 151k | hoister->environmentNode = it; |
840 | 151k | fxNodeDispatchHoist(self->body, param); |
841 | 151k | hoister->environmentNode = C_NULL; |
842 | 151k | self->variableCount = hoister->functionScope->declareNodeCount; |
843 | 151k | fxScopeHoisted(self->scope, param); |
844 | 151k | } |
845 | | |
846 | | void fxStatementNodeHoist(void* it, void* param) |
847 | 350k | { |
848 | 350k | txStatementNode* self = it; |
849 | 350k | fxNodeDispatchHoist(self->expression, param); |
850 | 350k | } |
851 | | |
852 | | void fxPropertyNodeHoist(void* it, void* param) |
853 | 35.8k | { |
854 | 35.8k | txPropertyNode* self = it; |
855 | 35.8k | if (self->value) { |
856 | 32.6k | if (self->value->description->token == XS_TOKEN_HOST) |
857 | 0 | ((txHostNode*)(self->value))->symbol = self->symbol; |
858 | 32.6k | fxNodeDispatchHoist(self->value, param); |
859 | 32.6k | } |
860 | 35.8k | } |
861 | | |
862 | | void fxStringNodeHoist(void* it, void* param) |
863 | 602k | { |
864 | 602k | txStringNode* self = it; |
865 | 602k | txHoister* hoister = param; |
866 | 602k | if ((self->flags & mxStringLegacyFlag) && (hoister->scope->flags & mxStrictFlag)) |
867 | 150 | self->flags |= mxStringErrorFlag; |
868 | 602k | } |
869 | | |
870 | | void fxSwitchNodeHoist(void* it, void* param) |
871 | 236 | { |
872 | 236 | txSwitchNode* self = it; |
873 | 236 | fxNodeDispatchHoist(self->expression, param); |
874 | 236 | self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK); |
875 | 236 | fxNodeListDistribute(self->items, fxNodeDispatchHoist, param); |
876 | 236 | fxScopeHoisted(self->scope, param); |
877 | 236 | } |
878 | | |
879 | | void fxWithNodeHoist(void* it, void* param) |
880 | 2.17k | { |
881 | 2.17k | txWithNode* self = it; |
882 | 2.17k | txHoister* hoister = param; |
883 | 2.17k | fxNodeDispatchHoist(self->expression, param); |
884 | 2.17k | self->scope = fxScopeNew(param, it, XS_TOKEN_WITH); |
885 | 2.17k | fxScopeEval(hoister->scope); |
886 | 2.17k | fxNodeDispatchHoist(self->statement, param); |
887 | 2.17k | fxScopeHoisted(self->scope, param); |
888 | 2.17k | } |
889 | | |
890 | | void fxNodeDispatchBind(void* it, void* param) |
891 | 3.46M | { |
892 | 3.46M | txNode* node = it; |
893 | 3.46M | fxCheckParserStack(((txBinder*)param)->parser, node->line); |
894 | 3.46M | (*node->description->dispatch->bind)(it, param); |
895 | 3.46M | } |
896 | | |
897 | | void fxNodeBind(void* it, void* param) |
898 | 2.06M | { |
899 | 2.06M | txNode* node = it; |
900 | 2.06M | (*node->description->dispatch->distribute)(node, fxNodeDispatchBind, param); |
901 | 2.06M | } |
902 | | |
903 | | void fxAccessNodeBind(void* it, void* param) |
904 | 345k | { |
905 | 345k | txAccessNode* self = it; |
906 | 345k | txBinder* binder = param; |
907 | 345k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
908 | 345k | } |
909 | | |
910 | | void fxArrayNodeBind(void* it, void* param) |
911 | 33.7k | { |
912 | 33.7k | txArrayNode* self = it; |
913 | 33.7k | fxBinderPushVariables(param, 1); |
914 | 33.7k | if (self->flags & mxSpreadFlag) { |
915 | 546 | fxBinderPushVariables(param, 2); |
916 | 546 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
917 | 546 | fxBinderPopVariables(param, 2); |
918 | 546 | } |
919 | 33.2k | else |
920 | 33.2k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
921 | 33.7k | fxBinderPopVariables(param, 1); |
922 | 33.7k | } |
923 | | |
924 | | void fxArrayBindingNodeBind(void* it, void* param) |
925 | 10.3k | { |
926 | 10.3k | txArrayBindingNode* self = it; |
927 | 10.3k | fxBinderPushVariables(param, 6); |
928 | 10.3k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
929 | 10.3k | fxBinderPopVariables(param, 6); |
930 | 10.3k | } |
931 | | |
932 | | void fxAssignNodeBind(void* it, void* param) |
933 | 21.9k | { |
934 | 21.9k | txAssignNode* self = it; |
935 | 21.9k | txToken token = self->reference->description->token; |
936 | 21.9k | fxNodeDispatchBind(self->reference, param); |
937 | 21.9k | 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 | 16.6k | fxFunctionNodeRename(self->value, ((txAccessNode*)self->reference)->symbol); |
939 | 21.9k | fxNodeDispatchBind(self->value, param); |
940 | 21.9k | } |
941 | | |
942 | | void fxBindingNodeBind(void* it, void* param) |
943 | 32.8k | { |
944 | 32.8k | txBindingNode* self = it; |
945 | 32.8k | txToken token = self->target->description->token; |
946 | 32.8k | fxNodeDispatchBind(self->target, param); |
947 | 32.8k | 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 | 32.1k | fxFunctionNodeRename(self->initializer, ((txAccessNode*)self->target)->symbol); |
949 | 32.8k | fxNodeDispatchBind(self->initializer, param); |
950 | 32.8k | } |
951 | | |
952 | | void fxBlockNodeBind(void* it, void* param) |
953 | 91.9k | { |
954 | 91.9k | txBlockNode* self = it; |
955 | 91.9k | fxScopeBinding(self->scope, param); |
956 | 91.9k | fxScopeBindDefineNodes(self->scope, param); |
957 | 91.9k | if (self->scope->disposableNodeCount) |
958 | 75 | fxBinderPushVariables(param, 2); |
959 | 91.9k | fxNodeDispatchBind(self->statement, param); |
960 | 91.9k | if (self->scope->disposableNodeCount) |
961 | 75 | fxBinderPopVariables(param, 2); |
962 | 91.9k | fxScopeBound(self->scope, param); |
963 | 91.9k | } |
964 | | |
965 | | void fxCatchNodeBind(void* it, void* param) |
966 | 1.37k | { |
967 | 1.37k | txCatchNode* self = it; |
968 | 1.37k | if (self->parameter) { |
969 | 1.30k | fxScopeBinding(self->scope, param); |
970 | 1.30k | fxNodeDispatchBind(self->parameter, param); |
971 | 1.30k | fxScopeBinding(self->statementScope, param); |
972 | 1.30k | fxScopeBindDefineNodes(self->statementScope, param); |
973 | 1.30k | if (self->statementScope->disposableNodeCount) |
974 | 0 | fxBinderPushVariables(param, 2); |
975 | 1.30k | fxNodeDispatchBind(self->statement, param); |
976 | 1.30k | if (self->statementScope->disposableNodeCount) |
977 | 0 | fxBinderPushVariables(param, 2); |
978 | 1.30k | fxScopeBound(self->statementScope, param); |
979 | 1.30k | fxScopeBound(self->scope, param); |
980 | 1.30k | } |
981 | 69 | else { |
982 | 69 | fxScopeBinding(self->statementScope, param); |
983 | 69 | fxScopeBindDefineNodes(self->statementScope, param); |
984 | 69 | if (self->statementScope->disposableNodeCount) |
985 | 0 | fxBinderPushVariables(param, 2); |
986 | 69 | fxNodeDispatchBind(self->statement, param); |
987 | 69 | if (self->statementScope->disposableNodeCount) |
988 | 0 | fxBinderPushVariables(param, 2); |
989 | 69 | fxScopeBound(self->statementScope, param); |
990 | 69 | } |
991 | 1.37k | } |
992 | | |
993 | | void fxClassNodeBind(void* it, void* param) |
994 | 2.79k | { |
995 | 2.79k | txClassNode* self = it; |
996 | 2.79k | txBinder* binder = param; |
997 | 2.79k | txClassNode* former = binder->classNode; |
998 | 2.79k | fxBinderPushVariables(param, 2); |
999 | 2.79k | if (self->symbol) |
1000 | 2.60k | fxScopeBinding(self->symbolScope, param); |
1001 | 2.79k | if (self->heritage) |
1002 | 289 | fxNodeDispatchBind(self->heritage, param); |
1003 | 2.79k | fxScopeBinding(self->scope, param); |
1004 | 2.79k | binder->classNode = self; |
1005 | 2.79k | fxNodeDispatchBind(self->constructor, param); |
1006 | 2.79k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1007 | 2.79k | if (self->constructorInit) |
1008 | 74 | fxNodeDispatchBind(self->constructorInit, param); |
1009 | 2.79k | if (self->instanceInit) |
1010 | 1.80k | fxNodeDispatchBind(self->instanceInit, param); |
1011 | 2.79k | binder->classNode = former; |
1012 | 2.79k | fxScopeBound(self->scope, param); |
1013 | 2.79k | if (self->symbol) |
1014 | 2.50k | fxScopeBound(self->symbolScope, param); |
1015 | 2.79k | fxBinderPopVariables(param, 2); |
1016 | 2.79k | } |
1017 | | |
1018 | | void fxDeclareNodeBind(void* it, void* param) |
1019 | 124k | { |
1020 | 124k | txBindingNode* self = it; |
1021 | 124k | txBinder* binder = param; |
1022 | 124k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1023 | 124k | } |
1024 | | |
1025 | | void fxDefineNodeBind(void* it, void* param) |
1026 | 5.87k | { |
1027 | 5.87k | txDefineNode* self = it; |
1028 | 5.87k | txBinder* binder = param; |
1029 | 5.87k | if (self->flags & mxDefineNodeBoundFlag) |
1030 | 2.89k | return; |
1031 | 2.98k | self->flags |= mxDefineNodeBoundFlag; |
1032 | 2.98k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1033 | 2.98k | fxNodeDispatchBind(self->initializer, param); |
1034 | 2.98k | } |
1035 | | |
1036 | | void fxDelegateNodeBind(void* it, void* param) |
1037 | 29 | { |
1038 | 29 | txStatementNode* self = it; |
1039 | 29 | fxBinderPushVariables(param, 5); |
1040 | 29 | fxNodeDispatchBind(self->expression, param); |
1041 | 29 | fxBinderPopVariables(param, 5); |
1042 | 29 | } |
1043 | | |
1044 | | void fxExportNodeBind(void* it, void* param) |
1045 | 392 | { |
1046 | 392 | txExportNode* self = it; |
1047 | 392 | txBinder* binder = param; |
1048 | 392 | if (self->from) |
1049 | 35 | return; |
1050 | 357 | if (self->specifiers) { |
1051 | 357 | txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first; |
1052 | 715 | while (specifier) { |
1053 | 358 | txAccessNode* node = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, specifier->symbol); |
1054 | 358 | fxScopeLookup(binder->scope, node, 0); |
1055 | 358 | if (node->declaration) { |
1056 | 356 | specifier->declaration = node->declaration; |
1057 | 356 | specifier->declaration->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag; |
1058 | 356 | specifier->nextSpecifier = specifier->declaration->firstExportSpecifier; |
1059 | 356 | specifier->declaration->firstExportSpecifier = specifier; |
1060 | 356 | } |
1061 | 2 | else |
1062 | 2 | fxReportParserError(binder->parser, specifier->line, "unknown variable %s", specifier->symbol->string); |
1063 | 358 | specifier = (txSpecifierNode*)specifier->next; |
1064 | 358 | } |
1065 | 357 | } |
1066 | 357 | } |
1067 | | |
1068 | | void fxFieldNodeBind(void* it, void* param) |
1069 | 7.98k | { |
1070 | 7.98k | txFieldNode* self = it; |
1071 | 7.98k | txBinder* binder = param; |
1072 | 7.98k | txNode* item = self->item; |
1073 | 7.98k | if (item->description->token == XS_TOKEN_PROPERTY_AT) |
1074 | 4.15k | fxScopeLookup(binder->scope, ((txPropertyAtNode*)item)->atAccess, 0); |
1075 | 3.83k | else if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) { |
1076 | 717 | if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) |
1077 | 111 | fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->valueAccess, 0); |
1078 | 717 | fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->symbolAccess, 0); |
1079 | 717 | } |
1080 | 7.98k | if (self->value) |
1081 | 7.87k | fxNodeDispatchBind(self->value, param); |
1082 | 7.98k | } |
1083 | | |
1084 | | void fxForNodeBind(void* it, void* param) |
1085 | 4.81k | { |
1086 | 4.81k | txForNode* self = it; |
1087 | 4.81k | fxScopeBinding(self->scope, param); |
1088 | 4.81k | fxScopeBindDefineNodes(self->scope, param); |
1089 | 4.81k | if (self->scope->disposableNodeCount) |
1090 | 0 | fxBinderPushVariables(param, 2); |
1091 | 4.81k | if (self->initialization) |
1092 | 4.68k | fxNodeDispatchBind(self->initialization, param); |
1093 | 4.81k | if (self->expression) |
1094 | 4.70k | fxNodeDispatchBind(self->expression, param); |
1095 | 4.81k | if (self->iteration) |
1096 | 4.68k | fxNodeDispatchBind(self->iteration, param); |
1097 | 4.81k | fxNodeDispatchBind(self->statement, param); |
1098 | 4.81k | if (self->scope->disposableNodeCount) |
1099 | 0 | fxBinderPopVariables(param, 2); |
1100 | 4.81k | fxScopeBound(self->scope, param); |
1101 | 4.81k | } |
1102 | | |
1103 | | void fxForInForOfNodeBind(void* it, void* param) |
1104 | 8.96k | { |
1105 | 8.96k | txForInForOfNode* self = it; |
1106 | 8.96k | fxBinderPushVariables(param, 6); |
1107 | 8.96k | fxScopeBinding(self->scope, param); |
1108 | 8.96k | fxScopeBindDefineNodes(self->scope, param); |
1109 | 8.96k | fxNodeDispatchBind(self->reference, param); |
1110 | 8.96k | fxNodeDispatchBind(self->expression, param); |
1111 | 8.96k | fxNodeDispatchBind(self->statement, param); |
1112 | 8.96k | fxScopeBound(self->scope, param); |
1113 | 8.96k | fxBinderPopVariables(param, 6); |
1114 | 8.96k | } |
1115 | | |
1116 | | void fxFunctionNodeBind(void* it, void* param) |
1117 | 86.4k | { |
1118 | 86.4k | txFunctionNode* self = it; |
1119 | 86.4k | txBinder* binder = param; |
1120 | 86.4k | txInteger scopeLevel = binder->scopeLevel; |
1121 | 86.4k | txInteger scopeMaximum = binder->scopeMaximum; |
1122 | 86.4k | scopeLevel = binder->scopeLevel; |
1123 | 86.4k | scopeMaximum = binder->scopeMaximum; |
1124 | 86.4k | binder->scopeLevel = 0; |
1125 | 86.4k | binder->scopeMaximum = 0; |
1126 | 86.4k | fxScopeBinding(self->scope, param); |
1127 | 86.4k | fxNodeDispatchBind(self->params, param); |
1128 | 86.4k | if (self->flags & mxBaseFlag) { |
1129 | 2.50k | if (binder->classNode->instanceInitAccess) { |
1130 | 1.89k | fxScopeLookup(binder->scope, binder->classNode->instanceInitAccess, 0); |
1131 | 1.89k | } |
1132 | 2.50k | } |
1133 | 86.4k | fxScopeBindDefineNodes(self->scope, param); |
1134 | 86.4k | fxNodeDispatchBind(self->body, param); |
1135 | 86.4k | fxScopeBound(self->scope, param); |
1136 | 86.4k | self->scopeCount = binder->scopeMaximum; |
1137 | 86.4k | binder->scopeMaximum = scopeMaximum; |
1138 | 86.4k | binder->scopeLevel = scopeLevel; |
1139 | 86.4k | } |
1140 | | |
1141 | | void fxFunctionNodeRename(void* it, txSymbol* symbol) |
1142 | 48.8k | { |
1143 | 48.8k | txNode* self = it; |
1144 | 48.8k | txToken token = self->description->token; |
1145 | 48.8k | if (token == XS_TOKEN_EXPRESSIONS) { |
1146 | 165 | self = ((txExpressionsNode*)self)->items->first; |
1147 | 165 | if (self->next) |
1148 | 15 | return; |
1149 | 150 | token = self->description->token; |
1150 | 150 | } |
1151 | 48.7k | if (token == XS_TOKEN_CLASS) { |
1152 | 1.32k | txClassNode* node = (txClassNode*)self; |
1153 | 1.32k | if (!node->symbol) |
1154 | 11 | ((txFunctionNode*)(node->constructor))->symbol = symbol; |
1155 | 1.32k | } |
1156 | 47.4k | else if ((token == XS_TOKEN_FUNCTION) || (token == XS_TOKEN_GENERATOR) || (token == XS_TOKEN_HOST)) { |
1157 | 3.09k | txFunctionNode* node = (txFunctionNode*)self; |
1158 | 3.09k | if (!node->symbol) |
1159 | 3.05k | node->symbol = symbol; |
1160 | 3.09k | } |
1161 | 48.7k | } |
1162 | | |
1163 | | void fxHostNodeBind(void* it, void* param) |
1164 | 0 | { |
1165 | 0 | } |
1166 | | |
1167 | | void fxModuleNodeBind(void* it, void* param) |
1168 | 224 | { |
1169 | 224 | txModuleNode* self = it; |
1170 | 224 | txBinder* binder = param; |
1171 | 224 | fxScopeBinding(self->scope, param); |
1172 | 224 | fxScopeBindDefineNodes(self->scope, param); |
1173 | 224 | fxNodeDispatchBind(self->body, param); |
1174 | 224 | fxScopeBound(self->scope, param); |
1175 | 224 | self->scopeCount = binder->scopeMaximum; |
1176 | 224 | } |
1177 | | |
1178 | | void fxObjectNodeBind(void* it, void* param) |
1179 | 19.1k | { |
1180 | 19.1k | txObjectNode* self = it; |
1181 | 19.1k | txNode* item = self->items->first; |
1182 | 19.1k | fxBinderPushVariables(param, 1); |
1183 | 53.0k | while (item) { |
1184 | 33.8k | txNode* value; |
1185 | 33.8k | if (item->description->token == XS_TOKEN_SPREAD) { |
1186 | 197 | } |
1187 | 33.6k | else { |
1188 | 33.6k | if (item->description->token == XS_TOKEN_PROPERTY) { |
1189 | 32.1k | value = ((txPropertyNode*)item)->value; |
1190 | 32.1k | } |
1191 | 1.54k | else { |
1192 | 1.54k | value = ((txPropertyAtNode*)item)->value; |
1193 | 1.54k | } |
1194 | 33.6k | if ((value->description->token == XS_TOKEN_FUNCTION) || (value->description->token == XS_TOKEN_GENERATOR) || (value->description->token == XS_TOKEN_HOST)) { |
1195 | 2.67k | txFunctionNode* node = (txFunctionNode*)value; |
1196 | 2.67k | node->flags |= item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag); |
1197 | 2.67k | } |
1198 | 30.9k | else if (value->description->token == XS_TOKEN_CLASS) { |
1199 | | // txFunctionNode* node = (txFunctionNode*)(((txClassNode*)value)->constructor); |
1200 | 3 | } |
1201 | 33.6k | } |
1202 | 33.8k | fxNodeDispatchBind(item, param); |
1203 | 33.8k | item = item->next; |
1204 | 33.8k | } |
1205 | 19.1k | fxBinderPopVariables(param, 1); |
1206 | 19.1k | } |
1207 | | |
1208 | | void fxObjectBindingNodeBind(void* it, void* param) |
1209 | 905 | { |
1210 | 905 | txObjectBindingNode* self = it; |
1211 | 905 | fxBinderPushVariables(param, 2); |
1212 | 905 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1213 | 905 | fxBinderPopVariables(param, 2); |
1214 | 905 | } |
1215 | | |
1216 | | void fxParamsNodeBind(void* it, void* param) |
1217 | 117k | { |
1218 | 117k | txParamsNode* self = it; |
1219 | 117k | if (self->flags & mxSpreadFlag) { |
1220 | 377 | fxBinderPushVariables(param, 1); |
1221 | 377 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1222 | 377 | fxBinderPopVariables(param, 1); |
1223 | 377 | } |
1224 | 116k | else |
1225 | 116k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1226 | 117k | } |
1227 | | |
1228 | | void fxParamsBindingNodeBind(void* it, void* param) |
1229 | 86.4k | { |
1230 | 86.4k | txParamsBindingNode* self = it; |
1231 | 86.4k | txBinder* binder = param; |
1232 | 86.4k | txScope* functionScope = binder->scope; |
1233 | 86.4k | txFunctionNode* functionNode = (txFunctionNode*)(functionScope->node); |
1234 | 86.4k | txInteger count = self->items->length; |
1235 | 86.4k | if (functionNode->flags & mxGetterFlag) { |
1236 | 428 | if (count != 0) |
1237 | 2 | fxReportParserError(binder->parser, self->line, "invalid getter arguments"); |
1238 | 428 | } |
1239 | 86.0k | else if (functionNode->flags & mxSetterFlag) { |
1240 | 114 | if ((count != 1) || (self->items->first->description->token == XS_TOKEN_REST_BINDING)) |
1241 | 1 | fxReportParserError(binder->parser, self->line, "invalid setter arguments"); |
1242 | 114 | } |
1243 | 85.9k | else { |
1244 | 85.9k | if (count > 255) |
1245 | 1 | fxReportParserError(binder->parser, self->line, "too many arguments"); |
1246 | 85.9k | } |
1247 | 86.4k | if (functionNode->flags & mxArgumentsFlag) { |
1248 | 3.42k | txNode* item; |
1249 | 3.42k | self->declaration = fxScopeGetDeclareNode(functionScope, binder->parser->argumentsSymbol); |
1250 | 3.42k | if (functionNode->flags & mxStrictFlag) |
1251 | 1.39k | goto bail; |
1252 | 2.03k | item = self->items->first; |
1253 | 2.69k | while (item) { |
1254 | 682 | if (item->description->token != XS_TOKEN_ARG) |
1255 | 14 | goto bail; |
1256 | 668 | item = item->next; |
1257 | 668 | } |
1258 | 2.01k | item = self->items->first; |
1259 | 2.67k | while (item) { |
1260 | 661 | ((txDeclareNode*)item)->flags |= mxDeclareNodeClosureFlag; |
1261 | 661 | item = item->next; |
1262 | 661 | } |
1263 | 2.01k | self->mapped = 1; |
1264 | 2.01k | } |
1265 | 86.4k | bail: |
1266 | 86.4k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1267 | 86.4k | } |
1268 | | |
1269 | | void fxPostfixExpressionNodeBind(void* it, void* param) |
1270 | 7.20k | { |
1271 | 7.20k | txPostfixExpressionNode* self = it; |
1272 | 7.20k | fxNodeDispatchBind(self->left, param); |
1273 | 7.20k | fxBinderPushVariables(param, 1); |
1274 | 7.20k | fxBinderPopVariables(param, 1); |
1275 | 7.20k | } |
1276 | | |
1277 | | void fxPrivateMemberNodeBind(void* it, void* param) |
1278 | 1.51k | { |
1279 | 1.51k | txBinder* binder = param; |
1280 | 1.51k | txPrivateMemberNode* self = it; |
1281 | 1.51k | fxScopeLookup(binder->scope, (txAccessNode*)self, 0); |
1282 | 1.51k | if (!self->declaration) |
1283 | 504 | fxReportParserError(binder->parser, self->line, "invalid private identifier"); |
1284 | 1.51k | fxNodeDispatchBind(self->reference, param); |
1285 | 1.51k | } |
1286 | | |
1287 | | void fxProgramNodeBind(void* it, void* param) |
1288 | 151k | { |
1289 | 151k | txProgramNode* self = it; |
1290 | 151k | txBinder* binder = param; |
1291 | 151k | fxScopeBinding(self->scope, param); |
1292 | 151k | fxScopeBindDefineNodes(self->scope, param); |
1293 | 151k | fxNodeDispatchBind(self->body, param); |
1294 | 151k | fxScopeBound(self->scope, param); |
1295 | 151k | self->scopeCount = binder->scopeMaximum; |
1296 | 151k | } |
1297 | | |
1298 | | void fxSpreadNodeBind(void* it, void* param) |
1299 | 1.43k | { |
1300 | 1.43k | txSpreadNode* self = it; |
1301 | 1.43k | fxBinderPushVariables(param, 1); |
1302 | 1.43k | fxNodeDispatchBind(self->expression, param); |
1303 | 1.43k | fxBinderPopVariables(param, 1); |
1304 | 1.43k | } |
1305 | | |
1306 | | void fxSuperNodeBind(void* it, void* param) |
1307 | 275 | { |
1308 | 275 | txSuperNode* self = it; |
1309 | 275 | txBinder* binder = param; |
1310 | 275 | fxScopeArrow(binder->scope); |
1311 | 275 | fxNodeDispatchBind(self->params, param); |
1312 | 275 | if (binder->classNode->instanceInitAccess) { |
1313 | 8 | self->instanceInitAccess = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, binder->classNode->instanceInitAccess->symbol); |
1314 | 8 | fxScopeLookup(binder->scope, self->instanceInitAccess, 0); |
1315 | 8 | } |
1316 | 275 | } |
1317 | | |
1318 | | void fxSwitchNodeBind(void* it, void* param) |
1319 | 234 | { |
1320 | 234 | txSwitchNode* self = it; |
1321 | 234 | fxNodeDispatchBind(self->expression, param); |
1322 | 234 | fxScopeBinding(self->scope, param); |
1323 | 234 | fxScopeBindDefineNodes(self->scope, param); |
1324 | 234 | if (self->scope->disposableNodeCount) |
1325 | 0 | fxBinderPushVariables(param, 2); |
1326 | 234 | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1327 | 234 | if (self->scope->disposableNodeCount) |
1328 | 0 | fxBinderPopVariables(param, 2); |
1329 | 234 | fxScopeBound(self->scope, param); |
1330 | 234 | } |
1331 | | |
1332 | | void fxTargetNodeBind(void* it, void* param) |
1333 | 5 | { |
1334 | 5 | txBinder* binder = param; |
1335 | 5 | fxScopeArrow(binder->scope); |
1336 | 5 | } |
1337 | | |
1338 | | void fxTemplateNodeBind(void* it, void* param) |
1339 | 235k | { |
1340 | 235k | txTemplateNode* self = it; |
1341 | 235k | if (self->reference) { |
1342 | 216k | fxBinderPushVariables(param, 2); |
1343 | 216k | fxNodeDispatchBind(self->reference, param); |
1344 | 216k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1345 | 216k | fxBinderPopVariables(param, 2); |
1346 | 216k | } |
1347 | 19.1k | else { |
1348 | 19.1k | fxNodeListDistribute(self->items, fxNodeDispatchBind, param); |
1349 | 19.1k | } |
1350 | 235k | } |
1351 | | |
1352 | | void fxThisNodeBind(void* it, void* param) |
1353 | 2.53k | { |
1354 | 2.53k | txBinder* binder = param; |
1355 | 2.53k | fxScopeArrow(binder->scope); |
1356 | 2.53k | } |
1357 | | |
1358 | | void fxTryNodeBind(void* it, void* param) |
1359 | 1.40k | { |
1360 | 1.40k | txTryNode* self = it; |
1361 | 1.40k | fxBinderPushVariables(param, 3); |
1362 | 1.40k | fxNodeDispatchBind(self->tryBlock, param); |
1363 | 1.40k | if (self->catchBlock) |
1364 | 1.37k | fxNodeDispatchBind(self->catchBlock, param); |
1365 | 1.40k | if (self->finallyBlock) |
1366 | 33 | fxNodeDispatchBind(self->finallyBlock, param); |
1367 | 1.40k | fxBinderPopVariables(param, 3); |
1368 | 1.40k | } |
1369 | | |
1370 | | void fxWithNodeBind(void* it, void* param) |
1371 | 2.15k | { |
1372 | 2.15k | txWithNode* self = it; |
1373 | 2.15k | fxNodeDispatchBind(self->expression, param); |
1374 | 2.15k | fxScopeBinding(self->scope, param); |
1375 | 2.15k | fxNodeDispatchBind(self->statement, param); |
1376 | 2.15k | fxScopeBound(self->scope, param); |
1377 | 2.15k | } |
1378 | | |
1379 | | |
1380 | | |