Coverage Report

Created: 2026-05-30 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsCode.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2025  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 mxCodePrint 1
41
42
#define mxByteCodePart\
43
  txByteCode* nextCode;\
44
  txInteger id;\
45
  txInteger stackLevel
46
  
47
struct sxByteCode {
48
  mxByteCodePart;
49
};
50
  
51
struct sxBigIntCode {
52
  mxByteCodePart;
53
  txBigInt bigint;
54
};
55
  
56
struct sxBranchCode {
57
  mxByteCodePart;
58
  txTargetCode* target;
59
};
60
  
61
struct sxIndexCode {
62
  mxByteCodePart;
63
  txInteger index;
64
};
65
  
66
struct sxIntegerCode {
67
  mxByteCodePart;
68
  txInteger integer;
69
};
70
  
71
struct sxNumberCode {
72
  mxByteCodePart;
73
  txNumber number;
74
};
75
  
76
struct sxStringCode {
77
  mxByteCodePart;
78
  txInteger length;
79
  txString string;
80
};
81
  
82
struct sxSymbolCode {
83
  mxByteCodePart;
84
  txSymbol* symbol;
85
};
86
87
struct sxTargetCode {
88
  mxByteCodePart;
89
  txInteger index;
90
  txLabelNode* label;
91
  txTargetCode* nextTarget;
92
  txInteger environmentLevel;
93
  txInteger scopeLevel;
94
  txInteger offset;
95
  txTargetCode* original;
96
  txBoolean used;
97
};
98
  
