Coverage Report

Created: 2026-08-14 06:19

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