Coverage Report

Created: 2026-10-17 07:17

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