99
struct sxVariableCode {
100
  mxByteCodePart;
101
  txSymbol* symbol;
102
  txInteger index;
103
};
104
105
struct sxCoder {
106
  txParser* parser;
107
  txByteCode* firstCode;
108
  txByteCode* lastCode;
109
  txTargetCode* firstBreakTarget;
110
  txTargetCode* firstContinueTarget;
111
  txTargetCode* returnTarget;
112
  txInteger environmentLevel;
113
  txInteger scopeLevel;
114
  txInteger stackLevel;
115
  txInteger targetIndex;
116
  txSymbol* path;
117
  txInteger line;
118
  txBoolean programFlag;
119
  txBoolean evalFlag;
120
  txBoolean importFlag;
121
  txBoolean importMetaFlag;
122
  txClassNode* classNode;
123
  txTargetCode* chainTarget;
124
};
125
126
typedef struct {
127
  txInteger exception;
128
  txInteger selector;
129
  txTargetCode* catchTarget;
130
} txUsingContext;
131
132
typedef void (*txCompound)(void* it, void* param, txByte step);
133
134
static void fxCoderAdd(txCoder* self, txInteger delta, void* it);
135
static void fxCoderAddBigInt(txCoder* self, txInteger delta, txInteger id, txBigInt* bigint);
136
static void fxCoderAddBranch(txCoder* self, txInteger delta, txInteger id, txTargetCode* target);
137
static void fxCoderAddByte(txCoder* self, txInteger delta, txInteger id);
138
static void fxCoderAddIndex(txCoder* self, txInteger delta, txInteger id, txInteger index);
139
static void fxCoderAddInteger(txCoder* self, txInteger delta, txInteger id, txInteger integer);
140
static void fxCoderAddLine(txCoder* self, txInteger delta, txInteger id, txNode* node);
141
static void fxCoderAddNumber(txCoder* self, txInteger delta, txInteger id, txNumber number);
142
static void fxCoderAddString(txCoder* self, txInteger delta, txInteger id, txInteger length, txString string);
143
static void fxCoderAddSymbol(txCoder* self, txInteger delta, txInteger id, txSymbol* symbol);
144
static void fxCoderAddVariable(txCoder* self, txInteger delta, txInteger id, txSymbol* symbol, txInteger index);
145
static void fxCoderAdjustEnvironment(txCoder* self, txTargetCode* target);
146
static void fxCoderAdjustScope(txCoder* self, txTargetCode* target);
147
static txTargetCode* fxCoderAliasTargets(txCoder* self, txTargetCode* target);
148
static txInteger fxCoderCountParameters(txCoder* self, txNode* it);
149
static txTargetCode* fxCoderCreateTarget(txCoder* self);
150
static txTargetCode* fxCoderFinalizeTargets(txCoder* self, txTargetCode* alias, txInteger selector, txInteger* address, txTargetCode* finallyTarget);
151
static void fxCoderJumpTargets(txCoder* self, txTargetCode* target, txInteger selector, txInteger* address);
152
static void fxCoderOptimize(txCoder* self);
153
static txInteger fxCoderUseTemporaryVariable(txCoder* self);
154
static void fxCoderUnuseTemporaryVariables(txCoder* self, txInteger count);
155
156
static void fxScopeCoded(txScope* self, txCoder* coder);
157
static void fxScopeCodedBody(txScope* self, txCoder* coder);
158
static void fxScopeCodingBlock(txScope* self, txCoder* coder);
159
static void fxScopeCodingBody(txScope* self, txCoder* coder);
160
static void fxScopeCodingParams(txScope* self, txCoder* coder);
161
static void fxScopeCodingProgram(txScope* self, txCoder* coder);
162
static void fxScopeCodeDefineNodes(txScope* self, txCoder* coder);
163
static void fxScopeCodeRefresh(txScope* self, txCoder* coder);
164
static void fxScopeCodeReset(txScope* self, txCoder* coder);
165
static void fxScopeCodeRetrieve(txScope* self, txCoder* coder);
166
static void fxScopeCodeStore(txScope* self, txCoder* coder);
167
static void fxScopeCodeStoreAll(txScope* self, txCoder* coder);
168
static void fxScopeCodeUsed(txScope* self, txCoder* coder, txUsingContext* context);
169
static void fxScopeCodeUsedReverse(txScope* self, txCoder* coder, txDeclareNode* node, txInteger exception, txInteger selector);
170
static void fxScopeCodeUsing(txScope* self, txCoder* coder, txUsingContext* context);
171
static void fxScopeCodeUsingStatement(txScope* self, txCoder* coder, txNode* statement);
172
173
static void fxNodeDispatchCode(void* it, void* param);
174
static void fxNodeDispatchCodeAssign(void* it, void* param, txFlag flag);
175
static void fxNodeDispatchCodeDelete(void* it, void* param);
176
static void fxNodeDispatchCodeReference(void* it, void* param, txFlag flag);
177
static txFlag fxNodeDispatchCodeThis(void* it, void* param, txFlag flag);
178
179
static txFlag fxNodeCodeName(txNode* value);
180
static void fxCompoundExpressionNodeCodeName(void* it, void* param);
181
static void fxSpreadNodeCode(void* it, void* param, txInteger counter);
182
183
txScript* fxParserCode(txParser* parser)
184
0
{
185
0
  txCoder coder;
186
0
  txByteCode* code;
187
0
  txScript* script;
188
0
  txSize size, delta, offset;
189
0
  txSymbol* symbol;
190
0
  txSymbol** address;
191
0
  txSize c, i;
192
0
  txID id, count;
193
0
  txSize total;
194
0
  txByte* p;
195
0
  txHostNode* node;
196
0
#ifdef mxMetering
197
0
  txUnsigned meterIndex = 0;
198
0
#endif
199
200
0
    c_memset(&coder, 0, sizeof(txCoder));
201
0
  coder.parser = parser;
202
0
  if (parser->errorCount == 0) {
203
0
    mxTryParser(parser) {
204
0
      txNode* self = parser->root;
205
0
      (*self->description->dispatch->code)(parser->root, &coder);
206
0
    }
207
0
    mxCatchParser(parser) {
208
0
    }
209
0
  }
210
0
  if (parser->errorCount) {
211
0
    if (parser->console) {
212
0
      coder.firstCode = NULL;
213
0
      coder.lastCode = NULL;
214
0
      fxCoderAddByte(&coder, 1, XS_CODE_GLOBAL);
215
0
      fxCoderAddSymbol(&coder, 0, XS_CODE_GET_VARIABLE, parser->errorSymbol);
216
0
      fxCoderAddByte(&coder, 2, XS_CODE_NEW);
217
0
      fxCoderAddString(&coder, 1, XS_CODE_STRING_1, mxStringLength(parser->errorMessage), parser->errorMessage);
218
0
      fxCoderAddInteger(&coder, -3, XS_CODE_RUN_1, 1);
219
0
      fxCoderAddByte(&coder, -1, XS_CODE_THROW);
220
0
    }
221
0
    else
222
0
      return C_NULL;
223
0
  }
224
  
225
0
  fxCoderOptimize(&coder);
226
  
227
0
  script = c_malloc(sizeof(txScript));
228
0
  if (!script) goto bail;
229
0
  c_memset(script, 0, sizeof(txScript));
230
  
231
0
  code = coder.firstCode;
232
0
  size = 0;
233
0
  delta = 0;
234
0
  while (code) {
235
0
    txInteger value;
236
0
    switch (code->id) {
237
0
    case XS_NO_CODE:
238
0
      ((txTargetCode*)code)->offset = size;
239
0
      break;
240
0
    case XS_CODE_BRANCH_1:
241
0
    case XS_CODE_BRANCH_CHAIN_1:
242
0
    case XS_CODE_BRANCH_COALESCE_1:
243
0
    case XS_CODE_BRANCH_ELSE_1:
244
0
    case XS_CODE_BRANCH_IF_1:
245
0
    case XS_CODE_BRANCH_STATUS_1:
246
0
    case XS_CODE_CATCH_1:
247
0
    case XS_CODE_CODE_1:
248
0
      size += 2;
249
0
      delta += 3;
250
0
      break;
251
      
252
0
    case XS_CODE_ARGUMENT:
253
0
    case XS_CODE_ARGUMENTS:
254
0
    case XS_CODE_ARGUMENTS_SLOPPY:
255
0
    case XS_CODE_ARGUMENTS_STRICT:
256
0
    case XS_CODE_BEGIN_SLOPPY:
257
0
    case XS_CODE_BEGIN_STRICT:
258
0
    case XS_CODE_BEGIN_STRICT_BASE:
259
0
    case XS_CODE_BEGIN_STRICT_DERIVED:
260
0
    case XS_CODE_BEGIN_STRICT_FIELD:
261
0
    case XS_CODE_MODULE:
262
0
      size += 2;
263
0
      break;
264
265
0
    case XS_CODE_LINE:
266
0
      size += 3;
267
0
      break;
268
0
    case XS_CODE_ASYNC_FUNCTION:
269
0
    case XS_CODE_ASYNC_GENERATOR_FUNCTION:
270
0
    case XS_CODE_CONSTRUCTOR_FUNCTION:
271
0
    case XS_CODE_DELETE_PROPERTY:
272
0
    case XS_CODE_DELETE_SUPER:
273
0
    case XS_CODE_FILE:
274
0
    case XS_CODE_FUNCTION:
275
0
    case XS_CODE_GENERATOR_FUNCTION:
276
0
    case XS_CODE_GET_PROPERTY:
277
0
    case XS_CODE_GET_SUPER:
278
0
    case XS_CODE_GET_THIS_VARIABLE:
279
0
    case XS_CODE_GET_VARIABLE:
280
0
    case XS_CODE_EVAL_PRIVATE:
281
0
    case XS_CODE_EVAL_REFERENCE:
282
0
    case XS_CODE_NAME:
283
0
    case XS_CODE_NEW_CLOSURE:
284
0
    case XS_CODE_NEW_LOCAL:
285
0
    case XS_CODE_NEW_PROPERTY:
286
0
    case XS_CODE_PROGRAM_REFERENCE:
287
0
    case XS_CODE_SET_PROPERTY:
288
0
    case XS_CODE_SET_SUPER:
289
0
    case XS_CODE_SET_VARIABLE:
290
0
    case XS_CODE_SYMBOL:
291
0
    case XS_CODE_PROFILE:
292
0
      size += 1 + sizeof(txID);
293
0
      break;
294
      
295
0
    case XS_CODE_STRING_1:
296
0
      size += ((txStringCode*)code)->length;
297
      // continue
298
0
      mxFallThrough;
299
0
    case XS_CODE_RESERVE_1:
300
0
    case XS_CODE_RETRIEVE_1:
301
0
    case XS_CODE_UNWIND_1:
302
0
      value = ((txIndexCode*)code)->index;
303
0
      if (value > 65535) {
304
0
        code->id += 2;
305
0
        size += 5;
306
0
      }
307
0
      else if (value > 255) {
308
0
        code->id += 1;
309
0
        size += 3;
310
0
      }
311
0
      else
312
0
        size += 2;
313
0
      break;
314
0
    case XS_CODE_BIGINT_1:
315
0
      value = fxBigIntMeasure(&((txBigIntCode*)code)->bigint);
316
0
      if (value > 255) {
317
0
        code->id += 1;
318
0
        size += 3;
319
0
      }
320
0
      else
321
0
        size += 2;
322
0
      size += value;
323
0
      break;
324
      
325
0
    case XS_CODE_CONST_CLOSURE_1:
326
0
    case XS_CODE_CONST_LOCAL_1:
327
0
    case XS_CODE_GET_CLOSURE_1:
328
0
    case XS_CODE_GET_LOCAL_1:
329
0
    case XS_CODE_GET_PRIVATE_1:
330
0
    case XS_CODE_HAS_PRIVATE_1:
331
0
    case XS_CODE_LET_CLOSURE_1:
332
0
    case XS_CODE_LET_LOCAL_1:
333
0
    case XS_CODE_NEW_PRIVATE_1:
334
0
    case XS_CODE_PULL_CLOSURE_1:
335
0
    case XS_CODE_PULL_LOCAL_1:
336
0
    case XS_CODE_REFRESH_CLOSURE_1:
337
0
    case XS_CODE_REFRESH_LOCAL_1:
338
0
    case XS_CODE_RESET_CLOSURE_1:
339
0
    case XS_CODE_RESET_LOCAL_1:
340
0
    case XS_CODE_SET_CLOSURE_1:
341
0
    case XS_CODE_SET_LOCAL_1:
342
0
    case XS_CODE_SET_PRIVATE_1:
343
0
    case XS_CODE_STORE_1:
344
0
    case XS_CODE_USED_1:
345
0
    case XS_CODE_VAR_CLOSURE_1:
346
0
    case XS_CODE_VAR_LOCAL_1:
347
0
      value = ((txIndexCode*)code)->index + 1;
348
0
      if (value > 65535) {
349
0
        code->id += 2;
350
0
        size += 5;
351
0
      }
352
0
      else if (value > 255) {
353
0
        code->id += 1;
354
0
        size += 3;
355
0
      }
356
0
      else
357
0
        size += 2;
358
0
      break;
359
      
360
0
    case XS_CODE_INTEGER_1: 
361
0
    case XS_CODE_RUN_1: 
362
0
    case XS_CODE_RUN_TAIL_1: 
363
0
      value = ((txIntegerCode*)code)->integer;
364
0
      if ((value < -32768) || (value > 32767)) {
365
0
        code->id += 2;
366
0
        size += 5;
367
0
      }
368
0
      else if ((value < -128) || (value > 127)) {
369
0
        code->id += 1;
370
0
        size += 3;
371
0
      }
372
0
      else
373
0
        size += 2;
374
0
      break;
375
0
    case XS_CODE_NUMBER:
376
0
      size += 9;
377
0
      break;
378
      
379
0
    case XS_CODE_HOST:
380
0
      size += 3;
381
0
      break;
382
      
383
0
    default:
384
0
      size++;
385
0
      break;
386
0
    }
387
0
    code = code->nextCode;
388
0
#ifdef mxMetering
389
0
    meterIndex++;
390
0
#endif
391
0
  }  
392
0
#ifdef mxMetering
393
0
  fxMeterSome(parser->console, meterIndex);
394
0
#endif
395
396
0
  code = coder.firstCode;
397
0
  size = 0;
398
0
  while (code) {
399
0
    switch (code->id) {
400
0
    case XS_NO_CODE:
401
0
      ((txTargetCode*)code)->offset = size;
402
0
      break;
403
0
    case XS_CODE_BRANCH_1:
404
0
    case XS_CODE_BRANCH_CHAIN_1:
405
0
    case XS_CODE_BRANCH_COALESCE_1:
406
0
    case XS_CODE_BRANCH_ELSE_1:
407
0
    case XS_CODE_BRANCH_IF_1:
408
0
    case XS_CODE_BRANCH_STATUS_1:
409
0
    case XS_CODE_CATCH_1:
410
0
    case XS_CODE_CODE_1:
411
0
      offset = ((txBranchCode*)code)->target->offset - (size + 5);
412
0
      if ((offset < -32768) || (offset + delta > 32767)) {
413
0
        code->id += 2;
414
0
        size += 5;
415
0
      }
416
0
      else if ((offset < -128) || (offset + delta > 127)) {
417
0
        code->id += 1;
418
0
        delta -= 2;
419
0
        size += 3;
420
0
      }
421
0
      else {
422
0
        delta -= 3;
423
0
        size += 2;
424
0
      }
425
0
      break;
426
      
427
0
    case XS_CODE_ARGUMENT:
428
0
    case XS_CODE_ARGUMENTS:
429
0
    case XS_CODE_ARGUMENTS_SLOPPY:
430
0
    case XS_CODE_ARGUMENTS_STRICT:
431
0
    case XS_CODE_BEGIN_SLOPPY:
432
0
    case XS_CODE_BEGIN_STRICT:
433
0
    case XS_CODE_BEGIN_STRICT_BASE:
434
0
    case XS_CODE_BEGIN_STRICT_DERIVED:
435
0
    case XS_CODE_BEGIN_STRICT_FIELD:
436
0
    case XS_CODE_MODULE:
437
0
      size += 2;
438
0
      break;
439
0
    case XS_CODE_LINE:
440
0
      size += 3;
441
0
      break;
442
0
    case XS_CODE_ASYNC_FUNCTION:
443
0
    case XS_CODE_ASYNC_GENERATOR_FUNCTION:
444
0
    case XS_CODE_CONSTRUCTOR_FUNCTION:
445
0
    case XS_CODE_DELETE_PROPERTY:
446
0
    case XS_CODE_DELETE_SUPER:
447
0
    case XS_CODE_FILE:
448
0
    case XS_CODE_FUNCTION:
449
0
    case XS_CODE_GENERATOR_FUNCTION:
450
0
    case XS_CODE_GET_PROPERTY:
451
0
    case XS_CODE_GET_SUPER:
452
0
    case XS_CODE_GET_THIS_VARIABLE:
453
0
    case XS_CODE_GET_VARIABLE:
454
0
    case XS_CODE_EVAL_PRIVATE:
455
0
    case XS_CODE_EVAL_REFERENCE:
456
0
    case XS_CODE_NAME:
457
0
    case XS_CODE_NEW_CLOSURE:
458
0
    case XS_CODE_NEW_LOCAL:
459
0
    case XS_CODE_NEW_PROPERTY:
460
0
    case XS_CODE_PROGRAM_REFERENCE:
461
0
    case XS_CODE_SET_PROPERTY:
462
0
    case XS_CODE_SET_SUPER:
463
0
    case XS_CODE_SET_VARIABLE:
464
0
    case XS_CODE_SYMBOL:
465
0
      symbol = ((txSymbolCode*)code)->symbol;
466
0
      if (symbol && symbol->string)
467
0
        symbol->usage |= 1;
468
0
      size += 1 + sizeof(txID);
469
0
      break;
470
0
    case XS_CODE_PROFILE:
471
0
      size += 1 + sizeof(txID);
472
0
      break;
473
      
474
0
    case XS_CODE_CONST_CLOSURE_1:
475
0
    case XS_CODE_CONST_LOCAL_1:
476
0
    case XS_CODE_GET_CLOSURE_1:
477
0
    case XS_CODE_GET_LOCAL_1:
478
0
    case XS_CODE_GET_PRIVATE_1:
479
0
    case XS_CODE_HAS_PRIVATE_1:
480
0
    case XS_CODE_LET_CLOSURE_1:
481
0
    case XS_CODE_LET_LOCAL_1:
482
0
    case XS_CODE_NEW_PRIVATE_1:
483
0
    case XS_CODE_PULL_CLOSURE_1:
484
0
    case XS_CODE_PULL_LOCAL_1:
485
0
    case XS_CODE_REFRESH_CLOSURE_1:
486
0
    case XS_CODE_REFRESH_LOCAL_1:
487
0
    case XS_CODE_RESERVE_1:
488
0
    case XS_CODE_RESET_CLOSURE_1:
489
0
    case XS_CODE_RESET_LOCAL_1:
490
0
    case XS_CODE_RETRIEVE_1:
491
0
    case XS_CODE_SET_CLOSURE_1:
492
0
    case XS_CODE_SET_LOCAL_1:
493
0
    case XS_CODE_SET_PRIVATE_1:
494
0
    case XS_CODE_STORE_1:
495
0
    case XS_CODE_UNWIND_1:
496
0
    case XS_CODE_USED_1:
497
0
    case XS_CODE_VAR_CLOSURE_1:
498
0
    case XS_CODE_VAR_LOCAL_1:
499
0
      size += 2;
500
0
      break;
501
0
    case XS_CODE_CONST_CLOSURE_2:
502
0
    case XS_CODE_CONST_LOCAL_2:
503
0
    case XS_CODE_GET_CLOSURE_2:
504
0
    case XS_CODE_GET_LOCAL_2:
505
0
    case XS_CODE_GET_PRIVATE_2:
506
0
    case XS_CODE_HAS_PRIVATE_2:
507
0
    case XS_CODE_LET_CLOSURE_2:
508
0
    case XS_CODE_LET_LOCAL_2:
509
0
    case XS_CODE_NEW_PRIVATE_2:
510
0
    case XS_CODE_PULL_CLOSURE_2:
511
0
    case XS_CODE_PULL_LOCAL_2:
512
0
    case XS_CODE_REFRESH_CLOSURE_2:
513
0
    case XS_CODE_REFRESH_LOCAL_2:
514
0
    case XS_CODE_RESERVE_2:
515
0
    case XS_CODE_RESET_CLOSURE_2:
516
0
    case XS_CODE_RESET_LOCAL_2:
517
0
    case XS_CODE_RETRIEVE_2:
518
0
    case XS_CODE_SET_CLOSURE_2:
519
0
    case XS_CODE_SET_LOCAL_2:
520
0
    case XS_CODE_SET_PRIVATE_2:
521
0
    case XS_CODE_STORE_2:
522
0
    case XS_CODE_UNWIND_2:
523
0
    case XS_CODE_USED_2:
524
0
    case XS_CODE_VAR_CLOSURE_2:
525
0
    case XS_CODE_VAR_LOCAL_2:
526
0
      size += 3;
527
0
      break;
528
    
529
0
    case XS_CODE_INTEGER_1: 
530
0
    case XS_CODE_RUN_1: 
531
0
    case XS_CODE_RUN_TAIL_1: 
532
0
      size += 2;
533
0
      break;
534
0
    case XS_CODE_INTEGER_2: 
535
0
    case XS_CODE_RUN_2: 
536
0
    case XS_CODE_RUN_TAIL_2: 
537
0
      size += 3;
538
0
      break;
539
0
    case XS_CODE_INTEGER_4: 
540
0
    case XS_CODE_RUN_4: 
541
0
    case XS_CODE_RUN_TAIL_4: 
542
0
      size += 5;
543
0
      break;
544
0
    case XS_CODE_NUMBER:
545
0
      size += 9;
546
0
      break;
547
0
    case XS_CODE_STRING_1:
548
0
      size += 2 + ((txStringCode*)code)->length;
549
0
      break;
550
0
    case XS_CODE_STRING_2:
551
0
      size += 3 + ((txStringCode*)code)->length;
552
0
      break;
553
0
    case XS_CODE_STRING_4:
554
0
      size += 5 + ((txStringCode*)code)->length;
555
0
      break;
556
0
    case XS_CODE_BIGINT_1:
557
0
      size += 2 + fxBigIntMeasure(&((txBigIntCode*)code)->bigint);
558
0
      break;
559
0
    case XS_CODE_BIGINT_2:
560
0
      size += 3 + fxBigIntMeasure(&((txBigIntCode*)code)->bigint);
561
0
      break;
562
      
563
0
    case XS_CODE_HOST:
564
0
      size += 3;
565
0
      break;
566
    
567
0
    default:
568
0
      size++;
569
0
      break;
570
0
    }
571
0
    code = code->nextCode;
572
0
  }  
573
  
574
0
  node = parser->firstHostNode;
575
0
  while (node) {
576
0
    if (node->symbol)
577
0
      node->symbol->usage |= 1;
578
0
    node = node->nextHostNode;
579
0
  }
580
  
581
0
  address = parser->symbolTable;
582
0
  c = parser->symbolModulo;
583
0
  id = 1;
584
0
  total = sizeof(txID);
585
0
  for (i = 0; i < c; i++) {
586
0
    txSymbol* symbol = *address;
587
0
    while (symbol) {
588
0
      if (symbol->usage & 1) {
589
0
        symbol->ID = id;
590
0
        id++;
591
0
        total += symbol->length;
592
0
      }
593
0
      symbol = symbol->next;
594
0
    }
595
0
    address++;
596
0
  }
597
0
  count = id;
598
    
599
0
  script->codeBuffer = c_malloc(size);
600
0
  if (!script->codeBuffer) goto bail;
601
0
  script->codeSize = size;
602
  
603
0
  code = coder.firstCode;
604
0
  p = script->codeBuffer;
605
0
  while (code) {
606
0
    txS1 s1; txS2 s2; txS4 s4; 
607
0
    txU1 u1; txU2 u2;
608
0
    txNumber n;
609
0
    if (code->id)
610
0
      *p++ = (txS1)(code->id);
611
0
    switch (code->id) {
612
0
    case XS_CODE_BRANCH_1:
613
0
    case XS_CODE_BRANCH_CHAIN_1:
614
0
    case XS_CODE_BRANCH_COALESCE_1:
615
0
    case XS_CODE_BRANCH_ELSE_1:
616
0
    case XS_CODE_BRANCH_IF_1:
617
0
    case XS_CODE_BRANCH_STATUS_1:
618
0
    case XS_CODE_CATCH_1:
619
0
    case XS_CODE_CODE_1:
620
0
      offset = mxPtrDiff(p + 1 - script->codeBuffer);
621
0
      s1 = (txS1)(((txBranchCode*)code)->target->offset - offset);
622
0
      *p++ = s1;
623
0
      break;
624
0
    case XS_CODE_BRANCH_2:
625
0
    case XS_CODE_BRANCH_CHAIN_2:
626
0
    case XS_CODE_BRANCH_COALESCE_2:
627
0
    case XS_CODE_BRANCH_ELSE_2:
628
0
    case XS_CODE_BRANCH_IF_2:
629
0
    case XS_CODE_BRANCH_STATUS_2:
630
0
    case XS_CODE_CATCH_2:
631
0
    case XS_CODE_CODE_2:
632
0
      offset = mxPtrDiff(p + 2 - script->codeBuffer);
633
0
      s2 = (txS2)(((txBranchCode*)code)->target->offset - offset);
634
0
      mxEncode2(p, s2);
635
0
      break;
636
0
    case XS_CODE_BRANCH_4:
637
0
    case XS_CODE_BRANCH_CHAIN_4:
638
0
    case XS_CODE_BRANCH_COALESCE_4:
639
0
    case XS_CODE_BRANCH_ELSE_4:
640
0
    case XS_CODE_BRANCH_IF_4:
641
0
    case XS_CODE_BRANCH_STATUS_4:
642
0
    case XS_CODE_CATCH_4:
643
0
    case XS_CODE_CODE_4:
644
0
      offset = mxPtrDiff(p + 4 - script->codeBuffer);
645
0
      s4 = (txS4)(((txBranchCode*)code)->target->offset  - offset);
646
0
      mxEncode4(p, s4);
647
0
      break;
648
      
649
0
    case XS_CODE_ASYNC_FUNCTION:
650
0
    case XS_CODE_ASYNC_GENERATOR_FUNCTION:
651
0
    case XS_CODE_CONSTRUCTOR_FUNCTION:
652
0
    case XS_CODE_DELETE_PROPERTY:
653
0
    case XS_CODE_DELETE_SUPER:
654
0
    case XS_CODE_FILE:
655
0
    case XS_CODE_FUNCTION:
656
0
    case XS_CODE_GENERATOR_FUNCTION:
657
0
    case XS_CODE_GET_PROPERTY:
658
0
    case XS_CODE_GET_SUPER:
659
0
    case XS_CODE_GET_THIS_VARIABLE:
660
0
    case XS_CODE_GET_VARIABLE:
661
0
    case XS_CODE_EVAL_PRIVATE:
662
0
    case XS_CODE_EVAL_REFERENCE:
663
0
    case XS_CODE_NAME:
664
0
    case XS_CODE_NEW_CLOSURE:
665
0
    case XS_CODE_NEW_LOCAL:
666
0
    case XS_CODE_NEW_PROPERTY:
667
0
    case XS_CODE_PROGRAM_REFERENCE:
668
0
    case XS_CODE_SET_PROPERTY:
669
0
    case XS_CODE_SET_SUPER:
670
0
    case XS_CODE_SET_VARIABLE:
671
0
    case XS_CODE_SYMBOL:
672
0
      symbol = ((txSymbolCode*)code)->symbol;
673
0
      if (symbol && symbol->string)
674
0
        id = symbol->ID;
675
0
      else
676
0
        id = XS_NO_ID;
677
0
      mxEncodeID(p, id);
678
0
      break;
679
0
    case XS_CODE_PROFILE:
680
0
      id = fxGenerateProfileID(parser->console);
681
0
      mxEncodeID(p, id);
682
0
      break;
683
      
684
0
    case XS_CODE_ARGUMENT:
685
0
    case XS_CODE_ARGUMENTS:
686
0
    case XS_CODE_ARGUMENTS_SLOPPY:
687
0
    case XS_CODE_ARGUMENTS_STRICT:
688
0
    case XS_CODE_BEGIN_SLOPPY:
689
0
    case XS_CODE_BEGIN_STRICT:
690
0
    case XS_CODE_BEGIN_STRICT_BASE:
691
0
    case XS_CODE_BEGIN_STRICT_DERIVED:
692
0
    case XS_CODE_BEGIN_STRICT_FIELD:
693
0
    case XS_CODE_MODULE:
694
0
    case XS_CODE_RESERVE_1:
695
0
    case XS_CODE_RETRIEVE_1:
696
0
    case XS_CODE_UNWIND_1:
697
0
      u1 = (txU1)(((txIndexCode*)code)->index);
698
0
      *((txU1*)p++) = u1;
699
0
      break;
700
0
    case XS_CODE_LINE:
701
0
    case XS_CODE_RESERVE_2:
702
0
    case XS_CODE_RETRIEVE_2:
703
0
    case XS_CODE_UNWIND_2:
704
0
      u2 = (txU2)(((txIndexCode*)code)->index);
705
0
      mxEncode2(p, u2);
706
0
      break;
707
708
0
    case XS_CODE_CONST_CLOSURE_1:
709
0
    case XS_CODE_CONST_LOCAL_1:
710
0
    case XS_CODE_GET_CLOSURE_1:
711
0
    case XS_CODE_GET_LOCAL_1:
712
0
    case XS_CODE_GET_PRIVATE_1:
713
0
    case XS_CODE_HAS_PRIVATE_1:
714
0
    case XS_CODE_LET_CLOSURE_1:
715
0
    case XS_CODE_LET_LOCAL_1:
716
0
    case XS_CODE_NEW_PRIVATE_1:
717
0
    case XS_CODE_PULL_CLOSURE_1:
718
0
    case XS_CODE_PULL_LOCAL_1:
719
0
    case XS_CODE_REFRESH_CLOSURE_1:
720
0
    case XS_CODE_REFRESH_LOCAL_1:
721
0
    case XS_CODE_RESET_CLOSURE_1:
722
0
    case XS_CODE_RESET_LOCAL_1:
723
0
    case XS_CODE_SET_CLOSURE_1:
724
0
    case XS_CODE_SET_LOCAL_1:
725
0
    case XS_CODE_SET_PRIVATE_1:
726
0
    case XS_CODE_STORE_1:
727
0
    case XS_CODE_USED_1:
728
0
    case XS_CODE_VAR_CLOSURE_1:
729
0
    case XS_CODE_VAR_LOCAL_1:
730
0
      u1 = (txU1)(((txIndexCode*)code)->index + 1);
731
0
      *((txU1*)p++) = u1;
732
0
      break;
733
734
0
    case XS_CODE_CONST_CLOSURE_2:
735
0
    case XS_CODE_CONST_LOCAL_2:
736
0
    case XS_CODE_GET_CLOSURE_2:
737
0
    case XS_CODE_GET_LOCAL_2:
738
0
    case XS_CODE_GET_PRIVATE_2:
739
0
    case XS_CODE_HAS_PRIVATE_2:
740
0
    case XS_CODE_LET_CLOSURE_2:
741
0
    case XS_CODE_LET_LOCAL_2:
742
0
    case XS_CODE_NEW_PRIVATE_2:
743
0
    case XS_CODE_PULL_CLOSURE_2:
744
0
    case XS_CODE_PULL_LOCAL_2:
745
0
    case XS_CODE_REFRESH_CLOSURE_2:
746
0
    case XS_CODE_REFRESH_LOCAL_2:
747
0
    case XS_CODE_RESET_CLOSURE_2:
748
0
    case XS_CODE_RESET_LOCAL_2:
749
0
    case XS_CODE_SET_CLOSURE_2:
750
0
    case XS_CODE_SET_LOCAL_2:
751
0
    case XS_CODE_SET_PRIVATE_2:
752
0
    case XS_CODE_STORE_2:
753
0
    case XS_CODE_USED_2:
754
0
    case XS_CODE_VAR_CLOSURE_2:
755
0
    case XS_CODE_VAR_LOCAL_2:
756
0
      u2 = (txU2)(((txIndexCode*)code)->index + 1);
757
0
      mxEncode2(p, u2);
758
0
      break;
759
  
760
0
    case XS_CODE_INTEGER_1: 
761
0
    case XS_CODE_RUN_1: 
762
0
    case XS_CODE_RUN_TAIL_1: 
763
0
      s1 = (txS1)(((txIntegerCode*)code)->integer);
764
0
      *p++ = s1;
765
0
      break;
766
0
    case XS_CODE_INTEGER_2: 
767
0
    case XS_CODE_RUN_2: 
768
0
    case XS_CODE_RUN_TAIL_2: 
769
0
      s2 = (txS2)(((txIntegerCode*)code)->integer);
770
0
      mxEncode2(p, s2);
771
0
      break;
772
0
    case XS_CODE_INTEGER_4: 
773
0
    case XS_CODE_RUN_4: 
774
0
    case XS_CODE_RUN_TAIL_4: 
775
0
      s4 = (txS4)(((txIntegerCode*)code)->integer);
776
0
      mxEncode4(p, s4);
777
0
      break;
778
0
    case XS_CODE_NUMBER:
779
0
      n = ((txNumberCode*)code)->number;
780
0
      mxEncode8(p, n);
781
0
      break;
782
0
    case XS_CODE_STRING_1:
783
0
      u1 = (txU1)(((txStringCode*)code)->length);
784
0
      *((txU1*)p++) = u1;
785
0
      c_memcpy(p, ((txStringCode*)code)->string, u1);
786
0
      p += u1;
787
0
      break;
788
0
    case XS_CODE_STRING_2:
789
0
      u2 = (txU2)(((txStringCode*)code)->length);
790
0
      mxEncode2(p, u2);
791
0
      c_memcpy(p, ((txStringCode*)code)->string, u2);
792
0
      p += u2;
793
0
      break;
794
0
    case XS_CODE_STRING_4:
795
0
      s4 = (txS4)(((txStringCode*)code)->length);
796
0
      mxEncode4(p, s4);
797
0
      c_memcpy(p, ((txStringCode*)code)->string, s4);
798
0
      p += s4;
799
0
      break;
800
0
    case XS_CODE_BIGINT_1:
801
0
      u1 = (txU1)fxBigIntMeasure(&((txBigIntCode*)code)->bigint);
802
0
      *((txU1*)p++) = u1;
803
0
      fxBigIntEncode(p, &((txBigIntCode*)code)->bigint, u1);
804
0
      p += u1;
805
0
      break;
806
0
    case XS_CODE_BIGINT_2:
807
0
      u2 = (txU2)fxBigIntMeasure(&((txBigIntCode*)code)->bigint);
808
0
            mxEncode2(p, u2);
809
0
      fxBigIntEncode(p, &((txBigIntCode*)code)->bigint, u2);
810
0
      p += u2;
811
0
      break;
812
      
813
0
    case XS_CODE_HOST:
814
0
      u2 = (txU2)(((txIndexCode*)code)->index);
815
0
      mxEncode2(p, u2);
816
0
      break;
817
0
    }
818
0
    code = code->nextCode;
819
0
  }  
820
  
821
#ifdef mxCodePrint
822
  fprintf(stderr, "\n");
823
  code = coder.firstCode;
824
  while (code) {
825
    txInteger tab;
826
    for (tab = 0; tab < code->stackLevel; tab++)
827
      fprintf(stderr, "\t");
828
    switch (code->id) {
829
    case XS_NO_CODE:
830
      fprintf(stderr, "_%d\n", ((txTargetCode*)code)->index);
831
      break;
832
    
833
    case XS_CODE_BRANCH_1:
834
    case XS_CODE_BRANCH_2:
835
    case XS_CODE_BRANCH_4:
836
    case XS_CODE_BRANCH_CHAIN_1:
837
    case XS_CODE_BRANCH_CHAIN_2:
838
    case XS_CODE_BRANCH_CHAIN_4:
839
    case XS_CODE_BRANCH_COALESCE_1:
840
    case XS_CODE_BRANCH_COALESCE_2:
841
    case XS_CODE_BRANCH_COALESCE_4:
842
    case XS_CODE_BRANCH_ELSE_1:
843
    case XS_CODE_BRANCH_ELSE_2:
844
    case XS_CODE_BRANCH_ELSE_4:
845
    case XS_CODE_BRANCH_IF_1:
846
    case XS_CODE_BRANCH_IF_2:
847
    case XS_CODE_BRANCH_IF_4:
848
    case XS_CODE_BRANCH_STATUS_1:
849
    case XS_CODE_BRANCH_STATUS_2:
850
    case XS_CODE_BRANCH_STATUS_4:
851
    case XS_CODE_CATCH_1:
852
    case XS_CODE_CATCH_2:
853
    case XS_CODE_CATCH_4:
854
    case XS_CODE_CODE_1:
855
    case XS_CODE_CODE_2:
856
    case XS_CODE_CODE_4:
857
      fprintf(stderr, "%s _%d\n", gxCodeNames[code->id], ((txBranchCode*)code)->target->index);
858
      break;
859
    
860
    case XS_CODE_ARGUMENT:
861
    case XS_CODE_ARGUMENTS:
862
    case XS_CODE_ARGUMENTS_SLOPPY:
863
    case XS_CODE_ARGUMENTS_STRICT:
864
    case XS_CODE_BEGIN_SLOPPY:
865
    case XS_CODE_BEGIN_STRICT:
866
    case XS_CODE_BEGIN_STRICT_BASE:
867
    case XS_CODE_BEGIN_STRICT_DERIVED:
868
    case XS_CODE_BEGIN_STRICT_FIELD:
869
    case XS_CODE_LINE:
870
    case XS_CODE_MODULE:
871
      fprintf(stderr, "%s %d\n", gxCodeNames[code->id], ((txIndexCode*)code)->index);
872
      break;
873
      
874
    case XS_CODE_ASYNC_FUNCTION:
875
    case XS_CODE_ASYNC_GENERATOR_FUNCTION:
876
    case XS_CODE_CONSTRUCTOR_FUNCTION:
877
    case XS_CODE_DELETE_PROPERTY:
878
    case XS_CODE_DELETE_SUPER:
879
    case XS_CODE_FILE:
880
    case XS_CODE_FUNCTION:
881
    case XS_CODE_GENERATOR_FUNCTION:
882
    case XS_CODE_GET_PROPERTY:
883
    case XS_CODE_GET_SUPER:
884
    case XS_CODE_GET_THIS_VARIABLE:
885
    case XS_CODE_GET_VARIABLE:
886
    case XS_CODE_EVAL_PRIVATE:
887
    case XS_CODE_EVAL_REFERENCE:
888
    case XS_CODE_NAME:
889
    case XS_CODE_NEW_PROPERTY:
890
    case XS_CODE_PROGRAM_REFERENCE:
891
    case XS_CODE_SET_PROPERTY:
892
    case XS_CODE_SET_SUPER:
893
    case XS_CODE_SET_VARIABLE:
894
    case XS_CODE_SYMBOL:
895
      symbol = ((txSymbolCode*)code)->symbol;
896
      if (symbol && symbol->string)
897
        fprintf(stderr, "%s %s\n", gxCodeNames[code->id], symbol->string);
898
      else
899
        fprintf(stderr, "%s ?\n", gxCodeNames[code->id]);
900
      break;
901
    
902
    case XS_CODE_CONST_CLOSURE_1:
903
    case XS_CODE_CONST_CLOSURE_2:
904
    case XS_CODE_CONST_LOCAL_1:
905
    case XS_CODE_CONST_LOCAL_2:
906
    case XS_CODE_GET_CLOSURE_1:
907
    case XS_CODE_GET_CLOSURE_2:
908
    case XS_CODE_GET_LOCAL_1:
909
    case XS_CODE_GET_LOCAL_2:
910
    case XS_CODE_GET_PRIVATE_1:
911
    case XS_CODE_GET_PRIVATE_2:
912
    case XS_CODE_HAS_PRIVATE_1:
913
    case XS_CODE_HAS_PRIVATE_2:
914
    case XS_CODE_LET_CLOSURE_1:
915
    case XS_CODE_LET_CLOSURE_2:
916
    case XS_CODE_LET_LOCAL_1:
917
    case XS_CODE_LET_LOCAL_2:
918
    case XS_CODE_NEW_PRIVATE_1:
919
    case XS_CODE_NEW_PRIVATE_2:
920
    case XS_CODE_PULL_CLOSURE_1:
921
    case XS_CODE_PULL_CLOSURE_2:
922
    case XS_CODE_PULL_LOCAL_1:
923
    case XS_CODE_PULL_LOCAL_2:
924
    case XS_CODE_REFRESH_CLOSURE_1:
925
    case XS_CODE_REFRESH_CLOSURE_2:
926
    case XS_CODE_REFRESH_LOCAL_1:
927
    case XS_CODE_REFRESH_LOCAL_2:
928
    case XS_CODE_RESET_CLOSURE_1:
929
    case XS_CODE_RESET_CLOSURE_2:
930
    case XS_CODE_RESET_LOCAL_1:
931
    case XS_CODE_RESET_LOCAL_2:
932
    case XS_CODE_SET_CLOSURE_1:
933
    case XS_CODE_SET_CLOSURE_2:
934
    case XS_CODE_SET_LOCAL_1:
935
    case XS_CODE_SET_LOCAL_2:
936
    case XS_CODE_SET_PRIVATE_1:
937
    case XS_CODE_SET_PRIVATE_2:
938
    case XS_CODE_STORE_1:
939
    case XS_CODE_STORE_2:
940
    case XS_CODE_USED_1:
941
    case XS_CODE_USED_2:
942
    case XS_CODE_VAR_CLOSURE_1:
943
    case XS_CODE_VAR_CLOSURE_2:
944
    case XS_CODE_VAR_LOCAL_1:
945
    case XS_CODE_VAR_LOCAL_2:
946
      fprintf(stderr, "%s [%d]\n", gxCodeNames[code->id], ((txIndexCode*)code)->index);
947
      break;
948
    
949
    case XS_CODE_RESERVE_1:
950
    case XS_CODE_RESERVE_2:
951
    case XS_CODE_UNWIND_1:
952
    case XS_CODE_UNWIND_2:
953
      fprintf(stderr, "%s #%d\n", gxCodeNames[code->id], ((txIndexCode*)code)->index);
954
      break;
955
    case XS_CODE_NEW_CLOSURE:
956
    case XS_CODE_NEW_LOCAL:
957
      fprintf(stderr, "[%d] %s %s\n", ((txVariableCode*)code)->index, gxCodeNames[code->id], ((txSymbolCode*)code)->symbol->string);
958
      break;
959
    case XS_CODE_NEW_TEMPORARY:
960
      fprintf(stderr, "[%d] %s\n", ((txIndexCode*)code)->index, gxCodeNames[code->id]);
961
      break;
962
    case XS_CODE_RETRIEVE_1:
963
    case XS_CODE_RETRIEVE_2:
964
      {
965
        txInteger i, c = ((txIndexCode*)code)->index;
966
        fprintf(stderr, "[0");
967
        for (i = 1; i < c; i++)
968
          fprintf(stderr, ",%d", i);
969
        fprintf(stderr, "] %s\n", gxCodeNames[code->id]);
970
      }
971
      break;
972
    
973
    case XS_CODE_INTEGER_1: 
974
    case XS_CODE_INTEGER_2: 
975
    case XS_CODE_INTEGER_4: 
976
    case XS_CODE_RUN_1: 
977
    case XS_CODE_RUN_2: 
978
    case XS_CODE_RUN_4: 
979
    case XS_CODE_RUN_TAIL_1: 
980
    case XS_CODE_RUN_TAIL_2: 
981
    case XS_CODE_RUN_TAIL_4: 
982
      fprintf(stderr, "%s %d\n", gxCodeNames[code->id], ((txIntegerCode*)code)->integer);
983
      break;
984
    case XS_CODE_NUMBER:
985
      fprintf(stderr, "%s %lf\n", gxCodeNames[code->id], ((txNumberCode*)code)->number);
986
      break;
987
    case XS_CODE_STRING_1:
988
    case XS_CODE_STRING_2:
989
    case XS_CODE_STRING_4:
990
      fprintf(stderr, "%s %d \"%s\"\n", gxCodeNames[code->id], ((txStringCode*)code)->length, ((txStringCode*)code)->string);
991
      break;
992
    case XS_CODE_BIGINT_1:
993
    case XS_CODE_BIGINT_2:
994
      fprintf(stderr, "%s %d\n", gxCodeNames[code->id], fxBigIntMeasure(&((txBigIntCode*)code)->bigint));
995
      break;
996
      
997
    case XS_CODE_HOST:
998
      fprintf(stderr, "%s %d\n", gxCodeNames[code->id], ((txIndexCode*)code)->index);
999
      break;
1000
  
1001
    default:
1002
      fprintf(stderr, "%s\n", gxCodeNames[code->id]);
1003
      break;
1004
    }
1005
    code = code->nextCode;
1006
  }
1007
#endif
1008
0
  script->symbolsBuffer = c_malloc(total);
1009
0
  if (!script->symbolsBuffer) goto bail;
1010
0
  script->symbolsSize = total;
1011
  
1012
0
  p = script->symbolsBuffer;
1013
0
  mxEncodeID(p, count);
1014
  
1015
0
  address = parser->symbolTable;
1016
0
  c = parser->symbolModulo;
1017
0
  for (i = 0; i < c; i++) {
1018
0
    txSymbol* symbol = *address;
1019
0
    while (symbol) {
1020
0
      if (symbol->usage & 1) {
1021
0
        c_memcpy(p, symbol->string, symbol->length);
1022
0
        p += symbol->length;
1023
0
      }
1024
0
      symbol = symbol->next;
1025
0
    }
1026
0
    address++;
1027
0
  }
1028
  
1029
0
  c = (txS2)(parser->hostNodeIndex);
1030
0
  if (c) {
1031
0
    size = sizeof(txID);
1032
0
    node = parser->firstHostNode;
1033
0
    while (node) {
1034
0
      size += 1 + sizeof(txID) + node->at->length + 1;
1035
0
      node = node->nextHostNode;
1036
0
    }
1037
  
1038
0
    script->hostsBuffer = c_malloc(size);
1039
0
    if (!script->hostsBuffer) goto bail;
1040
0
    script->hostsSize = size;
1041
  
1042
0
    p = script->hostsBuffer;
1043
0
    mxEncodeID(p, c);
1044
0
    node = parser->firstHostNode;
1045
0
    while (node) {
1046
0
      *p++ = (txS1)(node->paramsCount);
1047
0
      if (node->symbol)
1048
0
        c = node->symbol->ID;
1049
0
      else
1050
0
        c = XS_NO_ID;
1051
0
      mxEncodeID(p, c);
1052
0
      c_memcpy(p, node->at->value, node->at->length);
1053
0
      p += node->at->length;
1054
0
      *p++ = 0;
1055
0
      node = node->nextHostNode;
1056
0
    }
1057
0
  }
1058
1059
0
  return script;
1060
0
bail:
1061
0
  fxDeleteScript(script);
1062
0
  return C_NULL;
1063
0
}
1064
1065
void fxCoderAdd(txCoder* self, txInteger delta, void* it)
1066
0
{
1067
0
  txByteCode* code = it;
1068
0
  if (self->lastCode)
1069
0
    self->lastCode->nextCode = code;
1070
0
  else
1071
0
    self->firstCode = code;
1072
0
  self->lastCode = code;
1073
0
  self->stackLevel += delta;
1074
0
  code->stackLevel = self->stackLevel;
1075
//  if (self->stackLevel < 0)
1076
//    c_fprintf(stderr, "# oops %d\n", code->id);   //@@
1077
0
}
1078
1079
void fxCoderAddBigInt(txCoder* self, txInteger delta, txInteger id, txBigInt* bigint)
1080
0
{
1081
0
  txBigIntCode* code = fxNewParserChunkClear(self->parser, sizeof(txBigIntCode));
1082
0
  fxCoderAdd(self, delta, code);
1083
0
  code->id = id;
1084
0
  code->bigint = *bigint;
1085
0
}
1086
1087
void fxCoderAddBranch(txCoder* self, txInteger delta, txInteger id, txTargetCode* target)
1088
0
{
1089
0
  txBranchCode* code = fxNewParserChunkClear(self->parser, sizeof(txBranchCode));
1090
0
  fxCoderAdd(self, delta, code);
1091
0
  code->id = id;
1092
0
  code->target = target;
1093
0
  target->used = 1;
1094
0
}
1095
1096
void fxCoderAddByte(txCoder* self, txInteger delta, txInteger id)
1097
0
{
1098
0
  txByteCode* code = fxNewParserChunkClear(self->parser, sizeof(txByteCode));
1099
0
  fxCoderAdd(self, delta, code);
1100
0
  code->id = id;
1101
0
}
1102
1103
void fxCoderAddIndex(txCoder* self, txInteger delta, txInteger id, txInteger index)
1104
0
{
1105
0
  txIndexCode* code = fxNewParserChunkClear(self->parser, sizeof(txIndexCode));
1106
0
  fxCoderAdd(self, delta, code);
1107
0
  code->id = id;
1108
0
  code->index = index;
1109
0
}
1110
1111
void fxCoderAddInteger(txCoder* self, txInteger delta, txInteger id, txInteger integer)
1112
0
{
1113
0
  txIntegerCode* code = fxNewParserChunkClear(self->parser, sizeof(txIntegerCode));
1114
0
  fxCoderAdd(self, delta, code);
1115
0
  code->id = id;
1116
0
  code->integer = integer;
1117
0
}
1118
1119
void fxCoderAddLine(txCoder* self, txInteger delta, txInteger id, txNode* node)
1120
0
{
1121
0
  if (self->parser->flags & mxDebugFlag) {
1122
0
    if (self->parser->lines) {
1123
0
      if (node->path != self->parser->path) {
1124
0
        node->path = self->parser->path;
1125
0
        node->line = self->parser->lines[node->line];
1126
0
      }
1127
0
    }
1128
0
    else if (self->parser->source) {
1129
0
      node->path = self->parser->source;
1130
0
    }
1131
0
    if (self->path != node->path) {
1132
0
      if (node->path) {
1133
0
        fxCoderAddSymbol(self, 0, XS_CODE_FILE, node->path);
1134
0
        fxCoderAddIndex(self, 0, id, node->line);
1135
0
      }
1136
0
      self->path = node->path;
1137
0
      self->line = node->line;
1138
0
    }
1139
0
    else if (self->line != node->line) {
1140
0
      if (self->path) {
1141
0
        txIndexCode* code = (txIndexCode*)self->lastCode;
1142
0
        if (code && (code->id == id) && (code->index != 0))
1143
0
          code->index = node->line;
1144
0
        else
1145
0
          fxCoderAddIndex(self, 0, id, node->line);
1146
0
      }
1147
0
      self->line = node->line;
1148
0
    }
1149
0
  }
1150
0
}
1151
1152
void fxCoderAddNumber(txCoder* self, txInteger delta, txInteger id, txNumber number)
1153
0
{
1154
0
  txNumberCode* code = fxNewParserChunkClear(self->parser, sizeof(txNumberCode));
1155
0
  fxCoderAdd(self, delta, code);
1156
0
  code->id = id;
1157
0
  code->number = number;
1158
0
}
1159
1160
void fxCoderAddString(txCoder* self, txInteger delta, txInteger id, txInteger length, txString string)
1161
0
{
1162
0
  txStringCode* code = fxNewParserChunkClear(self->parser, sizeof(txStringCode));
1163
0
  fxCoderAdd(self, delta, code);
1164
0
  code->id = id;
1165
0
  code->length = length + 1;
1166
0
  code->string = string;
1167
0
}
1168
1169
void fxCoderAddSymbol(txCoder* self, txInteger delta, txInteger id, txSymbol* symbol)
1170
0
{
1171
0
  txSymbolCode* code = fxNewParserChunkClear(self->parser, sizeof(txSymbolCode));
1172
0
  fxCoderAdd(self, delta, code);
1173
0
  code->id = id;
1174
0
  code->symbol = symbol;
1175
0
}
1176
1177
void fxCoderAddVariable(txCoder* self, txInteger delta, txInteger id, txSymbol* symbol, txInteger index)
1178
0
{
1179
0
  txVariableCode* code = fxNewParserChunkClear(self->parser, sizeof(txVariableCode));
1180
0
  fxCoderAdd(self, delta, code);
1181
0
  code->id = id;
1182
0
  code->symbol = symbol;
1183
0
  code->index = index;
1184
0
}
1185
1186
void fxCoderAdjustEnvironment(txCoder* self, txTargetCode* target)
1187
0
{
1188
0
  txInteger count = self->environmentLevel - target->environmentLevel;
1189
0
  while (count) {
1190
0
    fxCoderAddByte(self, 0, XS_CODE_WITHOUT);
1191
0
    count--;
1192
0
  }
1193
0
}
1194
1195
void fxCoderAdjustScope(txCoder* self, txTargetCode* target)
1196
0
{
1197
0
  txInteger count = self->scopeLevel - target->scopeLevel;
1198
0
  if (count)
1199
0
    fxCoderAddIndex(self, 0, XS_CODE_UNWIND_1, count);
1200
0
}
1201
1202
txTargetCode* fxCoderAliasTargets(txCoder* self, txTargetCode* target)
1203
0
{
1204
0
  txTargetCode* result = NULL;
1205
0
  if (target) {
1206
0
    txTargetCode* alias = result = fxNewParserChunkClear(self->parser, sizeof(txTargetCode));
1207
0
    alias->index = self->targetIndex++;
1208
0
    alias->label = target->label;
1209
0
    alias->environmentLevel = self->environmentLevel;
1210
0
    alias->scopeLevel = self->scopeLevel;
1211
0
    alias->stackLevel = self->stackLevel;
1212
0
    alias->original = target;
1213
0
    target = target->nextTarget;
1214
0
    while (target) {
1215
0
      alias = alias->nextTarget = fxNewParserChunkClear(self->parser, sizeof(txTargetCode));
1216
0
      alias->index = self->targetIndex++;
1217
0
      alias->label = target->label;
1218
0
      alias->environmentLevel = self->environmentLevel;
1219
0
      alias->scopeLevel = self->scopeLevel;
1220
0
      alias->stackLevel = self->stackLevel;
1221
0
      alias->original = target;
1222
0
      target = target->nextTarget;
1223
0
    }
1224
0
  }
1225
0
  return result;
1226
0
}
1227
1228
txInteger fxCoderCountParameters(txCoder* self, txNode* params)
1229
0
{
1230
0
  txNode* item = ((txParamsBindingNode*)params)->items->first;
1231
0
  txInteger count = 0;
1232
0
  while (item) {
1233
0
    if (item->description->token == XS_TOKEN_REST_BINDING)
1234
0
      break;
1235
0
    if ((item->description->token != XS_TOKEN_ARG) && (item->description->token != XS_TOKEN_ARRAY_BINDING) && (item->description->token != XS_TOKEN_OBJECT_BINDING))
1236
0
      break;
1237
0
    count++;
1238
0
    item = item->next;
1239
0
  }
1240
0
  return count;
1241
0
}
1242
1243
txTargetCode* fxCoderCreateTarget(txCoder* self)
1244
0
{
1245
0
  txTargetCode* result = fxNewParserChunkClear(self->parser, sizeof(txTargetCode));
1246
0
  result->index = self->targetIndex++;
1247
0
  result->environmentLevel = self->environmentLevel;
1248
0
  result->scopeLevel = self->scopeLevel;
1249
0
  result->stackLevel = self->stackLevel;
1250
0
  return result;
1251
0
}
1252
1253
txTargetCode* fxCoderFinalizeTargets(txCoder* self, txTargetCode* alias, txInteger selector, txInteger* address, txTargetCode* finallyTarget)
1254
0
{
1255
0
  txTargetCode* result = NULL;
1256
0
  txInteger selection = *address;
1257
0
  if (alias) {
1258
0
    result = alias->original;
1259
0
    while (alias) {
1260
0
      if (alias->used) {
1261
0
        fxCoderAdd(self, 0, alias);
1262
0
        fxCoderAddInteger(self, 1, XS_CODE_INTEGER_1, selection);
1263
0
        fxCoderAddIndex(self, -1, XS_CODE_PULL_LOCAL_1, selector);
1264
0
        fxCoderAddBranch(self, 0, XS_CODE_BRANCH_1, finallyTarget);
1265
0
        alias->original->used = 1;
1266
0
      }
1267
0
      alias = alias->nextTarget;
1268
0
      selection++;
1269
0
    }
1270
0
  }
1271
0
  *address = selection;
1272
0
  return result;
1273
0
}
1274
1275
void fxCoderJumpTargets(txCoder* self, txTargetCode* target, txInteger selector, txInteger* address)
1276
0
{
1277
0
  txInteger selection = *address;
1278
0
  while (target) {
1279
0
    if (target->used) {
1280
0
      txTargetCode* elseTarget = fxCoderCreateTarget(self);
1281
0
      fxCoderAddInteger(self, 1, XS_CODE_INTEGER_1, selection);
1282
0
      fxCoderAddIndex(self, 1, XS_CODE_GET_LOCAL_1, selector);
1283
0
      fxCoderAddByte(self, -1, XS_CODE_STRICT_EQUAL);
1284
0
      fxCoderAddBranch(self, -1, XS_CODE_BRANCH_ELSE_1, elseTarget);
1285
0
      fxCoderAdjustEnvironment(self, target);
1286
0
      fxCoderAdjustScope(self, target);
1287
0
      fxCoderAddBranch(self, 0, XS_CODE_BRANCH_1, target);
1288
0
      fxCoderAdd(self, 0, elseTarget);
1289
0
    }
1290
0
    target = target->nextTarget;
1291
0
    selection++;
1292
0
  }
1293
0
  *address = selection;
1294
0
}
1295
1296
void fxCoderOptimize(txCoder* self)
1297
0
{
1298
0
  txByteCode** address;
1299
0
  txByteCode* code;
1300
  
1301
  // branch to (target | unwind)* end => end
1302
0
  address = &self->firstCode;
1303
0
  while ((code = *address)) {
1304
0
    if (code->id == XS_CODE_BRANCH_1) {
1305
0
      txByteCode* nextCode = ((txBranchCode*)code)->target->nextCode;
1306
0
      while ((nextCode->id == XS_NO_CODE) || (nextCode->id == XS_CODE_UNWIND_1))
1307
0
        nextCode = nextCode->nextCode;
1308
0
      if ((XS_CODE_END <= nextCode->id) && (nextCode->id <= XS_CODE_END_DERIVED)) {
1309
0
        txByteCode* end = fxNewParserChunkClear(self->parser, sizeof(txByteCode));
1310
0
        end->nextCode = code->nextCode;
1311
0
        end->id = nextCode->id;
1312
0
        end->stackLevel = code->stackLevel;
1313
0
        *address = end;
1314
0
      }
1315
0
      else
1316
0
        address = &code->nextCode;
1317
0
    }
1318
0
    else
1319
0
      address = &code->nextCode;
1320
0
  }
1321
  // unwind (target | unwind)* end => (target | unwind)* end
1322
0
  address = &self->firstCode;
1323
0
  while ((code = *address)) {
1324
0
    if (code->id == XS_CODE_UNWIND_1) {
1325
0
      txByteCode* nextCode = code->nextCode;
1326
0
      while ((nextCode->id == XS_NO_CODE) || (nextCode->id == XS_CODE_UNWIND_1))
1327
0
        nextCode = nextCode->nextCode;
1328
0
      if ((XS_CODE_END <= nextCode->id) && (nextCode->id <= XS_CODE_END_DERIVED))
1329
0
        *address = code->nextCode;
1330
0
      else
1331
0
        address = &code->nextCode;
1332
0
    }
1333
0
    else
1334
0
      address = &code->nextCode;
1335
0
  }
1336
  // end target* end => target* end
1337
0
  address = &self->firstCode;
1338
0
  while ((code = *address)) {
1339
0
    if ((XS_CODE_END <= code->id) && (code->id <= XS_CODE_END_DERIVED)) {
1340
0
      txByteCode* nextCode = code->nextCode;
1341
0
      if (!nextCode)
1342
0
        break;
1343
0
      while (nextCode->id == XS_NO_CODE)
1344
0
        nextCode = nextCode->nextCode;
1345
0
      if (nextCode->id == code->id)
1346
0
        *address = code->nextCode;
1347
0
      else
1348
0
        address = &code->nextCode;
1349
0
    }
1350
0
    else
1351
0
      address = &code->nextCode;
1352
0
  }
1353
  // branch to next =>
1354
0
  address = &self->firstCode;
1355
0
  while ((code = *address)) {
1356
0
    if (code->id == XS_CODE_BRANCH_1) {
1357
0
      if (code->nextCode == (txByteCode*)(((txBranchCode*)code)->target))
1358
0
        *address = code->nextCode;
1359
0
      else
1360
0
        address = &code->nextCode;
1361
0
    }
1362
0
    else
1363
0
      address = &code->nextCode;
1364
0
  }
1365
0
}
1366
1367
txInteger fxCoderUseTemporaryVariable(txCoder* self)
1368
0
{
1369
0
  txInteger result = self->scopeLevel++;
1370
0
  fxCoderAddIndex(self, 0, XS_CODE_NEW_TEMPORARY, result);
1371
0
  return result;
1372
0
}
1373
1374
void fxCoderUnuseTemporaryVariables(txCoder* self, txInteger count)
1375
0
{
1376
0
  fxCoderAddIndex(self, 0, XS_CODE_UNWIND_1, count);
1377
0
  self->scopeLevel -= count;
1378
0
}
1379
1380
void fxScopeCoded(txScope* self, txCoder* coder) 
1381
0
{
1382
0
  if (self->declareNodeCount) {
1383
0
    if (self->flags & mxEvalFlag) {
1384
0
      coder->environmentLevel--;
1385
0
      fxCoderAddByte(coder, 0, XS_CODE_WITHOUT);
1386
0
    }
1387
0
    fxCoderAddIndex(coder, 0, XS_CODE_UNWIND_1, self->declareNodeCount);
1388
0
    coder->scopeLevel -= self->declareNodeCount;
1389
0
  }
1390
0
}
1391
1392
void fxScopeCodedBody(txScope* self, txCoder* coder) 
1393
0
{
1394
0
  txScope* functionScope = self->scope;
1395
0
  if ((functionScope->node->flags & mxEvalFlag) && !(functionScope->node->flags & mxStrictFlag)) {
1396
0
    coder->environmentLevel--;
1397
0
    fxCoderAddByte(coder, 0, XS_CODE_WITHOUT);
1398
0
    coder->environmentLevel--;
1399
0
    fxCoderAddByte(coder, 0, XS_CODE_WITHOUT);
1400
0
    fxCoderAddIndex(coder, 0, XS_CODE_UNWIND_1, self->declareNodeCount);
1401
0
    coder->scopeLevel -= self->declareNodeCount;
1402
0
  }
1403
0
  else 
1404
0
    fxScopeCoded(self, coder);
1405
0
}
1406
1407
void fxScopeCodingBlock(txScope* self, txCoder* coder) 
1408
0
{
1409
0
  if (self->declareNodeCount) {
1410
0
    txDeclareNode* node = self->firstDeclareNode;
1411
0
    while (node) {
1412
0
      if (node->flags & mxDeclareNodeClosureFlag) {
1413
0
        if (!(node->flags & mxDeclareNodeUseClosureFlag)) {
1414
0
          node->index = coder->scopeLevel++;
1415
0
          fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1416
0
          if (node->description->token == XS_TOKEN_VAR) {
1417
0
            fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1418
0
            fxCoderAddIndex(coder, 0, XS_CODE_VAR_CLOSURE_1, node->index);
1419
0
            fxCoderAddByte(coder, -1, XS_CODE_POP);
1420
0
          }
1421
0
        }
1422
0
      }
1423
0
      else {
1424
0
        node->index = coder->scopeLevel++;
1425
0
        if (node->symbol)
1426
0
          fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1427
0
        else
1428
0
          fxCoderAddIndex(coder, 0, XS_CODE_NEW_TEMPORARY, node->index);
1429
0
        if (node->description->token == XS_TOKEN_VAR) {
1430
0
          fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1431
0
          fxCoderAddIndex(coder, 0, XS_CODE_VAR_LOCAL_1, node->index);
1432
0
          fxCoderAddByte(coder, -1, XS_CODE_POP);
1433
0
        }
1434
0
      }
1435
0
      node = node->nextDeclareNode;
1436
0
    }
1437
0
    if (self->flags & mxEvalFlag) {
1438
0
      fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1439
0
      fxCoderAddByte(coder, 0, XS_CODE_WITH);
1440
0
      node = self->firstDeclareNode;
1441
0
      while (node) {
1442
0
        fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->index);
1443
0
        node = node->nextDeclareNode;
1444
0
      }
1445
0
      fxCoderAddByte(coder, -1, XS_CODE_POP);
1446
0
      coder->environmentLevel++;
1447
0
    }
1448
0
  }
