Coverage Report

Created: 2025-11-11 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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