Coverage Report

Created: 2026-03-16 06:17

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