1449
0
}
1450
1451
void fxScopeCodingBody(txScope* self, txCoder* coder) 
1452
0
{
1453
0
  if ((self->node->flags & mxEvalFlag) && !(self->node->flags & mxStrictFlag)) {
1454
0
    txDeclareNode* node = self->firstDeclareNode;
1455
0
    while (node) {
1456
0
      if (node->description->token == XS_TOKEN_DEFINE) {
1457
0
        node->index = coder->scopeLevel++;
1458
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1459
0
        fxCoderAddByte(coder, 1, XS_CODE_NULL);
1460
0
        fxCoderAddIndex(coder, 0, XS_CODE_VAR_CLOSURE_1, node->index);
1461
0
        fxCoderAddByte(coder, -1, XS_CODE_POP);
1462
0
      }
1463
0
      else if (node->description->token == XS_TOKEN_VAR) {
1464
0
        node->index = coder->scopeLevel++;
1465
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1466
0
        fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1467
0
        fxCoderAddIndex(coder, 0, XS_CODE_VAR_CLOSURE_1, node->index);
1468
0
        fxCoderAddByte(coder, -1, XS_CODE_POP);
1469
0
      }
1470
0
      node = node->nextDeclareNode;
1471
0
    }
1472
0
    fxCoderAddByte(coder, 1, XS_CODE_NULL);
1473
0
    fxCoderAddByte(coder, 0, XS_CODE_WITH);
1474
0
    node = self->firstDeclareNode;
1475
0
    while (node) {
1476
0
      if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR))
1477
0
        fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->index);
1478
0
      node = node->nextDeclareNode;
1479
0
    }
1480
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
1481
0
    coder->environmentLevel++;
1482
0
    node = self->firstDeclareNode;
1483
0
    while (node) {
1484
0
      if ((node->description->token != XS_TOKEN_DEFINE) && (node->description->token != XS_TOKEN_VAR)) {
1485
0
        node->index = coder->scopeLevel++;
1486
0
        if (node->symbol)
1487
0
          fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1488
0
        else
1489
0
          fxCoderAddIndex(coder, 0, XS_CODE_NEW_TEMPORARY, node->index);
1490
0
      }
1491
0
      node = node->nextDeclareNode;
1492
0
    }
1493
0
    fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1494
0
    fxCoderAddByte(coder, 0, XS_CODE_WITH);
1495
0
    node = self->firstDeclareNode;
1496
0
    while (node) {
1497
0
      if ((node->description->token != XS_TOKEN_DEFINE) && (node->description->token != XS_TOKEN_VAR)) {
1498
0
        if (node->symbol)
1499
0
          fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->index);
1500
0
      }
1501
0
      node = node->nextDeclareNode;
1502
0
    }
1503
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
1504
0
    coder->environmentLevel++;
1505
0
  }
1506
0
  else 
1507
0
    fxScopeCodingBlock(self, coder);
1508
0
}
1509
1510
void fxScopeCodingEval(txScope* self, txCoder* coder) 
1511
0
{
1512
0
  txProgramNode* programNode = (txProgramNode*)self->node;
1513
0
  txDeclareNode* node;
1514
0
  if (self->flags & mxStrictFlag) {
1515
0
    if (programNode->scopeCount) {
1516
0
      fxCoderAddIndex(coder, 0, XS_CODE_RESERVE_1, programNode->scopeCount);
1517
0
      fxScopeCodingBlock(self, coder);
1518
0
      node = self->firstDeclareNode;
1519
0
      while (node) {
1520
0
        if (node->description->token == XS_TOKEN_PRIVATE) {
1521
0
          fxCoderAddSymbol(coder, 1, XS_CODE_EVAL_PRIVATE, node->symbol);
1522
0
          fxCoderAddIndex(coder, 0, XS_CODE_CONST_CLOSURE_1, node->index);
1523
0
          fxCoderAddByte(coder, -1, XS_CODE_POP);
1524
0
        }
1525
0
        node = node->nextDeclareNode;
1526
0
      }
1527
0
    }
1528
0
  }
1529
0
  else {
1530
0
    txInteger count = 0;
1531
0
    node = self->firstDeclareNode;
1532
0
    while (node) {
1533
0
      if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR))
1534
0
        count++;
1535
0
      node = node->nextDeclareNode;
1536
0
    }
1537
0
    if (count) {
1538
0
      fxCoderAddIndex(coder, 0, XS_CODE_RESERVE_1, count);
1539
0
      node = self->firstDeclareNode;
1540
0
      while (node) {
1541
0
        if (node->description->token == XS_TOKEN_DEFINE) {
1542
0
          node->index = coder->scopeLevel++;
1543
0
          fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1544
0
          fxCoderAddByte(coder, 1, XS_CODE_NULL);
1545
0
          fxCoderAddIndex(coder, 0, XS_CODE_VAR_LOCAL_1, node->index);
1546
0
          fxCoderAddByte(coder, -1, XS_CODE_POP);
1547
0
        }
1548
0
        else if (node->description->token == XS_TOKEN_VAR) {
1549
0
          node->index = coder->scopeLevel++;
1550
0
          fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1551
0
          fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1552
0
          fxCoderAddIndex(coder, 0, XS_CODE_VAR_LOCAL_1, node->index);
1553
0
          fxCoderAddByte(coder, -1, XS_CODE_POP);
1554
0
        }
1555
0
        node = node->nextDeclareNode;
1556
0
      }
1557
0
    }
1558
0
    fxCoderAddByte(coder, 0, XS_CODE_EVAL_ENVIRONMENT);
1559
0
    coder->scopeLevel = 0;
1560
0
    if (programNode->scopeCount) {
1561
0
      fxCoderAddIndex(coder, 0, XS_CODE_RESERVE_1, programNode->scopeCount);
1562
0
      if (self->declareNodeCount) {
1563
0
        node = self->firstDeclareNode;
1564
0
        while (node) {
1565
0
          if ((node->description->token != XS_TOKEN_DEFINE) && (node->description->token != XS_TOKEN_VAR)) {
1566
0
            node->index = coder->scopeLevel++;
1567
0
            if (node->flags & mxDeclareNodeClosureFlag) {
1568
0
              fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1569
0
            }
1570
0
            else {
1571
0
              fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1572
0
            }
1573
0
          }
1574
0
          node = node->nextDeclareNode;
1575
0
        }
1576
0
        if (self->flags & mxEvalFlag) {
1577
0
          fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1578
0
          fxCoderAddByte(coder, 0, XS_CODE_WITH);
1579
0
          node = self->firstDeclareNode;
1580
0
          while (node) {
1581
0
            if ((node->description->token != XS_TOKEN_DEFINE) && (node->description->token != XS_TOKEN_VAR))
1582
0
              fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->index);
1583
0
            node = node->nextDeclareNode;
1584
0
          }
1585
0
          fxCoderAddByte(coder, -1, XS_CODE_POP);
1586
0
          coder->environmentLevel++;
1587
0
        }
1588
0
      }
1589
0
    }
1590
0
  }
1591
0
}
1592
1593
void fxScopeCodingParams(txScope* self, txCoder* coder) 
1594
0
{
1595
0
  txDeclareNode* node = self->firstDeclareNode;
1596
0
  while (node) {
1597
0
    txToken token = node->description->token;
1598
0
    if ((token == XS_TOKEN_ARG) || (token == XS_TOKEN_VAR) || (token == XS_TOKEN_CONST)) {
1599
0
      if (node->flags & mxDeclareNodeClosureFlag) {
1600
0
        if (node->flags & mxDeclareNodeUseClosureFlag) {
1601
0
          fxReportParserError(self->parser, node->line, "argument %s use closure", node->symbol->string);
1602
0
        }
1603
0
        node->index = coder->scopeLevel++;
1604
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1605
0
      }
1606
0
      else {
1607
0
        node->index = coder->scopeLevel++;
1608
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1609
0
      }
1610
0
    }
1611
0
    node = node->nextDeclareNode;
1612
0
  }
1613
0
  if (self->flags & mxEvalFlag) {
1614
0
    if (!(self->node->flags & mxStrictFlag)) { 
1615
0
      fxCoderAddByte(coder, 1, XS_CODE_NULL);
1616
0
      fxCoderAddByte(coder, 0, XS_CODE_WITH);
1617
0
      fxCoderAddByte(coder, -1, XS_CODE_POP);
1618
0
      coder->environmentLevel++;
1619
0
    }
1620
0
    fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1621
0
    fxCoderAddByte(coder, 0, XS_CODE_WITH);
1622
0
    node = self->firstDeclareNode;
1623
0
    while (node) {
1624
0
      txToken token = node->description->token;
1625
0
      if ((token == XS_TOKEN_ARG) || (token == XS_TOKEN_VAR) || (token == XS_TOKEN_CONST))
1626
0
        fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->index);
1627
0
      node = node->nextDeclareNode;
1628
0
    }
1629
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
1630
0
    coder->environmentLevel++;
1631
0
  }
1632
0
}
1633
1634
void fxScopeCodingProgram(txScope* self, txCoder* coder) 
1635
0
{
1636
0
  txProgramNode* programNode = (txProgramNode*)self->node;
1637
0
  txDeclareNode* node;
1638
0
  txInteger count = 0;
1639
0
  if (programNode->variableCount) {
1640
0
    fxCoderAddIndex(coder, 0, XS_CODE_RESERVE_1, programNode->variableCount);
1641
0
    node = self->firstDeclareNode;
1642
0
    while (node) {
1643
0
      if ((node->description->token != XS_TOKEN_DEFINE) && (node->description->token != XS_TOKEN_VAR)) {
1644
0
        node->index = coder->scopeLevel++;
1645
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_CLOSURE, node->symbol, node->index);
1646
0
      }
1647
0
      node = node->nextDeclareNode;
1648
0
    }
1649
0
    count = coder->scopeLevel;
1650
0
    node = self->firstDeclareNode;
1651
0
    while (node) {
1652
0
      if (node->description->token == XS_TOKEN_DEFINE) {
1653
        // closure -> global property
1654
0
        node->index = coder->scopeLevel++;
1655
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1656
0
        fxCoderAddByte(coder, 1, XS_CODE_NULL);
1657
0
        fxCoderAddIndex(coder, 0, XS_CODE_VAR_LOCAL_1, node->index);
1658
0
        fxCoderAddByte(coder, -1, XS_CODE_POP);
1659
0
      }
1660
0
      else if (node->description->token == XS_TOKEN_VAR) {
1661
        // closure -> global property
1662
0
        node->index = coder->scopeLevel++;
1663
0
        fxCoderAddVariable(coder, 0, XS_CODE_NEW_LOCAL, node->symbol, node->index);
1664
0
        fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1665
0
        fxCoderAddIndex(coder, 0, XS_CODE_VAR_LOCAL_1, node->index);
1666
0
        fxCoderAddByte(coder, -1, XS_CODE_POP);
1667
0
      }
1668
0
      node = node->nextDeclareNode;
1669
0
    }
1670
0
    fxCoderAddByte(coder, 0, XS_CODE_PROGRAM_ENVIRONMENT);
1671
0
    coder->scopeLevel = count;
1672
0
  }
1673
0
  if (programNode->scopeCount > count)
1674
0
    fxCoderAddIndex(coder, 0, XS_CODE_RESERVE_1, programNode->scopeCount - count);
1675
0
}
1676
1677
void fxScopeCodeDefineNodes(txScope* self, txCoder* coder) 
1678
0
{
1679
0
  txDefineNode* node = self->firstDefineNode;
1680
0
  while (node) {
1681
0
    fxDefineNodeCode(node, coder);
1682
0
    node = node->nextDefineNode;
1683
0
  }
1684
0
}
1685
1686
txInteger fxScopeCodeSpecifierNodes(txScope* self, txCoder* coder) 
1687
0
{
1688
0
  txDeclareNode* node = self->firstDeclareNode;
1689
0
  txInteger count = 0;
1690
0
  while (node) {
1691
0
    if (node->flags & mxDeclareNodeUseClosureFlag) {
1692
0
      txSpecifierNode* specifier = node->importSpecifier;
1693
0
      txInteger index = 3;
1694
0
      txBoolean flag = 0;
1695
0
      if (node->symbol)
1696
0
        fxCoderAddSymbol(coder, 1, XS_CODE_SYMBOL, node->symbol);
1697
0
      else
1698
0
        fxCoderAddByte(coder, 1, XS_CODE_NULL);
1699
0
      if (specifier) {
1700
0
        if (coder->parser->flags & mxDebugFlag) {
1701
0
          fxCoderAddLine(coder, 0, XS_CODE_LINE, (txNode*)specifier);
1702
0
        }
1703
0
        fxStringNodeCode(specifier->from, coder);
1704
0
        if (specifier->with)
1705
0
          flag = 1;
1706
0
        if (specifier->symbol)
1707
0
          fxCoderAddSymbol(coder, 1, XS_CODE_SYMBOL, specifier->symbol);
1708
0
        else
1709
0
          fxCoderAddByte(coder, 1, XS_CODE_NULL);
1710
0
      }
1711
0
      else {
1712
0
        fxCoderAddByte(coder, 1, XS_CODE_NULL);
1713
0
        fxCoderAddByte(coder, 1, XS_CODE_NULL);
1714
0
      }
1715
0
      specifier = node->firstExportSpecifier;
1716
0
      while (specifier) {
1717
0
        if (specifier->asSymbol) {
1718
0
          fxCoderAddSymbol(coder, 1, XS_CODE_SYMBOL, specifier->asSymbol);
1719
0
          index++;
1720
0
        }
1721
0
        else if (specifier->symbol) {
1722
0
          fxCoderAddSymbol(coder, 1, XS_CODE_SYMBOL, specifier->symbol);
1723
0
          index++;
1724
0
        }
1725
0
        else {
1726
0
          fxCoderAddByte(coder, 1, XS_CODE_NULL);
1727
0
          index++;
1728
0
        }
1729
0
        specifier = specifier->nextSpecifier;
1730
0
      }
1731
0
      fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, index);
1732
0
      if (flag)
1733
0
        fxCoderAddByte(coder, 0 - index, XS_CODE_TRANSFER_JSON);
1734
0
      else
1735
0
        fxCoderAddByte(coder, 0 - index, XS_CODE_TRANSFER);
1736
0
      count++;
1737
0
    }
1738
0
    node = node->nextDeclareNode;
1739
0
  }
1740
0
  return count;
1741
0
}
1742
1743
void fxScopeCodeRefresh(txScope* self, txCoder* coder) 
1744
0
{
1745
0
  txDeclareNode* node = self->firstDeclareNode;
1746
0
  while (node) {
1747
0
    if (node->flags & mxDeclareNodeClosureFlag)
1748
0
      fxCoderAddIndex(coder, 0, XS_CODE_REFRESH_CLOSURE_1, node->index);
1749
0
    else
1750
0
      fxCoderAddIndex(coder, 0, XS_CODE_REFRESH_LOCAL_1, node->index);
1751
0
    node = node->nextDeclareNode;
1752
0
  }
1753
0
}
1754
1755
void fxScopeCodeReset(txScope* self, txCoder* coder) 
1756
0
{
1757
0
  txDeclareNode* node = self->firstDeclareNode;
1758
0
  while (node) {
1759
0
    if (node->flags & mxDeclareNodeClosureFlag)
1760
0
      fxCoderAddIndex(coder, 0, XS_CODE_RESET_CLOSURE_1, node->index);
1761
0
    else if (node->symbol)
1762
0
      fxCoderAddIndex(coder, 0, XS_CODE_RESET_LOCAL_1, node->index);
1763
0
    else {
1764
0
      fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1765
0
      fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, node->index);
1766
0
    }
1767
0
    node = node->nextDeclareNode;
1768
0
  }
1769
0
}
1770
1771
void fxScopeCodeRetrieve(txScope* self, txCoder* coder) 
1772
0
{
1773
0
  txDeclareNode* node;
1774
0
  txInteger count = 0;
1775
0
  node = self->firstDeclareNode;
1776
0
  while (node) {
1777
0
    if ((node->flags & mxDeclareNodeUseClosureFlag) && node->symbol) {
1778
0
      node->index = coder->scopeLevel++;
1779
0
      count++;
1780
0
    }
1781
0
    node = node->nextDeclareNode;
1782
0
  }
1783
0
  if ((self->node->flags & mxArrowFlag) && ((self->node->flags & mxDefaultFlag) || (self->flags & mxEvalFlag))) {
1784
0
    fxCoderAddIndex(coder, 0, XS_CODE_RETRIEVE_1, count);
1785
0
    fxCoderAddByte(coder, 0, XS_CODE_RETRIEVE_TARGET);
1786
0
    fxCoderAddByte(coder, 0, XS_CODE_RETRIEVE_THIS);
1787
0
  }
1788
0
  else if (count)
1789
0
    fxCoderAddIndex(coder, 0, XS_CODE_RETRIEVE_1, count);
1790
0
  self->closureNodeCount = count;
1791
0
}
1792
1793
void fxScopeCodeStore(txScope* self, txCoder* coder) 
1794
0
{
1795
0
  txDeclareNode* node = self->firstDeclareNode;
1796
0
  txUnsigned flags = self->flags & mxEvalFlag;
1797
0
  while (node) {
1798
0
    if (node->flags & mxDeclareNodeUseClosureFlag) {
1799
0
      fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->declaration->index);
1800
0
      node->declaration->flags |= flags;
1801
0
    }
1802
0
    node = node->nextDeclareNode;
1803
0
  }
1804
0
  if ((self->node->flags & mxArrowFlag) && ((self->node->flags & mxDefaultFlag) || (self->flags & mxEvalFlag)))
1805
0
    fxCoderAddByte(coder, 0, XS_CODE_STORE_ARROW);
1806
0
  if (self->flags & mxEvalFlag)
1807
0
    fxScopeCodeStoreAll(self->scope, coder);
1808
0
}
1809
1810
void fxScopeCodeStoreAll(txScope* self, txCoder* coder) 
1811
0
{
1812
0
  txScope* scope = self;
1813
0
  while (scope) {
1814
0
    txDeclareNode* node;
1815
0
    if (scope->token == XS_TOKEN_WITH)
1816
0
      break;
1817
0
    node = scope->firstDeclareNode;
1818
0
    while (node) {
1819
0
      if (node->flags & mxEvalFlag)
1820
0
        node->flags &= ~mxEvalFlag;
1821
0
      else if ((!(node->flags & mxDeclareNodeUseClosureFlag)) && node->declaration)
1822
0
        fxCoderAddIndex(coder, 0, XS_CODE_STORE_1, node->declaration->index);
1823
0
      node = node->nextDeclareNode;
1824
0
    }
1825
0
    if ((scope->token == XS_TOKEN_FUNCTION) || (scope->token == XS_TOKEN_MODULE))
1826
0
      break;
1827
0
    scope = scope->scope;
1828
0
  }
1829
0
}
1830
1831
void fxScopeCodeUsed(txScope* self, txCoder* coder, txUsingContext* context) 
1832
0
{
1833
0
  txTargetCode* normalTarget = fxCoderCreateTarget(coder);
1834
0
  txTargetCode* uncatchTarget = fxCoderCreateTarget(coder);
1835
0
  txTargetCode* finallyTarget = fxCoderCreateTarget(coder);
1836
0
  txTargetCode* elseTarget = fxCoderCreateTarget(coder);
1837
0
  txInteger selection;
1838
  
1839
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, normalTarget);
1840
0
  fxCoderAdd(coder, 0, context->catchTarget);
1841
0
  fxCoderAddByte(coder, 1, XS_CODE_EXCEPTION);
1842
0
  fxCoderAddIndex(coder, 0, XS_CODE_PULL_LOCAL_1, context->exception);
1843
0
  fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, 0);
1844
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, context->selector);
1845
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, finallyTarget);
1846
0
  selection = 1;
1847
0
  coder->firstBreakTarget = fxCoderFinalizeTargets(coder, coder->firstBreakTarget, context->selector, &selection, uncatchTarget);
1848
0
  coder->firstContinueTarget = fxCoderFinalizeTargets(coder, coder->firstContinueTarget, context->selector, &selection, uncatchTarget);
1849
0
  coder->returnTarget = fxCoderFinalizeTargets(coder, coder->returnTarget, context->selector, &selection, uncatchTarget);
1850
0
  fxCoderAdd(coder, 0, normalTarget);
1851
0
  fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, selection);
1852
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, context->selector);
1853
0
  fxCoderAdd(coder, 0, uncatchTarget);
1854
0
  fxCoderAddByte(coder, 0, XS_CODE_UNCATCH);
1855
0
  fxCoderAdd(coder, 0, finallyTarget);
1856
  
1857
0
  fxScopeCodeUsedReverse(self, coder, self->firstDeclareNode, context->exception, context->selector);
1858
  
1859
0
  fxCoderAddIndex(coder, 1, XS_CODE_GET_LOCAL_1, context->selector);
1860
0
  fxCoderAddBranch(coder, -1, XS_CODE_BRANCH_IF_1, elseTarget);
1861
0
  fxCoderAddIndex(coder, 1, XS_CODE_GET_LOCAL_1, context->exception);
1862
0
  fxCoderAddByte(coder, -1, XS_CODE_THROW);
1863
0
  fxCoderAdd(coder, 0, elseTarget);
1864
0
  selection = 1;
1865
0
  fxCoderJumpTargets(coder, coder->firstBreakTarget, context->selector, &selection);
1866
0
  fxCoderJumpTargets(coder, coder->firstContinueTarget, context->selector, &selection);
1867
0
  fxCoderJumpTargets(coder, coder->returnTarget, context->selector, &selection);
1868
0
  fxCoderUnuseTemporaryVariables(coder, 2);
1869
0
}
1870
1871
void fxScopeCodeUsedReverse(txScope* self, txCoder* coder, txDeclareNode* node, txInteger exception, txInteger selector) 
1872
0
{
1873
0
  if (node) {
1874
0
    fxCheckParserStack(coder->parser, node->line);
1875
0
    fxScopeCodeUsedReverse(self, coder, node->nextDeclareNode, exception, selector);
1876
0
    if (node->description->token == XS_TOKEN_USING) {
1877
0
      txTargetCode* catchTarget = fxCoderCreateTarget(coder);
1878
0
      txTargetCode* chainTarget = fxCoderCreateTarget(coder);
1879
0
      txTargetCode* normalTarget = fxCoderCreateTarget(coder);
1880
      
1881
0
      fxCoderAddIndex(coder, 1, XS_CODE_GET_LOCAL_1, node->index + 1);
1882
0
      fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
1883
0
      fxCoderAddByte(coder, -1, XS_CODE_STRICT_EQUAL);
1884
0
      fxCoderAddBranch(coder, -1, XS_CODE_BRANCH_IF_1, normalTarget);
1885
      
1886
0
      fxCoderAddBranch(coder, 0, XS_CODE_CATCH_1, catchTarget);
1887
      
1888
0
      fxCoderAddIndex(coder, 1, (node->flags & mxDeclareNodeClosureFlag) ? XS_CODE_GET_CLOSURE_1: XS_CODE_GET_LOCAL_1, node->index);
1889
0
      fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_CHAIN_1, chainTarget);
1890
0
      fxCoderAddIndex(coder, 1, XS_CODE_GET_LOCAL_1, node->index + 1);
1891
0
      fxCoderAddByte(coder, 1, XS_CODE_CALL);
1892
0
      fxCoderAddInteger(coder, -2, XS_CODE_RUN_1, 0);
1893
      
1894
0
      fxCoderAdd(coder, 0, chainTarget);
1895
0
      if (node->flags & mxAwaitingFlag) {
1896
0
        fxCoderAddByte(coder, 0, XS_CODE_AWAIT);
1897
0
        fxCoderAddByte(coder, 0, XS_CODE_THROW_STATUS);
1898
0
      }
1899
0
      fxCoderAddByte(coder, -1, XS_CODE_POP);
1900
      
1901
0
      fxCoderAddByte(coder, 0, XS_CODE_UNCATCH);
1902
0
      fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, normalTarget);
1903
0
      fxCoderAdd(coder, 0, catchTarget);
1904
0
      fxCoderAddIndex(coder, 1, XS_CODE_USED_1, selector);
1905
      
1906
0
      fxCoderAdd(coder, 0, normalTarget);
1907
0
    }
1908
0
  }
1909
0
}
1910
1911
void fxScopeCodeUsing(txScope* self, txCoder* coder, txUsingContext* context) 
1912
0
{
1913
0
  context->exception = fxCoderUseTemporaryVariable(coder);
1914
0
  context->selector = fxCoderUseTemporaryVariable(coder);
1915
0
  coder->firstBreakTarget = fxCoderAliasTargets(coder, coder->firstBreakTarget);
1916
0
  coder->firstContinueTarget = fxCoderAliasTargets(coder, coder->firstContinueTarget);
1917
0
  coder->returnTarget = fxCoderAliasTargets(coder, coder->returnTarget);
1918
0
  context->catchTarget = fxCoderCreateTarget(coder);
1919
0
  fxCoderAddBranch(coder, 0, XS_CODE_CATCH_1, context->catchTarget);
1920
0
}
1921
1922
void fxScopeCodeUsingStatement(txScope* self, txCoder* coder, txNode* statement) 
1923
0
{
1924
0
  if (self->disposableNodeCount) {
1925
0
    txUsingContext context;
1926
0
    fxScopeCodeUsing(self, coder, &context);
1927
0
    fxNodeDispatchCode(statement, coder);
1928
0
    fxScopeCodeUsed(self, coder, &context);
1929
0
  }
1930
0
  else
1931
0
    fxNodeDispatchCode(statement, coder);
1932
0
}
1933
1934
void fxNodeDispatchCode(void* it, void* param)
1935
0
{
1936
0
  txNode* self = it;
1937
0
  txCoder* coder = param;
1938
0
  fxCheckParserStack(coder->parser, self->line);
1939
0
  if (self->line >= 0)
1940
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, self); 
1941
0
  (*self->description->dispatch->code)(it, param);
1942
0
}
1943
1944
void fxNodeDispatchCodeAssign(void* it, void* param, txFlag flag)
1945
0
{
1946
0
  txNode* self = it;
1947
0
  txCoder* coder = param;
1948
0
  fxCheckParserStack(coder->parser, self->line);
1949
0
  if (self->line >= 0)
1950
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, self); 
1951
0
  (*self->description->dispatch->codeAssign)(self, param, flag);
1952
0
}
1953
1954
void fxNodeDispatchCodeDelete(void* it, void* param)
1955
0
{
1956
0
  txNode* self = it;
1957
0
  txCoder* coder = param;
1958
0
  fxCheckParserStack(coder->parser, self->line);
1959
0
  if (self->line >= 0)
1960
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, self); 
1961
0
  (*self->description->dispatch->codeDelete)(self, param);
1962
0
}
1963
1964
void fxNodeDispatchCodeReference(void* it, void* param, txFlag flag)
1965
0
{
1966
0
  txNode* self = it;
1967
0
  txCoder* coder = param;
1968
0
  fxCheckParserStack(coder->parser, self->line);
1969
0
  if (self->line >= 0)
1970
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, self); 
1971
0
  (*self->description->dispatch->codeReference)(self, param, flag);
1972
0
}
1973
1974
txFlag fxNodeDispatchCodeThis(void* it, void* param, txFlag flag) 
1975
0
{
1976
0
  txNode* self = it;
1977
0
  txCoder* coder = param;
1978
0
  fxCheckParserStack(coder->parser, self->line);
1979
0
  if (self->line >= 0)
1980
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, self); 
1981
0
  return (*self->description->dispatch->codeThis)(self, param, flag);
1982
0
}
1983
1984
void fxNodeCode(void* it, void* param) 
1985
0
{
1986
0
  txNode* self = it;
1987
0
  txCoder* coder = param;
1988
0
  fxReportParserError(coder->parser, self->line, "no value");
1989
0
  fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
1990
0
}
1991
1992
void fxNodeCodeAssign(void* it, void* param, txFlag flag) 
1993
0
{
1994
0
  txNode* self = it;
1995
0
  txCoder* coder = param;
1996
0
  fxReportParserError(coder->parser, self->line, "no reference");
1997
0
}
1998
1999
void fxNodeCodeDelete(void* it, void* param) 
2000
0
{
2001
0
  fxNodeDispatchCode(it, param);
2002
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2003
0
  fxCoderAddByte(param, 1, XS_CODE_TRUE);
2004
0
}
2005
2006
void fxNodeCodeReference(void* it, void* param, txFlag flag) 
2007
0
{
2008
0
}
2009
2010
txFlag fxNodeCodeName(txNode* value)
2011
0
{
2012
0
  txToken token = value->description->token;
2013
0
  if (token == XS_TOKEN_EXPRESSIONS) {
2014
0
    value = ((txExpressionsNode*)value)->items->first;
2015
0
    if (value->next)
2016
0
      return 0;
2017
0
    token = value->description->token;
2018
0
  }
2019
0
  if (token == XS_TOKEN_CLASS) {
2020
0
    txClassNode* node = (txClassNode*)value;
2021
0
    if (node->symbol)
2022
0
      return 0;
2023
0
  }
2024
0
  else if ((token == XS_TOKEN_FUNCTION) || (token == XS_TOKEN_GENERATOR) || (token == XS_TOKEN_HOST)) {
2025
0
    txFunctionNode* node = (txFunctionNode*)value;
2026
0
    if (node->symbol)
2027
0
      return 0;
2028
0
  }
2029
0
  else
2030
0
    return 0;
2031
0
  return 1;
2032
0
}
2033
2034
txFlag fxNodeCodeThis(void* it, void* param, txFlag flag) 
2035
0
{
2036
0
  fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2037
0
  fxNodeDispatchCode(it, param);
2038
0
  return 1;
2039
0
}
2040
2041
void fxAccessNodeCode(void* it, void* param) 
2042
0
{
2043
0
  txAccessNode* self = it;
2044
0
  txDeclareNode* declaration = self->declaration;
2045
0
  if (!declaration) {
2046
0
    fxAccessNodeCodeReference(it, param, 0);
2047
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_VARIABLE, self->symbol);
2048
0
  }
2049
0
  else
2050
0
    fxCoderAddIndex(param, 1, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_GET_CLOSURE_1 : XS_CODE_GET_LOCAL_1, declaration->index);
2051
0
}
2052
2053
void fxAccessNodeCodeAssign(void* it, void* param, txFlag flag) 
2054
0
{
2055
0
  txAccessNode* self = it;
2056
0
  txDeclareNode* declaration = self->declaration;
2057
0
  if (!declaration)
2058
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_VARIABLE, self->symbol);
2059
0
  else
2060
0
    fxCoderAddIndex(param, 0, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_SET_CLOSURE_1 : XS_CODE_SET_LOCAL_1, declaration->index);
2061
0
}
2062
2063
void fxAccessNodeCodeDelete(void* it, void* param) 
2064
0
{
2065
0
  txAccessNode* self = it;
2066
0
  txCoder* coder = param;
2067
0
  txDeclareNode* declaration = self->declaration;
2068
0
  if (self->flags & mxStrictFlag)
2069
0
    fxReportParserError(coder->parser, self->line, "delete identifier (strict code)");
2070
0
  if (!declaration) {
2071
0
    fxAccessNodeCodeReference(it, param, 0);
2072
0
    fxCoderAddSymbol(param, 0, XS_CODE_DELETE_PROPERTY, self->symbol);
2073
0
  }
2074
0
  else
2075
0
    fxCoderAddByte(param, 1, XS_CODE_FALSE);
2076
0
}
2077
2078
void fxAccessNodeCodeReference(void* it, void* param, txFlag flag) 
2079
0
{
2080
0
  txAccessNode* self = it;
2081
0
  txCoder* coder = param;
2082
0
  txDeclareNode* declaration = self->declaration;
2083
0
  if (!declaration) {
2084
0
    if (coder->evalFlag)
2085
0
      fxCoderAddSymbol(param, 1, XS_CODE_EVAL_REFERENCE, self->symbol);
2086
0
    else
2087
0
      fxCoderAddSymbol(param, 1, XS_CODE_PROGRAM_REFERENCE, self->symbol);
2088
0
  }
2089
0
}
2090
2091
txFlag fxAccessNodeCodeThis(void* it, void* param, txFlag flag) 
2092
0
{
2093
0
  txAccessNode* self = it;
2094
0
  txDeclareNode* declaration = self->declaration;
2095
0
  if (!flag)
2096
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2097
0
  if (!declaration) {
2098
0
    fxAccessNodeCodeReference(it, param, 0);
2099
0
    if (flag)
2100
0
      fxCoderAddByte(param, 1, XS_CODE_DUB);
2101
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_THIS_VARIABLE, self->symbol);
2102
0
  }
2103
0
  else {
2104
0
    fxCoderAddIndex(param, 1, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_GET_CLOSURE_1 : XS_CODE_GET_LOCAL_1, declaration->index);
2105
0
    flag = 0;
2106
0
  }
2107
0
  return flag;
2108
0
}
2109
2110
void fxAndExpressionNodeCode(void* it, void* param) 
2111
0
{
2112
0
  txBinaryExpressionNode* self = it;
2113
0
  txTargetCode* endTarget = fxCoderCreateTarget(param);
2114
0
  self->right->flags |= (self->flags & mxTailRecursionFlag);
2115
0
  fxNodeDispatchCode(self->left, param);
2116
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
2117
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, endTarget);
2118
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2119
0
  fxNodeDispatchCode(self->right, param);
2120
0
  fxCoderAdd(param, 0, endTarget);
2121
0
}
2122
2123
void fxArgumentsNodeCode(void* it, void* param) 
2124
0
{
2125
0
  fxCoderAddIndex(param, 1, XS_CODE_ARGUMENTS, 0);
2126
0
}
2127
2128
void fxArrayNodeCode(void* it, void* param) 
2129
0
{
2130
0
  txArrayNode* self = it;
2131
0
  txCoder* coder = param;
2132
0
  txInteger array = fxCoderUseTemporaryVariable(param);
2133
0
  fxCoderAddByte(param, 1, XS_CODE_ARRAY);
2134
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, array);
2135
0
  if (self->items) {
2136
0
    txNode* item = self->items->first;
2137
0
    if (self->flags & mxSpreadFlag) {
2138
0
      txInteger counter = fxCoderUseTemporaryVariable(param);
2139
0
      fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 0);
2140
0
      fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, counter);
2141
0
      while (item) {
2142
0
        if (item->description->token == XS_TOKEN_SPREAD) {
2143
0
          txInteger iterator = fxCoderUseTemporaryVariable(param);
2144
0
          txInteger result = fxCoderUseTemporaryVariable(param);
2145
0
          txTargetCode* nextTarget = fxCoderCreateTarget(param);
2146
0
          txTargetCode* doneTarget = fxCoderCreateTarget(param);
2147
0
          fxNodeDispatchCode(((txSpreadNode*)item)->expression, param);
2148
0
          fxCoderAddByte(param, 0, XS_CODE_FOR_OF);
2149
0
          fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, iterator);
2150
0
          fxCoderAddByte(param, -1, XS_CODE_POP);
2151
0
          fxCoderAdd(param, 0, nextTarget);
2152
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2153
0
          fxCoderAddByte(param, 1, XS_CODE_DUB);
2154
0
          fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->nextSymbol);
2155
0
          fxCoderAddByte(param, 1, XS_CODE_CALL);
2156
0
          fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2157
0
          fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2158
0
          fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
2159
0
          fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
2160
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2161
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
2162
0
          fxCoderAddByte(param, 0, XS_CODE_AT);
2163
0
          fxCoderAddIndex(param, 0, XS_CODE_GET_LOCAL_1, result);
2164
0
          fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
2165
0
          fxCoderAddByte(param, -2, XS_CODE_SET_PROPERTY_AT);
2166
0
          fxCoderAddByte(param, -1, XS_CODE_POP);
2167
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
2168
0
          fxCoderAddByte(param, 0, XS_CODE_INCREMENT);
2169
0
          fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, counter);
2170
0
          fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
2171
0
          fxCoderAdd(param, 1, doneTarget);
2172
0
          fxCoderUnuseTemporaryVariables(param, 2);
2173
0
        }
2174
0
        else {
2175
0
          if (item->description->token != XS_TOKEN_ELISION) {
2176
0
            fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2177
0
            fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
2178
0
            fxCoderAddByte(param, 0, XS_CODE_AT);
2179
0
            fxNodeDispatchCode(item, param);
2180
0
            fxCoderAddByte(param, -2, XS_CODE_SET_PROPERTY_AT);
2181
0
            fxCoderAddByte(param, -1, XS_CODE_POP);
2182
0
            fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
2183
0
            fxCoderAddByte(param, 0, XS_CODE_INCREMENT);
2184
0
            fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, counter);
2185
0
          }
2186
0
          else {
2187
0
            fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2188
0
            fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
2189
0
            fxCoderAddByte(param, 0, XS_CODE_INCREMENT);
2190
0
            fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, counter);
2191
0
            fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, coder->parser->lengthSymbol);
2192
0
            fxCoderAddByte(param, -1, XS_CODE_POP);
2193
0
          }
2194
0
        }
2195
0
        item = item->next;
2196
0
      }
2197
0
      fxCoderUnuseTemporaryVariables(param, 1);
2198
0
    }
2199
0
    else {
2200
0
      txInteger index = 0;
2201
0
      txInteger count = self->items->length;
2202
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2203
0
      fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, count);
2204
0
      fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, coder->parser->lengthSymbol);
2205
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
2206
0
      while (item) {
2207
0
        if (item->description->token == XS_TOKEN_ELISION)
2208
0
          break;
2209
0
        item = item->next;
2210
0
      }
2211
//      if (!item) {
2212
//        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2213
//        fxCoderAddByte(param, 1, XS_CODE_DUB);
2214
//        fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->fillSymbol);
2215
//        fxCoderAddByte(param, 1, XS_CODE_CALL);
2216
//        fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2217
//        fxCoderAddByte(param, -1, XS_CODE_POP);
2218
//      }
2219
0
      item = self->items->first;
2220
0
      while (item) {
2221
0
        if (item->description->token != XS_TOKEN_ELISION) {
2222
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, array);
2223
0
          fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, index);
2224
0
          fxCoderAddByte(param, 0, XS_CODE_AT);
2225
0
          fxNodeDispatchCode(item, param);
2226
0
          fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
2227
0
          fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, 0);
2228
0
        }
2229
0
        item = item->next;
2230
0
        index++;
2231
0
      }
2232
0
    }
2233
0
  }
2234
0
  fxCoderUnuseTemporaryVariables(param, 1);
2235
0
}
2236
2237
void fxArrayBindingNodeCode(void* it, void* param)
2238
0
{
2239
0
  txArrayBindingNode* self = it;
2240
0
  txCoder* coder = param;
2241
0
  fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
2242
0
  fxArrayBindingNodeCodeAssign(self, param, 0);
2243
0
}
2244
2245
void fxArrayBindingNodeCodeAssign(void* it, void* param, txFlag flag) 
2246
0
{
2247
0
  txArrayBindingNode* self = it;
2248
0
  txCoder* coder = param;
2249
0
  txNode* item = self->items->first;
2250
0
  txInteger iterator;
2251
0
  txInteger next;
2252
0
  txInteger done;
2253
0
  txInteger rest;
2254
0
  txInteger result;
2255
0
  txInteger selector;
2256
0
  txInteger selection;
2257
0
  txTargetCode* catchTarget;
2258
0
  txTargetCode* normalTarget;
2259
0
  txTargetCode* finallyTarget;
2260
  
2261
0
  txTargetCode* returnTarget;
2262
0
  txTargetCode* stepTarget;
2263
0
  txTargetCode* doneTarget;
2264
0
  txTargetCode* nextTarget;
2265
  
2266
0
  iterator = fxCoderUseTemporaryVariable(param);
2267
0
  next = fxCoderUseTemporaryVariable(param);
2268
0
  done = fxCoderUseTemporaryVariable(param);
2269
0
  selector = fxCoderUseTemporaryVariable(param);
2270
0
  rest = fxCoderUseTemporaryVariable(param);
2271
0
  result = fxCoderUseTemporaryVariable(param);
2272
  
2273
0
  coder->returnTarget = fxCoderAliasTargets(param, coder->returnTarget);
2274
0
  catchTarget = fxCoderCreateTarget(param);
2275
0
  normalTarget = fxCoderCreateTarget(param);
2276
0
  finallyTarget = fxCoderCreateTarget(param);
2277
  
2278
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
2279
0
  fxCoderAddByte(param, 0, XS_CODE_FOR_OF);
2280
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, iterator);
2281
0
  fxCoderAddByte(param, 1, XS_CODE_FALSE);
2282
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
2283
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 0);
2284
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, selector);
2285
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
2286
  
2287
0
  if (item) {
2288
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2289
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->nextSymbol);
2290
0
    fxCoderAddIndex(param, 0, XS_CODE_PULL_LOCAL_1, next);
2291
  
2292
0
    while (item && (item->description->token != XS_TOKEN_REST_BINDING)) {
2293
0
      stepTarget = fxCoderCreateTarget(param);
2294
      
2295
0
      if (item->description->token == XS_TOKEN_SKIP_BINDING) {
2296
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, done);
2297
0
        fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, stepTarget);
2298
0
        fxCoderAddByte(param, 1, XS_CODE_TRUE);
2299
0
        fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
2300
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2301
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, next);
2302
0
        fxCoderAddByte(param, 1, XS_CODE_CALL);
2303
0
        fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2304
0
        fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2305
0
        fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
2306
0
        fxCoderAddIndex(param, 0, XS_CODE_PULL_LOCAL_1, done);
2307
0
        fxCoderAdd(param, 1, stepTarget);
2308
0
      }
2309
0
      else {
2310
0
        doneTarget = fxCoderCreateTarget(param);
2311
0
        nextTarget = fxCoderCreateTarget(param);
2312
0
        fxNodeDispatchCodeReference(item, param, 1);
2313
        
2314
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, done);
2315
0
        fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, stepTarget);
2316
0
        fxCoderAddByte(param, 1, XS_CODE_TRUE);
2317
0
        fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
2318
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2319
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, next);
2320
0
        fxCoderAddByte(param, 1, XS_CODE_CALL);
2321
0
        fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2322
0
        fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2323
0
        fxCoderAddByte(param, 1, XS_CODE_DUB);
2324
0
        fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
2325
0
        fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, done);
2326
0
        fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
2327
0
        fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
2328
0
        fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
2329
0
        fxCoderAdd(param, 1, doneTarget);
2330
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
2331
0
        fxCoderAdd(param, 1, stepTarget);
2332
0
        fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2333
0
        fxCoderAdd(param, 1, nextTarget);
2334
0
        fxNodeDispatchCodeAssign(item, param, 1);
2335
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
2336
0
      }
2337
0
      item = item->next;
2338
0
    }
2339
0
    if (item) {
2340
0
      nextTarget = fxCoderCreateTarget(param);
2341
0
      doneTarget = fxCoderCreateTarget(param);
2342
    
2343
0
      fxNodeDispatchCodeReference(((txRestBindingNode*)item)->binding, param, 1);
2344
0
      fxCoderAddByte(param, 1, XS_CODE_ARRAY);
2345
0
      fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, rest);
2346
      
2347
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, done);
2348
0
      fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
2349
2350
0
      fxCoderAdd(param, 0, nextTarget);
2351
0
      fxCoderAddByte(param, 1, XS_CODE_TRUE);
2352
0
      fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
2353
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2354
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, next);
2355
0
      fxCoderAddByte(param, 1, XS_CODE_CALL);
2356
0
      fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2357
0
      fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2358
0
      fxCoderAddIndex(param, 1, XS_CODE_SET_LOCAL_1, result);
2359
0
      fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
2360
0
      fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, done);
2361
      
2362
0
      fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
2363
    
2364
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, rest);
2365
0
      fxCoderAddByte(param, 1, XS_CODE_DUB);
2366
0
      fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->lengthSymbol);
2367
0
      fxCoderAddByte(param, 0, XS_CODE_AT);
2368
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
2369
0
      fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
2370
0
      fxCoderAddByte(param, -2, XS_CODE_SET_PROPERTY_AT);
2371
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
2372
  
2373
0
      fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
2374
0
      fxCoderAdd(param, 1, doneTarget);
2375
    
2376
0
      fxCoderAddIndex(param, 0, XS_CODE_GET_LOCAL_1, rest);
2377
0
      fxNodeDispatchCodeAssign(((txRestBindingNode*)item)->binding, param, 1);
2378
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
2379
0
    }
2380
  
2381
0
  }
2382
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, normalTarget);
2383
  
2384
0
  selection = 1;
2385
0
  coder->returnTarget = fxCoderFinalizeTargets(param, coder->returnTarget, selector, &selection, finallyTarget);
2386
0
  fxCoderAdd(param, 0, normalTarget);
2387
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, selection);
2388
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, selector);
2389
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2390
0
  fxCoderAdd(param, 0, finallyTarget);
2391
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
2392
0
  fxCoderAdd(param, 0, catchTarget);
2393
  
2394
0
  nextTarget = fxCoderCreateTarget(param);
2395
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, selector);
2396
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, nextTarget);
2397
0
  fxCoderAddByte(param, 1, XS_CODE_EXCEPTION);
2398
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2399
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2400
0
  catchTarget = fxCoderCreateTarget(param);
2401
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
2402
0
  fxCoderAdd(param, 0, nextTarget);
2403
  
2404
0
  doneTarget = fxCoderCreateTarget(param);
2405
0
  returnTarget = fxCoderCreateTarget(param);
2406
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, done);
2407
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
2408
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2409
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->returnSymbol);
2410
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_CHAIN_1, returnTarget);
2411
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2412
0
  fxCoderAddByte(param, 0, XS_CODE_SWAP);
2413
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
2414
0
  fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2415
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2416
0
  fxCoderAdd(param, 0, returnTarget);
2417
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2418
0
  fxCoderAdd(param, 0, doneTarget);
2419
  
2420
0
  nextTarget = fxCoderCreateTarget(param);
2421
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, selector);
2422
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, nextTarget);
2423
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
2424
0
  fxCoderAdd(param, 0, catchTarget);
2425
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
2426
0
  fxCoderAddByte(param, -1, XS_CODE_THROW);
2427
0
  fxCoderAdd(param, 0, nextTarget);
2428
2429
0
  selection = 1;
2430
0
  fxCoderJumpTargets(param, coder->returnTarget, selector, &selection);
2431
2432
0
  fxCoderUnuseTemporaryVariables(param, 6);
2433
0
}
2434
2435
void fxAssignNodeCode(void* it, void* param) 
2436
0
{
2437
0
  txAssignNode* self = it;
2438
0
  fxNodeDispatchCodeReference(self->reference, param, 1);
2439
0
  fxNodeDispatchCode(self->value, param);
2440
0
  fxNodeDispatchCodeAssign(self->reference, param, 1);
2441
0
}
2442
2443
void fxAwaitNodeCode(void* it, void* param)
2444
0
{
2445
0
  txStatementNode* self = it;
2446
0
  txCoder* coder = param;
2447
0
  txTargetCode* target = fxCoderCreateTarget(coder);
2448
0
  fxNodeDispatchCode(self->expression, param);
2449
0
  fxCoderAddByte(param, 0, XS_CODE_AWAIT);
2450
0
  fxCoderAddBranch(coder, 1, XS_CODE_BRANCH_STATUS_1, target);
2451
0
  fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
2452
0
  fxCoderAdjustEnvironment(coder, coder->returnTarget);
2453
0
  fxCoderAdjustScope(coder, coder->returnTarget);
2454
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, coder->returnTarget);
2455
0
  fxCoderAdd(coder, 0, target);
2456
0
}
2457
2458
void fxBigIntNodeCode(void* it, void* param) 
2459
0
{
2460
0
  txBigIntNode* self = it;
2461
0
  fxCoderAddBigInt(param, 1, XS_CODE_BIGINT_1, &self->value);
2462
0
}
2463
2464
void fxBinaryExpressionNodeCode(void* it, void* param) 
2465
0
{
2466
0
  txBinaryExpressionNode* self = it;
2467
0
  fxNodeDispatchCode(self->left, param);
2468
0
  fxNodeDispatchCode(self->right, param);
2469
0
  fxCoderAddByte(param, -1, self->description->code);
2470
0
}
2471
2472
void fxBindingNodeCode(void* it, void* param) 
2473
0
{
2474
0
  txBindingNode* self = it;
2475
0
  txCoder* coder = param;
2476
  
2477
0
  if (self->target->description->token == XS_TOKEN_ACCESS) {
2478
0
    fxReportParserError(coder->parser, self->line, "invalid initializer");
2479
0
    fxNodeDispatchCode(self->initializer, param);
2480
0
    return;
2481
0
  }
2482
  
2483
0
  fxNodeDispatchCodeReference(self->target, param, 0);
2484
0
  fxNodeDispatchCode(self->initializer, param);
2485
0
  fxNodeDispatchCodeAssign(self->target, param, 0);
2486
0
  fxCoderAddByte(coder, -1, XS_CODE_POP);
2487
0
}
2488
2489
void fxBindingNodeCodeAssign(void* it, void* param, txFlag flag) 
2490
0
{
2491
0
  txBindingNode* self = it;
2492
0
  txTargetCode* target = fxCoderCreateTarget(param);
2493
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
2494
0
  fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2495
0
  fxCoderAddByte(param, -1, XS_CODE_STRICT_NOT_EQUAL);
2496
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, target);
2497
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2498
0
  fxNodeDispatchCode(self->initializer, param);
2499
0
  fxCoderAdd(param, 0, target);
2500
0
  fxNodeDispatchCodeAssign(self->target, param, flag);
2501
0
}
2502
2503
void fxBindingNodeCodeReference(void* it, void* param, txFlag flag) 
2504
0
{
2505
0
  txBindingNode* self = it;
2506
0
  fxNodeDispatchCodeReference(self->target, param, flag);
2507
0
}
2508
2509
void fxBlockNodeCode(void* it, void* param) 
2510
0
{
2511
0
  txBlockNode* self = it;
2512
0
  fxScopeCodingBlock(self->scope, param);
2513
0
  fxScopeCodeDefineNodes(self->scope, param);
2514
0
  fxScopeCodeUsingStatement(self->scope, param, self->statement);
2515
0
  fxScopeCoded(self->scope, param);
2516
0
}
2517
2518
void fxBodyNodeCode(void* it, void* param) 
2519
0
{
2520
0
  txBlockNode* self = it;
2521
0
  txCoder* coder = param;
2522
0
  txBoolean evalFlag = coder->evalFlag;
2523
0
  if ((self->flags & mxEvalFlag) && !(self->flags & mxStrictFlag))
2524
0
    coder->evalFlag = 1;
2525
0
  fxScopeCodingBody(self->scope, param);
2526
0
  fxScopeCodeDefineNodes(self->scope, param);
2527
0
  fxScopeCodeUsingStatement(self->scope, param, self->statement);
2528
0
  fxScopeCodedBody(self->scope, param);
2529
0
  if ((self->flags & mxEvalFlag) && !(self->flags & mxStrictFlag))
2530
0
    coder->evalFlag = evalFlag;
2531
0
}
2532
2533
void fxBreakContinueNodeCode(void* it, void* param) 
2534
0
{
2535
0
  txBreakContinueNode* self = it;
2536
0
  txCoder* coder = param;
2537
0
  txTargetCode* target = (self->description->token == XS_TOKEN_BREAK) ? coder->firstBreakTarget : coder->firstContinueTarget;
2538
0
  while (target) {
2539
0
    txLabelNode* label = target->label;
2540
0
    while (label) {
2541
0
      if (label->symbol == self->symbol) {
2542
0
        fxCoderAdjustEnvironment(coder, target);
2543
0
        fxCoderAdjustScope(coder, target);
2544
0
        fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, target);
2545
0
        return;
2546
0
      }
2547
0
      label = label->nextLabel;
2548
0
    }
2549
0
    target = target->nextTarget;
2550
0
  }
2551
0
  if (self->description->token == XS_TOKEN_BREAK)
2552
0
    fxReportParserError(coder->parser, self->line, "invalid break");
2553
0
  else
2554
0
    fxReportParserError(coder->parser, self->line, "invalid continue");
2555
0
}
2556
2557
void fxCallNodeCode(void* it, void* param) 
2558
0
{
2559
0
  txCallNewNode* self = it;
2560
0
  fxNodeDispatchCodeThis(self->reference, param, 0);
2561
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
2562
0
  self->params->flags |= self->flags & mxTailRecursionFlag;
2563
0
  fxNodeDispatchCode(self->params, param);
2564
0
}
2565
2566
void fxCatchNodeCode(void* it, void* param) 
2567
0
{
2568
0
  txCatchNode* self = it;
2569
0
  if (self->parameter) {
2570
0
    fxScopeCodingBlock(self->scope, param);
2571
0
    fxNodeDispatchCodeReference(self->parameter, param, 0);
2572
0
    fxCoderAddByte(param, 1, XS_CODE_EXCEPTION);
2573
0
    fxNodeDispatchCodeAssign(self->parameter, param, 0);
2574
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2575
0
    fxScopeCodingBlock(self->statementScope, param);
2576
0
    fxScopeCodeDefineNodes(self->statementScope, param);
2577
0
    fxScopeCodeUsingStatement(self->statementScope, param, self->statement);
2578
0
    fxScopeCoded(self->statementScope, param);
2579
0
    fxScopeCoded(self->scope, param);
2580
0
  }
2581
0
  else {
2582
0
    fxScopeCodingBlock(self->statementScope, param);
2583
0
    fxScopeCodeDefineNodes(self->statementScope, param);
2584
0
    fxScopeCodeUsingStatement(self->statementScope, param, self->statement);
2585
0
    fxScopeCoded(self->statementScope, param);
2586
0
  }
2587
0
}
2588
2589
void fxChainNodeCode(void* it, void* param)
2590
0
{
2591
0
  txUnaryExpressionNode* self = it;
2592
0
  txCoder* coder = param;
2593
0
  txTargetCode* chainTarget = coder->chainTarget;
2594
0
  coder->chainTarget = fxCoderCreateTarget(param);
2595
0
  fxNodeDispatchCode(self->right, param);
2596
0
  fxCoderAdd(param, 0, coder->chainTarget);
2597
0
  coder->chainTarget = chainTarget;
2598
0
}
2599
2600
txFlag fxChainNodeCodeThis(void* it, void* param, txFlag flag)
2601
0
{
2602
0
  txUnaryExpressionNode* self = it;
2603
0
  txCoder* coder = param;
2604
0
  txTargetCode* chainTarget = coder->chainTarget;
2605
0
  coder->chainTarget = fxCoderCreateTarget(param);
2606
0
  flag = fxNodeDispatchCodeThis(self->right, param, flag);
2607
0
    fxCoderAdd(param, 0, coder->chainTarget);
2608
0
  coder->chainTarget = chainTarget;
2609
0
  return flag;
2610
0
}
2611
2612
void fxClassNodeCode(void* it, void* param) 
2613
0
{
2614
0
  txClassNode* self = it;
2615
0
  txCoder* coder = param;
2616
0
  txClassNode* former = coder->classNode;
2617
0
  txFlag flag;
2618
0
  txInteger prototype = fxCoderUseTemporaryVariable(coder);
2619
0
  txInteger constructor = fxCoderUseTemporaryVariable(coder);
2620
0
  txDeclareNode* declaration = self->scope->firstDeclareNode;
2621
0
  txNode* item = self->items->first;
2622
0
  if (self->symbol)
2623
0
    fxScopeCodingBlock(self->symbolScope, param);
2624
0
  if (self->heritage) {
2625
0
    if (self->heritage->description->token == XS_TOKEN_HOST) {
2626
0
      fxCoderAddByte(param, 1, XS_CODE_NULL);
2627
0
      fxNodeDispatchCode(self->heritage, param);
2628
0
    }
2629
0
    else {
2630
0
      fxNodeDispatchCode(self->heritage, param);
2631
0
      fxCoderAddByte(param, 1, XS_CODE_EXTEND);
2632
0
    }
2633
0
  }
2634
0
  else {
2635
0
    fxCoderAddByte(param, 1, XS_CODE_NULL);
2636
0
    fxCoderAddByte(param, 1, XS_CODE_OBJECT);
2637
0
  }
2638
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, prototype);
2639
0
  fxScopeCodingBlock(self->scope, param);
2640
  
2641
0
  coder->classNode = self;
2642
0
  fxNodeDispatchCode(self->constructor, param);
2643
  
2644
0
  fxCoderAddByte(param, 0, XS_CODE_TO_INSTANCE);
2645
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, constructor);
2646
0
  fxCoderAddByte(param, -3, XS_CODE_CLASS);
2647
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, constructor);
2648
0
  if (self->symbol)
2649
0
    fxCoderAddSymbol(param, 0, XS_CODE_NAME, self->symbol);
2650
    
2651
0
  while (item) {
2652
0
    if (item->description->token == XS_TOKEN_PROPERTY) {
2653
0
      txPropertyNode* property = (txPropertyNode*)item;
2654
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2655
0
        if (item->flags & mxStaticFlag)
2656
0
          fxCoderAddByte(param, 1, XS_CODE_DUB);
2657
0
        else
2658
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, prototype);
2659
0
        fxNodeDispatchCode(property->value, param);
2660
0
        fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, property->symbol);
2661
0
        flag = XS_DONT_ENUM_FLAG;
2662
0
        if (item->flags & mxMethodFlag)
2663
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG;
2664
0
        else if (item->flags & mxGetterFlag)
2665
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_GETTER_FLAG;
2666
0
        else if (item->flags & mxSetterFlag)
2667
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_SETTER_FLAG;
2668
0
        fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, flag);
2669
0
      }
2670
0
    }
2671
0
    else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
2672
0
      txPropertyAtNode* property = (txPropertyAtNode*)item;
2673
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2674
0
        if (item->flags & mxStaticFlag)
2675
0
          fxCoderAddByte(param, 1, XS_CODE_DUB);
2676
0
        else
2677
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, prototype);
2678
0
        fxNodeDispatchCode(property->at, param);
2679
0
        fxCoderAddByte(param, 0, XS_CODE_AT);
2680
0
        fxNodeDispatchCode(property->value, param);
2681
0
        fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
2682
0
        flag = XS_DONT_ENUM_FLAG;
2683
0
        if (item->flags & mxMethodFlag)
2684
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG;
2685
0
        else if (item->flags & mxGetterFlag)
2686
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_GETTER_FLAG;
2687
0
        else if (item->flags & mxSetterFlag)
2688
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_SETTER_FLAG;
2689
0
        fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, flag);
2690
0
      }
2691
0
      else {
2692
0
        fxNodeDispatchCode(property->at, param);
2693
0
        fxCoderAddByte(param, 0, XS_CODE_AT);
2694
0
        fxCoderAddIndex(param, 0, XS_CODE_CONST_CLOSURE_1, declaration->index);
2695
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
2696
0
        declaration = declaration->nextDeclareNode;
2697
0
      }
2698
0
    }
2699
0
    else  {
2700
0
      txPrivatePropertyNode* property = (txPrivatePropertyNode*)item;
2701
0
      fxCoderAddIndex(param, 0, XS_CODE_CONST_CLOSURE_1, declaration->index);
2702
0
      declaration = declaration->nextDeclareNode;
2703
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2704
0
        fxNodeDispatchCode(property->value, param);
2705
0
        fxCoderAddIndex(param, 0, XS_CODE_CONST_CLOSURE_1, declaration->index);
2706
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
2707
0
        declaration = declaration->nextDeclareNode;
2708
0
      }
2709
0
    }
2710
0
    item = item->next;
2711
0
  }
2712
0
  if (self->symbol)
2713
0
    fxCoderAddIndex(param, 0, XS_CODE_CONST_CLOSURE_1, self->symbolScope->firstDeclareNode->index);
2714
0
  if (self->instanceInit) {
2715
0
    fxNodeDispatchCode(self->instanceInit, param);
2716
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, prototype);
2717
0
    fxCoderAddByte(param, -1, XS_CODE_SET_HOME);
2718
0
    fxCoderAddIndex(param, 0, XS_CODE_CONST_CLOSURE_1, declaration->index);
2719
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2720
0
  }
2721
0
  if (self->constructorInit) {
2722
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, constructor);
2723
0
    fxNodeDispatchCode(self->constructorInit, param);
2724
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, constructor);
2725
0
    fxCoderAddByte(param, -1, XS_CODE_SET_HOME);
2726
0
    fxCoderAddByte(param, 1, XS_CODE_CALL);
2727
0
    fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2728
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2729
0
  }
2730
0
  coder->classNode = former;
2731
0
  fxScopeCoded(self->scope, param);
2732
0
  if (self->symbol)
2733
0
    fxScopeCoded(self->symbolScope, param);
2734
0
  fxCoderUnuseTemporaryVariables(coder, 2);
2735
0
}
2736
2737
void fxCoalesceExpressionNodeCode(void* it, void* param) 
2738
0
{
2739
0
  txBinaryExpressionNode* self = it;
2740
0
  txTargetCode* endTarget = fxCoderCreateTarget(param);
2741
0
  self->right->flags |= (self->flags & mxTailRecursionFlag);
2742
0
  fxNodeDispatchCode(self->left, param);
2743
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_COALESCE_1, endTarget);
2744
0
  fxNodeDispatchCode(self->right, param);
2745
0
  fxCoderAdd(param, 0, endTarget);
2746
0
}
2747
2748
void fxCompoundExpressionNodeCode(void* it, void* param) 
2749
0
{
2750
0
  txAssignNode* self = it;
2751
0
  txCoder* coder = param;
2752
0
  txToken token = self->description->token;
2753
0
  txFlag shortcut = ((token == XS_TOKEN_AND_ASSIGN) || (token == XS_TOKEN_COALESCE_ASSIGN) || (token == XS_TOKEN_OR_ASSIGN)) ? 1 : 0;
2754
0
  txTargetCode* elseTarget = (shortcut) ? fxCoderCreateTarget(param) : C_NULL;
2755
0
  txTargetCode* endTarget = (shortcut) ? fxCoderCreateTarget(param) : C_NULL;
2756
0
  txInteger stackLevel = 0;
2757
0
  txFlag swap = fxNodeDispatchCodeThis(self->reference, param, 1);
2758
0
  switch (self->description->token) {
2759
0
  case XS_TOKEN_AND_ASSIGN:
2760
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
2761
0
    fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, elseTarget);
2762
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2763
0
    fxNodeDispatchCode(self->value, param);
2764
0
    fxCompoundExpressionNodeCodeName(it, param);
2765
0
    stackLevel = coder->stackLevel;
2766
0
    break;
2767
0
  case XS_TOKEN_COALESCE_ASSIGN:
2768
0
    fxCoderAddBranch(param, -1, XS_CODE_BRANCH_COALESCE_1, elseTarget);
2769
0
    fxNodeDispatchCode(self->value, param);
2770
0
    fxCompoundExpressionNodeCodeName(it, param);
2771
0
    stackLevel = coder->stackLevel;
2772
0
    break;
2773
0
  case XS_TOKEN_OR_ASSIGN:
2774
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
2775
0
    fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, elseTarget);
2776
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2777
0
    fxNodeDispatchCode(self->value, param);
2778
0
    fxCompoundExpressionNodeCodeName(it, param);
2779
0
    stackLevel = coder->stackLevel;
2780
0
    break;
2781
0
  default:
2782
0
    fxNodeDispatchCode(self->value, param);
2783
0
    fxCoderAddByte(param, -1, self->description->code);
2784
0
    break;
2785
0
  }
2786
0
  fxNodeDispatchCodeAssign(self->reference, param, 0);
2787
0
  if (shortcut) {
2788
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, endTarget);
2789
0
    coder->stackLevel = stackLevel;
2790
0
    fxCoderAdd(param, 0, elseTarget);
2791
0
    while (swap > 0) {
2792
0
      if (!(self->flags & mxExpressionNoValue))
2793
0
        fxCoderAddByte(param, 0, XS_CODE_SWAP);
2794
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
2795
0
      swap--;
2796
0
    }
2797
0
    fxCoderAdd(param, 0, endTarget);
2798
0
  }
2799
0
}
2800
2801
void fxCompoundExpressionNodeCodeName(void* it, void* param) 
2802
0
{
2803
0
  txAssignNode* self = it;
2804
0
  txAccessNode* reference = (txAccessNode*)(self->reference);
2805
0
  txToken token = reference->description->token;
2806
0
  txNode* value = self->value;
2807
0
  if (token != XS_TOKEN_ACCESS)
2808
0
    return;
2809
0
  if (fxNodeCodeName(value))
2810
0
    fxCoderAddSymbol(param, 0, XS_CODE_NAME, reference->symbol);
2811
0
}
2812
2813
void fxDebuggerNodeCode(void* it, void* param) 
2814
0
{
2815
0
  fxCoderAddByte(param, 0, XS_CODE_DEBUGGER);
2816
0
}
2817
2818
void fxDeclareNodeCode(void* it, void* param) 
2819
0
{
2820
0
  txDeclareNode* self = it;
2821
0
  txCoder* coder = param;
2822
0
  if (self->description->token == XS_TOKEN_CONST)
2823
0
    fxReportParserError(coder->parser, self->line, "invalid const");
2824
0
  else if (self->description->token == XS_TOKEN_LET) {
2825
0
    fxNodeDispatchCodeReference(self, param, 0);
2826
0
    fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
2827
0
    fxNodeDispatchCodeAssign(self, param, 0);
2828
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
2829
0
  }
2830
0
  else if (self->description->token == XS_TOKEN_USING)
2831
0
    fxReportParserError(coder->parser, self->line, "invalid using");
2832
0
}
2833
2834
void fxDeclareNodeCodeAssign(void* it, void* param, txFlag flag) 
2835
0
{
2836
0
  txDeclareNode* self = it;
2837
0
  txDeclareNode* declaration = self->declaration;
2838
0
  if (!declaration)
2839
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_VARIABLE, self->symbol);
2840
0
  else {
2841
0
    if (self->description->token == XS_TOKEN_CONST)
2842
0
      fxCoderAddIndex(param, 0, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_CONST_CLOSURE_1: XS_CODE_CONST_LOCAL_1, declaration->index);
2843
0
    else if (self->description->token == XS_TOKEN_LET)
2844
0
      fxCoderAddIndex(param, 0, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_LET_CLOSURE_1: XS_CODE_LET_LOCAL_1, declaration->index);
2845
0
    else if (self->description->token == XS_TOKEN_USING) {
2846
0
      fxCoderAddIndex(param, 0, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_CONST_CLOSURE_1: XS_CODE_CONST_LOCAL_1, declaration->index);
2847
0
      if (self->flags & mxAwaitingFlag)
2848
0
        fxCoderAddByte(param, 0, XS_CODE_USING_ASYNC);
2849
0
      else
2850
0
        fxCoderAddByte(param, 0, XS_CODE_USING);
2851
0
      fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, declaration->index + 1);
2852
0
    }
2853
0
    else
2854
0
      fxCoderAddIndex(param, 0, (declaration->flags & mxDeclareNodeClosureFlag) ? XS_CODE_VAR_CLOSURE_1 : XS_CODE_VAR_LOCAL_1, declaration->index);
2855
0
  }
2856
0
}
2857
2858
void fxDeclareNodeCodeReference(void* it, void* param, txFlag flag) 
2859
0
{
2860
0
  txAccessNode* self = it;
2861
0
  txCoder* coder = param;
2862
0
  txDeclareNode* declaration = self->declaration;
2863
0
  if (!declaration) {
2864
0
    if (coder->evalFlag)
2865
0
      fxCoderAddSymbol(param, 1, XS_CODE_EVAL_REFERENCE, self->symbol);
2866
0
    else
2867
0
      fxCoderAddSymbol(param, 1, XS_CODE_PROGRAM_REFERENCE, self->symbol);
2868
0
  }
2869
0
}
2870
2871
void fxDefineNodeCode(void* it, void* param) 
2872
0
{
2873
0
  txDefineNode* self = it;
2874
0
  txCoder* coder = param;
2875
0
  if (self->flags & mxDefineNodeCodedFlag)
2876
0
    return;
2877
0
  self->flags |= mxDefineNodeCodedFlag;
2878
0
  fxDeclareNodeCodeReference(it, param, 0);
2879
0
  fxNodeDispatchCode(self->initializer, coder);
2880
0
    self->initializer = C_NULL;
2881
0
  fxDeclareNodeCodeAssign(it, param, 0);
2882
0
  fxCoderAddByte(coder, -1, XS_CODE_POP);
2883
0
}
2884
2885
void fxDelegateNodeCode(void* it, void* param)
2886
0
{
2887
0
  txStatementNode* self = it;
2888
0
  txBoolean async = (self->flags & mxAsyncFlag) ? 1 : 0;
2889
0
  txCoder* coder = param;
2890
0
  txInteger iterator;
2891
0
  txInteger method;
2892
0
  txInteger next;
2893
0
  txInteger result;
2894
2895
0
  txTargetCode* nextTarget = fxCoderCreateTarget(param);
2896
0
  txTargetCode* catchTarget = fxCoderCreateTarget(param);
2897
0
  txTargetCode* rethrowTarget = fxCoderCreateTarget(param);
2898
0
  txTargetCode* returnTarget = fxCoderCreateTarget(param);
2899
0
  txTargetCode* normalTarget = fxCoderCreateTarget(param);
2900
0
  txTargetCode* doneTarget = fxCoderCreateTarget(param);
2901
  
2902
0
  iterator = fxCoderUseTemporaryVariable(param);
2903
0
  method = fxCoderUseTemporaryVariable(param);
2904
0
  next = fxCoderUseTemporaryVariable(param);
2905
0
  result = fxCoderUseTemporaryVariable(param);
2906
  
2907
0
  fxNodeDispatchCode(self->expression, param);
2908
0
  if (async)
2909
0
    fxCoderAddByte(param, 0, XS_CODE_FOR_AWAIT_OF);
2910
0
  else
2911
0
    fxCoderAddByte(param, 0, XS_CODE_FOR_OF);
2912
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, iterator);
2913
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->nextSymbol);
2914
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, next);
2915
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2916
  
2917
0
  fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2918
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2919
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2920
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
2921
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, normalTarget);
2922
  
2923
// LOOP 
2924
0
  fxCoderAdd(param, 0, nextTarget);
2925
0
  if (async)
2926
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
2927
0
  fxCoderAddByte(coder, 0, XS_CODE_YIELD_STAR);
2928
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2929
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2930
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
2931
0
  fxCoderAddBranch(coder, 1, XS_CODE_BRANCH_STATUS_1, normalTarget);
2932
  
2933
// RETURN 
2934
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
2935
0
  if (async) {
2936
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
2937
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
2938
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
2939
0
    fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2940
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
2941
0
  }  
2942
  
2943
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2944
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->returnSymbol);
2945
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_CHAIN_1, returnTarget);
2946
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2947
0
  fxCoderAddByte(param, 0, XS_CODE_SWAP);
2948
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
2949
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
2950
0
  fxCoderAddInteger(param, -3, XS_CODE_RUN_1, 1);
2951
0
  if (async) {
2952
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
2953
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
2954
0
  }
2955
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2956
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
2957
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
2958
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, nextTarget);
2959
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
2960
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
2961
0
  fxCoderAdd(coder, 0, returnTarget);
2962
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2963
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
2964
0
  if (async) {
2965
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
2966
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
2967
0
  }  
2968
0
  fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
2969
0
  fxCoderAdjustEnvironment(coder, coder->returnTarget);
2970
0
  fxCoderAdjustScope(coder, coder->returnTarget);
2971
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, coder->returnTarget);
2972
  
2973
// THROW  
2974
0
  fxCoderAdd(coder, 0, catchTarget);
2975
2976
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2977
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->throwSymbol);
2978
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, method);
2979
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_COALESCE_1, doneTarget);
2980
  
2981
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2982
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->returnSymbol);
2983
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_CHAIN_1, rethrowTarget);
2984
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
2985
0
  fxCoderAddByte(param, 0, XS_CODE_SWAP);
2986
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
2987
0
  fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
2988
0
  if (async) {
2989
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
2990
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
2991
0
  }
2992
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2993
0
  fxCoderAdd(coder, 0, rethrowTarget);
2994
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2995
  
2996
0
  fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
2997
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
2998
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
2999
  
3000
// NORMAL 
3001
0
  fxCoderAdd(coder, 0, normalTarget);
3002
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
3003
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, next);
3004
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, method);
3005
0
  fxCoderAdd(param, 1, doneTarget);
3006
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
3007
3008
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
3009
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, method);
3010
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
3011
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
3012
0
  fxCoderAddInteger(param, -3, XS_CODE_RUN_1, 1);
3013
0
  if (async) {
3014
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
3015
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
3016
0
  }
3017
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
3018
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
3019
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
3020
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, nextTarget);
3021
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
3022
3023
0
  fxCoderUnuseTemporaryVariables(param, 4);
3024
0
}
3025
3026
void fxDeleteNodeCode(void* it, void* param) 
3027
0
{
3028
0
  txDeleteNode* self = it;
3029
0
  fxNodeDispatchCodeDelete(self->reference, param);
3030
0
}
3031
3032
void fxDoNodeCode(void* it, void* param) 
3033
0
{
3034
0
  txDoNode* self = it;
3035
0
  txCoder* coder = param;
3036
0
  txTargetCode* loopTarget = fxCoderCreateTarget(param);
3037
0
  if (coder->programFlag) {
3038
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3039
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
3040
0
  }
3041
0
  fxCoderAdd(param, 0, loopTarget);
3042
0
  fxNodeDispatchCode(self->statement, param);
3043
0
  fxCoderAdd(param, 0, coder->firstContinueTarget);
3044
0
  fxNodeDispatchCode(self->expression, param);
3045
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, loopTarget);
3046
0
}
3047
3048
void fxExportNodeCode(void* it, void* param) 
3049
0
{
3050
0
}
3051
3052
void fxExpressionsNodeCode(void* it, void* param) 
3053
0
{
3054
0
  txExpressionsNode* self = it;
3055
0
  if (self->items) {
3056
0
    txNode* item = self->items->first;
3057
0
    txNode* previous = NULL;
3058
0
    txNode* next;
3059
0
    while (item) {
3060
0
      next = item->next;
3061
0
      if (previous)
3062
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
3063
0
      if (!next)
3064
0
        item->flags |= (self->flags & mxTailRecursionFlag);
3065
0
      fxNodeDispatchCode(item, param);
3066
0
      previous = item;
3067
0
      item = next;
3068
0
    }
3069
0
  }
3070
0
}
3071
3072
txFlag fxExpressionsNodeCodeThis(void* it, void* param, txFlag flag) 
3073
0
{
3074
0
  txExpressionsNode* self = it;
3075
0
  if (self->items) {
3076
0
    txNode* item = self->items->first;
3077
0
    if (item->next == C_NULL) {
3078
0
      return fxNodeDispatchCodeThis(item, param, flag);
3079
0
    }
3080
0
  }
3081
0
  return fxNodeCodeThis(it, param, flag);
3082
0
}
3083
3084
void fxExpressionsNodeCodeDelete(void* it, void* param) 
3085
0
 {
3086
0
  txExpressionsNode* self = it;
3087
0
  if (self->items) {
3088
0
    txNode* item = self->items->first;
3089
0
    if (item->next == C_NULL) {
3090
0
      fxNodeDispatchCodeDelete(item, param);
3091
0
      return;
3092
0
    }
3093
0
  }
3094
0
  fxNodeCodeDelete(it, param);
3095
0
 }
3096
3097
void fxFieldNodeCode(void* it, void* param) 
3098
0
{
3099
0
  txFieldNode* self = it;
3100
0
  txNode* item = self->item;
3101
0
  fxCoderAddByte(param, 1, XS_CODE_THIS);
3102
0
  if (item->description->token == XS_TOKEN_PROPERTY) {
3103
0
    fxNodeDispatchCode(self->value, param);
3104
0
    fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, ((txPropertyNode*)item)->symbol);
3105
0
    fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, fxNodeCodeName(self->value) ? XS_NAME_FLAG : 0);
3106
0
  }
3107
0
  else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
3108
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_CLOSURE_1, ((txPropertyAtNode*)item)->atAccess->declaration->index);
3109
0
    fxNodeDispatchCode(self->value, param);
3110
0
    fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
3111
0
    fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, fxNodeCodeName(self->value) ? XS_NAME_FLAG : 0);
3112
0
  }
3113
0
  else {
3114
0
    if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag))
3115
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_CLOSURE_1, ((txPrivatePropertyNode*)item)->valueAccess->declaration->index);
3116
0
    else
3117
0
      fxNodeDispatchCode(self->value, param);
3118
0
    fxCoderAddIndex(param, -2, XS_CODE_NEW_PRIVATE_1, ((txPrivatePropertyNode*)item)->symbolAccess->declaration->index);
3119
0
    if (item->flags & mxMethodFlag)
3120
0
      fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, XS_NAME_FLAG | XS_METHOD_FLAG);
3121
0
    else if (item->flags & mxGetterFlag)
3122
0
      fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, XS_NAME_FLAG | XS_METHOD_FLAG | XS_GETTER_FLAG);
3123
0
    else if (item->flags & mxSetterFlag)
3124
0
      fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, XS_NAME_FLAG | XS_METHOD_FLAG | XS_SETTER_FLAG);
3125
0
    else
3126
0
      fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, fxNodeCodeName(self->value) ? XS_NAME_FLAG : 0);
3127
0
  }
3128
0
}
3129
3130
void fxForNodeCode(void* it, void* param) 
3131
0
{
3132
0
  txForNode* self = it;
3133
0
  txCoder* coder = param;
3134
0
  txTargetCode* continueTarget;
3135
0
  txTargetCode* nextTarget;
3136
0
  txTargetCode* doneTarget;
3137
0
  txUsingContext context;
3138
  
3139
0
  continueTarget = coder->firstContinueTarget;
3140
0
  coder->firstContinueTarget = continueTarget->nextTarget;
3141
0
  continueTarget->nextTarget = C_NULL;
3142
  
3143
0
  fxScopeCodingBlock(self->scope, param);
3144
0
  fxScopeCodeDefineNodes(self->scope, param);
3145
0
  if (self->scope->disposableNodeCount)
3146
0
    fxScopeCodeUsing(self->scope, coder, &context); 
3147
0
  nextTarget = fxCoderCreateTarget(param);
3148
0
  doneTarget = fxCoderCreateTarget(param);
3149
0
  if (self->initialization)
3150
0
    fxNodeDispatchCode(self->initialization, param);
3151
0
  if (coder->programFlag) {
3152
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3153
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
3154
0
  }
3155
0
  fxScopeCodeRefresh(self->scope, param);
3156
0
  fxCoderAdd(param, 0, nextTarget);
3157
0
  if (self->expression) {
3158
0
    fxNodeDispatchCode(self->expression, param);
3159
0
    fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, doneTarget);
3160
0
  }
3161
  
3162
0
  continueTarget->environmentLevel = coder->environmentLevel;
3163
0
  continueTarget->scopeLevel = coder->scopeLevel;
3164
0
  continueTarget->stackLevel = coder->stackLevel;
3165
0
  continueTarget->nextTarget = coder->firstContinueTarget;
3166
0
  coder->firstContinueTarget = continueTarget;
3167
0
  fxNodeDispatchCode(self->statement, param);
3168
0
  fxCoderAdd(param, 0, continueTarget);
3169
0
  coder->firstContinueTarget = continueTarget->nextTarget;
3170
0
  continueTarget->nextTarget = C_NULL;
3171
  
3172
0
  if (self->iteration) {
3173
0
    fxScopeCodeRefresh(self->scope, param);
3174
0
    self->iteration->flags |= mxExpressionNoValue;
3175
0
    fxNodeDispatchCode(self->iteration, param);
3176
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
3177
0
  }
3178
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
3179
0
  fxCoderAdd(param, 0, doneTarget);
3180
0
  if (self->scope->disposableNodeCount)
3181
0
    fxScopeCodeUsed(self->scope, coder, &context);
3182
0
  fxScopeCoded(self->scope, param);
3183
  
3184
0
  continueTarget->nextTarget = coder->firstContinueTarget;
3185
0
  coder->firstContinueTarget = continueTarget;
3186
0
}
3187
3188
void fxForInForOfNodeCode(void* it, void* param) 
3189
0
{
3190
0
  txForInForOfNode* self = it;
3191
0
  txCoder* coder = param;
3192
0
  txBoolean async = (self->description->code == XS_CODE_FOR_AWAIT_OF) ? 1 : 0;
3193
0
  txTargetCode* continueTarget;
3194
0
  txInteger iterator;
3195
0
  txInteger next;
3196
0
  txInteger done;
3197
0
  txInteger result;
3198
0
  txInteger exception;
3199
0
  txInteger selector;
3200
0
  txInteger selection;
3201
0
  txTargetCode* nextTarget;
3202
0
  txTargetCode* returnTarget;
3203
0
  txTargetCode* doneTarget;
3204
0
  txTargetCode* catchTarget;
3205
0
  txTargetCode* normalTarget;
3206
0
  txTargetCode* uncatchTarget;
3207
0
  txTargetCode* finallyTarget;
3208
0
  txTargetCode* elseTarget;
3209
  
3210
0
  iterator = fxCoderUseTemporaryVariable(param);
3211
0
  next = fxCoderUseTemporaryVariable(param);
3212
0
  done = fxCoderUseTemporaryVariable(param);
3213
0
  result = fxCoderUseTemporaryVariable(param);
3214
0
  exception = fxCoderUseTemporaryVariable(coder);
3215
0
  selector = fxCoderUseTemporaryVariable(coder);
3216
  
3217
0
  continueTarget = coder->firstContinueTarget;
3218
0
  coder->firstContinueTarget = continueTarget->nextTarget;
3219
0
  continueTarget->nextTarget = C_NULL;
3220
  
3221
0
  fxScopeCodingBlock(self->scope, param);
3222
0
  fxScopeCodeDefineNodes(self->scope, param);
3223
3224
0
  if (coder->programFlag) {
3225
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3226
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
3227
0
  }
3228
0
  fxNodeDispatchCode(self->expression, param);
3229
0
  fxCoderAddByte(param, 0, self->description->code);
3230
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, iterator);
3231
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->nextSymbol);
3232
0
  fxCoderAddIndex(param, 0, XS_CODE_PULL_LOCAL_1, next);
3233
3234
0
  coder->firstBreakTarget = fxCoderAliasTargets(param, coder->firstBreakTarget);
3235
0
  coder->firstContinueTarget = fxCoderAliasTargets(param, coder->firstContinueTarget);
3236
0
  coder->returnTarget = fxCoderAliasTargets(param, coder->returnTarget);
3237
0
  catchTarget = fxCoderCreateTarget(param);
3238
0
  normalTarget = fxCoderCreateTarget(param);
3239
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
3240
  
3241
// LOOP 
3242
0
  nextTarget = fxCoderCreateTarget(param);
3243
0
  fxCoderAdd(param, 0, nextTarget);
3244
0
  fxCoderAddByte(param, 1, XS_CODE_TRUE);
3245
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
3246
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
3247
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, next);
3248
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
3249
0
  fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
3250
0
  if (async) {
3251
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
3252
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
3253
0
  }
3254
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
3255
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, result);
3256
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
3257
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, done);
3258
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, normalTarget);
3259
3260
0
  fxScopeCodeReset(self->scope, param);
3261
0
  fxNodeDispatchCodeReference(self->reference, param, 0);
3262
0
  fxCoderAddByte(param, 1, XS_CODE_TRUE);
3263
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
3264
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
3265
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
3266
0
  fxCoderAddByte(param, 1, XS_CODE_FALSE);
3267
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, done);
3268
0
  fxNodeDispatchCodeAssign(self->reference, param, 0);
3269
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
3270
3271
0
  continueTarget->environmentLevel = coder->environmentLevel;
3272
0
  continueTarget->scopeLevel = coder->scopeLevel;
3273
0
  continueTarget->stackLevel = coder->stackLevel;
3274
0
  continueTarget->nextTarget = coder->firstContinueTarget;
3275
0
  coder->firstContinueTarget = continueTarget;
3276
0
  fxNodeDispatchCode(self->statement, param);
3277
0
  fxCoderAdd(param, 0, coder->firstContinueTarget);
3278
0
  coder->firstContinueTarget = continueTarget->nextTarget;
3279
0
  continueTarget->nextTarget = C_NULL;
3280
  
3281
0
  fxScopeCodeUsedReverse(self->scope, coder, self->scope->firstDeclareNode, exception, selector);
3282
3283
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
3284
3285
//   PRE FINALLY
3286
0
  uncatchTarget = fxCoderCreateTarget(param);
3287
0
  finallyTarget = fxCoderCreateTarget(param);
3288
3289
0
  fxCoderAdd(coder, 0, catchTarget);
3290
0
  fxCoderAddByte(coder, 1, XS_CODE_EXCEPTION);
3291
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, exception);
3292
0
  fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, 0);
3293
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, selector);
3294
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, finallyTarget);
3295
0
  selection = 1;
3296
0
  coder->firstBreakTarget = fxCoderFinalizeTargets(param, coder->firstBreakTarget, selector, &selection, uncatchTarget);
3297
0
  coder->firstContinueTarget = fxCoderFinalizeTargets(param, coder->firstContinueTarget, selector, &selection, uncatchTarget);
3298
0
  coder->returnTarget = fxCoderFinalizeTargets(param, coder->returnTarget, selector, &selection, uncatchTarget);
3299
0
  fxCoderAdd(param, 0, normalTarget);
3300
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, selection);
3301
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, selector);
3302
0
  fxCoderAdd(coder, 0, uncatchTarget);
3303
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
3304
0
  fxCoderAdd(param, 0, finallyTarget);
3305
  
3306
//   FINALLY
3307
0
  catchTarget = fxCoderCreateTarget(param);
3308
0
  normalTarget = fxCoderCreateTarget(param);
3309
3310
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
3311
3312
0
  doneTarget = fxCoderCreateTarget(param);
3313
0
  returnTarget = fxCoderCreateTarget(param);
3314
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, done);
3315
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
3316
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
3317
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->returnSymbol);
3318
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_CHAIN_1, returnTarget);
3319
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
3320
0
  fxCoderAddByte(param, 0, XS_CODE_SWAP);
3321
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
3322
0
  fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
3323
0
  if (async) {
3324
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
3325
0
    fxCoderAddByte(param, 0, XS_CODE_THROW_STATUS);
3326
0
  }
3327
0
  fxCoderAddByte(param, 0, XS_CODE_CHECK_INSTANCE);
3328
0
  fxCoderAdd(param, 0, returnTarget);
3329
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
3330
0
  fxCoderAdd(param, 0, doneTarget);
3331
  
3332
0
  fxCoderAddByte(coder, 0, XS_CODE_UNCATCH);
3333
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, normalTarget);
3334
  
3335
0
  fxCoderAdd(coder, 0, catchTarget);
3336
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, selector);
3337
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, normalTarget);
3338
0
  fxCoderAddByte(coder, 1, XS_CODE_EXCEPTION);
3339
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, exception);
3340
0
  fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, 0);
3341
0
  fxCoderAddIndex(coder, -1, XS_CODE_PULL_LOCAL_1, selector);
3342
0
  fxCoderAdd(param, 0, normalTarget);
3343
3344
0
  fxScopeCodeUsedReverse(self->scope, coder, self->scope->firstDeclareNode, exception, selector);
3345
3346
//   POST FINALLY
3347
0
  elseTarget = fxCoderCreateTarget(param);
3348
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, selector);
3349
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, elseTarget);
3350
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, exception);
3351
0
  fxCoderAddByte(param, -1, XS_CODE_THROW);
3352
0
  fxCoderAdd(param, 0, elseTarget);
3353
0
  selection = 1;
3354
0
  fxCoderJumpTargets(param, coder->firstBreakTarget, selector, &selection);
3355
0
  fxCoderJumpTargets(param, coder->firstContinueTarget, selector, &selection);
3356
0
  fxCoderJumpTargets(param, coder->returnTarget, selector, &selection);
3357
  
3358
0
  fxScopeCoded(self->scope, param);
3359
0
  continueTarget->nextTarget = coder->firstContinueTarget;
3360
0
  coder->firstContinueTarget = continueTarget;
3361
  
3362
0
  fxCoderUnuseTemporaryVariables(param, 6);
3363
0
}
3364
3365
void fxFunctionNodeCode(void* it, void* param) 
3366
0
{
3367
0
  txFunctionNode* self = it;
3368
0
  txCoder* coder = param;
3369
0
  txInteger environmentLevel = coder->environmentLevel;
3370
0
  txBoolean evalFlag = coder->evalFlag;
3371
0
  txInteger line = coder->line;
3372
0
  txBoolean programFlag = coder->programFlag;
3373
0
  txInteger scopeLevel = coder->scopeLevel;
3374
0
  txTargetCode* firstBreakTarget = coder->firstBreakTarget;
3375
0
  txTargetCode* firstContinueTarget = coder->firstContinueTarget;
3376
0
  txTargetCode* returnTarget = coder->returnTarget;
3377
0
  txSymbol* name = self->symbol;
3378
0
  txTargetCode* target = fxCoderCreateTarget(param);
3379
  
3380
0
  if ((self->flags & mxEvalFlag) && !(self->flags & mxStrictFlag))
3381
0
    coder->evalFlag = 1;
3382
0
  coder->line = -1;
3383
0
  coder->programFlag = 0;
3384
0
  coder->scopeLevel = 0;
3385
0
  coder->firstBreakTarget = NULL;
3386
0
  coder->firstContinueTarget = NULL;
3387
3388
0
    if (name) {
3389
0
        if (self->flags & mxGetterFlag) {
3390
0
            txString buffer = coder->parser->buffer;
3391
0
            c_strcpy(buffer, "get ");
3392
0
            c_strcat(buffer, name->string);
3393
0
            name = fxNewParserSymbol(coder->parser, buffer);
3394
0
        }
3395
0
        else if (self->flags & mxSetterFlag) {
3396
0
            txString buffer = coder->parser->buffer;
3397
0
            c_strcpy(buffer, "set ");
3398
0
            c_strcat(buffer, name->string);
3399
0
            name = fxNewParserSymbol(coder->parser, buffer);
3400
0
        }
3401
0
    }
3402
    
3403
0
  if (self->flags & mxAsyncFlag) {
3404
0
    if (self->flags & mxGeneratorFlag)
3405
0
      fxCoderAddSymbol(param, 1, XS_CODE_ASYNC_GENERATOR_FUNCTION, name);
3406
0
    else
3407
0
      fxCoderAddSymbol(param, 1, XS_CODE_ASYNC_FUNCTION, name);
3408
0
  }
3409
0
  else if (self->flags & mxGeneratorFlag)
3410
0
    fxCoderAddSymbol(param, 1, XS_CODE_GENERATOR_FUNCTION, name);
3411
0
  else if (self->flags & (mxArrowFlag | mxMethodFlag | mxGetterFlag | mxSetterFlag))
3412
0
    fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name);
3413
0
  else
3414
0
    fxCoderAddSymbol(param, 1, XS_CODE_CONSTRUCTOR_FUNCTION, name);
3415
0
  if (coder->parser->flags & mxDebugFlag)
3416
0
    fxCoderAddByte(param, 0, XS_CODE_PROFILE);
3417
0
  fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target);
3418
0
  if (self->flags & mxFieldFlag)
3419
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT_FIELD, fxCoderCountParameters(coder, self->params));
3420
0
  else if (self->flags & mxDerivedFlag)
3421
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT_DERIVED, fxCoderCountParameters(coder, self->params));
3422
0
  else if (self->flags & mxBaseFlag)
3423
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT_BASE, fxCoderCountParameters(coder, self->params));
3424
0
  else if (self->flags & mxStrictFlag)
3425
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, fxCoderCountParameters(coder, self->params));
3426
0
  else
3427
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_SLOPPY, fxCoderCountParameters(coder, self->params));
3428
0
  coder->path = C_NULL;
3429
0
  if (self->line >= 0)
3430
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, it); 
3431
0
  if (self->scopeCount)
3432
0
    fxCoderAddIndex(param, 0, XS_CODE_RESERVE_1, self->scopeCount);
3433
0
  fxScopeCodeRetrieve(self->scope, param);
3434
0
  fxScopeCodingParams(self->scope, param);
3435
0
  if ((self->flags & mxAsyncFlag) && !(self->flags & mxGeneratorFlag))
3436
0
    fxCoderAddByte(param, 0, XS_CODE_START_ASYNC);
3437
0
  if (self->flags & mxBaseFlag) {
3438
0
    if (coder->classNode->instanceInitAccess) {
3439
0
      fxCoderAddByte(param, 1, XS_CODE_THIS);
3440
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_CLOSURE_1, coder->classNode->instanceInitAccess->declaration->index);
3441
0
      fxCoderAddByte(param, 1, XS_CODE_CALL);
3442
0
      fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
3443
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
3444
0
    }
3445
0
  }
3446
0
  fxNodeDispatchCode(self->params, param);
3447
0
  if ((coder->parser->flags & mxDebugFlag) && coder->path)
3448
0
    fxCoderAddIndex(coder, 0, XS_CODE_LINE, 0);
3449
0
  fxScopeCodeDefineNodes(self->scope, param);
3450
0
  coder->returnTarget = fxCoderCreateTarget(param);
3451
0
  if (self->flags & mxGeneratorFlag) {
3452
0
    if (self->flags & mxAsyncFlag)
3453
0
      fxCoderAddByte(param, 0, XS_CODE_START_ASYNC_GENERATOR);
3454
0
    else
3455
0
      fxCoderAddByte(param, 0, XS_CODE_START_GENERATOR);
3456
0
  }
3457
0
  fxNodeDispatchCode(self->body, param);
3458
0
  fxCoderAdd(param, 0, coder->returnTarget);
3459
0
  if (self->flags & mxArrowFlag)
3460
0
    fxCoderAddByte(param, 0, XS_CODE_END_ARROW);
3461
0
  else if (self->flags & mxBaseFlag)
3462
0
    fxCoderAddByte(param, 0, XS_CODE_END_BASE);
3463
0
  else if (self->flags & mxDerivedFlag)
3464
0
    fxCoderAddByte(param, 0, XS_CODE_END_DERIVED);
3465
0
  else
3466
0
    fxCoderAddByte(param, 0, XS_CODE_END);
3467
0
  fxCoderAdd(param, 0, target);
3468
  
3469
0
  if ((self->scope->flags & mxEvalFlag) || coder->evalFlag) {
3470
0
    fxCoderAddByte(coder, 1, XS_CODE_FUNCTION_ENVIRONMENT);
3471
0
    fxScopeCodeStore(self->scope, param);
3472
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
3473
0
  }
3474
0
  else if (self->scope->closureNodeCount || ((self->flags & mxArrowFlag) && (self->flags & mxDefaultFlag))) {
3475
0
    fxCoderAddByte(coder, 1, XS_CODE_ENVIRONMENT);
3476
0
    fxScopeCodeStore(self->scope, param);
3477
0
    fxCoderAddByte(coder, -1, XS_CODE_POP);
3478
0
  }
3479
0
  if ((self->flags & (mxArrowFlag | mxBaseFlag | mxDerivedFlag | mxGeneratorFlag | mxStrictFlag | mxMethodFlag)) == 0) {
3480
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
3481
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3482
0
    fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, coder->parser->callerSymbol);
3483
0
    fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, XS_DONT_ENUM_FLAG);
3484
0
  }
3485
  
3486
0
  coder->returnTarget = returnTarget;
3487
0
  coder->firstContinueTarget = firstContinueTarget;
3488
0
  coder->firstBreakTarget = firstBreakTarget;
3489
0
  coder->scopeLevel = scopeLevel;
3490
0
  coder->programFlag = programFlag;
3491
0
  coder->line = line;
3492
0
  coder->evalFlag = evalFlag;
3493
0
  coder->environmentLevel = environmentLevel;
3494
0
}
3495
3496
void fxHostNodeCode(void* it, void* param) 
3497
0
{
3498
0
  txHostNode* self = it;
3499
0
  txCoder* coder = param;
3500
0
  txParser* parser = coder->parser;
3501
0
  if (self->hostIndex < 0) {
3502
0
    if (self->symbol) {
3503
0
      if (self->flags & mxGetterFlag) {
3504
0
        txString buffer = coder->parser->buffer;
3505
0
        c_strcpy(buffer, "get ");
3506
0
        c_strcat(buffer, self->symbol->string);
3507
0
        self->symbol = fxNewParserSymbol(coder->parser, buffer);
3508
0
      }
3509
0
      else if (self->flags & mxSetterFlag) {
3510
0
        txString buffer = coder->parser->buffer;
3511
0
        c_strcpy(buffer, "set ");
3512
0
        c_strcat(buffer, self->symbol->string);
3513
0
        self->symbol = fxNewParserSymbol(coder->parser, buffer);
3514
0
      }
3515
0
    }
3516
0
    if (self->params)
3517
0
      self->paramsCount = fxCoderCountParameters(coder, self->params);
3518
0
    else
3519
0
      self->paramsCount = -1; 
3520
0
    if (parser->firstHostNode)
3521
0
      parser->lastHostNode->nextHostNode = self;
3522
0
    else
3523
0
      parser->firstHostNode = self;
3524
0
    parser->lastHostNode = self;
3525
0
    self->hostIndex = parser->hostNodeIndex;
3526
0
    parser->hostNodeIndex++;
3527
0
  }
3528
0
  fxCoderAddIndex(param, 1, XS_CODE_HOST, self->hostIndex);
3529
0
}
3530
3531
void fxIfNodeCode(void* it, void* param) 
3532
0
{
3533
0
  txIfNode* self = it;
3534
0
  txCoder* coder = param;
3535
0
  fxNodeDispatchCode(self->expression, param);
3536
0
  if (coder->programFlag) {
3537
0
    txTargetCode* elseTarget = fxCoderCreateTarget(param);
3538
0
    txTargetCode* endTarget = fxCoderCreateTarget(param);
3539
0
    fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, elseTarget);
3540
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3541
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
3542
0
    fxNodeDispatchCode(self->thenStatement, param);
3543
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, endTarget);
3544
0
    fxCoderAdd(param, 0, elseTarget);
3545
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3546
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
3547
0
    if (self->elseStatement)
3548
0
      fxNodeDispatchCode(self->elseStatement, param);
3549
0
    fxCoderAdd(param, 0, endTarget);
3550
0
  }
3551
0
  else {
3552
0
    if (self->elseStatement) {
3553
0
      txTargetCode* elseTarget = fxCoderCreateTarget(param);
3554
0
      txTargetCode* endTarget = fxCoderCreateTarget(param);
3555
0
      fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, elseTarget);
3556
0
      fxNodeDispatchCode(self->thenStatement, param);
3557
0
      fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, endTarget);
3558
0
      fxCoderAdd(param, 0, elseTarget);
3559
0
      fxNodeDispatchCode(self->elseStatement, param);
3560
0
      fxCoderAdd(param, 0, endTarget);
3561
0
    }
3562
0
    else {
3563
0
      txTargetCode* endTarget = fxCoderCreateTarget(param);
3564
0
      fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, endTarget);
3565
0
      fxNodeDispatchCode(self->thenStatement, param);
3566
0
      fxCoderAdd(param, 0, endTarget);
3567
0
    }
3568
0
  }
3569
0
}
3570
3571
void fxImportNodeCode(void* it, void* param) 
3572
0
{
3573
0
}
3574
3575
void fxImportCallNodeCode(void* it, void* param)
3576
0
{
3577
0
  txCoder* coder = param;
3578
0
  txImportCallNode* self = it;
3579
0
  fxNodeDispatchCode(self->expression, param);
3580
0
  if (self->withExpression)
3581
0
    fxNodeDispatchCode(self->withExpression, param);
3582
0
  else
3583
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3584
0
  coder->importFlag = 1;
3585
0
  fxCoderAddByte(param, -1, XS_CODE_IMPORT);
3586
0
}
3587
3588
void fxImportMetaNodeCode(void* it, void* param)
3589
0
{
3590
0
  txCoder* coder = param;
3591
0
  coder->importMetaFlag = 1;
3592
0
  fxCoderAddByte(param, 1, XS_CODE_IMPORT_META);
3593
0
}
3594
3595
void fxIncludeNodeCode(void* it, void* param) 
3596
0
{
3597
0
  txIncludeNode* self = it;
3598
0
  fxNodeDispatchCode(self->body, param);
3599
0
}
3600
3601
void fxIntegerNodeCode(void* it, void* param) 
3602
0
{
3603
0
  txIntegerNode* self = it;
3604
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, self->value);
3605
0
}
3606
3607
void fxLabelNodeCode(void* it, void* param) 
3608
0
{
3609
0
  txLabelNode* self = it;
3610
0
  txCoder* coder = param;
3611
0
  txNode* statement = self->statement;
3612
0
  txTargetCode* breakTarget;
3613
0
  while (statement->description->token == XS_TOKEN_LABEL) {
3614
0
    txLabelNode* former = (txLabelNode*)statement;
3615
0
    txLabelNode* current = self;
3616
0
    while (current) {
3617
0
      if (former->symbol && current->symbol && (former->symbol == current->symbol)) {
3618
0
        fxReportParserError(coder->parser, current->line, "duplicate label %s", current->symbol->string);
3619
0
      }
3620
0
      current = current->nextLabel;
3621
0
    }
3622
0
    former->nextLabel = self;
3623
0
    self = former;
3624
0
    statement = self->statement;
3625
0
  }
3626
0
  breakTarget = coder->firstBreakTarget;
3627
0
  while (breakTarget) {
3628
0
    txLabelNode* former = breakTarget->label;
3629
0
    if (former) {
3630
0
      txLabelNode* current = self;
3631
0
      while (current) {
3632
0
        if (former->symbol && current->symbol && (former->symbol == current->symbol)) {
3633
0
          fxReportParserError(coder->parser, current->line, "duplicate label %s", current->symbol->string);
3634
0
        }
3635
0
        current = current->nextLabel;
3636
0
      }
3637
0
    }
3638
0
    breakTarget = breakTarget->nextTarget;
3639
0
  }
3640
0
  breakTarget = fxCoderCreateTarget(coder);
3641
0
  breakTarget->nextTarget = coder->firstBreakTarget;
3642
0
  coder->firstBreakTarget = breakTarget;
3643
0
  breakTarget->label = self;
3644
0
  if (self->symbol)
3645
0
    fxNodeDispatchCode(statement, param);
3646
0
  else {
3647
0
    txTargetCode* continueTarget = fxCoderCreateTarget(coder);
3648
0
    continueTarget->nextTarget = coder->firstContinueTarget;
3649
0
    coder->firstContinueTarget = continueTarget;
3650
0
    continueTarget->label = self;
3651
0
    fxNodeDispatchCode(statement, param);
3652
0
    coder->firstContinueTarget = continueTarget->nextTarget;
3653
0
  }
3654
0
  fxCoderAdd(param, 0, coder->firstBreakTarget);
3655
0
  coder->firstBreakTarget = breakTarget->nextTarget;
3656
0
}
3657
3658
void fxMemberNodeCode(void* it, void* param) 
3659
0
{
3660
0
  txMemberNode* self = it;
3661
0
  fxNodeDispatchCode(self->reference, param);
3662
0
  fxCoderAddSymbol(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_GET_SUPER : XS_CODE_GET_PROPERTY, self->symbol);
3663
0
}
3664
3665
void fxMemberNodeCodeAssign(void* it, void* param, txFlag flag) 
3666
0
{
3667
0
  txMemberNode* self = it;
3668
0
  fxCoderAddSymbol(param, -1, (self->reference->flags & mxSuperFlag) ? XS_CODE_SET_SUPER : XS_CODE_SET_PROPERTY, self->symbol);
3669
0
}
3670
3671
void fxMemberNodeCodeDelete(void* it, void* param) 
3672
0
{
3673
0
  txMemberNode* self = it;
3674
0
  fxNodeDispatchCode(self->reference, param);
3675
0
  fxCoderAddSymbol(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_DELETE_SUPER : XS_CODE_DELETE_PROPERTY, self->symbol);
3676
0
}
3677
3678
void fxMemberNodeCodeReference(void* it, void* param, txFlag flag) 
3679
0
{
3680
0
  txMemberNode* self = it;
3681
0
  fxNodeDispatchCode(self->reference, param);
3682
0
}
3683
3684
txFlag fxMemberNodeCodeThis(void* it, void* param, txFlag flag) 
3685
0
{
3686
0
  txMemberNode* self = it;
3687
0
  fxNodeDispatchCode(self->reference, param);
3688
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
3689
0
  fxCoderAddSymbol(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_GET_SUPER : XS_CODE_GET_PROPERTY, self->symbol);
3690
0
  return 1;
3691
0
}
3692
3693
void fxMemberAtNodeCode(void* it, void* param) 
3694
0
{
3695
0
  txMemberAtNode* self = it;
3696
0
  fxNodeDispatchCode(self->reference, param);
3697
0
  fxNodeDispatchCode(self->at, param);
3698
0
  fxCoderAddByte(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_SUPER_AT : XS_CODE_AT);
3699
0
  fxCoderAddByte(param, -1, (self->reference->flags & mxSuperFlag) ? XS_CODE_GET_SUPER_AT : XS_CODE_GET_PROPERTY_AT);
3700
0
}
3701
3702
void fxMemberAtNodeCodeAssign(void* it, void* param, txFlag flag) 
3703
0
{
3704
0
  txMemberAtNode* self = it;
3705
0
  if (flag)
3706
0
    fxCoderAddByte(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_SUPER_AT_2 : XS_CODE_AT_2);
3707
0
  fxCoderAddByte(param, -2, (self->reference->flags & mxSuperFlag) ? XS_CODE_SET_SUPER_AT : XS_CODE_SET_PROPERTY_AT);
3708
0
}
3709
3710
void fxMemberAtNodeCodeDelete(void* it, void* param) 
3711
0
{
3712
0
  txMemberAtNode* self = it;
3713
0
  fxMemberAtNodeCodeReference(it, param, (self->reference->flags & mxSuperFlag) ? 1 : 0);
3714
0
  fxCoderAddByte(param, -1, (self->reference->flags & mxSuperFlag) ? XS_CODE_DELETE_SUPER_AT : XS_CODE_DELETE_PROPERTY_AT);
3715
0
}
3716
3717
void fxMemberAtNodeCodeReference(void* it, void* param, txFlag flag) 
3718
0
{
3719
0
  txMemberAtNode* self = it;
3720
0
  fxNodeDispatchCode(self->reference, param);
3721
0
  fxNodeDispatchCode(self->at, param);
3722
0
  if (!flag)
3723
0
    fxCoderAddByte(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_SUPER_AT : XS_CODE_AT);
3724
0
}
3725
3726
txFlag fxMemberAtNodeCodeThis(void* it, void* param, txFlag flag) 
3727
0
{
3728
0
  txMemberAtNode* self = it;
3729
0
  if (flag) {
3730
0
    fxMemberAtNodeCodeReference(it, param, 0);
3731
0
    fxCoderAddByte(param, 2, XS_CODE_DUB_AT);
3732
0
    flag = 2;
3733
0
  }
3734
0
  else {
3735
0
    fxNodeDispatchCode(self->reference, param);
3736
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
3737
0
    fxNodeDispatchCode(self->at, param);
3738
0
    fxCoderAddByte(param, 0, (self->reference->flags & mxSuperFlag) ? XS_CODE_SUPER_AT : XS_CODE_AT);
3739
0
  }
3740
0
  fxCoderAddByte(param, -1, (self->reference->flags & mxSuperFlag) ? XS_CODE_GET_SUPER_AT : XS_CODE_GET_PROPERTY_AT);
3741
0
  return flag;
3742
0
}
3743
3744
void fxModuleNodeCode(void* it, void* param) 
3745
0
{
3746
0
  txModuleNode* self = it;
3747
0
  txCoder* coder = param;
3748
0
  txTargetCode* target = fxCoderCreateTarget(param);
3749
0
  txDeclareNode* declaration;
3750
0
  txInteger count;
3751
0
  txSymbol* name = /*(coder->parser->flags & mxDebugFlag) ? self->path :*/ C_NULL;
3752
0
  txFlag flag = 0;
3753
  
3754
0
  coder->line = -1;
3755
0
  coder->programFlag = 0;
3756
0
  coder->scopeLevel = 0;
3757
0
  coder->firstBreakTarget = NULL;
3758
0
  coder->firstContinueTarget = NULL;
3759
3760
0
  count = 0;
3761
0
  declaration = self->scope->firstDeclareNode;
3762
0
  while (declaration) {
3763
0
    if ((declaration->description->token == XS_TOKEN_DEFINE) || (declaration->description->token == XS_TOKEN_VAR))
3764
0
      count++;
3765
0
    declaration = declaration->nextDeclareNode;
3766
0
  }
3767
0
  if (count) {
3768
0
    fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name);
3769
0
    if (coder->parser->flags & mxDebugFlag)
3770
0
      fxCoderAddByte(param, 0, XS_CODE_PROFILE);
3771
0
    fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target);
3772
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, 0);
3773
0
    coder->path = C_NULL;
3774
0
    if (self->line >= 0)
3775
0
      fxCoderAddLine(coder, 0, XS_CODE_LINE, it); 
3776
0
    if (self->scopeCount)
3777
0
      fxCoderAddIndex(param, 0, XS_CODE_RESERVE_1, self->scopeCount);
3778
0
    fxScopeCodeRetrieve(self->scope, param);
3779
0
    declaration = self->scope->firstDeclareNode;
3780
0
    while (declaration) {
3781
0
      if (declaration->description->token == XS_TOKEN_VAR) {
3782
0
        fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
3783
0
        fxCoderAddIndex(coder, 0, XS_CODE_VAR_CLOSURE_1, declaration->index);
3784
0
        fxCoderAddByte(coder, -1, XS_CODE_POP);
3785
0
      }
3786
0
      declaration = declaration->nextDeclareNode;
3787
0
    }
3788
0
    fxScopeCodeDefineNodes(self->scope, param);
3789
0
    fxCoderAddByte(param, 0, XS_CODE_END);
3790
0
    fxCoderAdd(param, 0, target);
3791
0
    fxCoderAddByte(param, 1, XS_CODE_ENVIRONMENT);
3792
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
3793
  
3794
0
    target = fxCoderCreateTarget(param);
3795
0
    coder->line = -1;
3796
0
    coder->programFlag = 0;
3797
0
    coder->scopeLevel = 0;
3798
0
    coder->firstBreakTarget = NULL;
3799
0
    coder->firstContinueTarget = NULL;
3800
0
  }
3801
0
  else {
3802
0
    fxCoderAddByte(coder, 1, XS_CODE_NULL);
3803
0
  }
3804
  
3805
0
  if (self->flags & mxAwaitingFlag)
3806
0
    fxCoderAddSymbol(param, 1, XS_CODE_ASYNC_FUNCTION, name);
3807
0
  else
3808
0
    fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name);
3809
0
  if (coder->parser->flags & mxDebugFlag)
3810
0
    fxCoderAddByte(param, 0, XS_CODE_PROFILE);
3811
0
  fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target);
3812
0
  fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, 0);
3813
0
  coder->path = C_NULL;
3814
0
  if (self->line >= 0)
3815
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, it); 
3816
0
  if (self->scopeCount)
3817
0
    fxCoderAddIndex(param, 0, XS_CODE_RESERVE_1, self->scopeCount);
3818
0
  fxScopeCodeRetrieve(self->scope, param);
3819
  
3820
0
  if (self->flags & mxAwaitingFlag)
3821
0
    fxCoderAddByte(param, 0, XS_CODE_START_ASYNC);
3822
3823
0
  coder->returnTarget = fxCoderCreateTarget(param);
3824
  
3825
0
  fxNodeDispatchCode(self->body, param);
3826
  
3827
0
  fxCoderAdd(param, 0, coder->returnTarget);
3828
0
  fxCoderAddByte(param, 0, XS_CODE_END);
3829
0
  fxCoderAdd(param, 0, target);
3830
  
3831
0
  fxCoderAddByte(param, 1, XS_CODE_ENVIRONMENT);
3832
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
3833
  
3834
0
  count = 2 + fxScopeCodeSpecifierNodes(self->scope, coder);
3835
0
  fxCoderAddInteger(coder, 1, XS_CODE_INTEGER_1, count);
3836
0
  if (!(self->flags & mxStrictFlag))
3837
0
    flag |= XS_JSON_MODULE_FLAG;
3838
0
  if (coder->importFlag)
3839
0
    flag |= XS_IMPORT_FLAG;
3840
0
  if (coder->importMetaFlag)
3841
0
    flag |= XS_IMPORT_META_FLAG;
3842
0
  fxCoderAddIndex(coder, 0 - count, XS_CODE_MODULE, flag);
3843
0
  fxCoderAddByte(coder, -1, XS_CODE_SET_RESULT);
3844
0
  fxCoderAddByte(coder, 0, XS_CODE_END);
3845
0
}
3846
3847
void fxNewNodeCode(void* it, void* param) 
3848
0
{
3849
0
  txCallNewNode* self = it;
3850
0
  fxNodeDispatchCode(self->reference, param);
3851
0
  fxCoderAddByte(param, 2, XS_CODE_NEW);
3852
0
  fxNodeDispatchCode(self->params, param);
3853
0
}
3854
3855
void fxNumberNodeCode(void* it, void* param) 
3856
0
{
3857
0
  txNumberNode* self = it;
3858
0
  fxCoderAddNumber(param, 1, XS_CODE_NUMBER, self->value);
3859
0
}
3860
3861
void fxObjectNodeCode(void* it, void* param) 
3862
0
{
3863
0
  txObjectNode* self = it;
3864
0
  txCoder* coder = param;
3865
0
  txInteger object = fxCoderUseTemporaryVariable(param);
3866
0
  txNode* item;
3867
0
  txFlag flag = 0;
3868
0
  if (self->items) {
3869
0
    item = self->items->first;
3870
0
    while (item) {
3871
0
      if (item->description->token == XS_TOKEN_PROPERTY) {
3872
0
        if (!(item->flags & mxShorthandFlag) && (((txPropertyNode*)item)->symbol == coder->parser->__proto__Symbol)) {
3873
0
          if (flag)
3874
0
            fxReportParserError(coder->parser, item->line, "invalid __proto__");
3875
0
          flag = 1;
3876
0
          fxNodeDispatchCode(((txPropertyNode*)item)->value, param);
3877
0
          fxCoderAddByte(param, 0, XS_CODE_INSTANTIATE);
3878
0
        }
3879
0
      }
3880
0
      item = item->next;
3881
0
    }
3882
0
  }
3883
0
  if (!flag)
3884
0
    fxCoderAddByte(param, 1, XS_CODE_OBJECT);
3885
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, object);
3886
0
  if (self->items) {
3887
0
    item = self->items->first;
3888
0
    while (item) {
3889
0
      if (item->description->token == XS_TOKEN_SPREAD) {
3890
0
        fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3891
0
        fxCoderAddByte(param, 1, XS_CODE_COPY_OBJECT);
3892
0
        fxCoderAddByte(param, 1, XS_CODE_CALL);
3893
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3894
0
        fxNodeDispatchCode(((txSpreadNode*)item)->expression, param);
3895
0
        fxCoderAddInteger(param, -4, XS_CODE_RUN_1, 2);
3896
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
3897
0
      }
3898
0
      else {
3899
0
        txNode* value;
3900
0
        if (item->description->token == XS_TOKEN_PROPERTY) {
3901
0
          if (!(item->flags & mxShorthandFlag) && (((txPropertyNode*)item)->symbol == coder->parser->__proto__Symbol)) {
3902
0
            item = item->next;
3903
0
            continue;
3904
0
          }
3905
0
          value = ((txPropertyNode*)item)->value;
3906
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3907
0
          fxNodeDispatchCode(value, param);
3908
0
          fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, ((txPropertyNode*)item)->symbol);
3909
0
        }
3910
0
        else {
3911
0
          value = ((txPropertyAtNode*)item)->value;
3912
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3913
0
          fxNodeDispatchCode(((txPropertyAtNode*)item)->at, param);
3914
0
          fxCoderAddByte(param, 0, XS_CODE_AT);
3915
0
          fxNodeDispatchCode(value, param);
3916
0
          fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
3917
0
        }
3918
0
        flag = 0;
3919
0
        if (item->flags & mxMethodFlag)
3920
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG;
3921
0
        else if (item->flags & mxGetterFlag)
3922
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_GETTER_FLAG;
3923
0
        else if (item->flags & mxSetterFlag)
3924
0
          flag |= XS_NAME_FLAG | XS_METHOD_FLAG | XS_SETTER_FLAG;
3925
0
        else if (fxNodeCodeName(value))
3926
0
          flag |= XS_NAME_FLAG;
3927
0
        fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, flag);
3928
0
      }
3929
0
      item = item->next;
3930
0
    }
3931
0
  }
3932
0
  fxCoderUnuseTemporaryVariables(param, 1);
3933
0
}
3934
3935
void fxObjectBindingNodeCode(void* it, void* param)
3936
0
{
3937
0
  txObjectBindingNode* self = it;
3938
0
  txCoder* coder = param;
3939
0
  fxCoderAddByte(coder, 1, XS_CODE_UNDEFINED);
3940
0
  fxObjectBindingNodeCodeAssign(self, param, 0);
3941
0
}
3942
3943
void fxObjectBindingNodeCodeAssign(void* it, void* param, txFlag flag) 
3944
0
{
3945
0
  txObjectBindingNode* self = it;
3946
0
  txNode* item = self->items->first;
3947
0
  txInteger object;
3948
0
  txInteger at;
3949
0
  txInteger c = 0;
3950
0
  object = fxCoderUseTemporaryVariable(param);
3951
0
  at = fxCoderUseTemporaryVariable(param);
3952
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
3953
0
  fxCoderAddByte(param, 0, XS_CODE_TO_INSTANCE);
3954
0
  fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, object);
3955
0
  if (self->flags & mxSpreadFlag) {
3956
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
3957
0
    fxCoderAddByte(param, 1, XS_CODE_COPY_OBJECT);
3958
0
    fxCoderAddByte(param, 1, XS_CODE_CALL);
3959
0
    fxCoderAddByte(param, 1, XS_CODE_OBJECT);
3960
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3961
0
    c = 2;
3962
0
  }
3963
0
  while (item && (item->description->token != XS_TOKEN_REST_BINDING)) {
3964
0
    if (item->description->token == XS_TOKEN_PROPERTY_BINDING) {
3965
0
      if (self->flags & mxSpreadFlag) {
3966
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3967
0
        fxCoderAddSymbol(param, 1, XS_CODE_SYMBOL, ((txPropertyBindingNode*)item)->symbol);
3968
0
        fxCoderAddByte(param, 0, XS_CODE_AT);
3969
0
        fxCoderAddByte(param, 0, XS_CODE_SWAP);
3970
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
3971
0
        c++;
3972
0
      }
3973
0
      fxNodeDispatchCodeReference(((txPropertyBindingNode*)item)->binding, param, 1);
3974
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3975
0
      fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, ((txPropertyBindingNode*)item)->symbol);
3976
0
      fxNodeDispatchCodeAssign(((txPropertyBindingNode*)item)->binding, param, 1);
3977
0
    }
3978
0
    else {
3979
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3980
0
      fxNodeDispatchCode(((txPropertyBindingAtNode*)item)->at, param);
3981
0
      fxCoderAddByte(param, 0, XS_CODE_AT);
3982
0
      if (self->flags & mxSpreadFlag) {
3983
0
        fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, at);
3984
0
        fxCoderAddByte(param, 0, XS_CODE_SWAP);
3985
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
3986
0
        c++;
3987
0
      }
3988
0
      else {
3989
0
        fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, at);
3990
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
3991
0
      }
3992
0
      fxNodeDispatchCodeReference(((txPropertyBindingAtNode*)item)->binding, param, 1);
3993
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
3994
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, at);
3995
0
      fxCoderAddByte(param, -1, XS_CODE_GET_PROPERTY_AT);
3996
0
      fxNodeDispatchCodeAssign(((txPropertyBindingAtNode*)item)->binding, param, 1);
3997
0
    }
3998
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
3999
0
    item = item->next;
4000
0
  }
4001
0
  if (self->flags & mxSpreadFlag) {
4002
0
    fxCoderAddInteger(param, -2 - c, XS_CODE_RUN_1, c);
4003
0
    fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, object);
4004
0
    fxNodeDispatchCodeReference(((txRestBindingNode*)item)->binding, param, 1);
4005
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, object);
4006
0
    fxNodeDispatchCodeAssign(((txRestBindingNode*)item)->binding, param, 1);
4007
0
        fxCoderAddByte(param, -1, XS_CODE_POP);
4008
0
  }
4009
0
  fxCoderUnuseTemporaryVariables(param, 2);
4010
0
}
4011
4012
void fxOptionNodeCode(void* it, void* param) 
4013
0
{
4014
0
  txUnaryExpressionNode* self = it;
4015
0
  txCoder* coder = param;
4016
0
  self->right->flags |= (self->flags & mxTailRecursionFlag);
4017
0
  fxNodeDispatchCode(self->right, param);
4018
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_CHAIN_1, coder->chainTarget);
4019
0
}
4020
4021
txFlag fxOptionNodeCodeThis(void* it, void* param, txFlag flag) 
4022
0
{
4023
0
  txUnaryExpressionNode* self = it;
4024
0
  txCoder* coder = param;
4025
0
  txTargetCode* swapTarget = fxCoderCreateTarget(param);
4026
0
  txTargetCode* skipTarget = fxCoderCreateTarget(param);
4027
0
  self->right->flags |= (self->flags & mxTailRecursionFlag);
4028
0
  flag = fxNodeDispatchCodeThis(self->right, param, flag);
4029
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_CHAIN_1, swapTarget);
4030
0
  fxCoderAddBranch(param, 1, XS_CODE_BRANCH_1, skipTarget);
4031
0
  fxCoderAdd(param, 0, swapTarget);
4032
0
  fxCoderAddByte(param, 0, XS_CODE_SWAP);
4033
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4034
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, coder->chainTarget);
4035
0
  fxCoderAdd(param, 0, skipTarget);
4036
0
  return flag;
4037
0
}
4038
4039
void fxOrExpressionNodeCode(void* it, void* param) 
4040
0
{
4041
0
  txBinaryExpressionNode* self = it;
4042
0
  txTargetCode* endTarget = fxCoderCreateTarget(param);
4043
0
  self->right->flags |= (self->flags & mxTailRecursionFlag);
4044
0
  fxNodeDispatchCode(self->left, param);
4045
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
4046
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, endTarget);
4047
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4048
0
  fxNodeDispatchCode(self->right, param);
4049
0
  fxCoderAdd(param, 0, endTarget);
4050
0
}
4051
4052
void fxParamsNodeCode(void* it, void* param) 
4053
0
{
4054
0
  txParamsNode* self = it;
4055
0
  txInteger c = 0;
4056
0
  if (self->flags & mxSpreadFlag) {
4057
0
    txInteger counter = fxCoderUseTemporaryVariable(param);
4058
0
    fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 0);
4059
0
    fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, counter);
4060
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4061
0
    if (self->items) {
4062
0
      txNode* item = self->items->first;
4063
0
      while (item) {
4064
0
        if (item->description->token == XS_TOKEN_SPREAD) {
4065
0
          fxSpreadNodeCode(item, param, counter);
4066
0
        }
4067
0
        else {
4068
0
          c++;
4069
0
          fxNodeDispatchCode(item, param);
4070
0
          fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
4071
0
          fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 1);
4072
0
          fxCoderAddByte(param, -1, XS_CODE_ADD);
4073
0
          fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, counter);
4074
0
          fxCoderAddByte(param, -1, XS_CODE_POP);
4075
0
        }
4076
0
        item = item->next;
4077
0
      }
4078
0
    }
4079
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
4080
0
    if (self->flags & mxEvalParametersFlag)
4081
0
      fxCoderAddByte(param, -3 - c, (self->flags & mxTailRecursionFlag) ? XS_CODE_EVAL_TAIL : XS_CODE_EVAL);
4082
0
    else
4083
0
      fxCoderAddByte(param, -3 - c, (self->flags & mxTailRecursionFlag) ? XS_CODE_RUN_TAIL : XS_CODE_RUN);
4084
0
    fxCoderUnuseTemporaryVariables(param, 1);
4085
0
  }
4086
0
  else {
4087
0
    if (self->items) {
4088
0
      txNode* item = self->items->first;
4089
0
      while (item) {
4090
0
        fxNodeDispatchCode(item, param);
4091
0
        c++;
4092
0
        item = item->next;
4093
0
      }
4094
0
      if (self->flags & mxEvalParametersFlag) {
4095
0
        fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, c);
4096
0
        fxCoderAddByte(param, -3 - c, (self->flags & mxTailRecursionFlag) ? XS_CODE_EVAL_TAIL : XS_CODE_EVAL);
4097
0
      }
4098
0
      else
4099
0
        fxCoderAddInteger(param, -2 - c, (self->flags & mxTailRecursionFlag) ? XS_CODE_RUN_TAIL_1 : XS_CODE_RUN_1, c);
4100
0
    }
4101
0
  }
4102
0
}
4103
4104
void fxParamsBindingNodeCode(void* it, void* param) 
4105
0
{
4106
0
  txParamsBindingNode* self = it;
4107
0
  txNode* item = self->items->first;
4108
0
  txInteger index = 0;
4109
0
  if (self->declaration) {
4110
0
    if (self->mapped)
4111
0
      fxCoderAddIndex(param, 1, XS_CODE_ARGUMENTS_SLOPPY, self->items->length);
4112
0
    else
4113
0
      fxCoderAddIndex(param, 1, XS_CODE_ARGUMENTS_STRICT, self->items->length);
4114
0
    if (self->declaration->flags & mxDeclareNodeClosureFlag)
4115
0
      fxCoderAddIndex(param, 0, XS_CODE_VAR_CLOSURE_1, self->declaration->index);
4116
0
    else 
4117
0
      fxCoderAddIndex(param, 0, XS_CODE_VAR_LOCAL_1, self->declaration->index);
4118
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4119
0
  }
4120
0
  while (item) {
4121
0
    if (item->description->token == XS_TOKEN_REST_BINDING) {
4122
0
      fxNodeDispatchCodeReference(((txRestBindingNode*)item)->binding, param, 0);
4123
0
      fxCoderAddIndex(param, 1, XS_CODE_ARGUMENTS, index);
4124
0
      fxNodeDispatchCodeAssign(((txRestBindingNode*)item)->binding, param, 0);
4125
0
    }
4126
0
    else {
4127
0
      fxNodeDispatchCodeReference(item, param, 0);
4128
0
      fxCoderAddIndex(param, 1, XS_CODE_ARGUMENT, index);
4129
0
      fxNodeDispatchCodeAssign(item, param, 0);
4130
0
    }
4131
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4132
0
    item = item->next;
4133
0
    index++;
4134
0
  }
4135
0
}
4136
4137
void fxPostfixExpressionNodeCode(void* it, void* param) 
4138
0
{
4139
0
  txPostfixExpressionNode* self = it;
4140
0
  txInteger value = 0;
4141
0
  fxNodeDispatchCodeThis(self->left, param, 1);
4142
0
  if (!(self->flags & mxExpressionNoValue)) {
4143
0
    value = fxCoderUseTemporaryVariable(param);
4144
0
    fxCoderAddByte(param, 0, XS_CODE_TO_NUMERIC);
4145
0
    fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, value);
4146
0
  }
4147
0
  fxCoderAddByte(param, 0, self->description->code);
4148
0
  fxNodeDispatchCodeAssign(self->left, param, 0);
4149
0
  if (!(self->flags & mxExpressionNoValue)) {
4150
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4151
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, value);
4152
0
    fxCoderUnuseTemporaryVariables(param, 1);
4153
0
  }
4154
0
}
4155
4156
void fxPrivateIdentifierNodeCode(void* it, void* param) 
4157
0
{
4158
0
  txPrivateMemberNode* self = it;
4159
0
  fxNodeDispatchCode(self->reference, param);
4160
0
  fxCoderAddIndex(param, 0,  XS_CODE_HAS_PRIVATE_1, self->declaration->index);
4161
0
}
4162
4163
void fxPrivateMemberNodeCode(void* it, void* param) 
4164
0
{
4165
0
  txPrivateMemberNode* self = it;
4166
0
  fxNodeDispatchCode(self->reference, param);
4167
0
  fxCoderAddIndex(param, 0,  XS_CODE_GET_PRIVATE_1, self->declaration->index);
4168
0
}
4169
4170
void fxPrivateMemberNodeCodeAssign(void* it, void* param, txFlag flag) 
4171
0
{
4172
0
  txPrivateMemberNode* self = it;
4173
0
  fxCoderAddIndex(param, -1, XS_CODE_SET_PRIVATE_1, self->declaration->index);
4174
0
}
4175
4176
void fxPrivateMemberNodeCodeDelete(void* it, void* param) 
4177
0
{
4178
0
  txPrivateMemberNode* self = it;
4179
0
  txCoder* coder = param;
4180
0
  fxNodeDispatchCode(self->reference, param);
4181
0
  fxReportParserError(coder->parser, self->line, "delete private property");
4182
0
}
4183
4184
void fxPrivateMemberNodeCodeReference(void* it, void* param, txFlag flag) 
4185
0
{
4186
0
  txPrivateMemberNode* self = it;
4187
0
  fxNodeDispatchCode(self->reference, param);
4188
0
}
4189
4190
txFlag fxPrivateMemberNodeCodeThis(void* it, void* param, txFlag flag) 
4191
0
{
4192
0
  txPrivateMemberNode* self = it;
4193
0
  fxNodeDispatchCode(self->reference, param);
4194
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
4195
0
  fxCoderAddIndex(param, 0, XS_CODE_GET_PRIVATE_1, self->declaration->index);
4196
0
  return 1;
4197
0
}
4198
4199
void fxProgramNodeCode(void* it, void* param) 
4200
0
{
4201
0
  txProgramNode* self = it;
4202
0
  txCoder* coder = param;
4203
  
4204
0
  coder->line = -1;
4205
0
  coder->programFlag = 1;
4206
0
  coder->scopeLevel = 0;
4207
0
  coder->firstBreakTarget = NULL;
4208
0
  coder->firstContinueTarget = NULL;
4209
  
4210
0
  if (self->flags & mxStrictFlag)
4211
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, 0);
4212
0
  else
4213
0
    fxCoderAddIndex(param, 0, XS_CODE_BEGIN_SLOPPY, 0);
4214
0
  coder->path = C_NULL;
4215
0
  if (self->line >= 0)
4216
0
    fxCoderAddLine(coder, 0, XS_CODE_LINE, it); 
4217
0
  if (coder->parser->flags & mxEvalFlag) {
4218
0
    coder->evalFlag = 1;
4219
0
    fxScopeCodingEval(self->scope, param);
4220
0
  }
4221
0
  else
4222
0
    fxScopeCodingProgram(self->scope, param);
4223
0
  coder->returnTarget = fxCoderCreateTarget(param);
4224
0
  fxScopeCodeDefineNodes(self->scope, param);
4225
0
  fxNodeDispatchCode(self->body, param);
4226
0
  fxCoderAdd(param, 0, coder->returnTarget);
4227
0
  fxCoderAddByte(param, 0, XS_CODE_RETURN);
4228
0
}
4229
4230
void fxQuestionMarkNodeCode(void* it, void* param) 
4231
0
{
4232
0
  txQuestionMarkNode* self = it;
4233
0
  txTargetCode* elseTarget = fxCoderCreateTarget(param);
4234
0
  txTargetCode* endTarget = fxCoderCreateTarget(param);
4235
0
  self->thenExpression->flags |= (self->flags & mxTailRecursionFlag);
4236
0
  self->elseExpression->flags |= (self->flags & mxTailRecursionFlag);
4237
0
  fxNodeDispatchCode(self->expression, param);
4238
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, elseTarget);
4239
0
  fxNodeDispatchCode(self->thenExpression, param);
4240
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, endTarget);
4241
0
  fxCoderAdd(param, -1, elseTarget);
4242
0
  fxNodeDispatchCode(self->elseExpression, param);
4243
0
  fxCoderAdd(param, 0, endTarget);
4244
0
}
4245
4246
void fxRegexpNodeCode(void* it, void* param) 
4247
0
{
4248
0
  txRegexpNode* self = it;
4249
0
  fxCoderAddByte(param, 1, XS_CODE_REGEXP);
4250
0
  fxCoderAddByte(param, 2, XS_CODE_NEW);
4251
0
  fxNodeDispatchCode(self->modifier, param);
4252
0
  fxNodeDispatchCode(self->value, param);
4253
0
  fxCoderAddInteger(param, -4, XS_CODE_RUN_1, 2);
4254
0
}
4255
4256
void fxReturnNodeCode(void* it, void* param) 
4257
0
{
4258
0
  txStatementNode* self = it;
4259
0
  txCoder* coder = param;
4260
0
  if (coder->programFlag)
4261
0
    fxReportParserError(coder->parser, self->line, "invalid return");
4262
0
  if (self->expression) { 
4263
0
    if (((self->flags & (mxStrictFlag | mxGeneratorFlag)) == mxStrictFlag) && (coder->returnTarget->original == NULL))
4264
0
      self->expression->flags |= mxTailRecursionFlag;
4265
0
    fxNodeDispatchCode(self->expression, param);
4266
0
    if ((self->flags & (mxAsyncFlag | mxGeneratorFlag)) == (mxAsyncFlag | mxGeneratorFlag)) {
4267
0
      fxCoderAddByte(param, 0, XS_CODE_AWAIT);
4268
0
      fxCoderAddByte(coder, 0, XS_CODE_THROW_STATUS);
4269
0
    }
4270
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4271
0
  }
4272
0
  else if ((self->flags & (mxAsyncFlag | mxGeneratorFlag)) != (mxAsyncFlag | mxGeneratorFlag)) {
4273
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4274
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4275
0
  }
4276
0
  fxCoderAdjustEnvironment(coder, coder->returnTarget);
4277
0
  fxCoderAdjustScope(coder, coder->returnTarget);
4278
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, coder->returnTarget);
4279
0
}
4280
4281
void fxSpreadNodeCode(void* it, void* param, txInteger counter) 
4282
0
{
4283
0
  txSpreadNode* self = it;
4284
0
  txCoder* coder = param;
4285
0
  txTargetCode* nextTarget = fxCoderCreateTarget(param);
4286
0
  txTargetCode* doneTarget = fxCoderCreateTarget(param);
4287
0
  txInteger iterator;
4288
0
  fxNodeDispatchCode(self->expression, param);
4289
0
  fxCoderAddByte(param, 0, XS_CODE_FOR_OF);
4290
0
  iterator = fxCoderUseTemporaryVariable(param);
4291
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, iterator);
4292
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4293
0
  fxCoderAdd(param, 0, nextTarget);
4294
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, iterator);
4295
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
4296
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->nextSymbol);
4297
0
  fxCoderAddByte(param, 1, XS_CODE_CALL);
4298
0
  fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
4299
0
  fxCoderAddByte(param, 1, XS_CODE_DUB);
4300
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->doneSymbol);
4301
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, doneTarget);
4302
0
  fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->valueSymbol);
4303
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, counter);
4304
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 1);
4305
0
  fxCoderAddByte(param, -1, XS_CODE_ADD);
4306
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, counter);
4307
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4308
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, nextTarget);
4309
0
  fxCoderAdd(param, 1, doneTarget);
4310
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4311
0
  fxCoderUnuseTemporaryVariables(param, 1);
4312
0
}
4313
4314
void fxStatementNodeCode(void* it, void* param) 
4315
0
{
4316
0
  txStatementNode* self = it;
4317
0
  txCoder* coder = param;
4318
0
  if (coder->programFlag) {
4319
0
    fxNodeDispatchCode(self->expression, param);
4320
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4321
0
  }
4322
0
  else {
4323
0
    self->expression->flags |= mxExpressionNoValue;
4324
0
    fxNodeDispatchCode(self->expression, param);
4325
0
    if (coder->lastCode->id == XS_CODE_SET_CLOSURE_1) {
4326
0
      coder->lastCode->id = XS_CODE_PULL_CLOSURE_1;
4327
0
      coder->stackLevel--;
4328
0
      coder->lastCode->stackLevel = coder->stackLevel;
4329
0
    }
4330
0
    else if (coder->lastCode->id == XS_CODE_SET_LOCAL_1) {
4331
0
      coder->lastCode->id = XS_CODE_PULL_LOCAL_1;
4332
0
      coder->stackLevel--;
4333
0
      coder->lastCode->stackLevel = coder->stackLevel;
4334
0
    }
4335
0
    else
4336
0
      fxCoderAddByte(param, -1, XS_CODE_POP);
4337
0
  }
4338
0
}
4339
4340
void fxStatementsNodeCode(void* it, void* param) 
4341
0
{
4342
0
  txStatementsNode* self = it;
4343
0
  txNode* item = self->items->first;
4344
0
  while (item) {
4345
0
    fxNodeDispatchCode(item, param);
4346
0
    item = item->next;
4347
0
  }
4348
0
}
4349
4350
void fxStringNodeCode(void* it, void* param) 
4351
0
{
4352
0
  txStringNode* self = it;
4353
0
  txCoder* coder = param;
4354
0
  txParser* parser = coder->parser;
4355
0
  if (self->flags & mxStringErrorFlag)
4356
0
    fxReportParserError(parser, self->line, "invalid escape sequence");
4357
0
  fxCoderAddString(param, 1, XS_CODE_STRING_1, self->length, self->value);
4358
0
}
4359
4360
void fxSuperNodeCode(void* it, void* param)
4361
0
{
4362
0
  txSuperNode* self = it;
4363
0
  txCoder* coder = param;
4364
0
  if (coder->classNode->heritage->description->token == XS_TOKEN_HOST) {
4365
0
    fxCoderAddByte(param, 1, XS_CODE_TARGET);
4366
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, coder->parser->prototypeSymbol);
4367
0
    fxCoderAddByte(param, 0, XS_CODE_INSTANTIATE);
4368
0
  }
4369
0
  else {
4370
0
    fxCoderAddByte(param, 3, XS_CODE_SUPER);
4371
0
    fxNodeDispatchCode(self->params, param);
4372
0
  }
4373
0
  fxCoderAddByte(param, 0, XS_CODE_SET_THIS);
4374
0
  if (self->instanceInitAccess) {
4375
0
    fxCoderAddByte(param, 1, XS_CODE_GET_THIS);
4376
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_CLOSURE_1, self->instanceInitAccess->declaration->index);
4377
0
    fxCoderAddByte(param, 1, XS_CODE_CALL);
4378
0
    fxCoderAddInteger(param, -2, XS_CODE_RUN_1, 0);
4379
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4380
0
  }
4381
0
}
4382
4383
void fxSwitchNodeCode(void* it, void* param) 
4384
0
{
4385
0
  txSwitchNode* self = it;
4386
0
  txCoder* coder = param;
4387
0
  txTargetCode* breakTarget;
4388
0
  txCaseNode* caseNode;
4389
0
  txCaseNode* defaultNode = NULL;
4390
0
  txUsingContext context;
4391
0
  fxNodeDispatchCode(self->expression, param);
4392
0
  fxScopeCodingBlock(self->scope, param);
4393
0
  if (self->scope->disposableNodeCount)
4394
0
    fxScopeCodeUsing(self->scope, coder, &context);
4395
0
  breakTarget = fxCoderCreateTarget(coder);
4396
0
  breakTarget->label = fxNewParserChunkClear(coder->parser, sizeof(txLabelNode));
4397
0
  breakTarget->nextTarget = coder->firstBreakTarget;
4398
0
  coder->firstBreakTarget = breakTarget;
4399
0
  if (coder->programFlag) {
4400
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4401
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4402
0
  }
4403
0
  caseNode = (txCaseNode*)self->items->first;
4404
0
  while (caseNode) {
4405
0
    caseNode->target = fxCoderCreateTarget(param);
4406
0
    if (caseNode->expression) {
4407
0
      fxCoderAddByte(param, 1, XS_CODE_DUB);
4408
0
      fxNodeDispatchCode(caseNode->expression, param);
4409
0
      fxCoderAddByte(param, -1, XS_CODE_STRICT_EQUAL);
4410
0
      fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, caseNode->target);
4411
0
    }
4412
0
    else
4413
0
      defaultNode = caseNode;
4414
0
    caseNode = (txCaseNode*)caseNode->next;
4415
0
  }
4416
0
  if (defaultNode)
4417
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, defaultNode->target);
4418
0
  else
4419
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, coder->firstBreakTarget);
4420
0
  caseNode = (txCaseNode*)self->items->first;
4421
0
  while (caseNode) {
4422
0
    fxCoderAdd(param, 0, caseNode->target);
4423
0
    if (caseNode->statement)
4424
0
      fxNodeDispatchCode(caseNode->statement, param);
4425
0
    caseNode = (txCaseNode*)caseNode->next;
4426
0
  }
4427
0
  fxCoderAdd(param, 0, coder->firstBreakTarget);
4428
0
  coder->firstBreakTarget = breakTarget->nextTarget;
4429
0
  if (self->scope->disposableNodeCount)
4430
0
    fxScopeCodeUsed(self->scope, coder, &context);
4431
0
  fxScopeCoded(self->scope, param);
4432
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4433
0
}
4434
4435
void fxTemplateNodeCode(void* it, void* param) 
4436
0
{
4437
0
  txTemplateNode* self = it;
4438
0
  txCoder* coder = param;
4439
0
  txParser* parser = coder->parser;
4440
0
  txNode* item = self->items->first;
4441
  
4442
0
  if (self->reference) {
4443
0
    txSymbol* symbol;
4444
0
    txTargetCode* cacheTarget = fxCoderCreateTarget(param);
4445
0
    txInteger i = (self->items->length / 2) + 1;
4446
0
    txInteger raws = fxCoderUseTemporaryVariable(param);
4447
0
    txInteger strings = fxCoderUseTemporaryVariable(param);
4448
0
    txFlag flag = XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG;
4449
4450
0
    fxNodeDispatchCodeThis(self->reference, param, 0);
4451
0
    fxCoderAddByte(param, 1, XS_CODE_CALL);
4452
4453
0
    fxGenerateTag(parser->console, parser->buffer, parser->bufferSize, (parser->path) ? parser->path->string : C_NULL);
4454
0
    symbol = fxNewParserSymbol(parser, parser->buffer);
4455
0
    fxCoderAddByte(param, 1, XS_CODE_TEMPLATE_CACHE);
4456
0
    fxCoderAddSymbol(param, 0, XS_CODE_GET_PROPERTY, symbol);
4457
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_COALESCE_1, cacheTarget);
4458
0
    fxCoderAddByte(param, 1, XS_CODE_TEMPLATE_CACHE);
4459
4460
0
    fxCoderAddByte(param, 1, XS_CODE_ARRAY);
4461
0
    fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, strings);
4462
0
    fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, i);
4463
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, coder->parser->lengthSymbol);
4464
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4465
0
    fxCoderAddByte(param, 1, XS_CODE_ARRAY);
4466
0
    fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, raws);
4467
0
    fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, i);
4468
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, coder->parser->lengthSymbol);
4469
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4470
0
    i = 0;
4471
0
    while (item) {
4472
0
      if (item->description->token == XS_TOKEN_TEMPLATE_MIDDLE) {
4473
    
4474
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, strings);
4475
0
        fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, i);
4476
0
        fxCoderAddByte(param, 0, XS_CODE_AT);
4477
0
        if (((txTemplateItemNode*)item)->string->flags & mxStringErrorFlag)
4478
0
          fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4479
0
        else
4480
0
          fxNodeDispatchCode(((txTemplateItemNode*)item)->string, param);
4481
0
        fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
4482
0
        fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, flag);
4483
      
4484
0
        fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, raws);
4485
0
        fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, i);
4486
0
        fxCoderAddByte(param, 0, XS_CODE_AT);
4487
0
        fxNodeDispatchCode(((txTemplateItemNode*)item)->raw, param);
4488
0
        fxCoderAddByte(param, -3, XS_CODE_NEW_PROPERTY_AT);
4489
0
        fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, flag);
4490
      
4491
0
        i++;
4492
0
      }
4493
0
      item = item->next;
4494
0
    }
4495
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, strings);
4496
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, raws);
4497
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, parser->rawSymbol);
4498
0
    fxCoderAddByte(param, -1, XS_CODE_POP);
4499
0
    fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, strings);
4500
0
    fxCoderAddByte(param, 0, XS_CODE_TEMPLATE);
4501
    
4502
0
    fxCoderAddSymbol(param, -1, XS_CODE_SET_PROPERTY, symbol);
4503
    
4504
0
    fxCoderAdd(param, 0, cacheTarget);
4505
    
4506
0
    i = 1;
4507
0
    item = self->items->first;
4508
0
    while (item) {
4509
0
      if (item->description->token != XS_TOKEN_TEMPLATE_MIDDLE) {
4510
0
        fxNodeDispatchCode(item, param);
4511
0
        i++;
4512
0
      }
4513
0
      item = item->next;
4514
0
    }
4515
0
    fxCoderAddInteger(param, -2 - i, (self->flags & mxTailRecursionFlag) ? XS_CODE_RUN_TAIL_1 : XS_CODE_RUN_1, i);
4516
0
    fxCoderUnuseTemporaryVariables(coder, 2);
4517
0
  }
4518
0
  else {
4519
0
    fxNodeDispatchCode(((txTemplateItemNode*)item)->string, param);
4520
0
    item = item->next;
4521
0
    while (item) {
4522
0
      if (item->description->token == XS_TOKEN_TEMPLATE_MIDDLE) {
4523
0
        fxNodeDispatchCode(((txTemplateItemNode*)item)->string, param);
4524
0
      }
4525
0
      else {
4526
0
        fxNodeDispatchCode(item, param);
4527
0
        fxCoderAddByte(param, 1, XS_CODE_TO_STRING);
4528
0
      }
4529
0
      fxCoderAddByte(param, -1, XS_CODE_ADD);
4530
0
      item = item->next;
4531
0
    }
4532
0
  }
4533
0
}
4534
4535
void fxThisNodeCode(void* it, void* param) 
4536
0
{
4537
0
  txNode* self = it;
4538
0
  if (self->flags & mxDerivedFlag)
4539
0
    fxCoderAddByte(param, 1, XS_CODE_GET_THIS);
4540
0
  else
4541
0
    fxCoderAddByte(param, 1, self->description->code);
4542
0
}
4543
4544
void fxThrowNodeCode(void* it, void* param) 
4545
0
{
4546
0
  txStatementNode* self = it;
4547
0
  fxNodeDispatchCode(self->expression, param);
4548
0
  fxCoderAddByte(param, -1, XS_CODE_THROW);
4549
0
}
4550
4551
void fxTryNodeCode(void* it, void* param) 
4552
0
{
4553
0
  txTryNode* self = it;
4554
0
  txCoder* coder = param;
4555
0
  txInteger exception;
4556
0
  txInteger selector;
4557
0
  txInteger result;
4558
0
  txInteger selection;
4559
0
  txTargetCode* catchTarget;
4560
0
  txTargetCode* normalTarget;
4561
0
  txTargetCode* finallyTarget;
4562
4563
0
  exception = fxCoderUseTemporaryVariable(coder);
4564
0
  selector = fxCoderUseTemporaryVariable(coder);
4565
0
  result = fxCoderUseTemporaryVariable(coder);
4566
4567
0
  coder->firstBreakTarget = fxCoderAliasTargets(param, coder->firstBreakTarget);
4568
0
  coder->firstContinueTarget = fxCoderAliasTargets(param, coder->firstContinueTarget);
4569
0
  coder->returnTarget = fxCoderAliasTargets(param, coder->returnTarget);
4570
0
  catchTarget = fxCoderCreateTarget(param);
4571
0
  normalTarget = fxCoderCreateTarget(param);
4572
0
  finallyTarget = fxCoderCreateTarget(param);
4573
4574
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, 0);
4575
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, selector);
4576
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4577
4578
0
  fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
4579
0
  if (coder->programFlag) {
4580
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4581
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4582
0
  }
4583
0
  fxNodeDispatchCode(self->tryBlock, param);
4584
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, normalTarget);
4585
0
  if (self->catchBlock) {
4586
0
    fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
4587
0
    fxCoderAdd(param, 0, catchTarget);
4588
0
    catchTarget = fxCoderCreateTarget(param);
4589
0
    fxCoderAddBranch(param, 0, XS_CODE_CATCH_1, catchTarget);
4590
0
    if (coder->programFlag) {
4591
0
      fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4592
0
      fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4593
0
    }
4594
0
    fxNodeDispatchCode(self->catchBlock, param);
4595
0
    fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, normalTarget);
4596
0
  }
4597
  
4598
0
  selection = 1;
4599
0
  coder->firstBreakTarget = fxCoderFinalizeTargets(param, coder->firstBreakTarget, selector, &selection, finallyTarget);
4600
0
  coder->firstContinueTarget = fxCoderFinalizeTargets(param, coder->firstContinueTarget, selector, &selection, finallyTarget);
4601
0
  coder->returnTarget = fxCoderFinalizeTargets(param, coder->returnTarget, selector, &selection, finallyTarget);
4602
0
  fxCoderAdd(param, 0, normalTarget);
4603
0
  fxCoderAddInteger(param, 1, XS_CODE_INTEGER_1, selection);
4604
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, selector);
4605
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4606
0
  fxCoderAdd(param, 0, finallyTarget);
4607
0
  fxCoderAddByte(param, 0, XS_CODE_UNCATCH);
4608
0
  fxCoderAdd(param, 0, catchTarget);
4609
0
  fxCoderAddByte(param, 1, XS_CODE_EXCEPTION);
4610
0
  fxCoderAddIndex(param, 0, XS_CODE_SET_LOCAL_1, exception);
4611
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4612
0
  if (self->finallyBlock) {
4613
0
    if (coder->programFlag) {
4614
0
      fxCoderAddByte(param, 1, XS_CODE_GET_RESULT);
4615
0
      fxCoderAddIndex(param, -1, XS_CODE_PULL_LOCAL_1, result);
4616
0
      fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4617
0
      fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4618
0
    }
4619
0
    fxNodeDispatchCode(self->finallyBlock, param);
4620
0
    if (coder->programFlag) {
4621
0
      fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, result);
4622
0
      fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4623
0
    }    
4624
0
  }
4625
0
  catchTarget = fxCoderCreateTarget(param);
4626
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, selector);
4627
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_IF_1, catchTarget);
4628
0
  fxCoderAddIndex(param, 1, XS_CODE_GET_LOCAL_1, exception);
4629
0
  fxCoderAddByte(param, -1, XS_CODE_THROW);
4630
0
  fxCoderAdd(param, 0, catchTarget);
4631
0
  selection = 1;
4632
0
  fxCoderJumpTargets(param, coder->firstBreakTarget, selector, &selection);
4633
0
  fxCoderJumpTargets(param, coder->firstContinueTarget, selector, &selection);
4634
0
  fxCoderJumpTargets(param, coder->returnTarget, selector, &selection);
4635
0
  fxCoderUnuseTemporaryVariables(coder, 3);
4636
0
}
4637
4638
void fxUnaryExpressionNodeCode(void* it, void* param) 
4639
0
{
4640
0
  txUnaryExpressionNode* self = it;
4641
0
  fxNodeDispatchCode(self->right, param);
4642
0
  fxCoderAddByte(param, 0, self->description->code);
4643
0
}
4644
4645
void fxUndefinedNodeCodeAssign(void* it, void* param, txFlag flag) 
4646
0
{
4647
0
  txCoder* coder = param;
4648
0
  fxCoderAddSymbol(param, -1, XS_CODE_SET_VARIABLE, coder->parser->undefinedSymbol);
4649
0
}
4650
4651
void fxUndefinedNodeCodeDelete(void* it, void* param) 
4652
0
{
4653
0
  txNode* self = it;
4654
0
  txCoder* coder = param;
4655
0
  if (self->flags & mxStrictFlag)
4656
0
    fxReportParserError(coder->parser, self->line, "delete identifier (strict code)");
4657
0
  fxCoderAddByte(param, 1, XS_CODE_FALSE);
4658
0
}
4659
4660
void fxUndefinedNodeCodeReference(void* it, void* param, txFlag flag) 
4661
0
{
4662
0
  txCoder* coder = param;
4663
0
  if (coder->evalFlag)
4664
0
    fxCoderAddSymbol(param, 1, XS_CODE_EVAL_REFERENCE, coder->parser->undefinedSymbol);
4665
0
  else
4666
0
    fxCoderAddSymbol(param, 1, XS_CODE_PROGRAM_REFERENCE, coder->parser->undefinedSymbol);
4667
0
}
4668
4669
void fxValueNodeCode(void* it, void* param) 
4670
0
{
4671
0
  txNode* self = it;
4672
0
  fxCoderAddByte(param, 1, self->description->code);
4673
0
}
4674
4675
void fxWhileNodeCode(void* it, void* param) 
4676
0
{
4677
0
  txWhileNode* self = it;
4678
0
  txCoder* coder = param;
4679
0
  if (coder->programFlag) {
4680
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4681
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4682
0
  }
4683
0
  fxCoderAdd(param, 0, coder->firstContinueTarget);
4684
0
  fxNodeDispatchCode(self->expression, param);
4685
0
  fxCoderAddBranch(param, -1, XS_CODE_BRANCH_ELSE_1, coder->firstBreakTarget);
4686
0
  fxNodeDispatchCode(self->statement, param);
4687
0
  fxCoderAddBranch(param, 0, XS_CODE_BRANCH_1, coder->firstContinueTarget);
4688
0
}
4689
4690
void fxWithNodeCode(void* it, void* param)
4691
0
{
4692
0
  txWithNode* self = it;
4693
0
  txCoder* coder = param;
4694
0
  txBoolean evalFlag;
4695
0
  fxNodeDispatchCode(self->expression, param);
4696
0
  fxCoderAddByte(param, 0, XS_CODE_TO_INSTANCE);
4697
0
  fxCoderAddByte(param, 0, XS_CODE_WITH);
4698
0
  fxCoderAddByte(param, -1, XS_CODE_POP);
4699
0
  evalFlag = coder->evalFlag;
4700
0
  coder->environmentLevel++;
4701
0
  coder->evalFlag = 1;
4702
0
  if (coder->programFlag) {
4703
0
    fxCoderAddByte(param, 1, XS_CODE_UNDEFINED);
4704
0
    fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4705
0
  }
4706
0
  fxNodeDispatchCode(self->statement, param);
4707
0
  coder->evalFlag = evalFlag;
4708
0
  coder->environmentLevel--;
4709
0
  fxCoderAddByte(param, 0, XS_CODE_WITHOUT);
4710
0
}
4711
4712
void fxYieldNodeCode(void* it, void* param) 
4713
0
{
4714
0
  txStatementNode* self = it;
4715
0
  txBoolean async = (self->flags & mxAsyncFlag) ? 1 : 0;
4716
0
  txCoder* coder = param;
4717
0
  txTargetCode* target = fxCoderCreateTarget(coder);
4718
0
  if (async) {
4719
0
    fxNodeDispatchCode(self->expression, param);
4720
0
  }
4721
0
  else {
4722
0
    fxCoderAddByte(param, 1, XS_CODE_OBJECT);
4723
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
4724
0
    fxNodeDispatchCode(self->expression, param);
4725
0
    fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, coder->parser->valueSymbol);
4726
0
    fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, 0);
4727
0
    fxCoderAddByte(param, 1, XS_CODE_DUB);
4728
0
    fxCoderAddByte(param, 1, XS_CODE_FALSE);
4729
0
    fxCoderAddSymbol(param, -2, XS_CODE_NEW_PROPERTY, coder->parser->doneSymbol);
4730
0
    fxCoderAddInteger(param, 0, XS_CODE_INTEGER_1, 0);
4731
0
  }
4732
0
  fxCoderAddByte(coder, 0, XS_CODE_YIELD);
4733
0
  fxCoderAddBranch(coder, 1, XS_CODE_BRANCH_STATUS_1, target);
4734
0
  if (async) {
4735
0
    fxCoderAddByte(param, 0, XS_CODE_AWAIT);
4736
0
    fxCoderAddByte(coder, 0, XS_CODE_THROW_STATUS);
4737
0
  }
4738
0
  fxCoderAddByte(param, -1, XS_CODE_SET_RESULT);
4739
0
  fxCoderAdjustEnvironment(coder, coder->returnTarget);
4740
0
  fxCoderAdjustScope(coder, coder->returnTarget);
4741
0
  fxCoderAddBranch(coder, 0, XS_CODE_BRANCH_1, coder->returnTarget);
4742
0
  fxCoderAdd(coder, 0, target);
4743
0
}
4744