UNPKG

334 kBJavaScriptView Raw
1import Ast, { TypeGuards, SyntaxKind, TypeFlags, DiagnosticCategory, Symbol as Symbol$1, ts, Scope } from 'ts-simple-ast';
2import stringify from 'safe-stable-stringify';
3import _ from 'lodash';
4import { BYTECODE_TO_BYTECODE_BUFFER, OPCODE_TO_BYTECODE, BinaryWriter, UnknownOpError, utils, ScriptBuilder } from '@neo-one/client-core';
5import BN from 'bn.js';
6import path__default, { sep, join, dirname } from 'path';
7import 'app-root-dir';
8import { pathExists, readFileSync, existsSync } from 'fs-extra';
9import Blockchain from '@neo-one/node-blockchain';
10import levelup from 'levelup';
11import levelUpStorage from '@neo-one/node-storage-levelup';
12import memdown from 'memdown';
13import { test } from '@neo-one/node-neo-settings';
14import vm from '@neo-one/node-vm';
15
16function _defineProperty(obj, key, value) {
17 if (key in obj) {
18 Object.defineProperty(obj, key, {
19 value: value,
20 enumerable: true,
21 configurable: true,
22 writable: true
23 });
24 } else {
25 obj[key] = value;
26 }
27
28 return obj;
29}
30
31function _objectSpread(target) {
32 for (var i = 1; i < arguments.length; i++) {
33 var source = arguments[i] != null ? arguments[i] : {};
34 var ownKeys = Object.keys(source);
35
36 if (typeof Object.getOwnPropertySymbols === 'function') {
37 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
38 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
39 }));
40 }
41
42 ownKeys.forEach(function (key) {
43 _defineProperty(target, key, source[key]);
44 });
45 }
46
47 return target;
48}
49
50class JumpTable {
51 constructor() {
52 _defineProperty(this, "jumpNumber", 0);
53
54 _defineProperty(this, "table", []);
55 }
56
57 add(sb, node, body) {
58 const jumpNumber = this.jumpNumber;
59 this.jumpNumber += 1;
60 const {
61 bytecode
62 } = sb.capture(() => {
63 body();
64 });
65 this.table.push({
66 jumpNumber,
67 node,
68 bytecode
69 });
70 return jumpNumber;
71 }
72
73 emitTable(sb, outerNode) {
74 this.table.forEach(({
75 node,
76 jumpNumber,
77 bytecode
78 }) => {
79 sb.emitHelper(node, {}, sb.helpers.if({
80 condition: () => {
81 sb.emitOp(node, 'DUP');
82 sb.emitPushInt(node, jumpNumber);
83 sb.emitOp(node, 'NUMEQUAL');
84 },
85 whenTrue: () => {
86 sb.emitOp(node, 'DROP');
87 sb.emitBytecode(bytecode);
88 }
89 }));
90 });
91 sb.emitOp(outerNode, 'THROW');
92 }
93
94}
95
96class ProgramCounter {}
97
98class DeferredProgramCounter extends ProgramCounter {
99 constructor(offset) {
100 super();
101 this.offset = offset;
102
103 _defineProperty(this, "pc", void 0);
104 }
105
106 plus(offset) {
107 return new DeferredProgramCounter((this.offset || 0) + offset);
108 }
109
110 equals(other) {
111 return this === other;
112 }
113
114 setPC(pc) {
115 this.pc = pc;
116 }
117
118 getPC() {
119 if (this.pc == null) {
120 throw new Error('Unknown PC');
121 }
122
123 return this.pc.getPC() + (this.offset || 0);
124 }
125
126}
127
128class Jump {
129 constructor(op, pc) {
130 this.op = op;
131 this.pc = pc;
132 }
133
134}
135
136class Call extends Jump {
137 constructor(pc) {
138 super('CALL', pc);
139 }
140
141 plus(pc) {
142 return new Call(this.pc.plus(pc));
143 }
144
145}
146
147class Jmp extends Jump {
148 constructor(op, pc) {
149 super(op, pc);
150 }
151
152 plus(pc) {
153 return new Jmp(this.op, this.pc.plus(pc));
154 }
155
156}
157
158class KnownProgramCounter extends ProgramCounter {
159 constructor(pc) {
160 super();
161 this.pc = pc;
162 }
163
164 plus(offset) {
165 return new KnownProgramCounter(this.pc + offset);
166 }
167
168 equals(other) {
169 return other instanceof KnownProgramCounter && this.pc === other.pc;
170 }
171
172 getPC() {
173 return this.pc;
174 }
175
176}
177
178class LastProgramCounter extends ProgramCounter {
179 constructor(startPC, offset) {
180 super();
181 this.startPC = startPC;
182 this.offset = offset;
183
184 _defineProperty(this, "pc", void 0);
185
186 _defineProperty(this, "children", []);
187 }
188
189 plus(offset) {
190 const pc = new LastProgramCounter(this.startPC, (this.offset || 0) + offset);
191 this.children.push(pc);
192
193 if (this.pc != null) {
194 pc.setPC(this.pc);
195 }
196
197 return pc;
198 }
199
200 equals(other) {
201 return other instanceof LastProgramCounter && this.startPC === other.startPC && this.offset === other.offset;
202 }
203
204 setPC(pc) {
205 this.pc = pc;
206 this.children.forEach(child => {
207 child.setPC(pc);
208 });
209 }
210
211 getPC() {
212 if (this.pc == null) {
213 throw new Error('Unknown PC');
214 }
215
216 return this.pc + (this.offset || 0);
217 }
218
219}
220
221class ProgramCounterHelper {
222 constructor(pc) {
223 _defineProperty(this, "pc", void 0);
224
225 _defineProperty(this, "first", void 0);
226
227 _defineProperty(this, "last", void 0);
228
229 this.pc = pc;
230 this.first = new KnownProgramCounter(this.pc());
231 this.last = new LastProgramCounter(this.pc());
232 }
233
234 getFirst() {
235 return this.first;
236 }
237
238 getCurrent() {
239 return new KnownProgramCounter(this.pc());
240 }
241
242 getLast() {
243 return this.last;
244 }
245
246 setLast() {
247 this.last.setPC(this.pc());
248 }
249
250}
251
252class NodeCompiler {
253 constructor() {
254 _defineProperty(this, "kind", void 0);
255 }
256
257}
258
259class Helper {
260 emitGlobal(sb, node, options) {// do nothing
261 }
262
263}
264
265// Input: [array]
266// Output: [array]
267class ArrFilterHelper extends Helper {
268 constructor(options) {
269 super();
270
271 _defineProperty(this, "map", void 0);
272
273 _defineProperty(this, "withIndex", void 0);
274
275 this.map = options.map;
276 this.withIndex = options.withIndex || false;
277 }
278
279 emit(sb, node, options) {
280 if (!options.pushValue) {
281 sb.emitOp(node, 'DROP');
282 return;
283 } // [size, ...array]
284
285
286 sb.emitOp(node, 'UNPACK'); // [0, size, ...array]
287
288 sb.emitPushInt(node, 0); // [arr, size, ...array]
289
290 sb.emitOp(node, 'NEWARRAY'); // [size, arr, ...array]
291
292 sb.emitOp(node, 'SWAP'); // [idx, size, arr, ...array]
293
294 sb.emitPushInt(node, 0);
295 sb.emitHelper(node, options, sb.helpers.forLoop({
296 condition: () => {
297 // [size, idx, arr, ...array]
298 sb.emitOp(node, 'SWAP'); // [size, idx, size, arr, ...array]
299
300 sb.emitOp(node, 'TUCK'); // [idx, size, idx, size, arr, ...array]
301
302 sb.emitOp(node, 'OVER'); // size > idx
303 // [size > idx, idx, size, arr, ...array]
304
305 sb.emitOp(node, 'GT');
306 },
307 each: () => {
308 // [arr, idx, size, ...array]
309 sb.emitOp(node, 'ROT'); // [idx, arr, idx, size, ...array]
310
311 sb.emitOp(node, 'OVER');
312
313 if (this.withIndex) {
314 // [4, idx, arr, idx, size, ...array]
315 sb.emitPushInt(node, 4); // [value, idx, arr, idx, size, ...array]
316
317 sb.emitOp(node, 'ROLL'); // [value, idx, value, arr, idx, size, ...array]
318
319 sb.emitOp(node, 'TUCK');
320 } else {
321 // [3, arr, idx, size, ...array]
322 sb.emitPushInt(node, 3); // [value, arr, idx, size, ...array]
323
324 sb.emitOp(node, 'ROLL'); // [value, value, arr, idx, size, ...array]
325
326 sb.emitOp(node, 'DUP');
327 }
328
329 sb.emitHelper(node, options, sb.helpers.if({
330 condition: () => {
331 // [keepVal, value, arr, idx, size, ...array]
332 this.map(); // [keep, value, arr, idx, size, ...array]
333
334 sb.emitHelper(node, options, sb.helpers.toBoolean({
335 type: undefined
336 }));
337 },
338 whenTrue: () => {
339 // [arr, value, arr, idx, size, ...array]
340 sb.emitOp(node, 'OVER'); // [value, arr, arr, idx, size, ...array]
341
342 sb.emitOp(node, 'SWAP'); // [arr, idx, size, ...array]
343
344 sb.emitOp(node, 'APPEND');
345 },
346 whenFalse: () => {
347 // [arr, idx, size, ...array]
348 sb.emitOp(node, 'DROP');
349 }
350 })); // [size, arr, idx, ...array]
351
352 sb.emitOp(node, 'ROT'); // [idx, size, arr, ...array]
353
354 sb.emitOp(node, 'ROT');
355 },
356 incrementor: () => {
357 // [idx, size, arr, ...array]
358 sb.emitOp(node, 'INC');
359 }
360 })); // [size, arr]
361
362 sb.emitOp(node, 'DROP'); // [arr]
363
364 sb.emitOp(node, 'DROP');
365 }
366
367}
368
369// Input: [array]
370// Output: []
371class ArrForEachHelper extends Helper {
372 constructor(options) {
373 super();
374
375 _defineProperty(this, "each", void 0);
376
377 _defineProperty(this, "withIndex", void 0);
378
379 this.each = options.each;
380 this.withIndex = options.withIndex || false;
381 }
382
383 emit(sb, node, options) {
384 if (!options.pushValue) {
385 sb.emitOp(node, 'DROP');
386 return;
387 } // [size, ...array]
388
389
390 sb.emitOp(node, 'UNPACK'); // [idx, size, ...array]
391
392 sb.emitPushInt(node, 0);
393 sb.emitHelper(node, options, sb.helpers.forLoop({
394 condition: () => {
395 // [size, idx, ...array]
396 sb.emitOp(node, 'SWAP'); // [size, idx, size, ...array]
397
398 sb.emitOp(node, 'TUCK'); // [idx, size, idx, size, ...array]
399
400 sb.emitOp(node, 'OVER'); // size > idx
401 // [size > idx, idx, size, ...array]
402
403 sb.emitOp(node, 'GT');
404 },
405 each: () => {
406 // [value, idx, size, ...array]
407 sb.emitOp(node, 'ROT');
408
409 if (this.withIndex) {
410 // [idx, value, idx, size, ...array]
411 sb.emitOp(node, 'OVER'); // [value, idx, idx, size, ...array]
412
413 sb.emitOp(node, 'SWAP');
414 } // [idx, size, ...array]
415
416
417 this.each();
418 },
419 incrementor: () => {
420 // [idx, size, ...array]
421 sb.emitOp(node, 'INC');
422 }
423 })); // [size]
424
425 sb.emitOp(node, 'DROP'); // []
426
427 sb.emitOp(node, 'DROP');
428 }
429
430}
431
432// Input: [array]
433// Output: [array]
434class ArrMapHelper extends Helper {
435 constructor(options) {
436 super();
437
438 _defineProperty(this, "map", void 0);
439
440 _defineProperty(this, "withIndex", void 0);
441
442 this.map = options.map;
443 this.withIndex = options.withIndex || false;
444 }
445
446 emit(sb, node, options) {
447 if (!options.pushValue) {
448 sb.emitOp(node, 'DROP');
449 return;
450 } // [size, ...array]
451
452
453 sb.emitOp(node, 'UNPACK'); // [idx, size, ...array]
454
455 sb.emitPushInt(node, 0);
456 sb.emitHelper(node, options, sb.helpers.forLoop({
457 condition: () => {
458 // [size, idx, ...array]
459 sb.emitOp(node, 'SWAP'); // [size, idx, size, ...array]
460
461 sb.emitOp(node, 'TUCK'); // [idx, size, idx, size, ...array]
462
463 sb.emitOp(node, 'OVER'); // size > idx
464 // [size > idx, idx, size, ...array]
465
466 sb.emitOp(node, 'GT');
467 },
468 each: () => {
469 // [idx, idx, size, ...array]
470 sb.emitOp(node, 'DUP'); // [3, idx, idx, size, ...array]
471
472 sb.emitPushInt(node, 3); // [idx + 3, idx, size, ...array]
473
474 sb.emitOp(node, 'ADD');
475
476 if (this.withIndex) {
477 // [idx, idx + 3, idx, size, ...array]
478 sb.emitOp(node, 'OVER'); // [idx, idx, idx + 3, idx, size, ...array]
479
480 sb.emitOp(node, 'DUP'); // [4, idx, idx, idx + 3, idx, size, ...array]
481
482 sb.emitPushInt(node, 4); // [idx + 4, idx, idx + 3, idx, size, ...array]
483
484 sb.emitOp(node, 'ADD'); // [value, idx, idx + 3, idx, size, ...array]
485
486 sb.emitOp(node, 'ROLL');
487 } else {
488 // [idx + 3, idx + 3, idx, size, ...array]
489 sb.emitOp(node, 'DUP'); // [value, idx + 3, idx, size, ...array]
490
491 sb.emitOp(node, 'ROLL');
492 } // [value, idx + 3, idx, size, ...array]
493
494
495 this.map(); // [idx + 3, value, idx, size, ...array]
496
497 sb.emitOp(node, 'SWAP'); // [value, idx, size, ...array]
498
499 sb.emitOp(node, 'XTUCK'); // [idx, size, ...array]
500
501 sb.emitOp(node, 'DROP');
502 },
503 incrementor: () => {
504 // [idx, size, ...array]
505 sb.emitOp(node, 'INC');
506 }
507 })); // [size, ...array]
508
509 sb.emitOp(node, 'DROP'); // [array]
510
511 sb.emitOp(node, 'PACK');
512 }
513
514}
515
516// Input: [array]
517// Output: [array]
518class CloneArrayHelper extends Helper {
519 emit(sb, node, options) {
520 if (!options.pushValue) {
521 sb.emitOp(node, 'DROP');
522 return;
523 } // [array]
524
525
526 sb.emitOp(node, 'UNPACK'); // [...array]
527
528 sb.emitOp(node, 'PACK');
529 }
530
531}
532
533// Input: [length, arr]
534// Output: []
535class ExtendArrayHelper extends Helper {
536 emit(sb, node, optionsIn) {
537 const options = sb.pushValueOptions(optionsIn); // [arr, length, arr]
538
539 sb.emitOp(node, 'OVER'); // [currentLength, length, arr]
540
541 sb.emitOp(node, 'ARRAYSIZE');
542 sb.emitHelper(node, options, sb.helpers.forLoop({
543 condition: () => {
544 // [currentLength, length, currentLength, arr]
545 sb.emitOp(node, 'TUCK'); // [length, currentLength, length, currentLength, arr]
546
547 sb.emitOp(node, 'OVER'); // [expectedLengthGTCurrentLength, length, currentLength, arr]
548
549 sb.emitOp(node, 'LT');
550 },
551 each: () => {
552 // [arr, length, currentLength]
553 sb.emitOp(node, 'ROT'); // [arr, arr, length, currentLength]
554
555 sb.emitOp(node, 'DUP'); // [undefinedVal, arr, arr, length, currentLength]
556
557 sb.emitHelper(node, options, sb.helpers.createUndefined); // [arr, length, currentLength]
558
559 sb.emitOp(node, 'APPEND');
560 },
561 incrementor: () => {
562 // [currentLength, arr, length]
563 sb.emitOp(node, 'ROT'); // [currentLength, arr, length]
564
565 sb.emitOp(node, 'INC'); // [length, currentLength, arr]
566
567 sb.emitOp(node, 'ROT'); // [currentLength, length, arr]
568
569 sb.emitOp(node, 'SWAP');
570 }
571 })); // [length, arr]
572
573 sb.emitOp(node, 'DROP'); // [arr]
574
575 sb.emitOp(node, 'DROP'); // []
576
577 sb.emitOp(node, 'DROP');
578 }
579
580}
581
582// Input: [val]
583// Output: []
584class ForTypeHelper extends Helper {
585 constructor({
586 types,
587 defaultCase
588 }) {
589 super();
590
591 _defineProperty(this, "types", void 0);
592
593 _defineProperty(this, "defaultCase", void 0);
594
595 this.types = types;
596 this.defaultCase = defaultCase;
597 }
598
599 emit(sb, node, optionsIn) {
600 const noCastOptions = sb.noCastOptions(optionsIn);
601 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn));
602 let type = optionsIn.cast;
603
604 if (type == null) {
605 type = sb.getType(node);
606 }
607
608 const types = this.types.filter(testType => testType.isType(type));
609
610 const defaultCase = this.defaultCase || (innerOptions => {
611 sb.emitOp(node, 'DROP');
612 sb.emitHelper(node, innerOptions, sb.helpers.throwTypeError);
613 });
614
615 if (types.length === 0) {
616 defaultCase(noCastOptions);
617 } else if (types.length === 1) {
618 types[0].process(noCastOptions);
619 } else {
620 sb.emitHelper(node, options, sb.helpers.case(types.map(forType => ({
621 condition: () => {
622 sb.emitOp(node, 'DUP');
623 forType.isRuntimeType(options);
624 },
625 whenTrue: () => {
626 forType.process(noCastOptions);
627 }
628 })), () => {
629 defaultCase(noCastOptions);
630 }));
631 }
632 }
633
634}
635
636let SerializableType;
637
638(function (SerializableType) {
639 SerializableType[SerializableType["Array"] = 7] = "Array";
640 SerializableType[SerializableType["Buffer"] = 8] = "Buffer";
641})(SerializableType || (SerializableType = {}));
642
643const invokeGlobal = (sb, node, options, name) => {
644 // [1, val]
645 sb.emitPushInt(node, 1); // [argsarr]
646
647 sb.emitOp(node, 'PACK'); // [globalObjectVal, argsarr]
648
649 sb.scope.getGlobal(sb, node, options); // [name, globalObjectVal, argsarr]
650
651 sb.emitPushString(node, name); // [objectVal, argsarr]
652
653 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty); // [val]
654
655 sb.emitHelper(node, options, sb.helpers.invokeCall());
656};
657
658const SERIALIZE_NAME = 'genericSerialize';
659const invokeSerialize = (sb, node, options) => invokeGlobal(sb, node, options, SERIALIZE_NAME);
660const DESERIALIZE_NAME = 'genericDeserialize';
661const invokeDeserialize = (sb, node, options) => invokeGlobal(sb, node, options, DESERIALIZE_NAME);
662const serializeType = (sb, node, options, type) => {
663 // [type, arr]
664 sb.emitPushInt(node, type); // [2, type, arr]
665
666 sb.emitPushInt(node, 2); // [arr]
667
668 sb.emitOp(node, 'PACK');
669};
670const deserializeType = (sb, node, options) => {
671 // [1, arr]
672 sb.emitPushInt(node, 1); // [value]
673
674 sb.emitOp(node, 'PICKITEM');
675};
676
677const isSerializedType = (sb, node, options, type) => {
678 // [0, val]
679 sb.emitPushInt(node, 0); // [type]
680
681 sb.emitOp(node, 'PICKITEM'); // [type, type]
682
683 sb.emitPushInt(node, type); // [isSerializedType]
684
685 sb.emitOp(node, 'NUMEQUAL');
686};
687
688const getTypes = (sb, node, options) => [{
689 isRuntimeType: () => {
690 // [isBoolean]
691 sb.emitHelper(node, options, sb.helpers.isBoolean);
692 },
693 serialize: () => {// do nothing
694 },
695 isSerializedType: () => {
696 // [isBoolean]
697 sb.emitHelper(node, options, sb.helpers.isBoolean);
698 },
699 deserialize: () => {// do nothing
700 }
701}, {
702 isRuntimeType: () => {
703 // [isString]
704 sb.emitHelper(node, options, sb.helpers.isString);
705 },
706 serialize: () => {// do nothing
707 },
708 isSerializedType: () => {
709 // [isString]
710 sb.emitHelper(node, options, sb.helpers.isString);
711 },
712 deserialize: () => {// do nothing
713 }
714}, {
715 isRuntimeType: () => {
716 // [isNumber]
717 sb.emitHelper(node, options, sb.helpers.isNumber);
718 },
719 serialize: () => {// do nothing
720 },
721 isSerializedType: () => {
722 // [isNumber]
723 sb.emitHelper(node, options, sb.helpers.isNumber);
724 },
725 deserialize: () => {// do nothing
726 }
727}, {
728 isRuntimeType: () => {
729 // [Array, val]
730 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
731 property: 'Buffer'
732 })); // [val instanceof Array]
733
734 sb.emitHelper(node, options, sb.helpers.instanceof);
735 },
736 serialize: () => {
737 // [bytearray]
738 sb.emitHelper(node, options, sb.helpers.unwrapBuffer); // [arr]
739
740 serializeType(sb, node, options, SerializableType.Buffer);
741 },
742 isSerializedType: () => {
743 isSerializedType(sb, node, options, SerializableType.Buffer);
744 },
745 deserialize: () => {
746 deserializeType(sb, node, options); // [val]
747
748 sb.emitHelper(node, options, sb.helpers.wrapBuffer);
749 }
750}, {
751 isRuntimeType: () => {
752 // [Array, val]
753 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
754 property: 'Array'
755 })); // [val instanceof Array]
756
757 sb.emitHelper(node, options, sb.helpers.instanceof);
758 },
759 serialize: () => {
760 // [arr]
761 sb.emitHelper(node, options, sb.helpers.unwrapArray); // [arr]
762
763 sb.emitHelper(node, options, sb.helpers.arrMap({
764 map: () => {
765 invokeSerialize(sb, node, options);
766 }
767 })); // [value]
768
769 serializeType(sb, node, options, SerializableType.Array);
770 },
771 isSerializedType: () => {
772 isSerializedType(sb, node, options, SerializableType.Array);
773 },
774 deserialize: () => {
775 // [arr]
776 deserializeType(sb, node, options); // [arr]
777
778 sb.emitHelper(node, options, sb.helpers.arrMap({
779 map: () => {
780 invokeDeserialize(sb, node, options);
781 }
782 })); // [val]
783
784 sb.emitHelper(node, options, sb.helpers.wrapArray);
785 }
786}];
787
788// Input: []
789// Output: [argsArray]
790class ArgumentsHelper extends Helper {
791 emit(sb, node, options) {
792 // Push the arguments
793 const args = [...node.getArguments()].reverse();
794
795 for (const arg of args) {
796 sb.visit(arg, sb.pushValueOptions(options));
797 } // [length, ...args]
798
799
800 sb.emitPushInt(node, args.length); // [argsarr]
801
802 sb.emitOp(node, 'PACK');
803 }
804
805}
806
807let InternalFunctionProperties;
808
809(function (InternalFunctionProperties) {
810 InternalFunctionProperties["CALL"] = "call";
811 InternalFunctionProperties["CONSTRUCT"] = "construct";
812})(InternalFunctionProperties || (InternalFunctionProperties = {}));
813
814// Output: [objectVal]
815
816// Input: [objectVal, this]
817// Output: [objectVal]
818class BindFunctionObjectThisHelper extends Helper {
819 constructor(options) {
820 super();
821
822 _defineProperty(this, "property", void 0);
823
824 _defineProperty(this, "both", void 0);
825
826 _defineProperty(this, "overwrite", void 0);
827
828 if (options.type === 'both') {
829 this.property = InternalFunctionProperties.CALL;
830 this.both = true;
831 } else {
832 this.property = options.property;
833 this.both = false;
834 }
835
836 this.overwrite = options.overwrite;
837 }
838
839 emit(sb, node, options) {
840 if (!options.pushValue) {
841 sb.emitOp(node, 'DROP');
842 return;
843 } // [objectVal, this]
844
845
846 sb.emitHelper(node, options, sb.helpers.cloneFunctionObject(this.both ? {
847 type: 'both'
848 } : {
849 type: 'single',
850 property: this.property
851 })); // [this, objectVal]
852
853 sb.emitOp(node, 'SWAP');
854
855 if (this.both) {
856 this.bindThis(sb, node, options, InternalFunctionProperties.CALL);
857 this.bindThis(sb, node, options, InternalFunctionProperties.CONSTRUCT);
858 } else {
859 this.bindThis(sb, node, options, this.property);
860 }
861
862 sb.emitOp(node, 'DROP');
863 }
864
865 bindThis(sb, node, options, property) {
866 // [this, objectVal, this]
867 sb.emitOp(node, 'TUCK'); // [objectVal, this, objectVal, this]
868
869 sb.emitOp(node, 'OVER'); // [property, objectVal, this, objectVal, this]
870
871 sb.emitPushString(node, property); // [func, this, objectVal, this]
872
873 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty); // [func, objectVal, this]
874
875 sb.emitHelper(node, options, sb.helpers.bindFunctionThis({
876 overwrite: this.overwrite
877 })); // [objectVal, this]
878
879 sb.emitOp(node, 'DROP'); // [this, objectVal]
880
881 sb.emitOp(node, 'SWAP');
882 }
883
884}
885
886// Input: [func, this]
887// Output: [func]
888class BindFunctionThisHelper extends Helper {
889 constructor(options) {
890 super();
891
892 _defineProperty(this, "overwrite", void 0);
893
894 this.overwrite = options.overwrite;
895 }
896
897 emit(sb, node, options) {
898 if (!options.pushValue) {
899 sb.emitOp(node, 'DROP');
900 sb.emitOp(node, 'DROP');
901 return;
902 }
903
904 let whenTrue;
905
906 if (this.overwrite) {
907 whenTrue = () => {
908 // [this, func, func]
909 sb.emitOp(node, 'SWAP'); // [2, this, func, func]
910
911 sb.emitPushInt(node, 2); // [func]
912
913 sb.emitOp(node, 'SETITEM');
914 };
915 } else {
916 whenTrue = () => {
917 // [this, func]
918 sb.emitOp(node, 'DROP'); // [func]
919
920 sb.emitOp(node, 'DROP');
921 };
922 } // [func, this]
923
924
925 sb.emitHelper(node, options, sb.helpers.cloneFunction); // [func, this, func]
926
927 sb.emitOp(node, 'TUCK'); // [func, func, this, func]
928
929 sb.emitOp(node, 'DUP'); // [func]
930
931 sb.emitHelper(node, options, sb.helpers.if({
932 condition: () => {
933 // [size, func, this, func]
934 sb.emitOp(node, 'ARRAYSIZE'); // [3, size, func, this, func]
935
936 sb.emitPushInt(node, 3); // [hasThis, func, this, func]
937
938 sb.emitOp(node, 'NUMEQUAL');
939 },
940 whenTrue,
941 whenFalse: () => {
942 // [this, func, func]
943 sb.emitOp(node, 'SWAP'); // [func]
944
945 sb.emitOp(node, 'APPEND');
946 }
947 }));
948 }
949
950}
951
952class CallHelper extends Helper {
953 emit(sb, node, optionsIn) {
954 const options = sb.pushValueOptions(optionsIn); // Push the scopes and this to the alt stack
955 // [func, func]
956
957 sb.emitOp(node, 'DUP'); // [1, func, func]
958
959 sb.emitPushInt(node, 1); // [[scopes, this], func]
960
961 sb.emitOp(node, 'PICKITEM'); // [[scopes, this], func]
962
963 sb.emitHelper(node, options, sb.helpers.cloneArray); // [[scopes, this], [scopes, this], func]
964
965 sb.emitOp(node, 'DUP'); // [0, [scopes, this], [scopes, this], func]
966
967 sb.emitPushInt(node, 0); // [[scopes, this], 0, [scopes, this], [scopes, this], func]
968
969 sb.emitOp(node, 'OVER'); // [0, [scopes, this], 0, [scopes, this], [scopes, this], func]
970
971 sb.emitPushInt(node, 0); // [scopes, 0, [scopes, this], [scopes, this], func]
972
973 sb.emitOp(node, 'PICKITEM'); // [scopes, 0, [scopes, this], [scopes, this], func]
974
975 sb.emitHelper(node, options, sb.helpers.cloneArray); // [[scopes, this], func]
976
977 sb.emitOp(node, 'SETITEM'); // [func, [scopes, this], func]
978
979 sb.emitOp(node, 'OVER'); // [[scopes, this], func]
980
981 sb.emitHelper(node, options, sb.helpers.if({
982 condition: () => {
983 // [size, [scopes, this], func]
984 sb.emitOp(node, 'ARRAYSIZE'); // [3, size, [scopes, this], func]
985
986 sb.emitPushInt(node, 3); // [size === 3, [scopes, this], func]
987
988 sb.emitOp(node, 'NUMEQUAL');
989 },
990 whenTrue: () => {
991 // [func, [scopes, this], func]
992 sb.emitOp(node, 'OVER'); // [2, func, [scopes, this], func]
993
994 sb.emitPushInt(node, 2); // [this, [scopes, this], func]
995
996 sb.emitOp(node, 'PICKITEM'); // [[scopes, this], this, [scopes, this], func]
997
998 sb.emitOp(node, 'OVER'); // [1, [scopes, this], this, [scopes, this], func]
999
1000 sb.emitPushInt(node, 1); // [this, 1, [scopes, this], [scopes, this], func]
1001
1002 sb.emitOp(node, 'ROT'); // [[scopes, this], func]
1003
1004 sb.emitOp(node, 'SETITEM');
1005 }
1006 })); // [func]
1007
1008 sb.emitOp(node, 'TOALTSTACK'); // Push the target on the stack
1009 // [0, func]
1010
1011 sb.emitPushInt(node, 0); // [target]
1012
1013 sb.emitOp(node, 'PICKITEM'); // Call function
1014
1015 sb.emitCall(node); // Remove scope
1016
1017 sb.emitOp(node, 'FROMALTSTACK');
1018 sb.emitOp(node, 'DROP');
1019
1020 if (optionsIn.pushValue) {
1021 sb.emitOp(node, 'DUP');
1022 }
1023
1024 sb.emitHelper(node, options, sb.helpers.handleCompletion);
1025
1026 if (optionsIn.pushValue) {
1027 sb.emitHelper(node, options, sb.helpers.getCompletionVal);
1028 }
1029 }
1030
1031}
1032
1033// Input: [func]
1034// Output: [func]
1035class CloneFunctionHelper extends Helper {
1036 emit(sb, node, options) {
1037 if (!options.pushValue) {
1038 sb.emitOp(node, 'DROP');
1039 return;
1040 }
1041
1042 sb.emitHelper(node, options, sb.helpers.cloneArray);
1043 }
1044
1045}
1046
1047// Input: [objectVal]
1048// Output: [objectVal]
1049class CloneFunctionObjectHelper extends Helper {
1050 constructor(options) {
1051 super();
1052
1053 _defineProperty(this, "property", void 0);
1054
1055 _defineProperty(this, "both", void 0);
1056
1057 if (options.type === 'both') {
1058 this.property = InternalFunctionProperties.CALL;
1059 this.both = true;
1060 } else {
1061 this.property = options.property;
1062 this.both = false;
1063 }
1064 }
1065
1066 emit(sb, node, options) {
1067 if (!options.pushValue) {
1068 sb.emitOp(node, 'DROP');
1069 return;
1070 } // [objectVal]
1071
1072
1073 sb.emitHelper(node, options, sb.helpers.shallowCloneObject);
1074
1075 if (this.both) {
1076 // [objectVal]
1077 this.cloneFunction(sb, node, options, InternalFunctionProperties.CALL); // [objectVal]
1078
1079 this.cloneFunction(sb, node, options, InternalFunctionProperties.CONSTRUCT);
1080 } else {
1081 // [objectVal]
1082 this.cloneFunction(sb, node, options, this.property);
1083 }
1084 }
1085
1086 cloneFunction(sb, node, options, property) {
1087 // [objectVal, objectVal]
1088 sb.emitOp(node, 'DUP'); // [property, objectVal, objectVal]
1089
1090 sb.emitPushString(node, property); // [func, objectVal]
1091
1092 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty); // [func, objectVal]
1093
1094 sb.emitHelper(node, options, sb.helpers.cloneFunction); // [objectVal, func, objectVal]
1095
1096 sb.emitOp(node, 'OVER'); // [property, objectVal, func, objectVal]
1097
1098 sb.emitPushString(node, property); // [func, property, objectVal, objectVal]
1099
1100 sb.emitOp(node, 'ROT'); // [objectVal]
1101
1102 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
1103 }
1104
1105}
1106
1107// Input: []
1108// Output: [farr]
1109class CreateCallArrayHelper extends Helper {
1110 emit(sb, node, outerOptions) {
1111 if (!outerOptions.pushValue) {
1112 return;
1113 }
1114
1115 sb.emitHelper(node, outerOptions, sb.helpers.createFunctionArray({
1116 body: () => {
1117 sb.withScope(node, outerOptions, options => {
1118 sb.emitHelper(node, options, sb.helpers.parameters);
1119 let body;
1120
1121 if (TypeGuards.isBodyableNode(node)) {
1122 body = node.getBodyOrThrow();
1123 } else {
1124 body = node.getBody();
1125 }
1126
1127 if (TypeGuards.isExpression(body)) {
1128 // [val]
1129 sb.visit(body, options); // [completion]
1130
1131 sb.emitHelper(node, options, sb.helpers.createNormalCompletion); // [completion]
1132
1133 sb.emitOp(node, 'RET');
1134 } else {
1135 sb.visit(body, options); // [undefinedVal]
1136
1137 sb.emitHelper(node, options, sb.helpers.createUndefined); // [completion]
1138
1139 sb.emitHelper(node, options, sb.helpers.createNormalCompletion); // [completion]
1140
1141 sb.emitOp(node, 'RET');
1142 }
1143 });
1144 }
1145 }));
1146 }
1147
1148}
1149
1150// Input: []
1151// Output: [farr]
1152class CreateConstructArrayHelper extends Helper {
1153 constructor({
1154 body,
1155 withoutScope
1156 }) {
1157 super();
1158
1159 _defineProperty(this, "body", void 0);
1160
1161 _defineProperty(this, "withoutScope", void 0);
1162
1163 this.body = body;
1164 this.withoutScope = withoutScope || false;
1165 }
1166
1167 emit(sb, node, outerOptions) {
1168 if (!outerOptions.pushValue) {
1169 return;
1170 }
1171
1172 const emit = options => {
1173 // []
1174 this.body(); // [undefinedVal]
1175
1176 sb.emitHelper(node, options, sb.helpers.createUndefined); // [completion]
1177
1178 sb.emitHelper(node, options, sb.helpers.createNormalCompletion); // [completion]
1179
1180 sb.emitOp(node, 'RET');
1181 };
1182
1183 sb.emitHelper(node, outerOptions, sb.helpers.createFunctionArray({
1184 body: () => {
1185 if (this.withoutScope) {
1186 emit(outerOptions);
1187 } else {
1188 sb.withScope(node, outerOptions, options => {
1189 emit(options);
1190 });
1191 }
1192 }
1193 }));
1194 }
1195
1196}
1197
1198// Input: []
1199// Output: [farr]
1200class CreateFunctionArrayHelper extends Helper {
1201 constructor({
1202 body
1203 }) {
1204 super();
1205
1206 _defineProperty(this, "body", void 0);
1207
1208 this.body = body;
1209 }
1210
1211 emit(sb, node, options) {
1212 if (options.pushValue) {
1213 /* create function */
1214 // [[scopes, this]]
1215 sb.scope.pushAll(sb, node, options); // [[scopes, this]]
1216
1217 sb.emitHelper(node, options, sb.helpers.cloneArray); // [[scopes, this], [scopes, this]]
1218
1219 sb.emitOp(node, 'DUP'); // [0, [scopes, this], [scopes, this]]
1220
1221 sb.emitPushInt(node, 0); // [[scopes, this], 0, [scopes, this], [scopes, this]]
1222
1223 sb.emitOp(node, 'OVER'); // [0, [scopes, this], 0, [scopes, this], [scopes, this]]
1224
1225 sb.emitOp(node, 'OVER'); // [scopes, 0, [scopes, this], [scopes, this]]
1226
1227 sb.emitOp(node, 'PICKITEM'); // [scopes, 0, [scopes, this], [scopes, this]]
1228
1229 sb.emitHelper(node, options, sb.helpers.cloneArray); // [[scopes, this]]
1230
1231 sb.emitOp(node, 'SETITEM'); // [target, scopes]
1232
1233 sb.emitHelper(node, options, sb.helpers.function({
1234 body: this.body
1235 })); // [2, target, scopes]
1236
1237 sb.emitPushInt(node, 2); // [arr]
1238
1239 sb.emitOp(node, 'PACK');
1240 }
1241 }
1242
1243}
1244
1245// Input: [farr]
1246// Output: [objectVal]
1247class CreateFunctionObjectHelper extends Helper {
1248 constructor({
1249 property
1250 }) {
1251 super();
1252
1253 _defineProperty(this, "property", void 0);
1254
1255 this.property = property;
1256 }
1257
1258 emit(sb, node, options) {
1259 if (options.pushValue) {
1260 // [objectVal, farr]
1261 sb.emitHelper(node, options, sb.helpers.createObject); // [objectVal, farr, objectVal]
1262
1263 sb.emitOp(node, 'TUCK'); // ['call', objectVal, farr, objectVal]
1264
1265 sb.emitPushString(node, this.property); // [farr, 'call', objectVal, objectVal]
1266
1267 sb.emitOp(node, 'ROT'); // [objectVal]
1268
1269 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
1270 }
1271 }
1272
1273}
1274
1275// Input: []
1276// Output: [jumpTarget]
1277class FunctionHelper extends Helper {
1278 constructor({
1279 body
1280 }) {
1281 super();
1282
1283 _defineProperty(this, "body", void 0);
1284
1285 this.body = body;
1286 }
1287
1288 emit(sb, node, options) {
1289 if (options.pushValue) {
1290 const jump = sb.jumpTable.add(sb, node, () => {
1291 this.body();
1292 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createUndefined);
1293 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createNormalCompletion);
1294 sb.emitOp(node, 'RET');
1295 });
1296 sb.emitPushInt(node, jump);
1297 }
1298 }
1299
1300}
1301
1302// Input: [objectVal, ?thisVal, ?argsarray]
1303// Output: [val]
1304class InvokeCallHelper extends Helper {
1305 static getKey(options = {
1306 bindThis: false,
1307 noArgs: false
1308 }) {
1309 const bindThis = options.bindThis || false;
1310 const overwriteThis = options.overwriteThis || false;
1311 const noArgs = options.noArgs || false;
1312 return stringify({
1313 bindThis,
1314 overwriteThis,
1315 noArgs
1316 });
1317 }
1318
1319 constructor(options = {
1320 bindThis: false,
1321 noArgs: false
1322 }) {
1323 super();
1324
1325 _defineProperty(this, "bindThis", void 0);
1326
1327 _defineProperty(this, "overwriteThis", void 0);
1328
1329 _defineProperty(this, "noArgs", void 0);
1330
1331 this.bindThis = options.bindThis || false;
1332 this.overwriteThis = options.overwriteThis || false;
1333 this.noArgs = options.noArgs || false;
1334 }
1335
1336 emit(sb, node, optionsIn) {
1337 const options = sb.pushValueOptions(optionsIn); // ['call', objectVal, ?thisVal, ?argsarray]
1338
1339 sb.emitPushString(node, InternalFunctionProperties.CALL); // [func, ?thisVal, ?argsarray]
1340
1341 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty);
1342
1343 if (this.bindThis) {
1344 // [func, ?argsarray]
1345 sb.emitHelper(node, options, sb.helpers.bindFunctionThis({
1346 overwrite: this.overwriteThis
1347 }));
1348 }
1349
1350 if (this.noArgs) {
1351 // [0, func]
1352 sb.emitPushInt(node, 0); // [argsarray, func]
1353
1354 sb.emitOp(node, 'NEWARRAY'); // [func, argsarray]
1355
1356 sb.emitOp(node, 'SWAP');
1357 } // [val]
1358
1359
1360 sb.emitHelper(node, optionsIn, sb.helpers.call);
1361 }
1362
1363}
1364
1365// Input: [objectVal, thisObjectVal, ?argsarray]
1366// Output: []
1367class InvokeConstructHelper extends Helper {
1368 constructor(options = {
1369 noArgs: false
1370 }) {
1371 super();
1372
1373 _defineProperty(this, "noArgs", void 0);
1374
1375 this.noArgs = options.noArgs || false;
1376 }
1377
1378 emit(sb, node, optionsIn) {
1379 const options = sb.pushValueOptions(optionsIn); // ['construct', objectVal, thisObjectVal, ?argsarray]
1380
1381 sb.emitPushString(node, InternalFunctionProperties.CONSTRUCT); // [func, thisObjectVal, ?argsarray]
1382
1383 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty); // [func, ?argsarray]
1384
1385 sb.emitHelper(node, options, sb.helpers.bindFunctionThis({
1386 overwrite: true
1387 }));
1388
1389 if (this.noArgs) {
1390 // [0, func]
1391 sb.emitPushInt(node, 0); // [argsarray, func]
1392
1393 sb.emitOp(node, 'NEWARRAY'); // [func, argsarray]
1394
1395 sb.emitOp(node, 'SWAP');
1396 } // []
1397
1398
1399 sb.emitHelper(node, sb.noPushValueOptions(optionsIn), sb.helpers.call);
1400 }
1401
1402}
1403
1404// Input: [objectVal, ?argsarr]
1405// Output: [thisVal]
1406class NewHelper extends Helper {
1407 constructor(options = {
1408 noArgs: false
1409 }) {
1410 super();
1411
1412 _defineProperty(this, "noArgs", void 0);
1413
1414 this.noArgs = options.noArgs || false;
1415 }
1416
1417 emit(sb, node, optionsIn) {
1418 const options = sb.pushValueOptions(optionsIn); // [thisVal, objectVal, ?argsarr]
1419
1420 sb.emitHelper(node, options, sb.helpers.createObject);
1421
1422 if (this.noArgs) {
1423 // [thisVal, objectVal, thisVal]
1424 sb.emitOp(node, 'TUCK');
1425 } else {
1426 // [3, thisVal, objectVal, argsarr]
1427 sb.emitPushInt(node, 3); // [thisVal, objectVal, argsarr, thisVal]
1428
1429 sb.emitOp(node, 'XTUCK');
1430 } // [thisVal, objectVal, thisVal, ?argsarr, thisVal]
1431
1432
1433 sb.emitOp(node, 'TUCK'); // [objectVal, thisVal, objectVal, thisVal, ?argsarr, thisVal]
1434
1435 sb.emitOp(node, 'OVER'); // ['prototype', objectVal, thisVal, objectVal, thisVal, ?argsarr, thisVal]
1436
1437 sb.emitPushString(node, 'prototype'); // [objectVal, 'prototype', thisVal, objectVal, thisVal, ?argsarr, thisVal]
1438
1439 sb.emitOp(node, 'SWAP'); // ['prototype', objectVal, 'prototype', thisVal, objectVal, thisVal, ?argsarr, thisVal]
1440
1441 sb.emitPushString(node, 'prototype'); // [prototype, 'prototype', thisVal, objectVal, thisVal, ?argsarr, thisVal]
1442
1443 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [objectVal, thisVal, ?argsarr, thisVal]
1444
1445 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [thisVal]
1446
1447 sb.emitHelper(node, options, sb.helpers.invokeConstruct({
1448 noArgs: this.noArgs
1449 }));
1450
1451 if (!optionsIn.pushValue) {
1452 // []
1453 sb.emitOp(node, 'DROP');
1454 }
1455 }
1456
1457}
1458
1459// Input: [argsArray]
1460// Output: []
1461class ParametersHelper extends Helper {
1462 emit(sb, node, optionsIn) {
1463 const options = sb.pushValueOptions(optionsIn); // [argsarr]
1464
1465 node.getParameters().forEach((param, idx) => {
1466 const name = sb.scope.add(param.getNameOrThrow());
1467 const initializer = param.getInitializer();
1468
1469 if (param.isRestParameter()) {
1470 sb.reportUnsupported(param);
1471 } else if (initializer != null) {
1472 sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
1473 condition: () => {
1474 // [argsarr, argsarr]
1475 sb.emitOp(param, 'DUP'); // [size, argsarr]
1476
1477 sb.emitOp(param, 'ARRAYSIZE'); // [idx, size, argsarr]
1478
1479 sb.emitPushInt(param, idx); // [lt, argsarr]
1480
1481 sb.emitOp(param, 'LTE');
1482 },
1483 whenTrue: () => {
1484 // [default, argsarr]
1485 sb.visit(initializer, sb.pushValueOptions(options));
1486 },
1487 whenFalse: () => {
1488 // [argsarr, argsarr]
1489 sb.emitOp(param, 'DUP'); // [idx, argsarr, argsarr]
1490
1491 sb.emitPushInt(param, idx); // [arg, argsarr]
1492
1493 sb.emitOp(param, 'PICKITEM'); // [arg, arg, argsarr]
1494
1495 sb.emitOp(param, 'DUP');
1496 sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
1497 condition: () => {
1498 // [isUndefined, arg, argsarr]
1499 sb.emitHelper(param, sb.pushValueOptions(options), sb.helpers.isUndefined);
1500 },
1501 whenTrue: () => {
1502 // [argsarr]
1503 sb.emitOp(param, 'DROP'); // [default, argsarr]
1504
1505 sb.visit(initializer, sb.pushValueOptions(options));
1506 }
1507 }));
1508 }
1509 }));
1510 } else if (param.isOptional()) {
1511 sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
1512 condition: () => {
1513 // [argsarr, argsarr]
1514 sb.emitOp(param, 'DUP'); // [size, argsarr]
1515
1516 sb.emitOp(param, 'ARRAYSIZE'); // [idx, size, argsarr]
1517
1518 sb.emitPushInt(param, idx); // [lt, argsarr]
1519
1520 sb.emitOp(param, 'LT');
1521 },
1522 whenTrue: () => {
1523 // [undefinedVal, argsarr]
1524 sb.emitHelper(param, sb.pushValueOptions(options), sb.helpers.createUndefined);
1525 },
1526 whenFalse: () => {
1527 // [argsarr, argsarr]
1528 sb.emitOp(param, 'DUP'); // [idx, argsarr, argsarr]
1529
1530 sb.emitPushInt(param, idx); // [arg, argsarr]
1531
1532 sb.emitOp(param, 'PICKITEM');
1533 }
1534 }));
1535 } else {
1536 // [argsarr, argsarr]
1537 sb.emitOp(param, 'DUP'); // [idx, argsarr, argsarr]
1538
1539 sb.emitPushInt(param, idx); // [arg, argsarr]
1540
1541 sb.emitOp(param, 'PICKITEM');
1542 }
1543
1544 const decorators = param.getDecorators();
1545
1546 if (decorators.length > 0) {
1547 sb.reportUnsupported(param);
1548 } // [argsarr]
1549
1550
1551 sb.scope.set(sb, param, sb.plainOptions(options), name);
1552 }); // []
1553
1554 sb.emitOp(node, 'DROP');
1555 }
1556
1557}
1558
1559// Output: []
1560
1561class GenericDeserializeHelper extends Helper {
1562 emitGlobal(sb, node, optionsIn) {
1563 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal]
1564
1565 sb.scope.getGlobal(sb, node, options); // [name, globalObjectVal]
1566
1567 sb.emitPushString(node, DESERIALIZE_NAME); // [farr, name, globalObjectVal]
1568
1569 sb.emitHelper(node, options, sb.helpers.createFunctionArray({
1570 body: () => {
1571 // [0, argsarr]
1572 sb.emitPushInt(node, 0); // [val]
1573
1574 sb.emitOp(node, 'PICKITEM');
1575 sb.emitHelper(node, options, sb.helpers.case(getTypes(sb, node, options).map(forType => ({
1576 condition: () => {
1577 sb.emitOp(node, 'DUP');
1578 forType.isSerializedType();
1579 },
1580 whenTrue: () => {
1581 forType.deserialize();
1582 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createNormalCompletion);
1583 sb.emitOp(node, 'RET');
1584 }
1585 })), () => {
1586 sb.emitOp(node, 'DROP');
1587 sb.emitHelper(node, options, sb.helpers.throwTypeError);
1588 }));
1589 }
1590 })); // [objectVal, name, globalObjectVal]
1591
1592 sb.emitHelper(node, options, sb.helpers.createFunctionObject({
1593 property: InternalFunctionProperties.CALL
1594 })); // []
1595
1596 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
1597 }
1598
1599 emit(sb, node, options) {
1600 if (!options.pushValue) {
1601 sb.emitOp(node, 'DROP');
1602 return;
1603 }
1604
1605 invokeDeserialize(sb, node, options);
1606 }
1607
1608}
1609
1610// Output: []
1611
1612class GenericSerializeHelper extends Helper {
1613 emitGlobal(sb, node, optionsIn) {
1614 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal]
1615
1616 sb.scope.getGlobal(sb, node, options); // [name, globalObjectVal]
1617
1618 sb.emitPushString(node, SERIALIZE_NAME); // [farr, name, globalObjectVal]
1619
1620 sb.emitHelper(node, options, sb.helpers.createFunctionArray({
1621 body: () => {
1622 // [0, argsarr]
1623 sb.emitPushInt(node, 0); // [val]
1624
1625 sb.emitOp(node, 'PICKITEM');
1626 sb.emitHelper(node, options, sb.helpers.case(getTypes(sb, node, options).map(forType => ({
1627 condition: () => {
1628 sb.emitOp(node, 'DUP');
1629 forType.isRuntimeType();
1630 },
1631 whenTrue: () => {
1632 forType.serialize();
1633 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createNormalCompletion);
1634 sb.emitOp(node, 'RET');
1635 }
1636 })), () => {
1637 sb.emitOp(node, 'DROP');
1638 sb.emitHelper(node, options, sb.helpers.throwTypeError);
1639 }));
1640 }
1641 })); // [objectVal, name, globalObjectVal]
1642
1643 sb.emitHelper(node, options, sb.helpers.createFunctionObject({
1644 property: InternalFunctionProperties.CALL
1645 })); // []
1646
1647 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
1648 }
1649
1650 emit(sb, node, options) {
1651 if (!options.pushValue) {
1652 sb.emitOp(node, 'DROP');
1653 return;
1654 }
1655
1656 invokeSerialize(sb, node, options);
1657 }
1658
1659}
1660
1661class TypedHelper extends Helper {
1662 constructor({
1663 knownType,
1664 type
1665 }) {
1666 super();
1667
1668 _defineProperty(this, "type", void 0);
1669
1670 _defineProperty(this, "knownType", void 0);
1671
1672 this.type = type;
1673 this.knownType = knownType;
1674 }
1675
1676}
1677
1678// Input: [val, errorVal]
1679// Output: [completion]
1680class CreateCompletionHelper extends Helper {
1681 emit(sb, node, options) {
1682 if (!options.pushValue) {
1683 sb.emitOp(node, 'DROP');
1684 sb.emitOp(node, 'DROP');
1685 return;
1686 } // [2, val, errorVal]
1687
1688
1689 sb.emitPushInt(node, 2); // [completion]
1690
1691 sb.emitOp(node, 'PACK');
1692 }
1693
1694}
1695
1696// Input: [val]
1697// Output: [completion]
1698class CreateNormalCompletionHelper extends Helper {
1699 emit(sb, node, options) {
1700 if (!options.pushValue) {
1701 sb.emitOp(node, 'DROP');
1702 return;
1703 } // [undefinedVal, val]
1704
1705
1706 sb.emitHelper(node, options, sb.helpers.createUndefined); // [val, undefinedVal]
1707
1708 sb.emitOp(node, 'SWAP'); // [completion]
1709
1710 sb.emitHelper(node, options, sb.helpers.createCompletion);
1711 }
1712
1713}
1714
1715// Input: [errorVal]
1716// Output: [completion]
1717class CreateThrowCompletionHelper extends Helper {
1718 emit(sb, node, options) {
1719 if (!options.pushValue) {
1720 sb.emitOp(node, 'DROP');
1721 return;
1722 } // [undefinedVal, errorVal]
1723
1724
1725 sb.emitHelper(node, options, sb.helpers.createUndefined); // [completion]
1726
1727 sb.emitHelper(node, options, sb.helpers.createCompletion);
1728 }
1729
1730}
1731
1732// Input: [completion]
1733// Output: [val]
1734class GetCompletionBaseHelper extends Helper {
1735 constructor(...args) {
1736 var _temp;
1737
1738 return _temp = super(...args), _defineProperty(this, "index", void 0), _temp;
1739 }
1740
1741 emit(sb, node, options) {
1742 if (!options.pushValue) {
1743 sb.emitOp(node, 'DROP');
1744 return;
1745 } // [index, completion]
1746
1747
1748 sb.emitPushInt(node, this.index); // [val]
1749
1750 sb.emitOp(node, 'PICKITEM');
1751 }
1752
1753}
1754
1755// Output: [errorVal]
1756
1757class GetCompletionErrorHelper extends GetCompletionBaseHelper {
1758 constructor(...args) {
1759 var _temp;
1760
1761 return _temp = super(...args), _defineProperty(this, "index", 1), _temp;
1762 }
1763
1764}
1765
1766// Output: [errorVal]
1767
1768class GetCompletionValHelper extends GetCompletionBaseHelper {
1769 constructor(...args) {
1770 var _temp;
1771
1772 return _temp = super(...args), _defineProperty(this, "index", 0), _temp;
1773 }
1774
1775}
1776
1777let DiagnosticCode;
1778
1779(function (DiagnosticCode) {
1780 DiagnosticCode[DiagnosticCode["UNSUPPORTED_SYNTAX"] = 0] = "UNSUPPORTED_SYNTAX";
1781 DiagnosticCode[DiagnosticCode["UNKNOWN_TYPE"] = 1] = "UNKNOWN_TYPE";
1782 DiagnosticCode[DiagnosticCode["EXPECTED_NUMBER"] = 2] = "EXPECTED_NUMBER";
1783 DiagnosticCode[DiagnosticCode["EXPECTED_STRING"] = 3] = "EXPECTED_STRING";
1784 DiagnosticCode[DiagnosticCode["REFERENCE_ERROR"] = 4] = "REFERENCE_ERROR";
1785 DiagnosticCode[DiagnosticCode["SOMETHING_WENT_WRONG"] = 5] = "SOMETHING_WENT_WRONG";
1786 DiagnosticCode[DiagnosticCode["EXPECTED_PROPERTY"] = 6] = "EXPECTED_PROPERTY";
1787 DiagnosticCode[DiagnosticCode["EXPECTED_CAST"] = 7] = "EXPECTED_CAST";
1788 DiagnosticCode[DiagnosticCode["TRANSPILATION_ERROR"] = 8] = "TRANSPILATION_ERROR";
1789 DiagnosticCode[DiagnosticCode["INVALID_CONTRACT_PARAMETER"] = 9] = "INVALID_CONTRACT_PARAMETER";
1790 DiagnosticCode[DiagnosticCode["INVALID_CONTRACT_TYPE"] = 10] = "INVALID_CONTRACT_TYPE";
1791 DiagnosticCode[DiagnosticCode["INVALID_CONTRACT_METHOD"] = 11] = "INVALID_CONTRACT_METHOD";
1792 DiagnosticCode[DiagnosticCode["INVALID_VALUE_TYPE"] = 12] = "INVALID_VALUE_TYPE";
1793 DiagnosticCode[DiagnosticCode["INVALID_SYS_CALL"] = 13] = "INVALID_SYS_CALL";
1794 DiagnosticCode[DiagnosticCode["UNKNOWN_SYMBOL"] = 14] = "UNKNOWN_SYMBOL";
1795})(DiagnosticCode || (DiagnosticCode = {}));
1796
1797const NORMAL_COMPLETION = 0;
1798const BREAK_COMPLETION = 1;
1799const CONTINUE_COMPLETION = 2;
1800const CATCH_COMPLETION = 3;
1801const ASSIGNMENT_OPERATORS = new Set([SyntaxKind.EqualsToken, SyntaxKind.PlusEqualsToken, SyntaxKind.MinusEqualsToken, SyntaxKind.AsteriskAsteriskEqualsToken, SyntaxKind.AsteriskEqualsToken, SyntaxKind.SlashEqualsToken, SyntaxKind.PercentEqualsToken, SyntaxKind.AmpersandEqualsToken, SyntaxKind.BarEqualsToken, SyntaxKind.CaretEqualsToken, SyntaxKind.LessThanLessThanEqualsToken, SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, SyntaxKind.GreaterThanGreaterThanEqualsToken]);
1802
1803const isValidParent = node => node != null && (TypeGuards.isTryStatement(node) || TypeGuards.isFunctionLikeDeclaration(node) || TypeGuards.isArrowFunction(node) || TypeGuards.isSourceFile(node)); // Input: [completion]
1804// Output: []
1805
1806
1807class HandleCompletionHelper extends Helper {
1808 emit(sb, node, optionsIn) {
1809 const options = sb.pushValueOptions(optionsIn);
1810 sb.emitHelper(node, options, sb.helpers.if({
1811 condition: () => {
1812 // [completion, completion]
1813 sb.emitOp(node, 'DUP'); // [errorVal, completion]
1814
1815 sb.emitHelper(node, options, sb.helpers.getCompletionError); // [isUndefined, completion]
1816
1817 sb.emitHelper(node, options, sb.helpers.isUndefined);
1818 },
1819 whenTrue: () => {
1820 sb.emitOp(node, 'DROP');
1821 },
1822 whenFalse: () => {
1823 let parent = node.getParent();
1824
1825 if (!isValidParent(parent)) {
1826 parent = node.getParentWhile(parentNode => !isValidParent(parentNode));
1827
1828 if (parent != null) {
1829 parent = parent.getParent();
1830 }
1831 }
1832
1833 if (TypeGuards.isSourceFile(node) || parent != null && TypeGuards.isSourceFile(parent)) {
1834 sb.emitOp(node, 'THROW');
1835 } else if (parent == null) {
1836 sb.reportError(node, 'Something went wrong, could not find a valid parent node.', DiagnosticCode.SOMETHING_WENT_WRONG);
1837 } else if (TypeGuards.isTryStatement(parent)) {
1838 if (options.catchPC == null) {
1839 sb.reportError(node, 'Something went wrong. Expected a catch jump location.', DiagnosticCode.SOMETHING_WENT_WRONG);
1840 } else {
1841 sb.emitPushInt(node, CATCH_COMPLETION);
1842 sb.emitJmp(node, 'JMP', options.catchPC);
1843 }
1844 } else {
1845 sb.emitOp(node, 'RET');
1846 }
1847 }
1848 }));
1849 }
1850
1851}
1852
1853// Input: [completion]
1854// Output: [val]
1855class PickCompletionValHelper extends Helper {
1856 emit(sb, node, options) {
1857 if (options.pushValue) {
1858 // [completion, completion]
1859 sb.emitOp(node, 'DUP');
1860 }
1861
1862 sb.emitHelper(node, options, sb.helpers.handleCompletion);
1863
1864 if (options.pushValue) {
1865 sb.emitHelper(node, options, sb.helpers.getCompletionVal);
1866 }
1867 }
1868
1869}
1870
1871// Input: [errorVal]
1872// Output: []
1873class ThrowHelper extends Helper {
1874 emit(sb, node, options) {
1875 // [throwCompletion]
1876 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createThrowCompletion); // []
1877
1878 sb.emitHelper(node, options, sb.helpers.handleCompletion);
1879 }
1880
1881}
1882
1883// Input: []
1884// Output: []
1885class ThrowTypeErrorHelper extends Helper {
1886 emit(sb, node, options) {
1887 // ['TypeError']
1888 sb.emitPushString(node, 'TypeError'); // [value]
1889
1890 sb.emitHelper(node, options, sb.helpers.createString); // []
1891
1892 sb.emitHelper(node, options, sb.helpers.throw);
1893 }
1894
1895}
1896
1897// Input: []
1898// Output: []
1899class CaseHelper extends Helper {
1900 constructor(cases, defaultCase) {
1901 super();
1902
1903 _defineProperty(this, "cases", void 0);
1904
1905 _defineProperty(this, "defaultCase", void 0);
1906
1907 this.cases = cases;
1908 this.defaultCase = defaultCase;
1909 }
1910
1911 emit(sb, node, options) {
1912 this.addCase(sb, node, options);
1913 }
1914
1915 addCase(sb, node, options, idx = 0) {
1916 if (idx >= this.cases.length) {
1917 this.defaultCase();
1918 } else {
1919 sb.emitHelper(node, options, sb.helpers.if({
1920 condition: this.cases[idx].condition,
1921 whenTrue: this.cases[idx].whenTrue,
1922 whenFalse: () => this.addCase(sb, node, options, idx + 1)
1923 }));
1924 }
1925 }
1926
1927}
1928
1929class ForLoopHelper extends Helper {
1930 constructor({
1931 each,
1932 initializer,
1933 condition,
1934 incrementor,
1935 withScope
1936 }) {
1937 super();
1938
1939 _defineProperty(this, "each", void 0);
1940
1941 _defineProperty(this, "initializer", void 0);
1942
1943 _defineProperty(this, "condition", void 0);
1944
1945 _defineProperty(this, "incrementor", void 0);
1946
1947 _defineProperty(this, "withScope", void 0);
1948
1949 this.each = each;
1950 this.initializer = initializer;
1951 this.condition = condition;
1952 this.incrementor = incrementor;
1953 this.withScope = withScope == null ? true : withScope;
1954 }
1955
1956 emit(sb, node, options) {
1957 if (this.withScope) {
1958 sb.withScope(node, options, innerOptions => {
1959 this.emitLoop(sb, node, innerOptions);
1960 });
1961 } else {
1962 this.emitLoop(sb, node, options);
1963 }
1964 }
1965
1966 emitLoop(sb, node, options) {
1967 if (this.initializer != null) {
1968 this.initializer();
1969 }
1970
1971 sb.withProgramCounter(loopPC => {
1972 if (this.condition != null) {
1973 this.condition();
1974 }
1975
1976 if (!loopPC.getFirst().equals(loopPC.getCurrent())) {
1977 sb.emitJmp(node, 'JMPIFNOT', loopPC.getLast());
1978 }
1979
1980 sb.withProgramCounter(breakPC => {
1981 sb.withProgramCounter(innerPC => {
1982 sb.withProgramCounter(continuePC => {
1983 this.each(sb.breakPCOptions(sb.continuePCOptions(options, continuePC.getLast()), breakPC.getLast()));
1984 sb.emitJmp(node, 'JMP', innerPC.getLast());
1985 }); // Drop continue completion
1986
1987 sb.emitOp(node, 'DROP');
1988 });
1989
1990 if (this.incrementor != null) {
1991 this.incrementor();
1992 }
1993
1994 sb.emitJmp(node, 'JMP', loopPC.getFirst());
1995 }); // Drop break completion
1996
1997 sb.emitOp(node, 'DROP');
1998 });
1999 }
2000
2001}
2002
2003class IfHelper extends Helper {
2004 constructor({
2005 condition,
2006 whenTrue,
2007 whenFalse
2008 }) {
2009 super();
2010
2011 _defineProperty(this, "condition", void 0);
2012
2013 _defineProperty(this, "whenTrue", void 0);
2014
2015 _defineProperty(this, "whenFalse", void 0);
2016
2017 this.condition = condition;
2018 this.whenTrue = whenTrue;
2019 this.whenFalse = whenFalse;
2020 }
2021
2022 emit(sb, node, options) {
2023 this.condition();
2024 const {
2025 whenTrue,
2026 whenFalse
2027 } = this;
2028
2029 if (whenTrue == null) {
2030 if (whenFalse == null) {
2031 throw new Error('If statement must have a true or false value');
2032 }
2033
2034 sb.withProgramCounter(endPC => {
2035 sb.emitJmp(node, 'JMPIF', endPC.getLast());
2036 whenFalse();
2037 });
2038 } else {
2039 sb.withProgramCounter(whenFalsePC => {
2040 sb.withProgramCounter(whenTruePC => {
2041 sb.emitJmp(node, 'JMPIFNOT', whenTruePC.getLast());
2042 whenTrue();
2043
2044 if (this.whenFalse != null) {
2045 sb.emitJmp(node, 'JMP', whenFalsePC.getLast());
2046 }
2047 });
2048
2049 if (this.whenFalse != null) {
2050 this.whenFalse();
2051 }
2052 });
2053 }
2054 }
2055
2056}
2057
2058class ProcessStatementsHelper extends Helper {
2059 constructor({
2060 createScope
2061 }) {
2062 super();
2063
2064 _defineProperty(this, "createScope", void 0);
2065
2066 this.createScope = createScope;
2067 }
2068
2069 emit(sb, node, options) {
2070 if (this.createScope) {
2071 sb.withScope(node, options, innerOptions => {
2072 this.emitStatements(sb, node, innerOptions);
2073 });
2074 } else {
2075 this.emitStatements(sb, node, options);
2076 }
2077 }
2078
2079 emitStatements(sb, node, options) {
2080 node.getFunctions().forEach(func => {
2081 sb.scope.add(func.getName());
2082 });
2083 node.getVariableDeclarations().forEach(decl => {
2084 sb.scope.add(decl.getName());
2085 });
2086 const compilerStatements = node.compilerNode.statements;
2087 let statements;
2088
2089 if (compilerStatements == null) {
2090 statements = node.getStatements();
2091 } else {
2092 statements = compilerStatements.map(statement => node.getNodeFromCompilerNode(statement));
2093 }
2094
2095 statements.forEach(statement => {
2096 sb.visit(statement, sb.noValueOptions(options));
2097 });
2098 }
2099
2100}
2101
2102// Input: [value]
2103// Output: [val]
2104class CreatePrimitiveHelper extends Helper {
2105 constructor(...args) {
2106 var _temp;
2107
2108 return _temp = super(...args), _defineProperty(this, "length", 2), _defineProperty(this, "type", void 0), _temp;
2109 }
2110
2111 emit(sb, node, options) {
2112 if (!options.pushValue) {
2113 sb.emitOp(node, 'DROP');
2114 return;
2115 } // [type, value]
2116
2117
2118 sb.emitPushInt(node, this.type); // [2, type, value]
2119
2120 sb.emitPushInt(node, this.length); // [[type, value]]
2121
2122 sb.emitOp(node, 'PACK');
2123 }
2124
2125}
2126
2127let Types;
2128
2129(function (Types) {
2130 Types[Types["Undefined"] = 0] = "Undefined";
2131 Types[Types["Null"] = 1] = "Null";
2132 Types[Types["Boolean"] = 2] = "Boolean";
2133 Types[Types["String"] = 3] = "String";
2134 Types[Types["Symbol"] = 4] = "Symbol";
2135 Types[Types["Number"] = 5] = "Number";
2136 Types[Types["Object"] = 6] = "Object";
2137})(Types || (Types = {}));
2138
2139// Output: [booleanVal]
2140
2141class CreateBooleanHelper extends CreatePrimitiveHelper {
2142 constructor(...args) {
2143 var _temp;
2144
2145 return _temp = super(...args), _defineProperty(this, "type", Types.Boolean), _temp;
2146 }
2147
2148}
2149
2150// Input: [val]
2151// Output: [value]
2152class GetPrimitiveHelper extends Helper {
2153 emit(sb, node, options) {
2154 if (!options.pushValue) {
2155 sb.emitOp(node, 'DROP');
2156 return;
2157 } // [1, val]
2158
2159
2160 sb.emitPushInt(node, 1); // [value]
2161
2162 sb.emitOp(node, 'PICKITEM');
2163 }
2164
2165}
2166
2167// Output: [boolean]
2168
2169class GetBooleanHelper extends GetPrimitiveHelper {}
2170
2171// Input: [val]
2172// Output: [boolean]
2173class IsHelper extends Helper {
2174 constructor(...args) {
2175 var _temp;
2176
2177 return _temp = super(...args), _defineProperty(this, "type", void 0), _temp;
2178 }
2179
2180 emit(sb, node, options) {
2181 if (!options.pushValue) {
2182 sb.emitOp(node, 'DROP');
2183 return;
2184 } // [0, value]
2185
2186
2187 sb.emitPushInt(node, 0); // [type]
2188
2189 sb.emitOp(node, 'PICKITEM'); // [type, type]
2190
2191 sb.emitPushInt(node, this.type); // [isType]
2192
2193 sb.emitOp(node, 'EQUAL');
2194 }
2195
2196}
2197
2198// Output: [boolean]
2199
2200class IsBooleanHelper extends IsHelper {
2201 constructor(...args) {
2202 var _temp;
2203
2204 return _temp = super(...args), _defineProperty(this, "type", Types.Boolean), _temp;
2205 }
2206
2207}
2208
2209function getType(type) {
2210 if (type == null) {
2211 return undefined;
2212 }
2213
2214 const constraint = type.getConstraint();
2215 return constraint == null ? type : constraint;
2216}
2217
2218const hasUnionType = (type, isType) => getType(type).isUnionType() && getType(type).getUnionTypes().some(isType);
2219const hasIntersectionType = (type, isType) => getType(type).isIntersectionType() && getType(type).getIntersectionTypes().some(isType);
2220const hasType = (type, isType) => isType(type) || hasUnionType(type, isType) || hasIntersectionType(type, isType);
2221const isOnly = (type, isType) => type != null && !getType(type).isNullable() && (isType(type) || getType(type).isUnionType() && getType(type).getUnionTypes().every(unionType => isOnly(unionType, isType)) || getType(type).isIntersectionType() && getType(type).getIntersectionTypes().every(intersectionType => isOnly(intersectionType, isType)));
2222const isUndefined = type => type != null && getType(type).isUndefinedType();
2223const isOnlyUndefined = type => isOnly(type, isUndefined);
2224const hasUndefined = type => hasType(type, isUndefined);
2225const isNull = type => type != null && (getType(type).isNullType() || getType(type).isNullable());
2226const isOnlyNull = type => isOnly(type, isNull);
2227const hasNull = type => hasType(type, isNull) || getType(type).isNullable();
2228const isOnlyNumberLiteral = type => type != null && isOnly(type, tpe => tpe != null && tpe.isNumberLiteralType());
2229const isNumber = type => type != null && (getType(type).isNumberType() || getType(type).isNumberLiteralType());
2230const isOnlyNumber = type => isOnly(type, isNumber);
2231const hasNumber = type => hasType(type, isNumber);
2232const isString = type => type != null && (getType(type).isStringType() || getType(type).isStringLiteralType());
2233const isOnlyString = type => isOnly(type, isString);
2234const hasString = type => hasType(type, isString);
2235const isBoolean = type => type != null && (getType(type).isBooleanType() || getType(type).isBooleanLiteralType());
2236const isOnlyBoolean = type => isOnly(type, isBoolean);
2237const hasBoolean = type => hasType(type, isBoolean);
2238
2239const hasTypeFlag = (type, flag // tslint:disable-next-line
2240) => (getType(type).compilerType.flags & flag) === flag;
2241
2242const isSymbol = type => type != null && (hasTypeFlag(type, TypeFlags.ESSymbol) || hasTypeFlag(type, TypeFlags.ESSymbolLike));
2243const isOnlySymbol = type => isOnly(type, isSymbol);
2244const isPrimitive = type => isUndefined(type) || isNull(type) || isString(type) || isNumber(type) || isBoolean(type) || isSymbol(type);
2245const isOnlyPrimitive = type => isOnly(type, isPrimitive);
2246const isOnlyObject = type => isOnly(type, tpe => !isPrimitive(tpe));
2247const isArray = type => type != null && getType(type).isArrayType();
2248const isOnlyArray = type => isOnly(type, isArray);
2249const isTuple = type => type != null && getType(type).isTupleType();
2250const isOnlyTuple = type => isOnly(type, isTuple);
2251const isSame = (type0, type1) => type0 != null && type1 != null && (type0 === type1 || isOnlyBoolean(type0) && isOnlyBoolean(type1) || isOnlyNumber(type0) && isOnlyNumber(type1) || isOnlyString(type0) && isOnlyString(type1));
2252const isUnion = type => type != null && getType(type).isUnionType();
2253const isIntersection = type => type != null && getType(type).isIntersectionType();
2254const isLiteral = type => type != null && getType(type).isLiteralType();
2255const isAnyType = type => type != null && hasTypeFlag(type, TypeFlags.Any);
2256const isVoid = type => type != null && hasTypeFlag(type, TypeFlags.Void);
2257
2258// Output: [boolean]
2259
2260class ToBooleanHelper extends TypedHelper {
2261 emit(sb, node, options) {
2262 if (!options.pushValue) {
2263 sb.emitOp(node, 'DROP');
2264 return;
2265 }
2266
2267 if (this.type != null) {
2268 this.convertType(sb, node, options, this.type);
2269 } else {
2270 this.convertUnknownType(sb, node, options);
2271 }
2272 }
2273
2274 convertType(sb, node, options, type) {
2275 if (isOnlyUndefined(type) || isOnlyNull(type)) {
2276 sb.emitPushBoolean(node, false);
2277 } else if (isOnlyBoolean(type)) {
2278 this.convertBoolean(sb, node, options);
2279 } else if (isOnlyNumber(type)) {
2280 this.convertNumber(sb, node, options);
2281 } else if (isOnlyString(type)) {
2282 this.convertString(sb, node, options);
2283 } else if ( // It's a symbol or an object
2284 !hasUndefined(type) && !hasNull(type) && !hasBoolean(type) && !hasNumber(type) && !hasString(type)) {
2285 sb.emitPushBoolean(node, true);
2286 } else {
2287 this.convertUnknownType(sb, node, options);
2288 }
2289 }
2290
2291 convertBoolean(sb, node, options) {
2292 sb.emitHelper(node, options, sb.helpers.getBoolean);
2293 }
2294
2295 convertNumber(sb, node, options) {
2296 sb.emitHelper(node, options, sb.helpers.getNumber);
2297 sb.emitPushInt(node, 0);
2298 sb.emitOp(node, 'NUMNOTEQUAL');
2299 }
2300
2301 convertString(sb, node, options) {
2302 sb.emitHelper(node, options, sb.helpers.getString);
2303 sb.emitPushString(node, '');
2304 sb.emitOp(node, 'EQUAL');
2305 sb.emitOp(node, 'NOT');
2306 }
2307
2308 convertUnknownType(sb, node, options) {
2309 sb.emitHelper(node, options, sb.helpers.case([{
2310 condition: () => {
2311 // [value, value]
2312 sb.emitOp(node, 'DUP'); // [isBoolean, value]
2313
2314 sb.emitHelper(node, options, sb.helpers.isBoolean);
2315 },
2316 whenTrue: () => {
2317 // [value]
2318 sb.emitHelper(node, options, sb.helpers.getBoolean);
2319 }
2320 }, {
2321 condition: () => {
2322 // [value, value]
2323 sb.emitOp(node, 'DUP'); // [isNull, value]
2324
2325 sb.emitHelper(node, options, sb.helpers.isNull); // [value, isNull, value]
2326
2327 sb.emitOp(node, 'OVER'); // [isUndefined, isNull, value]
2328
2329 sb.emitHelper(node, options, sb.helpers.isUndefined); // [isUndefinedOrNull, value]
2330
2331 sb.emitOp(node, 'OR');
2332 },
2333 whenTrue: () => {
2334 sb.emitPushBoolean(node, false);
2335 }
2336 }, {
2337 condition: () => {
2338 // [value, value]
2339 sb.emitOp(node, 'DUP'); // [isObject, value]
2340
2341 sb.emitHelper(node, options, sb.helpers.isObject); // [value, isObject, value]
2342
2343 sb.emitOp(node, 'OVER'); // [isSymbol, isObject, value]
2344
2345 sb.emitHelper(node, options, sb.helpers.isSymbol); // [isSymbolOrObject, value]
2346
2347 sb.emitOp(node, 'OR');
2348 },
2349 whenTrue: () => {
2350 sb.emitPushBoolean(node, true);
2351 }
2352 }, {
2353 condition: () => {
2354 // [value, value]
2355 sb.emitOp(node, 'DUP'); // [isNumber, value]
2356
2357 sb.emitHelper(node, options, sb.helpers.isNumber);
2358 },
2359 whenTrue: () => {
2360 this.convertNumber(sb, node, options);
2361 }
2362 }], () => {
2363 this.convertString(sb, node, options);
2364 }));
2365 }
2366
2367}
2368
2369// Output: [nullVal]
2370
2371class CreateNullHelper extends CreatePrimitiveHelper {
2372 constructor(...args) {
2373 var _temp;
2374
2375 return _temp = super(...args), _defineProperty(this, "length", 1), _defineProperty(this, "type", Types.Null), _temp;
2376 }
2377
2378}
2379
2380// Output: [boolean]
2381
2382class IsNullHelper extends IsHelper {
2383 constructor(...args) {
2384 var _temp;
2385
2386 return _temp = super(...args), _defineProperty(this, "type", Types.Null), _temp;
2387 }
2388
2389}
2390
2391// Output: [numberVal]
2392
2393class CreateNumberHelper extends CreatePrimitiveHelper {
2394 constructor(...args) {
2395 var _temp;
2396
2397 return _temp = super(...args), _defineProperty(this, "type", Types.Number), _temp;
2398 }
2399
2400}
2401
2402// Output: [number]
2403
2404class GetNumberHelper extends GetPrimitiveHelper {}
2405
2406// Output: [boolean]
2407
2408class IsNumberHelper extends IsHelper {
2409 constructor(...args) {
2410 var _temp;
2411
2412 return _temp = super(...args), _defineProperty(this, "type", Types.Number), _temp;
2413 }
2414
2415}
2416
2417// Output: [number]
2418
2419class ToNumberHelper extends TypedHelper {
2420 emit(sb, node, options) {
2421 if (!options.pushValue) {
2422 sb.emitOp(node, 'DROP');
2423 return;
2424 }
2425
2426 if (this.type != null) {
2427 this.convertType(sb, node, options, this.type);
2428 } else {
2429 this.convertUnknown(sb, node, options);
2430 }
2431 }
2432
2433 convertType(sb, node, options, type) {
2434 if (isOnlyUndefined(type)) {
2435 this.convertUndefined(sb, node, options);
2436 } else if (isOnlyNull(type)) {
2437 this.convertNull(sb, node, options);
2438 } else if (isOnlyBoolean(type)) {
2439 this.convertBoolean(sb, node, options);
2440 } else if (isOnlyNumber(type)) {
2441 this.convertNumber(sb, node, options);
2442 } else if (isOnlyString(type)) {
2443 this.convertString(sb, node, options);
2444 } else if (isOnlySymbol(type)) {
2445 this.convertSymbol(sb, node, options);
2446 } else if (isOnlyObject(type)) {
2447 this.convertObject(sb, node, options);
2448 } else {
2449 this.convertUnknown(sb, node, options);
2450 }
2451 }
2452
2453 convertUndefined(sb, node, options) {
2454 sb.emitHelper(node, options, sb.helpers.throwTypeError);
2455 }
2456
2457 convertNull(sb, node, options) {
2458 // []
2459 sb.emitOp(node, 'DROP'); // [0]
2460
2461 sb.emitPushInt(node, 0);
2462 }
2463
2464 convertBoolean(sb, node, options) {
2465 sb.emitHelper(node, options, sb.helpers.if({
2466 condition: () => {
2467 sb.emitHelper(node, options, sb.helpers.getBoolean);
2468 },
2469 whenTrue: () => {
2470 // [1]
2471 sb.emitPushInt(node, 1);
2472 },
2473 whenFalse: () => {
2474 // [0]
2475 sb.emitPushInt(node, 0);
2476 }
2477 }));
2478 }
2479
2480 convertNumber(sb, node, options) {
2481 // [value]
2482 sb.emitHelper(node, options, sb.helpers.getNumber);
2483 }
2484
2485 convertString(sb, node, options) {
2486 sb.emitHelper(node, options, sb.helpers.throwTypeError);
2487 }
2488
2489 convertSymbol(sb, node, options) {
2490 sb.emitHelper(node, options, sb.helpers.throwTypeError);
2491 }
2492
2493 convertObject(sb, node, options) {
2494 // [primitive]
2495 sb.emitHelper(node, options, sb.helpers.toPrimitive({
2496 type: this.type,
2497 knownType: Types.Object,
2498 preferredType: 'number'
2499 })); // [value]
2500
2501 this.convertUnknown(sb, node, options, true);
2502 }
2503
2504 convertUnknown(sb, node, options, shouldThrowOnObject = false) {
2505 const emitIf = (check, whenTrue, whenFalse) => sb.emitHelper(node, options, sb.helpers.if({
2506 condition: () => {
2507 // [value, value]
2508 sb.emitOp(node, 'DUP'); // [isValue, value]
2509
2510 sb.emitHelper(node, options, check);
2511 },
2512 whenTrue,
2513 whenFalse
2514 }));
2515
2516 emitIf(sb.helpers.isNumber, () => this.convertNumber(sb, node, options), () => emitIf(sb.helpers.isUndefined, () => this.convertUndefined(sb, node, options), () => emitIf(sb.helpers.isNull, () => this.convertNull(sb, node, options), () => emitIf(sb.helpers.isBoolean, () => this.convertBoolean(sb, node, options), () => emitIf(sb.helpers.isString, () => this.convertString(sb, node, options), () => emitIf(sb.helpers.isSymbol, () => this.convertSymbol(sb, node, options), () => shouldThrowOnObject ? sb.emitHelper(node, options, sb.helpers.throwTypeError) : this.convertObject(sb, node, options)))))));
2517 }
2518
2519}
2520
2521// Output: [objectVal]
2522
2523class CreateObjectHelper extends Helper {
2524 emit(sb, node, options) {
2525 if (options.pushValue) {
2526 /* create internal object */
2527 // [iobj]
2528 sb.emitOp(node, 'NEWMAP');
2529 /* create symbol obj */
2530 // [sobj, iobj]
2531
2532 sb.emitOp(node, 'NEWMAP');
2533 /* create obj */
2534 // [pobj, sobj, iobj]
2535
2536 sb.emitOp(node, 'NEWMAP');
2537 /* create object array */
2538 // [3, pobj, sobj, iobj]
2539
2540 sb.emitPushInt(node, 3); // [object]
2541
2542 sb.emitOp(node, 'PACK'); // [objectType, object]
2543
2544 sb.emitPushInt(node, Types.Object);
2545 /* create object */
2546 // [2, objectType, object]
2547
2548 sb.emitPushInt(node, 2); // [objectVal]
2549
2550 sb.emitOp(node, 'PACK');
2551 }
2552 }
2553
2554}
2555
2556// Input: [pobj]
2557// Output: [objectVal]
2558class CreatePropertyObjectHelper extends Helper {
2559 emit(sb, node, options) {
2560 if (options.pushValue) {
2561 const obj = sb.scope.addUnique();
2562 const pobj = sb.scope.addUnique(); // [pobj, pobj]
2563
2564 sb.emitOp(node, 'DUP'); // [pobj]
2565
2566 sb.scope.set(sb, node, options, pobj); // [objectVal, pobj]
2567
2568 sb.emitHelper(node, options, sb.helpers.createObject); // [objectVal, pobj, objectVal]
2569
2570 sb.emitOp(node, 'TUCK'); // [pobj, objectVal]
2571
2572 sb.scope.set(sb, node, options, obj); // [keysArr, objectVal]
2573
2574 sb.emitOp(node, 'KEYS'); // [objectVal]
2575
2576 sb.emitHelper(node, options, sb.helpers.arrForEach({
2577 each: () => {
2578 // [objectVal, key]
2579 sb.scope.get(sb, node, options, obj); // [pobj, objectVal, key]
2580
2581 sb.scope.get(sb, node, options, pobj); // [key, pobj, objectVal]
2582
2583 sb.emitOp(node, 'ROT'); // [key, pobj, key, objectVal]
2584
2585 sb.emitOp(node, 'TUCK'); // [val, key, objectVal]
2586
2587 sb.emitOp(node, 'PICKITEM'); // []
2588
2589 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty);
2590 }
2591 }));
2592 }
2593 }
2594
2595}
2596
2597// Output: [val]
2598
2599class ElementAccessHelper extends Helper {
2600 emit(sb, expr, optionsIn) {
2601 const options = sb.pushValueOptions(sb.noSetValueOptions(optionsIn));
2602 const value = expr.getExpression();
2603 const valueType = sb.getType(value);
2604 const prop = expr.getArgumentExpressionOrThrow();
2605 const propType = sb.getType(prop); // [objectVal]
2606
2607 sb.emitHelper(value, options, sb.helpers.toObject({
2608 type: sb.getType(value)
2609 })); // [propVal, objectVal]
2610
2611 sb.visit(prop, options);
2612
2613 if (optionsIn.setValue) {
2614 let valueIndex = 2;
2615
2616 if (optionsIn.pushValue) {
2617 // [objectVal, propVal]
2618 sb.emitOp(expr, 'SWAP'); // [objectVal, propVal, objectVal]
2619
2620 sb.emitOp(expr, 'TUCK'); // [propVal, objectVal, propVal, objectVal]
2621
2622 sb.emitOp(expr, 'OVER');
2623 valueIndex = 4;
2624 }
2625
2626 if (isOnlyString(propType)) {
2627 // [propString, objectVal]
2628 sb.emitHelper(prop, options, sb.helpers.getString); // []
2629
2630 this.setProperty(sb, prop, options, valueIndex);
2631 } else if (isOnlyNumber(propType)) {
2632 // []
2633 this.setNumberProperty(sb, prop, options, propType, valueType, valueIndex);
2634 } else if (isOnlySymbol(propType)) {
2635 // [propString, objectVal]
2636 sb.emitHelper(prop, options, sb.helpers.getSymbol); // []
2637
2638 this.setSymbol(sb, prop, options, valueIndex);
2639 } else {
2640 // []
2641 sb.emitHelper(prop, options, sb.helpers.case([{
2642 condition: () => {
2643 // [propVal, propVal, objectVal]
2644 sb.emitOp(prop, 'DUP'); // [isString, propVal, objectVal]
2645
2646 sb.emitHelper(prop, options, sb.helpers.isString);
2647 },
2648 whenTrue: () => {
2649 // [propString, objectVal]
2650 sb.emitHelper(prop, options, sb.helpers.getString); // []
2651
2652 this.setProperty(sb, prop, options, valueIndex);
2653 }
2654 }, {
2655 condition: () => {
2656 // [propVal, propVal, objectVal]
2657 sb.emitOp(prop, 'DUP'); // [isNumber, propVal, objectVal]
2658
2659 sb.emitHelper(prop, options, sb.helpers.isNumber);
2660 },
2661 whenTrue: () => {
2662 // []
2663 this.setNumberProperty(sb, prop, options, propType, valueType, valueIndex);
2664 }
2665 }], () => {
2666 // [propString, objectVal]
2667 sb.emitHelper(prop, options, sb.helpers.getSymbol); // []
2668
2669 this.setSymbol(sb, prop, options, valueIndex);
2670 }));
2671 }
2672 }
2673
2674 if (optionsIn.pushValue || !optionsIn.setValue) {
2675 if (isOnlyString(propType)) {
2676 // [propString, objectVal]
2677 sb.emitHelper(prop, options, sb.helpers.getString); // [val]
2678
2679 sb.emitHelper(expr, options, sb.helpers.getPropertyObjectProperty);
2680 } else if (isOnlyNumber(propType)) {
2681 // [val]
2682 this.getNumberProperty(sb, prop, options, propType, valueType);
2683 } else if (isOnlySymbol(propType)) {
2684 // [propString, objectVal]
2685 sb.emitHelper(prop, options, sb.helpers.getSymbol); // [val]
2686
2687 sb.emitHelper(expr, options, sb.helpers.getSymbolObjectProperty);
2688 } else {
2689 // [val]
2690 sb.emitHelper(prop, options, sb.helpers.case([{
2691 condition: () => {
2692 // [propVal, propVal, objectVal]
2693 sb.emitOp(prop, 'DUP'); // [propVal, objectVal]
2694
2695 sb.emitHelper(prop, options, sb.helpers.isString);
2696 },
2697 whenTrue: () => {
2698 // [propString, objectVal]
2699 sb.emitHelper(prop, options, sb.helpers.getString); // [val]
2700
2701 sb.emitHelper(expr, options, sb.helpers.getPropertyObjectProperty);
2702 }
2703 }, {
2704 condition: () => {
2705 // [propVal, propVal, objectVal]
2706 sb.emitOp(prop, 'DUP'); // [propVal, objectVal]
2707
2708 sb.emitHelper(prop, options, sb.helpers.isNumber);
2709 },
2710 whenTrue: () => {
2711 // [val]
2712 this.getNumberProperty(sb, prop, options, propType, valueType);
2713 }
2714 }], () => {
2715 // [propString, objectVal]
2716 sb.emitHelper(prop, options, sb.helpers.getSymbol); // [val]
2717
2718 sb.emitHelper(expr, options, sb.helpers.getSymbolObjectProperty);
2719 }));
2720 }
2721 }
2722
2723 if (!optionsIn.pushValue && !optionsIn.setValue) {
2724 sb.emitOp(expr, 'DROP');
2725 }
2726 }
2727
2728 getNumberProperty(sb, node, options, propType, valueType) {
2729 if (isOnlyArray(valueType) || isOnlyTuple(valueType)) {
2730 sb.emitHelper(node, options, sb.helpers.getNumber);
2731 sb.emitHelper(node, options, sb.helpers.getArrayIndex);
2732 } else {
2733 sb.emitHelper(node, options, sb.helpers.if({
2734 condition: () => {
2735 // [isArray, propVal, objectVal]
2736 this.isArrayInstance(sb, node, options);
2737 },
2738 whenTrue: () => {
2739 // [propNumber, objectVal]
2740 sb.emitHelper(node, options, sb.helpers.getNumber); // [val]
2741
2742 sb.emitHelper(node, options, sb.helpers.getArrayIndex);
2743 },
2744 whenFalse: () => {
2745 // [propString, objectVal]
2746 sb.emitHelper(node, options, sb.helpers.toString({
2747 type: propType
2748 })); // [val]
2749
2750 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty);
2751 }
2752 }));
2753 }
2754 }
2755
2756 setProperty(sb, node, options, index) {
2757 // [val, propString, objectVal]
2758 this.pickValue(sb, node, options, index); // []
2759
2760 sb.emitHelper(node, options, sb.helpers.setPropertyObjectProperty);
2761 }
2762
2763 setNumberProperty(sb, node, options, propType, valueType, index) {
2764 if (isOnlyArray(valueType) || isOnlyTuple(valueType)) {
2765 sb.emitHelper(node, options, sb.helpers.getNumber);
2766 this.setArrayIndex(sb, node, options, index);
2767 } else {
2768 sb.emitHelper(node, options, sb.helpers.if({
2769 condition: () => {
2770 // [isArray, propVal, objectVal]
2771 this.isArrayInstance(sb, node, options);
2772 },
2773 whenTrue: () => {
2774 sb.emitHelper(node, options, sb.helpers.getNumber);
2775 this.setArrayIndex(sb, node, options, index);
2776 },
2777 whenFalse: () => {
2778 // [propString, objectVal]
2779 sb.emitHelper(node, options, sb.helpers.toString({
2780 type: propType
2781 })); // []
2782
2783 this.setProperty(sb, node, options, index);
2784 }
2785 }));
2786 }
2787 }
2788
2789 setArrayIndex(sb, node, options, index) {
2790 // [val, propNumber, objectVal]
2791 this.pickValue(sb, node, options, index); // []
2792
2793 sb.emitHelper(node, options, sb.helpers.setArrayIndex);
2794 }
2795
2796 setSymbol(sb, node, options, index) {
2797 // [val, propString, objectVal]
2798 this.pickValue(sb, node, options, index); // []
2799
2800 sb.emitHelper(node, options, sb.helpers.setSymbolObjectProperty);
2801 }
2802
2803 isArrayInstance(sb, node, options) {
2804 // [objectVal, propVal, objectVal]
2805 sb.emitOp(node, 'OVER'); // [Array, objectVal, propVal, objectVal]
2806
2807 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
2808 property: 'Array'
2809 })); // [isArray, propVal, objectVal]
2810
2811 sb.emitHelper(node, options, sb.helpers.instanceof);
2812 }
2813
2814 pickValue(sb, node, options, index) {
2815 if (index === 2) {
2816 sb.emitOp(node, 'ROT');
2817 } else {
2818 // [index, ...]
2819 sb.emitPushInt(node, index); // [val, ...]
2820
2821 sb.emitOp(node, 'ROLL');
2822 }
2823 }
2824
2825}
2826
2827// Input: [stringProp, objectVal]
2828// Output: [val]
2829class FindObjectPropertyHelper extends Helper {
2830 constructor({
2831 accessor,
2832 dataExists,
2833 data,
2834 getObject
2835 }) {
2836 super();
2837
2838 _defineProperty(this, "accessor", void 0);
2839
2840 _defineProperty(this, "dataExists", void 0);
2841
2842 _defineProperty(this, "data", void 0);
2843
2844 _defineProperty(this, "getObject", void 0);
2845
2846 this.accessor = accessor;
2847 this.dataExists = dataExists;
2848 this.data = data;
2849 this.getObject = getObject;
2850 }
2851
2852 emit(sb, node, options) {
2853 if (!options.pushValue) {
2854 sb.emitOp(node, 'DROP');
2855 sb.emitOp(node, 'DROP');
2856 return;
2857 } // [objectVal, prop]
2858
2859
2860 sb.emitOp(node, 'SWAP');
2861
2862 const prepareLoop = () => {
2863 // [objectVal, objectVal, prop]
2864 sb.emitOp(node, 'DUP'); // [pobj, objectVal, prop]
2865
2866 sb.emitHelper(node, options, sb.helpers.getPropertyObject); // [pobj, pobj, objectVal, prop]
2867
2868 sb.emitOp(node, 'DUP'); // [objectVal, pobj, pobj, prop]
2869
2870 sb.emitOp(node, 'ROT'); // [obj, pobj, pobj, prop]
2871
2872 sb.emitHelper(node, options, this.getObject(sb)); // [obj, obj, pobj, pobj, prop]
2873
2874 sb.emitOp(node, 'DUP'); // [4, obj, obj, pobj, pobj, prop]
2875
2876 sb.emitPushInt(node, 4); // [prop, obj, obj, pobj, pobj, prop]
2877
2878 sb.emitOp(node, 'PICK');
2879 }; // [prop, obj, obj, pobj, pobj, prop]
2880
2881
2882 prepareLoop();
2883 sb.emitHelper(node, options, sb.helpers.forLoop({
2884 condition: () => {
2885 // [hasKey, obj, pobj, pobj, prop]
2886 sb.emitOp(node, 'HASKEY'); // [notHasKey, obj, pobj, pobj, prop]
2887
2888 sb.emitOp(node, 'NOT'); // [pobj, notHasKey, obj, pobj, prop]
2889
2890 sb.emitOp(node, 'ROT'); // ['prototype', pobj, notHasKey, obj, pobj, prop]
2891
2892 sb.emitPushString(node, 'prototype'); // [hasPrototypeKey, notHasKey, obj, pobj, prop]
2893
2894 sb.emitOp(node, 'HASKEY'); // [condition, obj, pobj, prop]
2895
2896 sb.emitOp(node, 'AND');
2897 },
2898 each: () => {
2899 // [pobj, prop]
2900 sb.emitOp(node, 'DROP'); // ['prototype', pobj, prop]
2901
2902 sb.emitPushString(node, 'prototype'); // [propVal, prop]
2903
2904 sb.emitOp(node, 'PICKITEM'); // [0, propVal, prop]
2905
2906 sb.emitPushInt(node, 0); // [objectVal, prop]
2907
2908 sb.emitOp(node, 'PICKITEM'); // [prop, obj, obj, pobj, pobj, prop]
2909
2910 prepareLoop();
2911 },
2912 withScope: false
2913 })); // [obj, prop]
2914
2915 sb.emitOp(node, 'NIP'); // [obj, prop, obj]
2916
2917 sb.emitOp(node, 'TUCK'); // [prop, obj, prop, obj]
2918
2919 sb.emitOp(node, 'OVER'); // [val]
2920
2921 sb.emitHelper(node, options, sb.helpers.if({
2922 condition: () => {
2923 // [hasKey, prop, obj]
2924 sb.emitOp(node, 'HASKEY');
2925 },
2926 whenTrue: () => {
2927 // [propVal]
2928 sb.emitOp(node, 'PICKITEM'); // [propVal, propVal]
2929
2930 sb.emitOp(node, 'DUP');
2931 sb.emitHelper(node, options, sb.helpers.if({
2932 condition: () => {
2933 // [size, propVal]
2934 sb.emitOp(node, 'ARRAYSIZE'); // [2, size, propVal]
2935
2936 sb.emitPushInt(node, 2); // [size === 2, propVal]
2937
2938 sb.emitOp(node, 'EQUAL');
2939 },
2940 whenTrue: () => {
2941 this.accessor();
2942 },
2943 whenFalse: () => {
2944 this.dataExists();
2945 }
2946 }));
2947 },
2948 whenFalse: () => {
2949 // [obj]
2950 sb.emitOp(node, 'DROP'); // []
2951
2952 sb.emitOp(node, 'DROP');
2953 this.data();
2954 }
2955 }));
2956 }
2957
2958}
2959
2960// Input: [objectVal]
2961// Output: [obj]
2962class GetObjectHelperBase extends Helper {
2963 constructor(...args) {
2964 var _temp;
2965
2966 return _temp = super(...args), _defineProperty(this, "index", void 0), _temp;
2967 }
2968
2969 emit(sb, node, options) {
2970 if (!options.pushValue) {
2971 sb.emitOp(node, 'DROP');
2972 return;
2973 } // [object]
2974
2975
2976 sb.emitHelper(node, options, sb.helpers.getObject); // [2, object]
2977
2978 sb.emitPushInt(node, this.index); // [obj]
2979
2980 sb.emitOp(node, 'PICKITEM');
2981 }
2982
2983}
2984
2985// Output: [iobj]
2986
2987class GetInternalObjectHelper extends GetObjectHelperBase {
2988 constructor(...args) {
2989 var _temp;
2990
2991 return _temp = super(...args), _defineProperty(this, "index", 2), _temp;
2992 }
2993
2994}
2995
2996// Input: [stringProp, objectVal]
2997// Output: [val]
2998class GetInternalObjectPropertyHelper extends Helper {
2999 emit(sb, node, options) {
3000 if (!options.pushValue) {
3001 sb.emitOp(node, 'DROP');
3002 sb.emitOp(node, 'DROP');
3003 return;
3004 } // [objectVal, stringProp]
3005
3006
3007 sb.emitOp(node, 'SWAP'); // [iobj, stringProp]
3008
3009 sb.emitHelper(node, options, sb.helpers.getInternalObject); // [stringProp, iobj]
3010
3011 sb.emitOp(node, 'SWAP'); // [val]
3012
3013 sb.emitOp(node, 'PICKITEM');
3014 }
3015
3016}
3017
3018// Output: [object]
3019
3020class GetObjectHelper extends GetPrimitiveHelper {}
3021
3022// Output: [pobj]
3023
3024class GetPropertyObjectHelper extends GetObjectHelperBase {
3025 constructor(...args) {
3026 var _temp;
3027
3028 return _temp = super(...args), _defineProperty(this, "index", 0), _temp;
3029 }
3030
3031}
3032
3033// Input: [stringProp, objectVal]
3034// Output: [val]
3035class GetObjectPropertyHelperBase extends Helper {
3036 emit(sb, node, options) {
3037 // [objectVal, stringProp, objectVal]
3038 sb.emitOp(node, 'OVER'); // [stringProp, objectVal, objectVal]
3039
3040 sb.emitOp(node, 'SWAP');
3041 sb.emitHelper(node, options, sb.helpers.findObjectProperty({
3042 accessor: () => {
3043 // [0, propVal, objectVal]
3044 sb.emitPushInt(node, 0); // [getObjectVal, objectVal]
3045
3046 sb.emitOp(node, 'PICKITEM'); // [val]
3047
3048 sb.emitHelper(node, options, sb.helpers.invokeCall({
3049 bindThis: true,
3050 noArgs: true
3051 }));
3052 },
3053 dataExists: () => {
3054 // [propVal]
3055 sb.emitOp(node, 'NIP');
3056
3057 if (options.pushValue) {
3058 // [0, propVal]
3059 sb.emitPushInt(node, 0); // [val]
3060
3061 sb.emitOp(node, 'PICKITEM');
3062 } else {
3063 // []
3064 sb.emitOp(node, 'DROP');
3065 }
3066 },
3067 data: () => {
3068 // []
3069 sb.emitOp(node, 'DROP');
3070
3071 if (options.pushValue) {
3072 // [val]
3073 sb.emitHelper(node, options, sb.helpers.createUndefined);
3074 }
3075 },
3076 getObject: this.getObject.bind(this)
3077 }));
3078 }
3079
3080}
3081
3082// Output: [val]
3083
3084class GetPropertyObjectPropertyHelper extends GetObjectPropertyHelperBase {
3085 getObject(sb) {
3086 return sb.helpers.getPropertyObject;
3087 }
3088
3089}
3090
3091// Output: [sobj]
3092
3093class GetSymbolObjectHelper extends GetObjectHelperBase {
3094 constructor(...args) {
3095 var _temp;
3096
3097 return _temp = super(...args), _defineProperty(this, "index", 1), _temp;
3098 }
3099
3100}
3101
3102// Output: [val]
3103
3104class GetSymbolObjectPropertyHelper extends GetObjectPropertyHelperBase {
3105 getObject(sb) {
3106 return sb.helpers.getSymbolObject;
3107 }
3108
3109}
3110
3111// Input: [constructorObjectVal, objectVal]
3112// Output: [boolean]
3113class InstanceofHelper extends Helper {
3114 emit(sb, node, options) {
3115 if (!options.pushValue) {
3116 sb.emitOp(node, 'DROP');
3117 sb.emitOp(node, 'DROP');
3118 return;
3119 } // ['prototype', constructorObjectVal, objectVal]
3120
3121
3122 sb.emitPushString(node, 'prototype'); // [prototypeVal, objectVal]
3123
3124 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [objectVal, prototypeVal]
3125
3126 sb.emitOp(node, 'SWAP');
3127
3128 const prepareLoop = () => {
3129 // [objectVal, objectVal, prototypeVal]
3130 sb.emitOp(node, 'DUP'); // ['prototype', objectVal, objectVal, prototypeVal]
3131
3132 sb.emitPushString(node, 'prototype'); // [nextPrototypeVal, objectVal, prototypeVal]
3133
3134 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [nextPrototypeVal, nextPrototypeVal, objectVal, prototypeVal]
3135
3136 sb.emitOp(node, 'DUP'); // [objectVal, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3137
3138 sb.emitOp(node, 'ROT'); // [3, objectVal, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3139
3140 sb.emitPushInt(node, 3); // [prototypeVal, objectVal, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3141
3142 sb.emitOp(node, 'PICK');
3143 }; // [prototypeVal, objectVal, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3144
3145
3146 prepareLoop();
3147 sb.emitHelper(node, options, sb.helpers.forLoop({
3148 condition: () => {
3149 // [samePrototype, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3150 sb.emitOp(node, 'EQUAL'); // [samePrototype, samePrototype, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3151
3152 sb.emitOp(node, 'DUP'); // [notSamePrototype, samePrototype, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3153
3154 sb.emitOp(node, 'NOT'); // [nextPrototypeVal, notSamePrototype, samePrototype, nextPrototypeVal, prototypeVal]
3155
3156 sb.emitOp(node, 'ROT'); // [isUndefined, notSamePrototype, samePrototype, nextPrototypeVal, prototypeVal]
3157
3158 sb.emitHelper(node, options, sb.helpers.isUndefined); // [hasPrototype, notSamePrototype, samePrototype, nextPrototypeVal, prototypeVal]
3159
3160 sb.emitOp(node, 'NOT'); // [hasPrototypeAndNotSame, samePrototype, nextPrototypeVal, prototypeVal]
3161
3162 sb.emitOp(node, 'AND');
3163 },
3164 each: () => {
3165 // [nextPrototypeVal, prototypeVal]
3166 sb.emitOp(node, 'DROP'); // [prototypeVal, objectVal, nextPrototypeVal, nextPrototypeVal, prototypeVal]
3167
3168 prepareLoop();
3169 }
3170 })); // [samePrototype, prototypeVal]
3171
3172 sb.emitOp(node, 'NIP'); // [samePrototype]
3173
3174 sb.emitOp(node, 'NIP');
3175 }
3176
3177}
3178
3179// Output: [boolean]
3180
3181class IsObjectHelper extends IsHelper {
3182 constructor(...args) {
3183 var _temp;
3184
3185 return _temp = super(...args), _defineProperty(this, "type", Types.Object), _temp;
3186 }
3187
3188}
3189
3190// Input: [?getObjectVal, ?setObjectVal, stringProp, objectVal]
3191// Output: []
3192class SetObjectAccessorPropertyHelperBase extends Helper {
3193 constructor({
3194 hasSet,
3195 hasGet
3196 }) {
3197 super();
3198
3199 _defineProperty(this, "hasSet", void 0);
3200
3201 _defineProperty(this, "hasGet", void 0);
3202
3203 this.hasSet = hasSet == null ? false : hasSet;
3204 this.hasGet = hasGet == null ? false : hasGet;
3205
3206 if (!(this.hasSet || this.hasGet)) {
3207 throw new Error('Something went wrong. Must have either a getter or setter');
3208 }
3209 }
3210
3211 emit(sb, node, optionsIn) {
3212 const options = sb.pushValueOptions(optionsIn);
3213
3214 if (!(this.hasSet && this.hasGet)) {
3215 // [val, ?getObjectVal, ?setObjectVal, stringProp, objectVal]
3216 sb.emitHelper(node, options, sb.helpers.createUndefined);
3217
3218 if (this.hasGet) {
3219 // [getObjectVal, setObjectVal, stringProp, objectVal]
3220 sb.emitOp(node, 'SWAP');
3221 }
3222 } // [2, getObjectVal, setObjectVal, stringProp, objectVal]
3223
3224
3225 sb.emitPushInt(node, 2); // [val, stringProp, objectVal]
3226
3227 sb.emitOp(node, 'PACK'); // [objectVal, val, stringProp]
3228
3229 sb.emitOp(node, 'ROT'); // [obj, val, stringProp]
3230
3231 sb.emitHelper(node, options, this.getObject(sb)); // [stringProp, obj, val]
3232
3233 sb.emitOp(node, 'ROT'); // [val, stringProp, obj]
3234
3235 sb.emitOp(node, 'ROT'); // []
3236
3237 sb.emitOp(node, 'SETITEM');
3238 }
3239
3240}
3241
3242// Output: []
3243
3244class SetAccessorPropertyObjectPropertyHelper extends SetObjectAccessorPropertyHelperBase {
3245 getObject(sb) {
3246 return sb.helpers.getPropertyObject;
3247 }
3248
3249}
3250
3251// Output: []
3252
3253class SetAccessorSymbolObjectPropertyHelper extends SetObjectAccessorPropertyHelperBase {
3254 getObject(sb) {
3255 return sb.helpers.getSymbolObject;
3256 }
3257
3258}
3259
3260// Input: [val, stringProp, objectVal]
3261// Output: []
3262class SetObjectDataPropertyHelperBase extends Helper {
3263 emit(sb, node, options) {
3264 // [objectVal, val, stringProp]
3265 sb.emitOp(node, 'ROT'); // [obj, val, stringProp]
3266
3267 sb.emitHelper(node, sb.pushValueOptions(options), this.getObject(sb)); // [stringProp, obj, val]
3268
3269 sb.emitOp(node, 'ROT'); // [val, stringProp, obj]
3270
3271 sb.emitOp(node, 'ROT'); // [1, val, stringProp, obj]
3272
3273 sb.emitPushInt(node, 1); // [propVal, stringProp, obj]
3274
3275 sb.emitOp(node, 'PACK'); // []
3276
3277 sb.emitOp(node, 'SETITEM');
3278 }
3279
3280}
3281
3282// Output: []
3283
3284class SetDataPropertyObjectPropertyHelper extends SetObjectDataPropertyHelperBase {
3285 getObject(sb) {
3286 return sb.helpers.getPropertyObject;
3287 }
3288
3289}
3290
3291// Output: []
3292
3293class SetDataSymbolObjectPropertyHelper extends SetObjectDataPropertyHelperBase {
3294 getObject(sb) {
3295 return sb.helpers.getSymbolObject;
3296 }
3297
3298}
3299
3300// Input: [val, stringProp, objectVal]
3301// Output: []
3302class SetInternalObjectPropertyHelper extends Helper {
3303 emit(sb, node, options) {
3304 // [objectVal, val, stringProp]
3305 sb.emitOp(node, 'ROT'); // [obj, val, stringProp]
3306
3307 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.getInternalObject); // [stringProp, obj, val]
3308
3309 sb.emitOp(node, 'ROT'); // [val, stringProp, obj]
3310
3311 sb.emitOp(node, 'ROT'); // []
3312
3313 sb.emitOp(node, 'SETITEM');
3314 }
3315
3316}
3317
3318// Input: [val, stringProp, objectVal]
3319// Output: [val]
3320class SetObjectPropertyHelperBase extends Helper {
3321 emit(sb, node, options) {
3322 // [objectVal, val, stringProp]
3323 sb.emitOp(node, 'ROT'); // [stringProp, objectVal, val]
3324
3325 sb.emitOp(node, 'ROT'); // [stringProp, objectVal, stringProp, val]
3326
3327 sb.emitOp(node, 'TUCK'); // [objectVal, stringProp, objectVal, stringProp, val]
3328
3329 sb.emitOp(node, 'OVER'); // [stringProp, objectVal, objectVal, stringProp, val]
3330
3331 sb.emitOp(node, 'SWAP');
3332 sb.emitHelper(node, options, sb.helpers.findObjectProperty({
3333 accessor: () => {
3334 // [1, propVal, objectVal, stringProp, val]
3335 sb.emitPushInt(node, 1); // [setObjectVal, objectVal, stringProp, val]
3336
3337 sb.emitOp(node, 'PICKITEM'); // [stringProp, setObjectVal, objectVal, val]
3338
3339 sb.emitOp(node, 'ROT'); // [setObjectVal, objectVal, val]
3340
3341 sb.emitOp(node, 'DROP'); // [val, setObjectVal, objectVal]
3342
3343 sb.emitOp(node, 'ROT'); // [1, val, setObjectVal, objectVal]
3344
3345 sb.emitPushInt(node, 1); // [argsarr, setObjectVal, objectVal]
3346
3347 sb.emitOp(node, 'PACK'); // [objectVal, argsarr, setObjectVal]
3348
3349 sb.emitOp(node, 'ROT'); // [setObjectVal, objectVal, argsarr]
3350
3351 sb.emitOp(node, 'ROT'); // [val]
3352
3353 sb.emitHelper(node, options, sb.helpers.invokeCall({
3354 bindThis: true,
3355 noArgs: false
3356 }));
3357 },
3358 dataExists: () => {
3359 // [propVal, stringProp, val]
3360 sb.emitOp(node, 'NIP'); // [propVal, val]
3361
3362 sb.emitOp(node, 'NIP'); // [0, propVal, val]
3363
3364 sb.emitPushInt(node, 0); // [val, 0, propVal]
3365
3366 sb.emitOp(node, 'ROT'); // []
3367
3368 sb.emitOp(node, 'SETITEM');
3369 },
3370 data: () => {
3371 // [stringProp, objectVal, val]
3372 sb.emitOp(node, 'SWAP'); // [val, stringProp, objectVal]
3373
3374 sb.emitOp(node, 'ROT'); // []
3375
3376 sb.emitHelper(node, options, this.setDataProperty(sb));
3377 },
3378 getObject: this.getObject.bind(this)
3379 }));
3380 }
3381
3382}
3383
3384// Output: []
3385
3386class SetPropertyObjectPropertyHelper extends SetObjectPropertyHelperBase {
3387 getObject(sb) {
3388 return sb.helpers.getPropertyObject;
3389 }
3390
3391 setDataProperty(sb) {
3392 return sb.helpers.setDataPropertyObjectProperty;
3393 }
3394
3395}
3396
3397// Output: []
3398
3399class SetSymbolObjectPropertyHelper extends SetObjectPropertyHelperBase {
3400 getObject(sb) {
3401 return sb.helpers.getSymbolObject;
3402 }
3403
3404 setDataProperty(sb) {
3405 return sb.helpers.setDataSymbolObjectProperty;
3406 }
3407
3408}
3409
3410// Output: [objectVal]
3411
3412class ShallowCloneObjectHelper extends Helper {
3413 emit(sb, node, options) {
3414 if (!options.pushValue) {
3415 sb.emitOp(node, 'DROP');
3416 return;
3417 } // [object]
3418
3419
3420 sb.emitHelper(node, options, sb.helpers.getObject); // [length, pobj, sobj, iobj, ...]
3421
3422 sb.emitOp(node, 'UNPACK');
3423
3424 const roll = () => {
3425 // [3, length, pobj, sobj, iobj, ...]
3426 sb.emitPushInt(node, 3); // [iobj, length, pobj, sobj, ...]
3427
3428 sb.emitOp(node, 'ROLL');
3429 };
3430
3431 const clone = () => {
3432 roll(); // [iobj, length, pobj, sobj, ...]
3433
3434 sb.emitHelper(node, options, sb.helpers.shallowCloneObj);
3435 }; // [iobj, length, pobj, sobj, ...]
3436
3437
3438 clone(); // [sobj, iobj, length, pobj, ...]
3439
3440 clone(); // [pobj, sobj, iobj, length, ...]
3441
3442 clone(); // [length, pobj, sobj, iobj, ...]
3443
3444 roll(); // [object]
3445
3446 sb.emitOp(node, 'PACK'); // [objectType, object]
3447
3448 sb.emitPushInt(node, Types.Object);
3449 /* create object */
3450 // [2, objectType, object]
3451
3452 sb.emitPushInt(node, 2); // [objectVal]
3453
3454 sb.emitOp(node, 'PACK');
3455 }
3456
3457}
3458
3459// Input: [obj]
3460// Output: [obj]
3461class ShallowCloneObjHelper extends Helper {
3462 emit(sb, node, options) {
3463 if (!options.pushValue) {
3464 sb.emitOp(node, 'DROP');
3465 return;
3466 }
3467 /* create new obj */
3468 // [newObj, oldObj]
3469
3470
3471 sb.emitOp(node, 'NEWMAP'); // [oldObj, newObj]
3472
3473 sb.emitOp(node, 'SWAP');
3474 /* get keys and values */
3475 // [oldObj, oldObj, newObj]
3476
3477 sb.emitOp(node, 'DUP'); // [valuesArray, oldObj, newObj]
3478
3479 sb.emitOp(node, 'VALUES'); // [oldObj, valuesArray, newObj]
3480
3481 sb.emitOp(node, 'SWAP'); // [keysArray, valuesArray, newObj]
3482
3483 sb.emitOp(node, 'KEYS');
3484 /* set keys/values on new obj */
3485
3486 sb.withScope(node, options, scopeOptions => {
3487 const counter = sb.scope.addUnique();
3488 const length = sb.scope.addUnique();
3489 sb.emitHelper(node, scopeOptions, sb.helpers.forLoop({
3490 initializer: () => {
3491 // [keysArray, keysArray, valuesArray, newObj]
3492 sb.emitOp(node, 'DUP'); // [length, keysArray, valuesArray, newObj]
3493
3494 sb.emitOp(node, 'ARRAYSIZE'); // [keysArray, valuesArray, newObj]
3495
3496 sb.scope.set(sb, node, scopeOptions, length); // [counter, keysArray, valuesArray, newObj]
3497
3498 sb.emitPushInt(node, 0); // [keysArray, valuesArray, newObj]
3499
3500 sb.scope.set(sb, node, scopeOptions, counter);
3501 },
3502 condition: () => {
3503 // [counter]
3504 sb.scope.get(sb, node, scopeOptions, counter); // [length, counter]
3505
3506 sb.scope.get(sb, node, scopeOptions, length); // [lt]
3507
3508 sb.emitOp(node, 'LT');
3509 },
3510 incrementor: () => {
3511 // [counter]
3512 sb.scope.get(sb, node, scopeOptions, counter); // [counter]
3513
3514 sb.emitOp(node, 'INC'); // []
3515
3516 sb.scope.set(sb, node, scopeOptions, counter);
3517 },
3518 each: innerOptions => {
3519 // [keysArray, valuesArray, keysArray, newObj]
3520 sb.emitOp(node, 'TUCK'); // [valuesArray, keysArray, valuesArray, keysArray, newObj]
3521
3522 sb.emitOp(node, 'OVER'); // [counter, valuesArray, keysArray, valuesArray, keysArray, newObj]
3523
3524 sb.scope.get(sb, node, innerOptions, counter); // [counter, valuesArray, counter, keysArray, valuesArray, keysArray, newObj]
3525
3526 sb.emitOp(node, 'TUCK'); // [value, counter, keysArray, valuesArray, keysArray, newObj]
3527
3528 sb.emitOp(node, 'PICKITEM'); // [keysArray, value, counter, valuesArray, keysArray, newObj]
3529
3530 sb.emitOp(node, 'ROT'); // [counter, keysArray, value, valuesArray, keysArray, newObj]
3531
3532 sb.emitOp(node, 'ROT'); // [key, value, valuesArray, keysArray, newObj]
3533
3534 sb.emitOp(node, 'PICKITEM'); // [4, key, value, valuesArray, keysArray, newObj]
3535
3536 sb.emitPushInt(node, 4); // [newObj, key, value, valuesArray, keysArray, newObj]
3537
3538 sb.emitOp(node, 'PICK'); // [key, newObj, value, valuesArray, keysArray, newObj]
3539
3540 sb.emitOp(node, 'SWAP'); // [value, key, newObj, valuesArray, keysArray, newObj]
3541
3542 sb.emitOp(node, 'ROT'); // [valuesArray, keysArray, newObj]
3543
3544 sb.emitOp(node, 'SETITEM');
3545 }
3546 }));
3547 }); // [keysArray, newObj]
3548
3549 sb.emitOp(node, 'DROP'); // [newObj]
3550
3551 sb.emitOp(node, 'DROP');
3552 }
3553
3554}
3555
3556// Output: [objectVal]
3557
3558class ToObjectHelper extends TypedHelper {
3559 emit(sb, node, options) {
3560 if (!options.pushValue) {
3561 sb.emitOp(node, 'DROP');
3562 return;
3563 }
3564
3565 const type = this.type;
3566
3567 if (isOnlyBoolean(type)) {
3568 this.convertPrimitive(sb, node, options, 'Boolean');
3569 } else if (isOnlyNumber(type)) {
3570 this.convertPrimitive(sb, node, options, 'Number');
3571 } else if (isOnlyString(type)) {
3572 this.convertPrimitive(sb, node, options, 'String');
3573 } else if (isOnlySymbol(type)) {
3574 this.convertPrimitive(sb, node, options, 'Symbol');
3575 } else if (isOnlyObject(type)) {
3576 return;
3577 } else {
3578 sb.emitHelper(node, options, sb.helpers.case([{
3579 condition: () => {
3580 // [val, val]
3581 sb.emitOp(node, 'DUP'); // [isObject, val]
3582
3583 sb.emitHelper(node, options, sb.helpers.isObject);
3584 },
3585 whenTrue: () => {// do nothing
3586 }
3587 }].concat([{
3588 helper: sb.helpers.isBoolean,
3589 primitive: 'Boolean'
3590 }, {
3591 helper: sb.helpers.isNumber,
3592 primitive: 'Number'
3593 }, {
3594 helper: sb.helpers.isString,
3595 primitive: 'String'
3596 }, {
3597 helper: sb.helpers.isSymbol,
3598 primitive: 'Symbol'
3599 }].map(({
3600 helper,
3601 primitive
3602 }) => ({
3603 condition: () => {
3604 // [val, val]
3605 sb.emitOp(node, 'DUP'); // [isObject, val]
3606
3607 sb.emitHelper(node, options, sb.helpers.isObject);
3608 },
3609 whenTrue: () => {
3610 this.convertPrimitive(sb, node, options, primitive);
3611 }
3612 }))), () => {
3613 sb.emitHelper(node, options, sb.helpers.throwTypeError);
3614 }));
3615 }
3616 }
3617
3618 convertPrimitive(sb, node, options, primitive) {
3619 // [1, val]
3620 sb.emitPushInt(node, 1); // [valArgsArray]
3621
3622 sb.emitOp(node, 'PACK'); // [globalObjectVal, valArgsArray]
3623
3624 sb.scope.getGlobal(sb, node, options); // [primitiveString, globalObjectVal, valArgsArray]
3625
3626 sb.emitPushString(node, primitive); // [primitiveObjectVal, valArgsArray]
3627
3628 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [val]
3629
3630 sb.emitHelper(node, options, sb.helpers.invokeCall());
3631 }
3632
3633}
3634
3635// Output: [stringVal]
3636
3637class CreateStringHelper extends CreatePrimitiveHelper {
3638 constructor(...args) {
3639 var _temp;
3640
3641 return _temp = super(...args), _defineProperty(this, "type", Types.String), _temp;
3642 }
3643
3644}
3645
3646// Output: [string]
3647
3648class GetStringHelper extends GetPrimitiveHelper {}
3649
3650// Output: [boolean]
3651
3652class IsStringHelper extends IsHelper {
3653 constructor(...args) {
3654 var _temp;
3655
3656 return _temp = super(...args), _defineProperty(this, "type", Types.String), _temp;
3657 }
3658
3659}
3660
3661// Output: [string]
3662
3663class ToStringHelper extends TypedHelper {
3664 emit(sb, node, options) {
3665 if (!options.pushValue) {
3666 sb.emitOp(node, 'DROP');
3667 return;
3668 }
3669
3670 if (this.type != null) {
3671 this.convertType(sb, node, options, this.type);
3672 } else {
3673 this.convertUnknown(sb, node, options);
3674 }
3675 }
3676
3677 convertType(sb, node, options, type) {
3678 if (isOnlyUndefined(type)) {
3679 this.convertUndefined(sb, node, options);
3680 } else if (isOnlyNull(type)) {
3681 this.convertNull(sb, node, options);
3682 } else if (isOnlyBoolean(type)) {
3683 this.convertBoolean(sb, node, options);
3684 } else if (isOnlyNumber(type)) {
3685 this.convertNumber(sb, node, options);
3686 } else if (isOnlyString(type)) {
3687 this.convertString(sb, node, options);
3688 } else if (isOnlySymbol(type)) {
3689 this.convertSymbol(sb, node, options);
3690 } else if (isOnlyObject(type)) {
3691 this.convertObject(sb, node, options);
3692 } else {
3693 this.convertUnknown(sb, node, options);
3694 }
3695 }
3696
3697 convertUndefined(sb, node, options) {
3698 sb.emitPushString(node, 'undefined');
3699 }
3700
3701 convertNull(sb, node, options) {
3702 sb.emitPushString(node, 'null');
3703 }
3704
3705 convertBoolean(sb, node, options) {
3706 sb.emitHelper(node, options, sb.helpers.if({
3707 condition: () => {
3708 sb.emitHelper(node, options, sb.helpers.getBoolean);
3709 },
3710 whenTrue: () => {
3711 sb.emitPushString(node, 'true');
3712 },
3713 whenFalse: () => {
3714 sb.emitPushString(node, 'false');
3715 }
3716 }));
3717 }
3718
3719 convertNumber(sb, node, options) {
3720 sb.emitHelper(node, options, sb.helpers.throwTypeError);
3721 }
3722
3723 convertString(sb, node, options) {
3724 sb.emitHelper(node, options, sb.helpers.getString);
3725 }
3726
3727 convertSymbol(sb, node, options) {
3728 sb.emitHelper(node, options, sb.helpers.throwTypeError);
3729 }
3730
3731 convertObject(sb, node, options) {
3732 // [primitive]
3733 sb.emitHelper(node, options, sb.helpers.toPrimitive({
3734 type: this.type,
3735 preferredType: 'string'
3736 })); // [value]
3737
3738 this.convertUnknown(sb, node, options, true);
3739 }
3740
3741 convertUnknown(sb, node, options, shouldThrowOnObject = false) {
3742 const emitIf = (check, whenTrue, whenFalse) => sb.emitHelper(node, options, sb.helpers.if({
3743 condition: () => {
3744 // [value, value]
3745 sb.emitOp(node, 'DUP'); // [isValue, value]
3746
3747 sb.emitHelper(node, options, check);
3748 },
3749 whenTrue,
3750 whenFalse
3751 }));
3752
3753 emitIf(sb.helpers.isString, () => this.convertString(sb, node, options), () => emitIf(sb.helpers.isUndefined, () => this.convertUndefined(sb, node, options), () => emitIf(sb.helpers.isNull, () => this.convertNull(sb, node, options), () => emitIf(sb.helpers.isBoolean, () => this.convertBoolean(sb, node, options), () => emitIf(sb.helpers.isNumber, () => this.convertNumber(sb, node, options), () => emitIf(sb.helpers.isSymbol, () => this.convertSymbol(sb, node, options), () => shouldThrowOnObject ? sb.emitHelper(node, options, sb.helpers.throwTypeError) : this.convertObject(sb, node, options)))))));
3754 }
3755
3756}
3757
3758// Output: [symbolVal]
3759
3760class CreateSymbolHelper extends CreatePrimitiveHelper {
3761 constructor(...args) {
3762 var _temp;
3763
3764 return _temp = super(...args), _defineProperty(this, "type", Types.Symbol), _temp;
3765 }
3766
3767}
3768
3769// Output: [string]
3770
3771class GetSymbolHelper extends GetPrimitiveHelper {}
3772
3773// Output: [boolean]
3774
3775class IsSymbolHelper extends IsHelper {
3776 constructor(...args) {
3777 var _temp;
3778
3779 return _temp = super(...args), _defineProperty(this, "type", Types.Symbol), _temp;
3780 }
3781
3782}
3783
3784// Output: [undefinedVal]
3785
3786class CreateUndefinedHelper extends CreatePrimitiveHelper {
3787 constructor(...args) {
3788 var _temp;
3789
3790 return _temp = super(...args), _defineProperty(this, "length", 1), _defineProperty(this, "type", Types.Undefined), _temp;
3791 }
3792
3793}
3794
3795// Output: [boolean]
3796
3797class IsUndefinedHelper extends IsHelper {
3798 constructor(...args) {
3799 var _temp;
3800
3801 return _temp = super(...args), _defineProperty(this, "type", Types.Undefined), _temp;
3802 }
3803
3804}
3805
3806// Input: [val]
3807// Output: [boolean]
3808class IsNullOrUndefinedHelper extends Helper {
3809 emit(sb, node, options) {
3810 if (!options.pushValue) {
3811 sb.emitOp(node, 'DROP');
3812 return;
3813 } // [val, val]
3814
3815
3816 sb.emitOp(node, 'DUP'); // [isNullBoolean, val]
3817
3818 sb.emitHelper(node, options, sb.helpers.isNull); // [val, isNullBoolean]
3819
3820 sb.emitOp(node, 'SWAP'); // [isUndefinedBoolean, isNullBoolean]
3821
3822 sb.emitHelper(node, options, sb.helpers.isUndefined); // [boolean]
3823
3824 sb.emitOp(node, 'BOOLOR');
3825 }
3826
3827}
3828
3829// Input: [val0, val1]
3830// Output: [boolean]
3831class IsSameTypeHelper extends Helper {
3832 emit(sb, node, options) {
3833 if (!options.pushValue) {
3834 sb.emitOp(node, 'DROP');
3835 sb.emitOp(node, 'DROP');
3836 return;
3837 } // [type0, val1]
3838
3839
3840 sb.emitHelper(node, options, sb.helpers.unwrapType); // [val1, type0]
3841
3842 sb.emitOp(node, 'SWAP'); // [type1, type0]
3843
3844 sb.emitHelper(node, options, sb.helpers.unwrapType); // [boolean]
3845
3846 sb.emitOp(node, 'EQUAL');
3847 }
3848
3849}
3850
3851// NOTE: Unlike the other To* methods, this returns a wrapped value.
3852// Input: [val]
3853// Output: [val]
3854class ToPrimitiveHelper extends Helper {
3855 constructor({
3856 type,
3857 knownType,
3858 preferredType
3859 }) {
3860 super();
3861
3862 _defineProperty(this, "type", void 0);
3863
3864 _defineProperty(this, "knownType", void 0);
3865
3866 _defineProperty(this, "preferredType", void 0);
3867
3868 this.type = type;
3869 this.knownType = knownType;
3870 this.preferredType = preferredType || 'default';
3871 }
3872
3873 emit(sb, node, options) {
3874 if (!options.pushValue) {
3875 sb.emitOp(node, 'DROP');
3876 return;
3877 }
3878
3879 if (!isOnlyPrimitive(this.type)) {
3880 if (this.type == null && this.knownType !== Types.Object) {
3881 this.toPrimitive(sb, node, options);
3882 } else {
3883 this.toPrimitiveObject(sb, node, options);
3884 }
3885 }
3886 }
3887
3888 toPrimitive(sb, node, options) {
3889 sb.emitHelper(node, options, sb.helpers.if({
3890 condition: () => {
3891 // [value, value]
3892 sb.emitOp(node, 'DUP'); // [isObject, value]
3893
3894 sb.emitHelper(node, options, sb.helpers.isObject);
3895 },
3896 whenTrue: () => {
3897 this.toPrimitiveObject(sb, node, options);
3898 }
3899 }));
3900 }
3901
3902 toPrimitiveObject(sb, node, options) {
3903 // [value, value]
3904 sb.emitOp(node, 'DUP'); // [symbol, value, value]
3905
3906 sb.emitPushString(node, '@@toPrimitive'); // [toPrimitive, value]
3907
3908 sb.emitHelper(node, options, sb.helpers.getSymbolObjectProperty);
3909 sb.emitHelper(node, options, sb.helpers.if({
3910 condition: () => {
3911 // [toPrimitive, toPrimitive, value]
3912 sb.emitOp(node, 'DUP'); // [isUndefined, toPrimitive, value]
3913
3914 sb.emitHelper(node, options, sb.helpers.isUndefined);
3915 },
3916 whenTrue: () => {
3917 // [value]
3918 sb.emitOp(node, 'DROP'); // [value]
3919
3920 this.tryConvert(sb, node, options, this.preferredType);
3921 },
3922 whenFalse: () => {
3923 // [preferredType, toPrimitiveVal, val]
3924 sb.emitPushString(node, this.preferredType); // [1, preferredType, toPrimitiveVal, val]
3925
3926 sb.emitPushInt(node, 1); // [args, toPrimitiveVal, val]
3927
3928 sb.emitOp(node, 'PACK'); // [val, args, toPrimitiveVal]
3929
3930 sb.emitOp(node, 'ROT'); // [toPrimitiveVal, val, args]
3931
3932 sb.emitOp(node, 'ROT'); // [val]
3933
3934 sb.emitHelper(node, options, sb.helpers.invokeCall({
3935 bindThis: true
3936 }));
3937 }
3938 }));
3939 }
3940
3941 tryConvert(sb, node, options, preferredType) {
3942 const methods = preferredType === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString']; // [value, value]
3943
3944 sb.emitOp(node, 'DUP'); // [method, value]
3945
3946 sb.emitPushString(node, methods[0]); // [func, value]
3947
3948 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty);
3949 sb.emitHelper(node, options, sb.helpers.if({
3950 condition: () => {
3951 // [func, func, value]
3952 sb.emitOp(node, 'DUP'); // [isUndefined, func, value]
3953
3954 sb.emitHelper(node, options, sb.helpers.isUndefined);
3955 },
3956 whenTrue: () => {
3957 // [value]
3958 sb.emitOp(node, 'DROP'); // [value, value]
3959
3960 sb.emitOp(node, 'DUP'); // [method, value]
3961
3962 sb.emitPushString(node, methods[1]); // [func, value]
3963
3964 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty);
3965 sb.emitHelper(node, options, sb.helpers.if({
3966 condition: () => {
3967 // [func, func, value]
3968 sb.emitOp(node, 'DUP'); // [isUndefined, func, value]
3969
3970 sb.emitHelper(node, options, sb.helpers.isUndefined);
3971 },
3972 whenTrue: () => {
3973 // [value]
3974 sb.emitOp(node, 'DROP'); // []
3975
3976 sb.emitOp(node, 'DROP'); // []
3977
3978 sb.emitHelper(node, options, sb.helpers.throwTypeError);
3979 },
3980 whenFalse: () => {
3981 sb.emitHelper(node, options, sb.helpers.invokeCall({
3982 bindThis: true,
3983 noArgs: true
3984 }));
3985 }
3986 }));
3987 },
3988 whenFalse: () => {
3989 sb.emitHelper(node, options, sb.helpers.invokeCall({
3990 bindThis: true,
3991 noArgs: true
3992 }));
3993 }
3994 }));
3995 }
3996
3997}
3998
3999// Input: [val]
4000// Output: [type]
4001class UnwrapTypeHelper extends Helper {
4002 emit(sb, node, options) {
4003 if (!options.pushValue) {
4004 sb.emitOp(node, 'DROP');
4005 return;
4006 } // [0, val]
4007
4008
4009 sb.emitPushInt(node, 0); // [value]
4010
4011 sb.emitOp(node, 'PICKITEM');
4012 }
4013
4014}
4015
4016// Input: [val]
4017// Output: [value]
4018// Must not be undefined or null
4019class UnwrapValHelper extends Helper {
4020 emit(sb, node, options) {
4021 if (!options.pushValue) {
4022 sb.emitOp(node, 'DROP');
4023 return;
4024 } // [1, val]
4025
4026
4027 sb.emitPushInt(node, 1); // [value]
4028
4029 sb.emitOp(node, 'PICKITEM');
4030 }
4031
4032}
4033
4034// Input: []
4035// Output: [boolean]
4036class EqualsEqualsEqualsHelper extends Helper {
4037 constructor(options) {
4038 super();
4039
4040 _defineProperty(this, "left", void 0);
4041
4042 _defineProperty(this, "right", void 0);
4043
4044 this.left = options.left;
4045 this.right = options.right;
4046 }
4047
4048 emit(sb, node, options) {
4049 sb.visit(this.left, options);
4050 sb.visit(this.right, options);
4051
4052 if (!options.pushValue) {
4053 sb.emitOp(node, 'DROP');
4054 sb.emitOp(node, 'DROP');
4055 return;
4056 }
4057
4058 if (isSame(sb.getType(this.left), sb.getType(this.right))) {
4059 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsSameType);
4060 } else {
4061 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsUnknown);
4062 }
4063 }
4064
4065}
4066
4067// Input: [numberVal, numberVal]
4068// Output: [boolean]
4069class EqualsEqualsEqualsNumberHelper extends Helper {
4070 emit(sb, node, options) {
4071 if (!options.pushValue) {
4072 sb.emitOp(node, 'DROP');
4073 sb.emitOp(node, 'DROP');
4074 return;
4075 } // [number, numberVal]
4076
4077
4078 sb.emitHelper(node, options, sb.helpers.getNumber); // [numberVal, number]
4079
4080 sb.emitOp(node, 'SWAP'); // [number, number]
4081
4082 sb.emitHelper(node, options, sb.helpers.getNumber); // [boolean]
4083
4084 sb.emitOp(node, 'NUMEQUAL');
4085 }
4086
4087}
4088
4089// Input: [val0, val1]
4090// Output: [boolean]
4091class EqualsEqualsEqualsSameTypeHelper extends Helper {
4092 emit(sb, node, options) {
4093 if (!options.pushValue) {
4094 sb.emitOp(node, 'DROP');
4095 sb.emitOp(node, 'DROP');
4096 return;
4097 }
4098
4099 sb.emitHelper(node, options, sb.helpers.if({
4100 condition: () => {
4101 // [val0, val0, val1]
4102 sb.emitOp(node, 'DUP'); // [isNullOrUndefined]
4103
4104 sb.emitHelper(node, options, sb.helpers.isNullOrUndefined);
4105 },
4106 whenTrue: () => {
4107 // [val1]
4108 sb.emitOp(node, 'DROP'); // []
4109
4110 sb.emitOp(node, 'DROP'); // [boolean]
4111
4112 sb.emitPushBoolean(node, true);
4113 },
4114 whenFalse: () => {
4115 // [value0, val1]
4116 sb.emitHelper(node, options, sb.helpers.unwrapVal); // [val1, value0]
4117
4118 sb.emitOp(node, 'SWAP'); // [value1, value0]
4119
4120 sb.emitHelper(node, options, sb.helpers.unwrapVal); // [boolean]
4121
4122 sb.emitOp(node, 'EQUAL');
4123 }
4124 }));
4125 }
4126
4127}
4128
4129// Input: [val0, val1]
4130// Output: [boolean]
4131class EqualsEqualsEqualsUnknownHelper extends Helper {
4132 emit(sb, node, options) {
4133 if (!options.pushValue) {
4134 sb.emitOp(node, 'DROP');
4135 sb.emitOp(node, 'DROP');
4136 return;
4137 }
4138
4139 sb.emitHelper(node, options, sb.helpers.if({
4140 condition: () => {
4141 // [val1, val0, val1]
4142 sb.emitOp(node, 'TUCK'); // [val0, val1, val0, val1]
4143
4144 sb.emitOp(node, 'OVER');
4145 sb.emitHelper(node, options, sb.helpers.isSameType);
4146 },
4147 whenTrue: () => {
4148 // [boolean]
4149 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsSameType);
4150 },
4151 whenFalse: () => {
4152 // [val1]
4153 sb.emitOp(node, 'DROP'); // []
4154
4155 sb.emitOp(node, 'DROP'); // [boolean]
4156
4157 sb.emitPushBoolean(node, false);
4158 }
4159 }));
4160 }
4161
4162}
4163
4164// Input: []
4165// Output: [boolean]
4166class EqualsEqualsHelper extends Helper {
4167 constructor(options) {
4168 super();
4169
4170 _defineProperty(this, "left", void 0);
4171
4172 _defineProperty(this, "right", void 0);
4173
4174 this.left = options.left;
4175 this.right = options.right;
4176 }
4177
4178 emit(sb, node, options) {
4179 if (!options.pushValue) {
4180 sb.visit(this.left, options);
4181 sb.visit(this.right, options);
4182 return;
4183 }
4184
4185 const leftType = sb.getType(this.left);
4186 const rightType = sb.getType(this.right);
4187
4188 if (leftType != null && rightType != null) {
4189 this.equalsEqualsType(sb, node, options, leftType, rightType);
4190 } else {
4191 this.equalsEqualsUnknown(sb, node, options);
4192 }
4193 }
4194
4195 equalsEqualsType(sb, node, options, leftType, rightType) {
4196 if (isSame(leftType, rightType)) {
4197 sb.emitHelper(node, options, sb.helpers.equalsEqualsEquals({
4198 left: this.left,
4199 right: this.right
4200 }));
4201 } else if ((hasNull(leftType) || hasUndefined(leftType)) && (isOnlyUndefined(rightType) || isOnlyNull(rightType))) {
4202 // [left]
4203 sb.visit(this.left, options); // [right, left]
4204
4205 sb.visit(this.right, options); // [left]
4206
4207 sb.emitOp(this.right, 'DROP'); // [equals]
4208
4209 sb.emitHelper(node, options, sb.helpers.isNullOrUndefined);
4210 } else if (isOnlyNumber(leftType) && (isOnlyString(rightType) || isOnlyBoolean(rightType))) {
4211 // [left]
4212 sb.visit(this.left, options); // [right, left]
4213
4214 sb.visit(this.right, options); // [equals]
4215
4216 this.equalsEqualsLeftNumberRightBooleanOrString(sb, node, options);
4217 } else if (isOnlyBoolean(leftType) && (isOnlyString(rightType) || isOnlyBoolean(rightType))) {
4218 // [left]
4219 sb.visit(this.left, options); // [leftNumber]
4220
4221 sb.emitHelper(this.left, options, sb.helpers.toNumber({
4222 type: sb.getType(this.left)
4223 })); // [leftNumberVal]
4224
4225 sb.emitHelper(this.left, options, sb.helpers.createNumber); // [right, leftNumberVal]
4226
4227 sb.visit(this.right, options); // [equals]
4228
4229 this.equalsEqualsLeftNumberRightBooleanOrString(sb, node, options);
4230 } else if ((isOnlyString(leftType) || isOnlyBoolean(leftType)) && isOnlyNumber(rightType)) {
4231 // [left]
4232 sb.visit(this.left, options); // [right, left]
4233
4234 sb.visit(this.right, options); // [equals]
4235
4236 this.equalsEqualsRightNumberLeftBooleanOrString(sb, node, options);
4237 } else if ((isOnlyString(leftType) || isOnlyBoolean(leftType)) && isOnlyBoolean(rightType)) {
4238 // [left]
4239 sb.visit(this.left, options); // [right, left]
4240
4241 sb.visit(this.right, options); // [rightNumber, left]
4242
4243 sb.emitHelper(this.right, options, sb.helpers.toNumber({
4244 type: sb.getType(this.right)
4245 })); // [rightNumberVal, left]
4246
4247 sb.emitHelper(this.right, options, sb.helpers.createNumber); // [equals]
4248
4249 this.equalsEqualsRightNumberLeftBooleanOrString(sb, node, options);
4250 } else {
4251 this.equalsEqualsUnknown(sb, node, options);
4252 }
4253 }
4254
4255 equalsEqualsLeftNumberRightBooleanOrString(sb, node, options) {
4256 // [rightNumber, left]
4257 sb.emitHelper(this.right, options, sb.helpers.toNumber({
4258 type: sb.getType(this.right)
4259 })); // [rightNumber, left]
4260
4261 sb.emitHelper(this.right, options, sb.helpers.createNumber); // [equals]
4262
4263 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsNumber);
4264 }
4265
4266 equalsEqualsRightNumberLeftBooleanOrString(sb, node, options) {
4267 // [left, right]
4268 sb.emitOp(node, 'SWAP'); // [leftNumber, right]
4269
4270 sb.emitHelper(this.left, options, sb.helpers.toNumber({
4271 type: sb.getType(this.left)
4272 })); // [leftNumber, right]
4273
4274 sb.emitHelper(this.left, options, sb.helpers.createNumber); // [right, leftNumber]
4275
4276 sb.emitOp(node, 'SWAP'); // [equals]
4277
4278 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsNumber);
4279 }
4280
4281 equalsEqualsUnknown(sb, node, options) {
4282 const copy = () => {
4283 // [right, left, right]
4284 sb.emitOp(this.right, 'TUCK'); // [left, right, left, right]
4285
4286 sb.emitOp(this.right, 'OVER');
4287 }; // [left]
4288
4289
4290 sb.visit(this.left, options); // [right, left]
4291
4292 sb.visit(this.right, options);
4293 const cases = [{
4294 condition: () => {
4295 copy(); // [right, left]
4296
4297 sb.emitHelper(node, options, sb.helpers.isSameType);
4298 },
4299 whenTrue: () => {
4300 sb.emitHelper(node, options, sb.helpers.equalsEqualsEqualsSameType);
4301 }
4302 }, {
4303 condition: () => {
4304 copy(); // [rightIsNullOrUndefined, left, right, left]
4305
4306 sb.emitHelper(node, options, sb.helpers.isNullOrUndefined); // [left, rightIsNullOrUndefined, right, left]
4307
4308 sb.emitOp(node, 'SWAP'); // [leftIsNullOrUndefined, rightIsNullOrUndefined, right, left]
4309
4310 sb.emitHelper(node, options, sb.helpers.isNullOrUndefined); // [equals, right, left]
4311
4312 sb.emitOp(node, 'BOOLOR');
4313 },
4314 whenTrue: () => {
4315 // [left]
4316 sb.emitOp(node, 'DROP'); // []
4317
4318 sb.emitOp(node, 'DROP'); // [equals]
4319
4320 sb.emitPushBoolean(node, true);
4321 }
4322 }, {
4323 condition: () => {
4324 copy(); // [right, right, left, right, left]
4325
4326 sb.emitOp(node, 'DUP'); // [isString, right, left, right, left]
4327
4328 sb.emitHelper(this.right, options, sb.helpers.isString); // [right, isString, left, right, left]
4329
4330 sb.emitOp(node, 'SWAP'); // [isBoolean, isString, left, right, left]
4331
4332 sb.emitHelper(this.right, options, sb.helpers.isBoolean); // [isBooleanOrString, left, right, left]
4333
4334 sb.emitOp(node, 'BOOLOR'); // [left, isBooleanOrString, right, left]
4335
4336 sb.emitOp(node, 'SWAP'); // [left, left, isBooleanOrString, right, left]
4337
4338 sb.emitOp(node, 'DUP'); // [isNumber, left, isBooleanOrString, right, left]
4339
4340 sb.emitHelper(this.right, options, sb.helpers.isNumber); // [left, isNumber, isBooleanOrString, right, left]
4341
4342 sb.emitOp(node, 'SWAP'); // [isBoolean, isNumber, isBooleanOrString, right, left]
4343
4344 sb.emitHelper(this.right, options, sb.helpers.isBoolean); // [isBooleanOrNumber, isBooleanOrString, right, left]
4345
4346 sb.emitOp(node, 'BOOLOR'); // [is(BooleanOrNumber)And(BooleanOrString), right, left]
4347
4348 sb.emitOp(node, 'BOOLAND');
4349 },
4350 whenTrue: () => {
4351 // [left, right]
4352 sb.emitOp(node, 'SWAP'); // [leftNumber, right]
4353
4354 sb.emitHelper(node, options, sb.helpers.toNumber({
4355 type: sb.getType(this.left)
4356 })); // [leftNumber, right]
4357
4358 sb.emitHelper(node, options, sb.helpers.createNumber); // [right, leftNumber]
4359
4360 sb.emitOp(node, 'SWAP');
4361 this.equalsEqualsLeftNumberRightBooleanOrString(sb, node, options);
4362 }
4363 }, {
4364 condition: () => {
4365 copy(); // [left, right, right, left]
4366
4367 sb.emitOp(node, 'SWAP'); // [left, left, right, right, left]
4368
4369 sb.emitOp(node, 'DUP'); // [isString, left, right, right, left]
4370
4371 sb.emitHelper(this.right, options, sb.helpers.isString); // [left, isString, right, right, left]
4372
4373 sb.emitOp(node, 'SWAP'); // [isBoolean, isString, right, right, left]
4374
4375 sb.emitHelper(this.right, options, sb.helpers.isBoolean); // [isBooleanOrString, right, right, left]
4376
4377 sb.emitOp(node, 'BOOLOR'); // [right, isBooleanOrString, right, left]
4378
4379 sb.emitOp(node, 'SWAP'); // [right, right, isBooleanOrString, right, left]
4380
4381 sb.emitOp(node, 'DUP'); // [isNumber, right, isBooleanOrString, right, left]
4382
4383 sb.emitHelper(this.right, options, sb.helpers.isNumber); // [right, isNumber, isBooleanOrString, right, left]
4384
4385 sb.emitOp(node, 'SWAP'); // [isBoolean, isNumber, isBooleanOrString, right, left]
4386
4387 sb.emitHelper(this.right, options, sb.helpers.isBoolean); // [isBooleanOrNumber, isBooleanOrString, right, left]
4388
4389 sb.emitOp(node, 'BOOLOR'); // [is(BooleanOrNumber)And(BooleanOrString), right, left]
4390
4391 sb.emitOp(node, 'BOOLAND');
4392 },
4393 whenTrue: () => {
4394 // [rightNumber, left]
4395 sb.emitHelper(node, options, sb.helpers.toNumber({
4396 type: sb.getType(this.right)
4397 })); // [rightNumber, left]
4398
4399 sb.emitHelper(node, options, sb.helpers.createNumber);
4400 this.equalsEqualsRightNumberLeftBooleanOrString(sb, node, options);
4401 }
4402 }];
4403 sb.emitHelper(node, options, sb.helpers.case(cases, () => {
4404 // [rightPrim, left]
4405 sb.emitHelper(node, options, sb.helpers.toPrimitive({
4406 type: sb.getType(this.right)
4407 })); // [left, rightPrim]
4408
4409 sb.emitOp(node, 'SWAP'); // [leftPrim, rightPrim]
4410
4411 sb.emitHelper(node, options, sb.helpers.toPrimitive({
4412 type: sb.getType(this.left)
4413 })); // [rightPrim, leftPrim]
4414
4415 sb.emitOp(node, 'SWAP');
4416 sb.emitHelper(node, options, sb.helpers.case(cases, () => {
4417 // [leftPrim]
4418 sb.emitOp(node, 'DROP'); // []
4419
4420 sb.emitOp(node, 'DROP'); // [equals]
4421
4422 sb.emitPushBoolean(node, false);
4423 }));
4424 }));
4425 }
4426
4427}
4428
4429// Input: []
4430// Output: [boolean]
4431class LessThanHelper extends Helper {
4432 constructor(options) {
4433 super();
4434
4435 _defineProperty(this, "leftFirst", void 0);
4436
4437 _defineProperty(this, "left", void 0);
4438
4439 _defineProperty(this, "right", void 0);
4440
4441 this.leftFirst = options.leftFirst;
4442 this.left = options.left;
4443 this.right = options.right;
4444 }
4445
4446 emit(sb, node, options) {
4447 if (!options.pushValue) {
4448 if (this.leftFirst) {
4449 sb.visit(this.left, options);
4450 sb.visit(this.right, options);
4451 } else {
4452 sb.visit(this.right, options);
4453 sb.visit(this.left, options);
4454 }
4455
4456 return;
4457 }
4458
4459 if (this.leftFirst) {
4460 // [left]
4461 sb.visit(this.left, options); // [leftPrim]
4462
4463 sb.emitHelper(this.left, options, sb.helpers.toPrimitive({
4464 type: sb.getType(this.left),
4465 preferredType: 'number'
4466 })); // [right, leftPrim]
4467
4468 sb.visit(this.right, options); // [rightPrim, leftPrim]
4469
4470 sb.emitHelper(this.right, options, sb.helpers.toPrimitive({
4471 type: sb.getType(this.right),
4472 preferredType: 'number'
4473 }));
4474 } else {
4475 // [right]
4476 sb.visit(this.right, options); // [rightPrim]
4477
4478 sb.emitHelper(this.right, options, sb.helpers.toPrimitive({
4479 type: sb.getType(this.right),
4480 preferredType: 'number'
4481 })); // [left, rightPrim]
4482
4483 sb.visit(this.left, options); // [leftPrim, rightPrim]
4484
4485 sb.emitHelper(this.left, options, sb.helpers.toPrimitive({
4486 type: sb.getType(this.left),
4487 preferredType: 'number'
4488 })); // [rightPrim, leftPrim]
4489
4490 sb.emitOp(node, 'SWAP');
4491 }
4492
4493 if (isOnlyString(sb.getType(this.left)) && isOnlyString(sb.getType(this.right))) {
4494 sb.reportUnsupported(node);
4495 } else {
4496 // [rightNumber, leftPrim]
4497 sb.emitHelper(this.right, options, sb.helpers.toNumber({
4498 type: sb.getType(this.right)
4499 })); // [leftPrim, rightNumber]
4500
4501 sb.emitOp(node, 'SWAP'); // [leftNumber, rightNumber]
4502
4503 sb.emitHelper(this.left, options, sb.helpers.toNumber({
4504 type: sb.getType(this.left)
4505 })); // [rightNumber, leftNumber]
4506
4507 sb.emitOp(node, 'SWAP'); // [lt]
4508
4509 sb.emitOp(node, 'LT');
4510
4511 if (!options.pushValue) {
4512 sb.emitOp(node, 'DROP');
4513 }
4514 }
4515 }
4516
4517}
4518
4519const GLOBAL_PROPERTIES = new Set(['Array', 'Boolean', 'Buffer', 'Error', 'Number', 'Object', 'String', 'Symbol', 'process']);
4520
4521let InternalGlobalProperties;
4522
4523(function (InternalGlobalProperties) {
4524 InternalGlobalProperties["MODULES"] = "modules";
4525 InternalGlobalProperties["ARGUMENTS"] = "arguments";
4526})(InternalGlobalProperties || (InternalGlobalProperties = {}));
4527
4528// Output: []
4529
4530class AddArgumentsHelper extends Helper {
4531 emit(sb, node, optionsIn) {
4532 const options = sb.pushValueOptions(optionsIn); // ['arguments', argv, globalObjectVal]
4533
4534 sb.emitPushString(node, InternalGlobalProperties.ARGUMENTS); // [argv, 'arguments', globalObjectVal]
4535
4536 sb.emitOp(node, 'SWAP'); // []
4537
4538 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
4539 }
4540
4541}
4542
4543// Output: [objectPrototypeVal, globalObjectVal]
4544
4545class AddConstructorObjectHelper extends Helper {
4546 constructor(...args) {
4547 var _temp;
4548
4549 return _temp = super(...args), _defineProperty(this, "name", void 0), _temp;
4550 }
4551
4552 emit(sb, node, optionsIn) {
4553 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal, objectPrototypeVal]
4554
4555 sb.emitOp(node, 'SWAP'); // [globalObjectVal, objectPrototypeVal, globalObjectVal]
4556
4557 sb.emitOp(node, 'TUCK'); // [objectPrototypeVal, globalObjectVal, objectPrototypeVal, globalObjectVal]
4558
4559 sb.emitOp(node, 'OVER');
4560 /* create constructor prototype */
4561 // [prototypeVal, objectPrototypeVal, globalObjectVal]
4562
4563 sb.emitHelper(node, options, sb.helpers.createObject); // [prototypeVal, objectPrototypeVal, prototypeVal, globalObjectVal]
4564
4565 sb.emitOp(node, 'TUCK'); // ['prototype', prototypeVal, objectPrototypeVal, prototypeVal, globalObjectVal]
4566
4567 sb.emitPushString(node, 'prototype'); // [objectPrototypeVal, 'prototype', prototypeVal, prototypeVal, globalObjectVal]
4568
4569 sb.emitOp(node, 'ROT'); // [prototypeVal, globalObjectVal]
4570
4571 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [prototypeVal, globalObjectVal]
4572
4573 this.addPrototypeProperties(sb, node, options);
4574 /* create object */
4575 // [objectVal, prototypeVal, globalObjectVal]
4576
4577 sb.emitHelper(node, options, sb.helpers.createObject); // [objectVal, prototypeVal, objectVal, globalObjectVal]
4578
4579 sb.emitOp(node, 'TUCK'); // [prototypeVal, objectVal, prototypeVal, objectVal, globalObjectVal]
4580
4581 sb.emitOp(node, 'OVER'); // ['prototype', prototypeVal, objectVal, prototypeVal, objectVal, globalObjectVal]
4582
4583 sb.emitPushString(node, 'prototype'); // [prototypeVal, 'prototype', objectVal, prototypeVal, objectVal, globalObjectVal]
4584
4585 sb.emitOp(node, 'SWAP'); // [prototypeVal, objectVal, globalObjectVal]
4586
4587 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [objectVal, prototypeVal, objectVal, globalObjectVal]
4588
4589 sb.emitOp(node, 'OVER'); // ['constructor', objectVal, prototypeVal, objectVal, globalObjectVal]
4590
4591 sb.emitPushString(node, 'constructor'); // [objectVal, 'constructor', prototypeVal, objectVal, globalObjectVal]
4592
4593 sb.emitOp(node, 'SWAP'); // [objectVal, globalObjectVal]
4594
4595 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [objectVal, globalObjectVal]
4596
4597 this.addConstructorProperties(sb, node, options); // [name, objectVal, globalObjectVal]
4598
4599 sb.emitPushString(node, this.name); // [objectVal, name, globalObjectVal]
4600
4601 sb.emitOp(node, 'SWAP'); // [objectPrototypeVal, globalObjectVal]
4602
4603 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty);
4604 }
4605
4606 addPrototypeProperties(sb, node, options) {// do nothing
4607 }
4608
4609 addConstructorProperties(sb, node, options) {// do nothing
4610 }
4611
4612 addMethod(sb, node, options, name, body) {
4613 // [prototypeVal, prototypeVal, globalObjectVal]
4614 sb.emitOp(node, 'DUP'); // [name, prototypeVal, prototypeVal, globalObjectVal]
4615
4616 sb.emitPushString(node, name); // [farr, name, prototypeVal, prototypeVal, globalObjectVal]
4617
4618 sb.emitHelper(node, options, sb.helpers.createFunctionArray({
4619 body: () => {
4620 sb.withScope(node, options, body);
4621 sb.emitHelper(node, options, sb.helpers.createNormalCompletion);
4622 sb.emitOp(node, 'RET');
4623 }
4624 })); // [fobjectVal, name, prototypeVal, prototypeVal, globalObjectVal]
4625
4626 sb.emitHelper(node, options, sb.helpers.createFunctionObject({
4627 property: InternalFunctionProperties.CALL
4628 })); // [prototypeVal, globalObjectVal]
4629
4630 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty);
4631 }
4632
4633}
4634
4635// Input: [objectPrototypeVal, globalObjectVal]
4636// Output: [objectPrototypeVal, globalObjectVal]
4637class AddArrayObjectHelper extends AddConstructorObjectHelper {
4638 constructor(...args) {
4639 var _temp;
4640
4641 return _temp = super(...args), _defineProperty(this, "name", 'Array'), _temp;
4642 }
4643
4644 addPrototypeProperties(sb, node, options) {
4645 this.addMap(sb, node, options);
4646 this.addFilter(sb, node, options);
4647 this.addReduce(sb, node, options);
4648 }
4649
4650 addConstructorProperties(sb, node, options) {
4651 // [objectVal, objectVal, globalObjectVal]
4652 sb.emitOp(node, 'DUP'); // ['construct', objectVal, objectVal, globalObjectVal]
4653
4654 sb.emitPushString(node, InternalFunctionProperties.CONSTRUCT); // [func, 'construct', objectVal, objectVal, globalObjectVal]
4655
4656 sb.emitHelper(node, options, sb.helpers.createConstructArray({
4657 withoutScope: true,
4658 body: () => {
4659 // [argsarray, argsarray]
4660 sb.emitOp(node, 'DUP'); // [size, argsarray]
4661
4662 sb.emitOp(node, 'ARRAYSIZE');
4663 sb.emitHelper(node, options, sb.helpers.case([{
4664 condition: () => {
4665 // [size, size, argsarray]
4666 sb.emitOp(node, 'DUP'); // [0, size, size, argsarray]
4667
4668 sb.emitPushInt(node, 0); // [size === 0, size, argsarray]
4669
4670 sb.emitOp(node, 'EQUAL');
4671 },
4672 whenTrue: () => {
4673 // [argsarray]
4674 sb.emitOp(node, 'DROP'); // []
4675
4676 sb.emitOp(node, 'DROP'); // [length]
4677
4678 sb.emitPushInt(node, 0); // [0, length]
4679
4680 sb.emitPushInt(node, 0); // [array, length]
4681
4682 sb.emitOp(node, 'NEWARRAY');
4683 }
4684 }, {
4685 condition: () => {
4686 // [size, size, argsarray]
4687 sb.emitOp(node, 'DUP'); // [1, size, size, argsarray]
4688
4689 sb.emitPushInt(node, 1); // [size === 1, size, argsarray]
4690
4691 sb.emitOp(node, 'EQUAL');
4692 },
4693 whenTrue: () => {
4694 // [argsarray]
4695 sb.emitOp(node, 'DROP'); // [0, argsarray]
4696
4697 sb.emitPushInt(node, 0); // [lengthVal]
4698
4699 sb.emitOp(node, 'PICKITEM'); // [length]
4700
4701 sb.emitHelper(node, options, sb.helpers.getNumber); // [length, length]
4702
4703 sb.emitOp(node, 'DUP'); // [0, length, length]
4704
4705 sb.emitPushInt(node, 0); // [arr, length, length]
4706
4707 sb.emitOp(node, 'NEWARRAY'); // [arr, length, arr, length]
4708
4709 sb.emitOp(node, 'TUCK'); // [length, arr, arr, length]
4710
4711 sb.emitOp(node, 'SWAP'); // [array, length]
4712
4713 sb.emitHelper(node, options, sb.helpers.extendArray);
4714 }
4715 }], () => {
4716 // [array, length]
4717 sb.emitOp(node, 'SWAP');
4718 })); // [objectVal, arr, length]
4719
4720 sb.scope.getThis(sb, node, options); // [objectVal, objectVal, arr, length]
4721
4722 sb.emitOp(node, 'DUP'); // [arr, objectVal, objectVal, length]
4723
4724 sb.emitOp(node, 'ROT'); // [objectVal, length]
4725
4726 sb.emitHelper(node, options, sb.helpers.setArrayValue); // ['length', objectVal, length]
4727
4728 sb.emitPushString(node, 'length'); // [length, 'length', objectVal]
4729
4730 sb.emitOp(node, 'ROT'); // [lengthVal, 'length', objectVal]
4731
4732 sb.emitHelper(node, options, sb.helpers.createNumber); // []
4733
4734 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty);
4735 }
4736 })); // [objectVal, globalObjectVal]
4737
4738 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
4739 }
4740
4741 addMap(sb, node, options) {
4742 this.addMapLike(sb, node, options, 'map', sb.helpers.arrMap);
4743 }
4744
4745 addFilter(sb, node, options) {
4746 this.addMapLike(sb, node, options, 'filter', sb.helpers.arrFilter);
4747 }
4748
4749 addReduce(sb, node, outerOptions) {
4750 this.addMethod(sb, node, outerOptions, 'reduce', options => {
4751 const func = sb.scope.addUnique();
4752 const accum = sb.scope.addUnique(); // [argsarr, argsarr]
4753
4754 sb.emitOp(node, 'DUP'); // [0, argsarr, argsarr]
4755
4756 sb.emitPushInt(node, 0); // [fObjectVal, argsarr]
4757
4758 sb.emitOp(node, 'PICKITEM'); // [argsarr]
4759
4760 sb.scope.set(sb, node, options, func); // [argsarr, argsarr]
4761
4762 sb.emitOp(node, 'DUP'); // [size, argsarr]
4763
4764 sb.emitOp(node, 'ARRAYSIZE'); // [val]
4765
4766 sb.emitHelper(node, options, sb.helpers.if({
4767 condition: () => {
4768 // [2, size, argsarr]
4769 sb.emitPushInt(node, 2); // [size === 2, argsarr]
4770
4771 sb.emitOp(node, 'NUMEQUAL');
4772 },
4773 whenTrue: () => {
4774 // [1, argsarr]
4775 sb.emitPushInt(node, 1); // [val]
4776
4777 sb.emitOp(node, 'PICKITEM');
4778 },
4779 whenFalse: () => {
4780 // []
4781 sb.emitOp(node, 'DROP'); // [val]
4782
4783 sb.emitHelper(node, options, sb.helpers.createUndefined);
4784 }
4785 })); // []
4786
4787 sb.scope.set(sb, node, options, accum); // [arrayObjectVal]
4788
4789 sb.scope.getThis(sb, node, options); // [arr]
4790
4791 sb.emitHelper(node, options, sb.helpers.unwrapArray); // [arr]
4792
4793 sb.emitHelper(node, options, sb.helpers.arrForEach({
4794 each: () => {
4795 // [accum, val, index]
4796 sb.scope.get(sb, node, options, accum); // [index, accum, val]
4797
4798 sb.emitOp(node, 'ROT'); // [indexVal, accum, val]
4799
4800 sb.emitHelper(node, options, sb.helpers.createNumber); // [accum, indexVal, val]
4801
4802 sb.emitOp(node, 'SWAP'); // [val, accum, indexVal]
4803
4804 sb.emitOp(node, 'ROT'); // [3, val, accum, indexVal]
4805
4806 sb.emitPushInt(node, 3); // [argsarr]
4807
4808 sb.emitOp(node, 'PACK'); // [fObjectVal, argsarr]
4809
4810 sb.scope.get(sb, node, options, func); // [val]
4811
4812 sb.emitHelper(node, options, sb.helpers.invokeCall()); // []
4813
4814 sb.scope.set(sb, node, options, accum);
4815 },
4816 withIndex: true
4817 })); // [val]
4818
4819 sb.scope.get(sb, node, options, accum);
4820 });
4821 }
4822
4823 addMapLike(sb, node, outerOptions, name, helper) {
4824 this.addMethod(sb, node, outerOptions, name, options => {
4825 const func = sb.scope.addUnique(); // [0, argsarr]
4826
4827 sb.emitPushInt(node, 0); // [fObjectVal]
4828
4829 sb.emitOp(node, 'PICKITEM'); // []
4830
4831 sb.scope.set(sb, node, options, func); // [arrayObjectVal]
4832
4833 sb.scope.getThis(sb, node, options); // [arr]
4834
4835 sb.emitHelper(node, options, sb.helpers.unwrapArray); // [arr]
4836
4837 sb.emitHelper(node, options, helper({
4838 map: () => {
4839 // [index, val]
4840 sb.emitOp(node, 'SWAP'); // [indexVal, val]
4841
4842 sb.emitHelper(node, options, sb.helpers.createNumber); // [val, indexVal]
4843
4844 sb.emitOp(node, 'SWAP'); // [2, val, indexVal]
4845
4846 sb.emitPushInt(node, 2); // [argsarr]
4847
4848 sb.emitOp(node, 'PACK'); // [fObjectVal, argsarr]
4849
4850 sb.scope.get(sb, node, options, func); // [val]
4851
4852 sb.emitHelper(node, options, sb.helpers.invokeCall());
4853 },
4854 withIndex: true
4855 })); // [arrayObjectVal]
4856
4857 sb.emitHelper(node, options, sb.helpers.wrapArray);
4858 });
4859 }
4860
4861}
4862
4863// Output: [objectPrototypeVal, globalObjectVal]
4864
4865class AddBufferObjectHelper extends AddConstructorObjectHelper {
4866 constructor(...args) {
4867 var _temp;
4868
4869 return _temp = super(...args), _defineProperty(this, "name", 'Buffer'), _temp;
4870 }
4871
4872 addConstructorProperties(sb, node, options) {
4873 this.addConstructor(sb, node, options);
4874 this.addConcat(sb, node, options);
4875 }
4876
4877 addConstructor(sb, node, options) {
4878 // [objectVal, objectVal, globalObjectVal]
4879 sb.emitOp(node, 'DUP'); // ['construct', objectVal, objectVal, globalObjectVal]
4880
4881 sb.emitPushString(node, InternalFunctionProperties.CONSTRUCT); // [func, 'construct', objectVal, objectVal, globalObjectVal]
4882
4883 sb.emitHelper(node, options, sb.helpers.createConstructArray({
4884 withoutScope: true,
4885 body: () => {
4886 // Drop the args array
4887 // []
4888 sb.emitOp(node, 'DROP');
4889 }
4890 })); // [objectVal, globalObjectVal]
4891
4892 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
4893 }
4894
4895 addConcat(sb, node, outerOptions) {
4896 this.addMethod(sb, node, outerOptions, 'concat', options => {
4897 // [0, argsarr]
4898 sb.emitPushInt(node, 0); // [arrayObjectVal]
4899
4900 sb.emitOp(node, 'PICKITEM'); // [array]
4901
4902 sb.emitHelper(node, options, sb.helpers.unwrapArray); // [buffer, array]
4903
4904 sb.emitOp(node, 'PUSH0');
4905 sb.emitHelper(node, options, sb.helpers.forLoop({
4906 condition: () => {
4907 // [array, buffer, array]
4908 sb.emitOp(node, 'OVER'); // [size, buffer, array]
4909
4910 sb.emitOp(node, 'ARRAYSIZE'); // [0, size, buffer, array]
4911
4912 sb.emitPushInt(node, 0); // [size > 0, buffer, array]
4913
4914 sb.emitOp(node, 'GT');
4915 },
4916 each: () => {
4917 // [array, buffer, array]
4918 sb.emitOp(node, 'OVER'); // [0, array, buffer, array]
4919
4920 sb.emitPushInt(node, 0); // [rightBufferVal, buffer, array]
4921
4922 sb.emitOp(node, 'PICKITEM'); // [rightBuffer, buffer, array]
4923
4924 sb.emitHelper(node, options, sb.helpers.unwrapBuffer); // [buffer + rightBuffer, array]
4925
4926 sb.emitOp(node, 'CAT'); // [array, buffer, array]
4927
4928 sb.emitOp(node, 'OVER'); // [0, array, buffer, array]
4929
4930 sb.emitPushInt(node, 0); // [buffer, array]
4931
4932 sb.emitOp(node, 'REMOVE');
4933 }
4934 })); // [buffer]
4935
4936 sb.emitOp(node, 'NIP'); // [bufferVal]
4937
4938 sb.emitHelper(node, options, sb.helpers.wrapBuffer);
4939 });
4940 }
4941
4942}
4943
4944// Output: [objectPrototypeVal, globalObjectVal]
4945
4946class AddBooleanObjectHelper extends AddConstructorObjectHelper {
4947 constructor(...args) {
4948 var _temp;
4949
4950 return _temp = super(...args), _defineProperty(this, "name", 'Boolean'), _temp;
4951 }
4952
4953}
4954
4955// Output: [objectPrototypeVal, globalObjectVal]
4956
4957class AddErrorObjectHelper extends AddConstructorObjectHelper {
4958 constructor(...args) {
4959 var _temp;
4960
4961 return _temp = super(...args), _defineProperty(this, "name", 'Error'), _temp;
4962 }
4963
4964 addConstructorProperties(sb, node, options) {
4965 // [objectVal, objectVal, globalObjectVal]
4966 sb.emitOp(node, 'DUP'); // ['construct', objectVal, objectVal, globalObjectVal]
4967
4968 sb.emitPushString(node, InternalFunctionProperties.CONSTRUCT); // [func, 'construct', objectVal, objectVal, globalObjectVal]
4969
4970 sb.emitHelper(node, options, sb.helpers.createConstructArray({
4971 withoutScope: true,
4972 body: () => {
4973 // Drop the args array
4974 // []
4975 sb.emitOp(node, 'DROP');
4976 }
4977 })); // [objectVal, globalObjectVal]
4978
4979 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
4980 }
4981
4982}
4983
4984// Output: [objectPrototypeVal, globalObjectVal]
4985
4986class AddModulesHelper extends Helper {
4987 emit(sb, node, optionsIn) {
4988 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal, objectPrototypeVal, globalObjectVal]
4989
4990 sb.emitOp(node, 'OVER'); // ['modules', globalObjectVal, objectPrototypeVal, globalObjectVal]
4991
4992 sb.emitPushString(node, InternalGlobalProperties.MODULES); // [0, 'modules', globalObjectVal, objectPrototypeVal, globalObjectVal]
4993
4994 sb.emitPushInt(node, 0); // [arr, 'modules', globalObjectVal, objectPrototypeVal, globalObjectVal]
4995
4996 sb.emitOp(node, 'NEWARRAY'); // [objectPrototypeVal, globalObjectVal]]
4997
4998 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
4999 }
5000
5001}
5002
5003// Output: [objectPrototypeVal, globalObjectVal]
5004
5005class AddNumberObjectHelper extends AddConstructorObjectHelper {
5006 constructor(...args) {
5007 var _temp;
5008
5009 return _temp = super(...args), _defineProperty(this, "name", 'Number'), _temp;
5010 }
5011
5012}
5013
5014// Input: [globalObjectVal]
5015// Output: [objectPrototypeVal, globalObjectVal]
5016class AddObjectObjectHelper extends Helper {
5017 emit(sb, node, optionsIn) {
5018 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal, globalObjectVal]
5019
5020 sb.emitOp(node, 'DUP');
5021 /* create object prototype */
5022 // [objectPrototypeVal, globalObjectVal, globalObjectVal]
5023
5024 sb.emitHelper(node, options, sb.helpers.createObject); // [objectPrototypeVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5025
5026 sb.emitOp(node, 'DUP');
5027 /* create object */
5028 // [objectVal, objectPrototypeVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5029
5030 sb.emitHelper(node, options, sb.helpers.createObject); // [objectVal, objectPrototypeVal, objectVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5031
5032 sb.emitOp(node, 'TUCK'); // ['prototype', objectVal, objectPrototypeVal, objectVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5033
5034 sb.emitPushString(node, 'prototype'); // [objectPrototypeVal, 'prototype', objectVal, objectVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5035
5036 sb.emitOp(node, 'ROT'); // [objectVal, objectPrototypeVal, globalObjectVal, globalObjectVal]
5037
5038 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [objectVal, objectPrototypeVal, objectVal, globalObjectVal, globalObjectVal]
5039
5040 sb.emitOp(node, 'TUCK'); // [objectPrototypeVal, objectVal, objectPrototypeVal, objectVal, globalObjectVal, globalObjectVal]
5041
5042 sb.emitOp(node, 'OVER'); // ['constructor', objectPrototypeVal, objectVal, objectPrototypeVal, objectVal, globalObjectVal, globalObjectVal]
5043
5044 sb.emitPushString(node, 'constructor'); // [objectVal, 'constructor', objectPrototypeVal, objectPrototypeVal, objectVal, globalObjectVal, globalObjectVal]
5045
5046 sb.emitOp(node, 'ROT'); // [objectPrototypeVal, objectVal, globalObjectVal, globalObjectVal]
5047
5048 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [globalObjectVal, objectPrototypeVal, objectVal, globalObjectVal]
5049
5050 sb.emitOp(node, 'ROT'); // ['Object', globalObjectVal, objectPrototypeVal, objectVal, globalObjectVal]
5051
5052 sb.emitPushString(node, 'Object'); // ['Object', globalObjectVal, objectPrototypeVal, objectVal, globalObjectVal]
5053
5054 sb.emitPushInt(node, 3); // [objectVal, 'Object', globalObjectVal, objectPrototypeVal, globalObjectVal]
5055
5056 sb.emitOp(node, 'ROLL'); // [objectPrototypeVal, globalObjectVal]
5057
5058 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty);
5059 }
5060
5061}
5062
5063// Output: [objectPrototypeVal, globalObjectVal]
5064
5065class AddStringObjectHelper extends AddConstructorObjectHelper {
5066 constructor(...args) {
5067 var _temp;
5068
5069 return _temp = super(...args), _defineProperty(this, "name", 'String'), _temp;
5070 }
5071
5072}
5073
5074// Output: [objectPrototypeVal, globalObjectVal]
5075
5076class AddSymbolObjectHelper extends AddConstructorObjectHelper {
5077 constructor(...args) {
5078 var _temp;
5079
5080 return _temp = super(...args), _defineProperty(this, "name", 'Symbol'), _temp;
5081 }
5082
5083}
5084
5085// Input: []
5086// Output: [globalObjectVal]
5087class SetGlobalObjectHelper extends Helper {
5088 emit(sb, node, optionsIn) {
5089 const options = sb.pushValueOptions(optionsIn); // [length, ...args]
5090
5091 sb.emitOp(node, 'DEPTH'); // [argv]
5092
5093 sb.emitOp(node, 'PACK'); // [globalObjectVal, argv]
5094
5095 sb.emitHelper(node, options, sb.helpers.createObject); // [globalObjectVal, globalObjectVal, argv]
5096
5097 sb.emitOp(node, 'DUP'); // [globalObjectVal, argv]
5098
5099 sb.scope.setGlobal(sb, node, options); // [globalObjectVal, argv, globalObjectVal]
5100
5101 sb.emitOp(node, 'TUCK'); // [argv, globalObjectVal, globalObjectVal]
5102
5103 sb.emitOp(node, 'SWAP'); // [globalObjectVal]
5104
5105 sb.emitHelper(node, options, sb.helpers.addArguments); // [objectPrototypeVal, globalObjectVal]
5106
5107 sb.emitHelper(node, options, sb.helpers.addObjectObject); // [objectPrototypeVal, globalObjectVal]
5108
5109 sb.emitHelper(node, options, sb.helpers.addBooleanObject); // [objectPrototypeVal, globalObjectVal]
5110
5111 sb.emitHelper(node, options, sb.helpers.addNumberObject); // [objectPrototypeVal, globalObjectVal]
5112
5113 sb.emitHelper(node, options, sb.helpers.addStringObject); // [objectPrototypeVal, globalObjectVal]
5114
5115 sb.emitHelper(node, options, sb.helpers.addSymbolObject); // [objectPrototypeVal, globalObjectVal]
5116
5117 sb.emitHelper(node, options, sb.helpers.addArrayObject); // [objectPrototypeVal, globalObjectVal]
5118
5119 sb.emitHelper(node, options, sb.helpers.addBufferObject); // [objectPrototypeVal, globalObjectVal]
5120
5121 sb.emitHelper(node, options, sb.helpers.addErrorObject); // [objectPrototypeVal, globalObjectVal]
5122
5123 sb.emitHelper(node, options, sb.helpers.addModules); // [globalObjectVal]
5124
5125 sb.emitOp(node, 'DROP');
5126
5127 if (!optionsIn.pushValue) {
5128 sb.emitOp(node, 'DROP');
5129 }
5130 }
5131
5132}
5133
5134// Output: [value]
5135
5136class GetArgumentHelper extends TypedHelper {
5137 emit(sb, node, options) {
5138 if (!options.pushValue) {
5139 sb.emitOp(node, 'DROP');
5140 return;
5141 } // [globalObjectVal, numberVal]
5142
5143
5144 sb.scope.getGlobal(sb, node, options); // [arguments, globalObjectVal, numberVal]
5145
5146 sb.emitPushString(node, InternalGlobalProperties.ARGUMENTS); // [argv, numberVal]
5147
5148 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty); // [numberVal, argv]
5149
5150 sb.emitOp(node, 'SWAP'); // [number, argv]
5151
5152 sb.emitHelper(node, options, sb.helpers.toNumber({
5153 type: this.type
5154 })); // [value]
5155
5156 sb.emitOp(node, 'PICKITEM');
5157 }
5158
5159}
5160
5161// Input: []
5162// Output: [val]
5163class GetGlobalPropertyHelper extends Helper {
5164 constructor(options) {
5165 super();
5166
5167 _defineProperty(this, "property", void 0);
5168
5169 this.property = options.property;
5170 }
5171
5172 emit(sb, node, optionsIn) {
5173 const options = sb.pushValueOptions(optionsIn); // [globalObjectVal]
5174
5175 sb.scope.getGlobal(sb, node, options); // [propertyString, globalObjectVal]
5176
5177 sb.emitPushString(node, this.property); // [val]
5178
5179 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty);
5180
5181 if (!optionsIn.pushValue) {
5182 sb.emitOp(node, 'DROP');
5183 }
5184 }
5185
5186}
5187
5188// Input: []
5189// Output: [objectVal]
5190class CreateArrayHelper extends Helper {
5191 emit(sb, node, options) {
5192 if (options.pushValue) {
5193 // [Array]
5194 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
5195 property: 'Array'
5196 })); // [objectVal]
5197
5198 sb.emitHelper(node, options, sb.helpers.new({
5199 noArgs: true
5200 }));
5201 }
5202 }
5203
5204}
5205
5206// Input: [indexNumber, objectVal]
5207// Output: [val]
5208class GetArrayIndexHelper extends Helper {
5209 emit(sb, node, optionsIn) {
5210 const options = sb.pushValueOptions(optionsIn);
5211 sb.emitHelper(node, options, sb.helpers.if({
5212 condition: () => {
5213 // [objectVal, indexNumber, objectVal]
5214 sb.emitOp(node, 'OVER'); // ['length', objectVal, indexNumber, objectVal]
5215
5216 sb.emitPushString(node, 'length'); // [lengthNumberVal, indexNumber, objectVal]
5217
5218 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [lengthNumber, indexNumber, objectVal]
5219
5220 sb.emitHelper(node, options, sb.helpers.getNumber); // [indexNumber, lengthNumber, indexNumber, objectVal]
5221
5222 sb.emitOp(node, 'OVER'); // [lessThanLength, indexNumber, objectVal]
5223
5224 sb.emitOp(node, 'GT');
5225 },
5226 whenTrue: () => {
5227 // [objectVal, indexNumber]
5228 sb.emitOp(node, 'SWAP'); // [arr, indexNumber]
5229
5230 sb.emitHelper(node, options, sb.helpers.getArrayValue); // [indexNumber, arr]
5231
5232 sb.emitOp(node, 'SWAP'); // []
5233
5234 sb.emitOp(node, 'PICKITEM');
5235 },
5236 whenFalse: () => {
5237 // [indexNumber]
5238 sb.emitOp(node, 'DROP'); // []
5239
5240 sb.emitOp(node, 'DROP'); // [val]
5241
5242 sb.emitHelper(node, options, sb.helpers.createUndefined);
5243 }
5244 }));
5245 }
5246
5247}
5248
5249let InternalArrayProperties;
5250
5251(function (InternalArrayProperties) {
5252 InternalArrayProperties["DATA_ARRAY"] = "DataArray";
5253})(InternalArrayProperties || (InternalArrayProperties = {}));
5254
5255// Output: [arr]
5256
5257class GetArrayValueHelper extends Helper {
5258 emit(sb, node, options) {
5259 if (!options.pushValue) {
5260 sb.emitOp(node, 'DROP');
5261 return;
5262 } // ['DataArray', objectVal]
5263
5264
5265 sb.emitPushString(node, InternalArrayProperties.DATA_ARRAY); // [arr]
5266
5267 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty);
5268 }
5269
5270}
5271
5272// Input: [val, indexNumber, objectVal]
5273// Output: []
5274class SetArrayIndexHelper extends Helper {
5275 emit(sb, node, optionsIn) {
5276 const options = sb.pushValueOptions(optionsIn);
5277 sb.emitHelper(node, options, sb.helpers.if({
5278 condition: () => {
5279 // [objectVal, val, indexNumber]
5280 sb.emitOp(node, 'ROT'); // [indexNumber, objectVal, val]
5281
5282 sb.emitOp(node, 'ROT'); // [objectVal, indexNumber, objectVal, val]
5283
5284 sb.emitOp(node, 'OVER'); // ['length', objectVal, indexNumber, objectVal, val]
5285
5286 sb.emitPushString(node, 'length'); // [lengthNumberVal, indexNumber, objectVal, val]
5287
5288 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [lengthNumber, indexNumber, objectVal, val]
5289
5290 sb.emitHelper(node, options, sb.helpers.getNumber); // [indexNumber, lengthNumber, indexNumber, objectVal, val]
5291
5292 sb.emitOp(node, 'OVER'); // [lessThanLength, indexNumber, objectVal, val]
5293
5294 sb.emitOp(node, 'GT');
5295 },
5296 whenTrue: () => {
5297 // [objectVal, indexNumber, val]
5298 sb.emitOp(node, 'SWAP'); // []
5299
5300 this.setIndex(sb, node, options);
5301 },
5302 whenFalse: () => {
5303 // [objectVal, indexNumber, objectVal, val]
5304 sb.emitOp(node, 'OVER'); // [arr, indexNumber, objectVal, val]
5305
5306 sb.emitHelper(node, options, sb.helpers.getArrayValue); // [indexNumber, arr, indexNumber, objectVal, val]
5307
5308 sb.emitOp(node, 'OVER'); // [indexNumber + 1, arr, indexNumber, objectVal, val]
5309
5310 sb.emitOp(node, 'INC'); // [length, arr, length, indexNumber, objectVal, val]
5311
5312 sb.emitOp(node, 'TUCK'); // [length, indexNumber, objectVal, val]
5313
5314 sb.emitHelper(node, options, sb.helpers.extendArray); // [objectVal, length, indexNumber, val]
5315
5316 sb.emitOp(node, 'ROT'); // [objectVal, length, objectVal, indexNumber, val]
5317
5318 sb.emitOp(node, 'TUCK'); // ['length', objectVal, length, objectVal, indexNumber, val]
5319
5320 sb.emitPushString(node, 'length'); // [length, 'length', objectVal, objectVal, indexNumber, val]
5321
5322 sb.emitOp(node, 'ROT'); // [lengthVal, 'length', objectVal, objectVal, indexNumber, val]
5323
5324 sb.emitHelper(node, options, sb.helpers.createNumber); // [objectVal, indexNumber, val]
5325
5326 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // []
5327
5328 this.setIndex(sb, node, options);
5329 }
5330 }));
5331 }
5332
5333 setIndex(sb, node, options) {
5334 // [arr, indexNumber, val]
5335 sb.emitHelper(node, options, sb.helpers.getArrayValue); // [indexNumber, arr, val]
5336
5337 sb.emitOp(node, 'SWAP'); // [val, indexNumber, arr]
5338
5339 sb.emitOp(node, 'ROT'); // []
5340
5341 sb.emitOp(node, 'SETITEM');
5342 }
5343
5344}
5345
5346// Output: []
5347
5348class SetArrayValueHelper extends Helper {
5349 emit(sb, node, optionsIn) {
5350 const options = sb.pushValueOptions(optionsIn); // ['DataArray', arr, objectVal]
5351
5352 sb.emitPushString(node, InternalArrayProperties.DATA_ARRAY); // [arr, 'DataArray', objectVal]
5353
5354 sb.emitOp(node, 'SWAP'); // []
5355
5356 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
5357 }
5358
5359}
5360
5361// Input: [objectVal]
5362// Output: [arr]
5363class UnwrapArrayHelper extends Helper {
5364 emit(sb, node, optionsIn) {
5365 if (!optionsIn.pushValue) {
5366 sb.emitOp(node, 'DROP');
5367 return;
5368 }
5369
5370 const options = sb.pushValueOptions(optionsIn); // [arr]
5371
5372 sb.emitHelper(node, options, sb.helpers.getArrayValue);
5373 }
5374
5375}
5376
5377// Input: [arr]
5378// Output: [objectVal]
5379class WrapArrayHelper extends Helper {
5380 emit(sb, node, options) {
5381 if (!options.pushValue) {
5382 sb.emitOp(node, 'DROP');
5383 return;
5384 }
5385
5386 const invokeArrayConstruct = () => {
5387 // [Array, argsarr]
5388 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
5389 property: 'Array'
5390 })); // [objectVal]
5391
5392 sb.emitHelper(node, options, sb.helpers.new());
5393 };
5394
5395 sb.emitHelper(node, options, sb.helpers.if({
5396 condition: () => {
5397 // [arr, arr]
5398 sb.emitOp(node, 'DUP'); // [size, arr]
5399
5400 sb.emitOp(node, 'ARRAYSIZE'); // [1, size, arr]
5401
5402 sb.emitPushInt(node, 1); // [size === 1, arr]
5403
5404 sb.emitOp(node, 'EQUAL');
5405 },
5406 whenTrue: () => {
5407 // [0, arr]
5408 sb.emitPushInt(node, 0); // [val]
5409
5410 sb.emitOp(node, 'PICKITEM'); // [1, val]
5411
5412 sb.emitPushInt(node, 1); // [lengthVal, val]
5413
5414 sb.emitHelper(node, options, sb.helpers.createNumber); // [1, lengthVal, val]
5415
5416 sb.emitPushInt(node, 1); // [argsarr, val]
5417
5418 sb.emitOp(node, 'PACK'); // [arrayObjectVal, val]
5419
5420 invokeArrayConstruct(); // [arrayObjectVal, val, arrayObjectVal]
5421
5422 sb.emitOp(node, 'TUCK'); // [0, arrayObjectVal, val, arrayObjectVal]
5423
5424 sb.emitPushInt(node, 0); // [val, 0, arrayObjectVal, arrayObjectVal]
5425
5426 sb.emitOp(node, 'ROT'); // [arrayObjectVal]
5427
5428 sb.emitHelper(node, options, sb.helpers.setArrayIndex);
5429 },
5430 whenFalse: () => {
5431 // [arrayObjectVal]
5432 invokeArrayConstruct();
5433 }
5434 }));
5435 }
5436
5437}
5438
5439// Input: [globalObjectVal]
5440// Output: []
5441class AddEmptyModuleHelper extends Helper {
5442 emit(sb, node, optionsIn) {
5443 const options = sb.pushValueOptions(optionsIn); // [modules]
5444
5445 sb.emitHelper(node, options, sb.helpers.getModules); // [exports, modules]
5446
5447 sb.emitOp(node, 'NEWMAP'); // []
5448
5449 sb.emitOp(node, 'APPEND');
5450 }
5451
5452}
5453
5454// Input: [val, exports]
5455// Output: []
5456class ExportHelper extends Helper {
5457 constructor({
5458 name,
5459 defaultExport
5460 }) {
5461 super();
5462
5463 _defineProperty(this, "name", void 0);
5464
5465 _defineProperty(this, "defaultExport", void 0);
5466
5467 this.name = name;
5468 this.defaultExport = defaultExport || false;
5469 }
5470
5471 emit(sb, node, optionsIn) {
5472 if (this.name != null) {
5473 sb.addExport(this.name); // [name, val, exports]
5474
5475 sb.emitPushString(node, this.name);
5476 } else if (this.defaultExport) {
5477 // [name, val, exports]
5478 sb.emitPushString(node, 'default');
5479 } else {
5480 sb.reportUnsupported(node);
5481 } // [val, name, exports]
5482
5483
5484 sb.emitOp(node, 'SWAP'); // []
5485
5486 sb.emitOp(node, 'SETITEM');
5487 }
5488
5489}
5490
5491// Input: [val]
5492// Output: []
5493class ExportSingleHelper extends Helper {
5494 constructor(options) {
5495 super();
5496
5497 _defineProperty(this, "options", void 0);
5498
5499 this.options = options;
5500 }
5501
5502 emit(sb, node, optionsIn) {
5503 const options = sb.pushValueOptions(optionsIn); // [exports, val]
5504
5505 sb.emitHelper(node, options, sb.helpers.getCurrentModule); // [val, exports]
5506
5507 sb.emitOp(node, 'SWAP'); // []
5508
5509 sb.emitHelper(node, options, sb.helpers.export(this.options));
5510 }
5511
5512}
5513
5514// Input: []
5515// Output: [exports]
5516class GetCurrentModuleHelper extends Helper {
5517 emit(sb, node, options) {
5518 if (options.pushValue) {
5519 // [globalObjectVal]
5520 sb.scope.getGlobal(sb, node, options); // [exports]
5521
5522 sb.emitHelper(node, options, sb.helpers.getModule({
5523 moduleIndex: sb.moduleIndex
5524 }));
5525 }
5526 }
5527
5528}
5529
5530// Input: [globalObjectVal]
5531// Output: [exports]
5532class GetModuleHelper extends Helper {
5533 constructor(options) {
5534 super();
5535
5536 _defineProperty(this, "moduleIndex", void 0);
5537
5538 this.moduleIndex = options.moduleIndex;
5539 }
5540
5541 emit(sb, node, options) {
5542 if (options.pushValue) {
5543 // [modules, index]
5544 sb.emitHelper(node, options, sb.helpers.getModules); // [index, modules]
5545
5546 sb.emitPushInt(node, this.moduleIndex); // [exports]
5547
5548 sb.emitOp(node, 'PICKITEM');
5549 }
5550 }
5551
5552}
5553
5554// Output: [modules]
5555
5556class GetModulesHelper extends Helper {
5557 emit(sb, node, options) {
5558 if (options.pushValue) {
5559 // ['modules', globalObjectVal]
5560 sb.emitPushString(node, InternalGlobalProperties.MODULES); // [modules]
5561
5562 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty);
5563 }
5564 }
5565
5566}
5567
5568let InternalBlockchainInterfaceProperties;
5569
5570(function (InternalBlockchainInterfaceProperties) {
5571 InternalBlockchainInterfaceProperties["BLOCKCHAIN_INTERFACE"] = "BlockchainInterface";
5572})(InternalBlockchainInterfaceProperties || (InternalBlockchainInterfaceProperties = {}));
5573
5574// Input: [objectVal]
5575// Output: [boolean]
5576class IsBlockchainInterfaceHelper extends Helper {
5577 constructor(options) {
5578 super();
5579
5580 _defineProperty(this, "name", void 0);
5581
5582 this.name = options.name;
5583 }
5584
5585 emit(sb, node, optionsIn) {
5586 if (!optionsIn.pushValue) {
5587 sb.emitOp(node, 'DROP');
5588 return;
5589 }
5590
5591 const options = sb.pushValueOptions(optionsIn); // ['__brand', objectVal]
5592
5593 sb.emitPushString(node, '__brand'); // [brandVal]
5594
5595 sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); // [brand]
5596
5597 sb.emitHelper(node, options, sb.helpers.getString); // [name, brand]
5598
5599 sb.emitPushString(node, this.name); // [boolean]
5600
5601 sb.emitOp(node, 'EQUAL');
5602 }
5603
5604}
5605
5606// Output: [blockchainInterface]
5607
5608class UnwrapBlockchainInterfaceHelper extends Helper {
5609 emit(sb, node, optionsIn) {
5610 if (!optionsIn.pushValue) {
5611 sb.emitOp(node, 'DROP');
5612 return;
5613 }
5614
5615 const options = sb.pushValueOptions(optionsIn); // ['blockchain_interface', objectVal]
5616
5617 sb.emitPushString(node, InternalBlockchainInterfaceProperties.BLOCKCHAIN_INTERFACE); // [blockchainInterface]
5618
5619 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty);
5620 }
5621
5622}
5623
5624// Input: [blockchainInterface]
5625// Output: [objectVal]
5626class WrapBlockchainInterfaceHelper extends Helper {
5627 constructor(options) {
5628 super();
5629
5630 _defineProperty(this, "name", void 0);
5631
5632 this.name = options.name;
5633 }
5634
5635 emit(sb, node, optionsIn) {
5636 if (!optionsIn.pushValue) {
5637 sb.emitOp(node, 'DROP');
5638 return;
5639 }
5640
5641 const options = sb.pushValueOptions(optionsIn); // [objectVal, blockchainInterface]
5642
5643 sb.emitHelper(node, options, sb.helpers.createObject); // [objectVal, blockchainInterface, objectVal]
5644
5645 sb.emitOp(node, 'TUCK'); // ['__brand', objectVal, blockchainInterface, objectVal]
5646
5647 sb.emitPushString(node, '__brand'); // [name, '__brand', objectVal, blockchainInterface, objectVal]
5648
5649 sb.emitPushString(node, this.name); // [nameVal, '__brand', objectVal, blockchainInterface, objectVal]
5650
5651 sb.emitHelper(node, options, sb.helpers.createString); // [blockchainInterface, objectVal]
5652
5653 sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); // [objectVal, blockchainInterface, objectVal]
5654
5655 sb.emitOp(node, 'OVER'); // ['blockchain_interface', objectVal, blockchainInterface, objectVal]
5656
5657 sb.emitPushString(node, InternalBlockchainInterfaceProperties.BLOCKCHAIN_INTERFACE); // [blockchainInterface, 'blockchain_interface', objectVal, objectVal]
5658
5659 sb.emitOp(node, 'ROT'); // [objectVal]
5660
5661 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
5662 }
5663
5664}
5665
5666// Input: []
5667// Output: [objectVal]
5668class CreateBufferHelper extends Helper {
5669 emit(sb, node, options) {
5670 if (options.pushValue) {
5671 // [Buffer]
5672 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
5673 property: 'Buffer'
5674 })); // [objectVal]
5675
5676 sb.emitHelper(node, options, sb.helpers.new({
5677 noArgs: true
5678 }));
5679 }
5680 }
5681
5682}
5683
5684let InternalBufferProperties;
5685
5686(function (InternalBufferProperties) {
5687 InternalBufferProperties["DATA"] = "Data";
5688})(InternalBufferProperties || (InternalBufferProperties = {}));
5689
5690// Output: [byteArray]
5691
5692class GetBufferValueHelper extends Helper {
5693 emit(sb, node, optionsIn) {
5694 const options = sb.pushValueOptions(optionsIn); // ['data', objectVal]
5695
5696 sb.emitPushString(node, InternalBufferProperties.DATA); // [byteArray]
5697
5698 sb.emitHelper(node, options, sb.helpers.getInternalObjectProperty);
5699 }
5700
5701}
5702
5703// Output: []
5704
5705class SetBufferValueHelper extends Helper {
5706 emit(sb, node, optionsIn) {
5707 const options = sb.pushValueOptions(optionsIn); // ['data', byteArray, objectVal]
5708
5709 sb.emitPushString(node, InternalBufferProperties.DATA); // [byteArray, 'data', objectVal]
5710
5711 sb.emitOp(node, 'SWAP'); // []
5712
5713 sb.emitHelper(node, options, sb.helpers.setInternalObjectProperty);
5714 }
5715
5716}
5717
5718// Input: [objectVal]
5719// Output: [byteArray]
5720class UnwrapBufferHelper extends Helper {
5721 emit(sb, node, options) {
5722 if (!options.pushValue) {
5723 sb.emitOp(node, 'DROP');
5724 return;
5725 } // [byteArray]
5726
5727
5728 sb.emitHelper(node, options, sb.helpers.getBufferValue);
5729 }
5730
5731}
5732
5733// Input: [byteArray]
5734// Output: [objectVal]
5735class WrapBufferHelper extends Helper {
5736 emit(sb, node, options) {
5737 if (!options.pushValue) {
5738 sb.emitOp(node, 'DROP');
5739 return;
5740 } // [objectVal, byteArray]
5741
5742
5743 sb.emitHelper(node, options, sb.helpers.createBuffer); // [objectVal, byteArray, objectVal]
5744
5745 sb.emitOp(node, 'TUCK'); // [byteArray, objectVal, objectVal]
5746
5747 sb.emitOp(node, 'SWAP'); // [objectVal]
5748
5749 sb.emitHelper(node, options, sb.helpers.setBufferValue);
5750 }
5751
5752}
5753
5754const createHelpers = () => {
5755 const cache = {};
5756
5757 function memoized(HelperClass) {
5758 return options => {
5759 const key = HelperClass.getKey(options);
5760
5761 if (cache[key] == null) {
5762 cache[key] = new HelperClass(options);
5763 }
5764
5765 return cache[key];
5766 };
5767 }
5768
5769 return {
5770 arrFilter: options => new ArrFilterHelper(options),
5771 arrMap: options => new ArrMapHelper(options),
5772 arrForEach: options => new ArrForEachHelper(options),
5773 cloneArray: new CloneArrayHelper(),
5774 extendArray: new ExtendArrayHelper(),
5775 forType: options => new ForTypeHelper(options),
5776 genericDeserialize: new GenericDeserializeHelper(),
5777 genericSerialize: new GenericSerializeHelper(),
5778 equalsEqualsEquals: options => new EqualsEqualsEqualsHelper(options),
5779 equalsEqualsEqualsNumber: new EqualsEqualsEqualsNumberHelper(),
5780 equalsEqualsEqualsSameType: new EqualsEqualsEqualsSameTypeHelper(),
5781 equalsEqualsEqualsUnknown: new EqualsEqualsEqualsUnknownHelper(),
5782 equalsEquals: options => new EqualsEqualsHelper(options),
5783 lessThan: options => new LessThanHelper(options),
5784 processStatements: options => new ProcessStatementsHelper(options),
5785 args: new ArgumentsHelper(),
5786 bindFunctionObjectThis: options => new BindFunctionObjectThisHelper(options),
5787 bindFunctionThis: options => new BindFunctionThisHelper(options),
5788 call: new CallHelper(),
5789 cloneFunction: new CloneFunctionHelper(),
5790 cloneFunctionObject: options => new CloneFunctionObjectHelper(options),
5791 createCallArray: new CreateCallArrayHelper(),
5792 createConstructArray: options => new CreateConstructArrayHelper(options),
5793 createFunctionArray: options => new CreateFunctionArrayHelper(options),
5794 createFunctionObject: options => new CreateFunctionObjectHelper(options),
5795 function: options => new FunctionHelper(options),
5796 invokeCall: memoized(InvokeCallHelper),
5797 invokeConstruct: options => new InvokeConstructHelper(options),
5798 new: options => new NewHelper(options),
5799 parameters: new ParametersHelper(),
5800 forLoop: options => new ForLoopHelper(options),
5801 if: options => new IfHelper(options),
5802 case: (cases, defaultCase) => new CaseHelper(cases, defaultCase),
5803 createCompletion: new CreateCompletionHelper(),
5804 createNormalCompletion: new CreateNormalCompletionHelper(),
5805 createThrowCompletion: new CreateThrowCompletionHelper(),
5806 getCompletionError: new GetCompletionErrorHelper(),
5807 getCompletionVal: new GetCompletionValHelper(),
5808 handleCompletion: new HandleCompletionHelper(),
5809 pickCompletionVal: new PickCompletionValHelper(),
5810 throw: new ThrowHelper(),
5811 throwTypeError: new ThrowTypeErrorHelper(),
5812 createBoolean: new CreateBooleanHelper(),
5813 createNull: new CreateNullHelper(),
5814 createNumber: new CreateNumberHelper(),
5815 createObject: new CreateObjectHelper(),
5816 createString: new CreateStringHelper(),
5817 createSymbol: new CreateSymbolHelper(),
5818 createUndefined: new CreateUndefinedHelper(),
5819 isBoolean: new IsBooleanHelper(),
5820 isNull: new IsNullHelper(),
5821 isNumber: new IsNumberHelper(),
5822 isObject: new IsObjectHelper(),
5823 isString: new IsStringHelper(),
5824 isSymbol: new IsSymbolHelper(),
5825 isUndefined: new IsUndefinedHelper(),
5826 isNullOrUndefined: new IsNullOrUndefinedHelper(),
5827 isSameType: new IsSameTypeHelper(),
5828 getBoolean: new GetBooleanHelper(),
5829 getNumber: new GetNumberHelper(),
5830 getString: new GetStringHelper(),
5831 getSymbol: new GetSymbolHelper(),
5832 getObject: new GetObjectHelper(),
5833 toBoolean: options => new ToBooleanHelper(options),
5834 toString: options => new ToStringHelper(options),
5835 toNumber: options => new ToNumberHelper(options),
5836 toObject: options => new ToObjectHelper(options),
5837 toPrimitive: options => new ToPrimitiveHelper(options),
5838 getSymbolObject: new GetSymbolObjectHelper(),
5839 getSymbolObjectProperty: new GetSymbolObjectPropertyHelper(),
5840 setSymbolObjectProperty: new SetSymbolObjectPropertyHelper(),
5841 setDataSymbolObjectProperty: new SetDataSymbolObjectPropertyHelper(),
5842 setAccessorSymbolObjectProperty: options => new SetAccessorSymbolObjectPropertyHelper(options),
5843 getPropertyObject: new GetPropertyObjectHelper(),
5844 getPropertyObjectProperty: new GetPropertyObjectPropertyHelper(),
5845 setPropertyObjectProperty: new SetPropertyObjectPropertyHelper(),
5846 setDataPropertyObjectProperty: new SetDataPropertyObjectPropertyHelper(),
5847 setAccessorPropertyObjectProperty: options => new SetAccessorPropertyObjectPropertyHelper(options),
5848 getInternalObject: new GetInternalObjectHelper(),
5849 getInternalObjectProperty: new GetInternalObjectPropertyHelper(),
5850 setInternalObjectProperty: new SetInternalObjectPropertyHelper(),
5851 shallowCloneObject: new ShallowCloneObjectHelper(),
5852 shallowCloneObj: new ShallowCloneObjHelper(),
5853 elementAccess: new ElementAccessHelper(),
5854 unwrapType: new UnwrapTypeHelper(),
5855 unwrapVal: new UnwrapValHelper(),
5856 instanceof: new InstanceofHelper(),
5857 createPropertyObject: new CreatePropertyObjectHelper(),
5858 findObjectProperty: options => new FindObjectPropertyHelper(options),
5859 getArrayValue: new GetArrayValueHelper(),
5860 createArray: new CreateArrayHelper(),
5861 setArrayValue: new SetArrayValueHelper(),
5862 getArrayIndex: new GetArrayIndexHelper(),
5863 setArrayIndex: new SetArrayIndexHelper(),
5864 wrapArray: new WrapArrayHelper(),
5865 unwrapArray: new UnwrapArrayHelper(),
5866 createBuffer: new CreateBufferHelper(),
5867 getBufferValue: new GetBufferValueHelper(),
5868 setBufferValue: new SetBufferValueHelper(),
5869 unwrapBuffer: new UnwrapBufferHelper(),
5870 wrapBuffer: new WrapBufferHelper(),
5871 export: options => new ExportHelper(options),
5872 exportSingle: options => new ExportSingleHelper(options),
5873 getModule: options => new GetModuleHelper(options),
5874 getCurrentModule: new GetCurrentModuleHelper(),
5875 getModules: new GetModulesHelper(),
5876 addEmptyModule: new AddEmptyModuleHelper(),
5877 isBlockchainInterface: options => new IsBlockchainInterfaceHelper(options),
5878 wrapBlockchainInterface: options => new WrapBlockchainInterfaceHelper(options),
5879 unwrapBlockchainInterface: new UnwrapBlockchainInterfaceHelper(),
5880 addArguments: new AddArgumentsHelper(),
5881 addArrayObject: new AddArrayObjectHelper(),
5882 addBooleanObject: new AddBooleanObjectHelper(),
5883 addBufferObject: new AddBufferObjectHelper(),
5884 addErrorObject: new AddErrorObjectHelper(),
5885 addModules: new AddModulesHelper(),
5886 addNumberObject: new AddNumberObjectHelper(),
5887 addObjectObject: new AddObjectObjectHelper(),
5888 addStringObject: new AddStringObjectHelper(),
5889 addSymbolObject: new AddSymbolObjectHelper(),
5890 setGlobalObject: new SetGlobalObjectHelper(),
5891 getArgument: options => new GetArgumentHelper(options),
5892 getGlobalProperty: options => new GetGlobalPropertyHelper(options),
5893 globalProperties: GLOBAL_PROPERTIES
5894 };
5895};
5896
5897class ClassDeclarationCompiler extends NodeCompiler {
5898 constructor(...args) {
5899 var _temp;
5900
5901 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ClassDeclaration), _temp;
5902 }
5903
5904 visitNode(sb, decl, optionsIn) {
5905 let options = sb.pushValueOptions(sb.noSuperClassOptions(optionsIn));
5906 const name = sb.scope.add(decl.getNameOrThrow());
5907 const extendsExpr = decl.getExtends();
5908 let superClassIn;
5909
5910 if (extendsExpr != null) {
5911 superClassIn = sb.scope.addUnique();
5912 options = sb.superClassOptions(options, superClassIn); // [superClass]
5913
5914 sb.visit(extendsExpr.getExpression(), options); // []
5915
5916 sb.scope.set(sb, extendsExpr, options, superClassIn);
5917 }
5918
5919 const superClass = superClassIn;
5920 /* Create constructor function */
5921 // [farr]
5922
5923 sb.emitHelper(decl, options, sb.helpers.createConstructArray({
5924 body: () => {
5925 // [argsarr]
5926 const ctorImpl = decl.getConstructors().find(ctor => ctor.isImplementation()); // Default value assignments
5927
5928 if (ctorImpl != null) {
5929 // []
5930 sb.emitHelper(ctorImpl, options, sb.helpers.parameters); // Super call statement
5931 } else if (superClass != null && extendsExpr != null) {
5932 // [thisObjectVal, argsarr]
5933 sb.scope.getThis(sb, decl, options); // [ctor, thisObjectVal, argsarr]
5934
5935 sb.scope.get(sb, decl, options, superClass); // []
5936
5937 sb.emitHelper(decl, options, sb.helpers.invokeConstruct()); // Drop the argsarray, we must not use it
5938 } else {
5939 // []
5940 sb.emitOp(decl, 'DROP');
5941 } // Parameter property assignments
5942 // Member variable assignments
5943 // [thisObjectVal]
5944
5945
5946 sb.scope.getThis(sb, decl, options);
5947 decl.getInstanceProperties().filter(TypeGuards.isPropertyDeclaration).forEach(property => {
5948 const initializer = property.getInitializer();
5949
5950 if (initializer != null) {
5951 sb.emitOp(decl, 'DUP'); // [prop, thisObjectVal, thisObjectVal]
5952
5953 sb.emitPushString(initializer, property.getName()); // [init, prop, thisObjectVal, thisObjectVal]
5954
5955 sb.visit(initializer, options); // [thisObjectVal]
5956
5957 sb.emitHelper(initializer, options, sb.helpers.setDataPropertyObjectProperty);
5958 }
5959 }); // []
5960
5961 sb.emitOp(decl, 'DROP'); // Constructor statements
5962
5963 if (ctorImpl != null) {
5964 sb.visit(ctorImpl.getBodyOrThrow(), options);
5965 }
5966 }
5967 })); // [fobjectVal]
5968
5969 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
5970 property: InternalFunctionProperties.CONSTRUCT
5971 }));
5972 /* Create prototype */
5973 // [fobjectVal, fobjectVal]
5974
5975 sb.emitOp(decl, 'DUP'); // ['prototype', fobjectVal, fobjectVal]
5976
5977 sb.emitPushString(decl, 'prototype'); // [fobjectVal, 'prototype', fobjectVal, fobjectVal]
5978
5979 sb.emitOp(decl, 'OVER'); // [objectVal, fobjectVal, 'prototype', fobjectVal, fobjectVal]
5980
5981 sb.emitHelper(decl, options, sb.helpers.createObject); // [objectVal, fobjectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5982
5983 sb.emitOp(decl, 'TUCK'); // ['constructor', objectVal, fobjectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5984
5985 sb.emitPushString(decl, 'constructor'); // [fobjectVal, 'constructor', objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5986
5987 sb.emitOp(decl, 'ROT'); // [objectVal, 'prototype', fobjectVal, fobjectVal]
5988
5989 sb.emitHelper(decl, options, sb.helpers.setDataPropertyObjectProperty);
5990 decl.getInstanceMethods().forEach(method => {
5991 if (method.isImplementation()) {
5992 // [objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5993 sb.emitOp(method, 'DUP'); // [name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5994
5995 sb.emitPushString(method, method.getName()); // [farr, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5996
5997 sb.emitHelper(method, options, sb.helpers.createCallArray); // [methodObjectVal, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
5998
5999 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
6000 property: InternalFunctionProperties.CALL
6001 })); // [objectVal, 'prototype', fobjectVal, fobjectVal]
6002
6003 sb.emitHelper(method, options, sb.helpers.setDataPropertyObjectProperty);
6004 }
6005 });
6006 decl.getSetAccessors().filter(accessor => !accessor.isStatic()).forEach(accessor => {
6007 // [objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6008 sb.emitOp(accessor, 'DUP'); // [name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6009
6010 sb.emitPushString(accessor, accessor.getName()); // [farr, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6011
6012 sb.emitHelper(accessor, options, sb.helpers.createCallArray); // [methodObjectVal, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6013
6014 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
6015 property: InternalFunctionProperties.CALL
6016 }));
6017 const getAccessor = accessor.getGetAccessor();
6018 const hasGet = getAccessor != null;
6019
6020 if (getAccessor != null) {
6021 sb.emitHelper(getAccessor, options, sb.helpers.createCallArray);
6022 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
6023 property: InternalFunctionProperties.CALL
6024 }));
6025 } // [objectVal, 'prototype', fobjectVal, fobjectVal]
6026
6027
6028 sb.emitHelper(accessor, options, sb.helpers.setAccessorPropertyObjectProperty({
6029 hasSet: true,
6030 hasGet
6031 }));
6032 });
6033 decl.getGetAccessors().filter(accessor => !accessor.isStatic() && accessor.getSetAccessor() == null).forEach(accessor => {
6034 // [objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6035 sb.emitOp(accessor, 'DUP'); // [name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6036
6037 sb.emitPushString(accessor, accessor.getName()); // [farr, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6038
6039 sb.emitHelper(accessor, options, sb.helpers.createCallArray); // [methodObjectVal, name, objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6040
6041 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
6042 property: InternalFunctionProperties.CALL
6043 })); // [objectVal, 'prototype', fobjectVal, fobjectVal]
6044
6045 sb.emitHelper(accessor, options, sb.helpers.setAccessorPropertyObjectProperty({
6046 hasSet: false,
6047 hasGet: true
6048 }));
6049 });
6050 /* Set superclass prototype */
6051
6052 if (superClass != null && extendsExpr != null) {
6053 // [objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6054 sb.emitOp(extendsExpr, 'DUP'); // ['prototype', objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6055
6056 sb.emitPushString(extendsExpr, 'prototype'); // [superobjectVal, 'prototype', objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6057
6058 sb.scope.get(sb, extendsExpr, options, superClass); // ['prototype', superobjectVal, 'prototype', objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6059
6060 sb.emitPushString(extendsExpr, 'prototype'); // [superprototype, 'prototype', objectVal, objectVal, 'prototype', fobjectVal, fobjectVal]
6061
6062 sb.emitHelper(extendsExpr, options, sb.helpers.getPropertyObjectProperty); // [objectVal, 'prototype', fobjectVal, fobjectVal]
6063
6064 sb.emitHelper(extendsExpr, options, sb.helpers.setDataPropertyObjectProperty);
6065 } // [fobjectVal]
6066
6067
6068 sb.emitHelper(decl, options, sb.helpers.setDataPropertyObjectProperty);
6069
6070 if (decl.isNamedExport() || decl.isDefaultExport()) {
6071 // [fobjectVal, fobjectVal]
6072 sb.emitOp(decl, 'DUP'); // [fobjectVal]
6073
6074 sb.emitHelper(decl, options, sb.helpers.exportSingle({
6075 name: decl.isNamedExport() ? decl.getNameOrThrow() : undefined,
6076 defaultExport: decl.isDefaultExport()
6077 }));
6078 } // []
6079
6080
6081 sb.scope.set(sb, decl, options, name);
6082 }
6083
6084}
6085
6086class EnumDeclarationCompiler extends NodeCompiler {
6087 constructor(...args) {
6088 var _temp;
6089
6090 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.EnumDeclaration), _temp;
6091 }
6092
6093 visitNode(sb, decl, options) {
6094 sb.reportUnsupported(decl);
6095 }
6096
6097}
6098
6099class EnumMemberCompiler extends NodeCompiler {
6100 constructor(...args) {
6101 var _temp;
6102
6103 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.EnumMember), _temp;
6104 }
6105
6106 visitNode(sb, decl, options) {
6107 sb.reportUnsupported(decl);
6108 }
6109
6110}
6111
6112class ExportAssignmentCompiler extends NodeCompiler {
6113 constructor(...args) {
6114 var _temp;
6115
6116 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ExportAssignment), _temp;
6117 }
6118
6119 visitNode(sb, node, optionsIn) {
6120 if (node.isExportEquals()) {
6121 sb.reportUnsupported(node);
6122 } else {
6123 const options = sb.pushValueOptions(optionsIn); // [val]
6124
6125 sb.visit(node.getExpression(), options); // []
6126
6127 sb.emitHelper(node, options, sb.helpers.exportSingle({
6128 defaultExport: true
6129 }));
6130 }
6131 }
6132
6133}
6134
6135class ExportDeclarationCompiler extends NodeCompiler {
6136 constructor(...args) {
6137 var _temp;
6138
6139 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ExportDeclaration), _temp;
6140 }
6141
6142 visitNode(sb, node, optionsIn) {
6143 const options = sb.pushValueOptions(optionsIn);
6144
6145 const getName = namedExport => {
6146 let name = namedExport.getNameNode().getText();
6147 const alias = namedExport.getAliasIdentifier();
6148
6149 if (alias != null) {
6150 name = alias.getText();
6151 }
6152
6153 return name;
6154 };
6155
6156 const moduleSpecifier = node.getModuleSpecifierSourceFile(); // [exports]
6157
6158 sb.emitHelper(node, options, sb.helpers.getCurrentModule);
6159
6160 if (moduleSpecifier == null) {
6161 node.getNamedExports().filter(namedExport => namedExport.getLocalTargetDeclarations().some(decl => !TypeGuards.isTypeAliasDeclaration(decl))).forEach(namedExport => {
6162 // [exports, exports]
6163 sb.emitOp(node, 'DUP'); // [val, exports, exports]
6164
6165 sb.scope.get(sb, node, options, namedExport.getNameNode().getText()); // [exports]
6166
6167 sb.emitHelper(node, options, sb.helpers.export({
6168 name: getName(namedExport)
6169 }));
6170 });
6171 } else {
6172 // [moduleExports, exports]
6173 sb.loadModule(moduleSpecifier);
6174 node.getNamedExports().filter(namedExport => sb.hasExport(moduleSpecifier, namedExport.getNameNode().getText())).forEach(namedExport => {
6175 // [exports, moduleExports]
6176 sb.emitOp(node, 'SWAP'); // [exports, moduleExports, exports]
6177
6178 sb.emitOp(node, 'TUCK'); // [moduleExports, exports, moduleExports, exports]
6179
6180 sb.emitOp(node, 'OVER'); // [name, moduleExports, exports, moduleExports, exports]
6181
6182 sb.emitPushString(node, namedExport.getNameNode().getText()); // [val, exports, moduleExports, exports]
6183
6184 sb.emitOp(node, 'PICKITEM'); // [moduleExports, exports]
6185
6186 sb.emitHelper(node, options, sb.helpers.export({
6187 name: getName(namedExport)
6188 }));
6189 }); // [exports]
6190
6191 sb.emitOp(node, 'DROP');
6192 } // []
6193
6194
6195 sb.emitOp(node, 'DROP');
6196 }
6197
6198}
6199
6200class FunctionDeclarationCompiler extends NodeCompiler {
6201 constructor(...args) {
6202 var _temp;
6203
6204 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.FunctionDeclaration), _temp;
6205 }
6206
6207 visitNode(sb, decl, optionsIn) {
6208 const options = sb.pushValueOptions(optionsIn);
6209 const name = sb.scope.add(decl.getName()); // [callArray]
6210
6211 sb.emitHelper(decl, options, sb.helpers.createCallArray); // [callObjectVal]
6212
6213 sb.emitHelper(decl, options, sb.helpers.createFunctionObject({
6214 property: InternalFunctionProperties.CALL
6215 }));
6216
6217 if (decl.isNamedExport() || decl.isDefaultExport()) {
6218 // [callObjectVal, callObjectVal]
6219 sb.emitOp(decl, 'DUP'); // [callObjectVal]
6220
6221 sb.emitHelper(decl, options, sb.helpers.exportSingle({
6222 name: decl.isNamedExport() ? decl.getName() : undefined,
6223 defaultExport: decl.isDefaultExport()
6224 }));
6225 } // []
6226
6227
6228 sb.scope.set(sb, decl, options, name);
6229 }
6230
6231}
6232
6233class ImportDeclarationCompiler extends NodeCompiler {
6234 constructor(...args) {
6235 var _temp;
6236
6237 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ImportDeclaration), _temp;
6238 }
6239
6240 visitNode(sb, node, optionsIn) {
6241 const options = sb.pushValueOptions(optionsIn); // [exports]
6242
6243 sb.loadModule(node.getModuleSpecifierSourceFileOrThrow());
6244 const namespaceImport = node.getNamespaceImport();
6245
6246 if (namespaceImport != null) {
6247 const name = namespaceImport.getText();
6248 sb.scope.add(name); // [objectVal]
6249
6250 sb.emitHelper(node, options, sb.helpers.createPropertyObject); // []
6251
6252 sb.scope.set(sb, node, options, name);
6253 } else {
6254 const defaultImport = node.getDefaultImport();
6255 const namedImports = node.getNamedImports().filter(namedImport => sb.hasExport(namedImport.getImportDeclaration().getModuleSpecifierSourceFileOrThrow(), namedImport.getName()));
6256
6257 if (defaultImport != null) {
6258 if (namedImports.length > 0) {
6259 // [exports, exports]
6260 sb.emitOp(node, 'DUP');
6261 } // ['default', exports]
6262
6263
6264 sb.emitPushString(node, 'default'); // [val]
6265
6266 sb.emitOp(node, 'PICKITEM');
6267 const name = defaultImport.getText();
6268 sb.scope.add(name); // []
6269
6270 sb.scope.set(sb, node, options, name);
6271 }
6272
6273 if (namedImports.length > 0) {
6274 for (const namedImport of namedImports) {
6275 // [exports, exports]
6276 sb.emitOp(node, 'DUP'); // [name, exports, exports]
6277
6278 sb.emitPushString(node, namedImport.getName()); // [val, exports]
6279
6280 sb.emitOp(node, 'PICKITEM');
6281 let name = namedImport.getName();
6282 const alias = namedImport.getAliasIdentifier();
6283
6284 if (alias != null) {
6285 name = alias.getText();
6286 }
6287
6288 sb.scope.add(name); // [exports]
6289
6290 sb.scope.set(sb, node, options, name);
6291 }
6292
6293 sb.emitOp(node, 'DROP');
6294 }
6295 }
6296 }
6297
6298}
6299
6300class TypeAliasDeclarationCompiler extends NodeCompiler {
6301 constructor(...args) {
6302 var _temp;
6303
6304 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.TypeAliasDeclaration), _temp;
6305 }
6306
6307 visitNode(sb, node, optionsIn) {// do nothing
6308 }
6309
6310}
6311
6312class VariableDeclarationCompiler extends NodeCompiler {
6313 constructor(...args) {
6314 var _temp;
6315
6316 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.VariableDeclaration), _temp;
6317 }
6318
6319 visitNode(sb, node, options) {
6320 const name = sb.scope.add(node.getName());
6321 const expr = node.getInitializer();
6322
6323 if (expr != null) {
6324 sb.visit(expr, sb.pushValueOptions(options));
6325 sb.scope.set(sb, node, options, name);
6326 }
6327 }
6328
6329}
6330
6331class VariableDeclarationListCompiler extends NodeCompiler {
6332 constructor(...args) {
6333 var _temp;
6334
6335 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.VariableDeclarationList), _temp;
6336 }
6337
6338 visitNode(sb, node, options) {
6339 node.getDeclarations().forEach(decl => {
6340 sb.visit(decl, options);
6341 });
6342 }
6343
6344}
6345
6346var declarations = [ClassDeclarationCompiler, EnumDeclarationCompiler, EnumMemberCompiler, ExportAssignmentCompiler, ExportDeclarationCompiler, FunctionDeclarationCompiler, ImportDeclarationCompiler, TypeAliasDeclarationCompiler, VariableDeclarationCompiler, VariableDeclarationListCompiler];
6347
6348class DecoratorCompiler extends NodeCompiler {
6349 constructor(...args) {
6350 var _temp;
6351
6352 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.Decorator), _temp;
6353 }
6354
6355 visitNode(sb, decl, options) {
6356 sb.reportUnsupported(decl);
6357 }
6358
6359}
6360
6361var decorator = [DecoratorCompiler];
6362
6363class ArrayLiteralExpressionCompiler extends NodeCompiler {
6364 constructor(...args) {
6365 var _temp;
6366
6367 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ArrayLiteralExpression), _temp;
6368 }
6369
6370 visitNode(sb, node, optionsIn) {
6371 const options = sb.pushValueOptions(optionsIn);
6372 const elements = [...node.getElements()].reverse();
6373
6374 for (const element of elements) {
6375 sb.visit(element, options);
6376 } // [length, ...vals]
6377
6378
6379 sb.emitPushInt(node, elements.length); // [valArr]
6380
6381 sb.emitOp(node, 'PACK'); // [arrayObjectVal]
6382
6383 sb.emitHelper(node, options, sb.helpers.wrapArray);
6384
6385 if (!optionsIn.pushValue) {
6386 sb.emitOp(node, 'DROP');
6387 }
6388 }
6389
6390}
6391
6392class ArrowFunctionCompiler extends NodeCompiler {
6393 constructor(...args) {
6394 var _temp;
6395
6396 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ArrowFunction), _temp;
6397 }
6398
6399 visitNode(sb, expr, options) {
6400 if (options.pushValue) {
6401 // [this]
6402 sb.scope.getThis(sb, expr, options); // [callArray, this]
6403
6404 sb.emitHelper(expr, options, sb.helpers.createCallArray); // [callArray]
6405
6406 sb.emitHelper(expr, options, sb.helpers.bindFunctionThis({
6407 overwrite: true
6408 })); // [callObjectVal]
6409
6410 sb.emitHelper(expr, options, sb.helpers.createFunctionObject({
6411 property: InternalFunctionProperties.CALL
6412 }));
6413 }
6414 }
6415
6416}
6417
6418class AsExpressionCompiler extends NodeCompiler {
6419 constructor(...args) {
6420 var _temp;
6421
6422 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.AsExpression), _temp;
6423 }
6424
6425 visitNode(sb, expr, options) {
6426 const type = sb.getType(expr);
6427
6428 if (options.cast != null && isAnyType(type)) {
6429 sb.visit(expr.getExpression(), options);
6430 } else {
6431 sb.visit(expr.getExpression(), sb.castOptions(options, type));
6432 }
6433 }
6434
6435}
6436
6437class AwaitExpressionCompiler extends NodeCompiler {
6438 constructor(...args) {
6439 var _temp;
6440
6441 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.AwaitExpression), _temp;
6442 }
6443
6444 visitNode(sb, expr) {
6445 sb.reportUnsupported(expr);
6446 }
6447
6448}
6449
6450class BinaryExpressionCompiler extends NodeCompiler {
6451 constructor(...args) {
6452 var _temp;
6453
6454 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.BinaryExpression), _temp;
6455 }
6456
6457 visitNode(sb, expr, options) {
6458 const kind = expr.getOperatorToken().getKind();
6459
6460 switch (kind) {
6461 case SyntaxKind.EqualsToken:
6462 case SyntaxKind.PlusEqualsToken:
6463 case SyntaxKind.MinusEqualsToken:
6464 case SyntaxKind.AsteriskAsteriskEqualsToken:
6465 case SyntaxKind.AsteriskEqualsToken:
6466 case SyntaxKind.SlashEqualsToken:
6467 case SyntaxKind.PercentEqualsToken:
6468 case SyntaxKind.AmpersandEqualsToken:
6469 case SyntaxKind.BarEqualsToken:
6470 case SyntaxKind.CaretEqualsToken:
6471 case SyntaxKind.LessThanLessThanEqualsToken:
6472 case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
6473 case SyntaxKind.GreaterThanGreaterThanEqualsToken:
6474 this.visitAssignmentOperator(sb, kind, expr, options);
6475 break;
6476
6477 case SyntaxKind.AsteriskToken:
6478 case SyntaxKind.SlashToken:
6479 case SyntaxKind.PercentToken:
6480 case SyntaxKind.PlusToken:
6481 case SyntaxKind.MinusToken:
6482 case SyntaxKind.GreaterThanGreaterThanToken:
6483 case SyntaxKind.LessThanLessThanToken:
6484 case SyntaxKind.LessThanToken:
6485 case SyntaxKind.LessThanEqualsToken:
6486 case SyntaxKind.GreaterThanToken:
6487 case SyntaxKind.GreaterThanEqualsToken:
6488 case SyntaxKind.ExclamationEqualsToken:
6489 case SyntaxKind.EqualsEqualsToken:
6490 case SyntaxKind.AmpersandToken:
6491 case SyntaxKind.BarToken:
6492 case SyntaxKind.CaretToken:
6493 case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
6494 case SyntaxKind.InKeyword:
6495 case SyntaxKind.InstanceOfKeyword:
6496 case SyntaxKind.CommaToken:
6497 case SyntaxKind.AsteriskAsteriskToken:
6498 case SyntaxKind.EqualsEqualsEqualsToken:
6499 case SyntaxKind.ExclamationEqualsEqualsToken:
6500 this.visitExpressionOperator(sb, kind, expr, options);
6501 break;
6502
6503 case SyntaxKind.AmpersandAmpersandToken:
6504 case SyntaxKind.BarBarToken:
6505 this.visitLogicalExpressionOperator(sb, kind, expr, options);
6506 break;
6507
6508 default:
6509 sb.assertUnreachable(kind);
6510 }
6511 }
6512
6513 visitAssignmentOperator(sb, kind, expr, options) {
6514 const left = expr.getLeft();
6515 const right = expr.getRight();
6516 const token = expr.getOperatorToken();
6517 const pushValueOptions = sb.pushValueOptions(options);
6518
6519 switch (kind) {
6520 case SyntaxKind.EqualsToken:
6521 sb.visit(expr.getRight(), pushValueOptions);
6522 break;
6523
6524 case SyntaxKind.PlusEqualsToken:
6525 this.visitExpressionOperatorBase(sb, token, SyntaxKind.PlusToken, left, right, pushValueOptions);
6526 break;
6527
6528 case SyntaxKind.MinusEqualsToken:
6529 this.visitExpressionOperatorBase(sb, token, SyntaxKind.MinusToken, left, right, pushValueOptions);
6530 break;
6531
6532 case SyntaxKind.AsteriskAsteriskEqualsToken:
6533 this.visitExpressionOperatorBase(sb, token, SyntaxKind.AsteriskAsteriskToken, left, right, pushValueOptions);
6534 break;
6535
6536 case SyntaxKind.AsteriskEqualsToken:
6537 this.visitExpressionOperatorBase(sb, token, SyntaxKind.AsteriskToken, left, right, pushValueOptions);
6538 break;
6539
6540 case SyntaxKind.SlashEqualsToken:
6541 this.visitExpressionOperatorBase(sb, token, SyntaxKind.SlashToken, left, right, pushValueOptions);
6542 break;
6543
6544 case SyntaxKind.PercentEqualsToken:
6545 this.visitExpressionOperatorBase(sb, token, SyntaxKind.PercentToken, left, right, pushValueOptions);
6546 break;
6547
6548 case SyntaxKind.AmpersandEqualsToken:
6549 this.visitExpressionOperatorBase(sb, token, SyntaxKind.AmpersandToken, left, right, pushValueOptions);
6550 break;
6551
6552 case SyntaxKind.BarEqualsToken:
6553 this.visitExpressionOperatorBase(sb, token, SyntaxKind.BarToken, left, right, pushValueOptions);
6554 break;
6555
6556 case SyntaxKind.CaretEqualsToken:
6557 this.visitExpressionOperatorBase(sb, token, SyntaxKind.CaretToken, left, right, pushValueOptions);
6558 break;
6559
6560 case SyntaxKind.LessThanLessThanEqualsToken:
6561 this.visitExpressionOperatorBase(sb, token, SyntaxKind.LessThanLessThanToken, left, right, pushValueOptions);
6562 break;
6563
6564 case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
6565 this.visitExpressionOperatorBase(sb, token, SyntaxKind.GreaterThanGreaterThanGreaterThanToken, left, right, pushValueOptions);
6566 break;
6567
6568 case SyntaxKind.GreaterThanGreaterThanEqualsToken:
6569 this.visitExpressionOperatorBase(sb, token, SyntaxKind.GreaterThanGreaterThanToken, left, right, pushValueOptions);
6570 break;
6571
6572 default:
6573 sb.assertUnreachable(kind);
6574 }
6575
6576 sb.visit(expr.getLeft(), sb.setValueOptions(options));
6577 }
6578
6579 visitExpressionOperator(sb, kind, expr, options) {
6580 this.visitExpressionOperatorBase(sb, expr.getOperatorToken(), kind, expr.getLeft(), expr.getRight(), options);
6581 }
6582
6583 visitLogicalExpressionOperator(sb, kind, expr, options) {
6584 this.visitLogicalExpressionOperatorBase(sb, expr.getOperatorToken(), kind, expr.getLeft(), expr.getRight(), options);
6585 }
6586
6587 visitExpressionOperatorBase(sb, node, kind, left, right, options) {
6588 if (!options.pushValue) {
6589 sb.visit(left, options);
6590 sb.visit(right, options);
6591 return;
6592 }
6593
6594 const visit = (leftHelper, rightHelper) => {
6595 sb.visit(left, options);
6596 sb.emitHelper(left, options, leftHelper({
6597 type: sb.getType(left)
6598 }));
6599 sb.visit(right, options);
6600 sb.emitHelper(right, options, (rightHelper || leftHelper)({
6601 type: sb.getType(right)
6602 }));
6603 };
6604
6605 const visitNumeric = () => visit(sb.helpers.toNumber);
6606
6607 const leftType = sb.getType(left);
6608 const rightType = sb.getType(right);
6609 const isBinaryNumeric = isOnlyNumber(leftType) && isOnlyNumber(rightType);
6610
6611 switch (kind) {
6612 case SyntaxKind.AsteriskToken:
6613 visitNumeric();
6614 sb.emitOp(node, 'MUL');
6615 sb.emitHelper(node, options, sb.helpers.createNumber);
6616 break;
6617
6618 case SyntaxKind.SlashToken:
6619 visitNumeric();
6620 sb.emitOp(node, 'DIV');
6621 sb.emitHelper(node, options, sb.helpers.createNumber);
6622 break;
6623
6624 case SyntaxKind.PercentToken:
6625 visitNumeric();
6626 sb.emitOp(node, 'MOD');
6627 sb.emitHelper(node, options, sb.helpers.createNumber);
6628 break;
6629
6630 case SyntaxKind.PlusToken:
6631 if (isBinaryNumeric) {
6632 visitNumeric();
6633 sb.emitOp(node, 'ADD');
6634 sb.emitHelper(node, options, sb.helpers.createNumber);
6635 } else if (isOnlyString(leftType) && isOnlyString(rightType)) {
6636 visit(() => sb.helpers.getString);
6637 sb.emitOp(node, 'CAT');
6638 sb.emitHelper(node, options, sb.helpers.createString);
6639 } else if (isOnlyString(leftType)) {
6640 visit(() => sb.helpers.getString, sb.helpers.toString);
6641 sb.emitOp(node, 'CAT');
6642 sb.emitHelper(node, options, sb.helpers.createString);
6643 } else if (isOnlyString(rightType)) {
6644 visit(sb.helpers.toString, () => sb.helpers.getString);
6645 sb.emitOp(node, 'CAT');
6646 sb.emitHelper(node, options, sb.helpers.createString);
6647 } else {
6648 // [right, left]
6649 visit(sb.helpers.toPrimitive); // [left, right]
6650
6651 sb.emitOp(node, 'SWAP'); // [left, right, left]
6652
6653 sb.emitOp(node, 'TUCK'); // [right, left, right, left]
6654
6655 sb.emitOp(node, 'TUCK'); // [isString, left, right, left]
6656
6657 sb.emitHelper(node, options, sb.helpers.isString); // [left, isString, right, left]
6658
6659 sb.emitOp(node, 'SWAP'); // [isString, isString, right, left]
6660
6661 sb.emitHelper(node, options, sb.helpers.isString);
6662 sb.emitHelper(node, options, sb.helpers.if({
6663 condition: () => {
6664 // [isEitherString, right, left]
6665 sb.emitOp(node, 'BOOLOR');
6666 },
6667 whenTrue: () => {
6668 // [string0, left]
6669 sb.emitHelper(node, options, sb.helpers.toString({
6670 type: sb.getType(right)
6671 })); // [left, string0]
6672
6673 sb.emitOp(node, 'SWAP'); // [string1, string0]
6674
6675 sb.emitHelper(node, options, sb.helpers.toString({
6676 type: sb.getType(left)
6677 })); // [string0, string1]
6678
6679 sb.emitOp(node, 'SWAP'); // [string]
6680
6681 sb.emitOp(node, 'CAT'); // [string]
6682
6683 sb.emitHelper(node, options, sb.helpers.createString);
6684 },
6685 whenFalse: () => {
6686 // [number0, left]
6687 sb.emitHelper(node, options, sb.helpers.toNumber({
6688 type: sb.getType(right)
6689 })); // [left, number0]
6690
6691 sb.emitOp(node, 'SWAP'); // [number1, number0]
6692
6693 sb.emitHelper(node, options, sb.helpers.toNumber({
6694 type: sb.getType(left)
6695 })); // [number0, number1]
6696
6697 sb.emitOp(node, 'SWAP'); // [number]
6698
6699 sb.emitOp(node, 'ADD'); // [number]
6700
6701 sb.emitHelper(node, options, sb.helpers.createNumber);
6702 }
6703 }));
6704 }
6705
6706 break;
6707
6708 case SyntaxKind.MinusToken:
6709 visitNumeric();
6710 sb.emitOp(node, 'SUB');
6711 sb.emitHelper(node, options, sb.helpers.createNumber);
6712 break;
6713
6714 case SyntaxKind.GreaterThanGreaterThanToken:
6715 visitNumeric();
6716 sb.emitOp(node, 'SHR');
6717 sb.emitHelper(node, options, sb.helpers.createNumber);
6718 break;
6719
6720 case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
6721 visitNumeric();
6722 sb.emitOp(node, 'SHR');
6723 sb.emitHelper(node, options, sb.helpers.createNumber);
6724 break;
6725
6726 case SyntaxKind.LessThanLessThanToken:
6727 visitNumeric();
6728 sb.emitOp(node, 'SHL');
6729 sb.emitHelper(node, options, sb.helpers.createNumber);
6730 break;
6731
6732 case SyntaxKind.LessThanToken:
6733 sb.emitHelper(node, options, sb.helpers.lessThan({
6734 leftFirst: true,
6735 left,
6736 right
6737 }));
6738 sb.emitHelper(node, options, sb.helpers.createBoolean);
6739 break;
6740
6741 case SyntaxKind.LessThanEqualsToken:
6742 sb.emitHelper(node, options, sb.helpers.lessThan({
6743 leftFirst: false,
6744 left: right,
6745 right: left
6746 }));
6747 sb.emitOp(node, 'NOT');
6748 sb.emitHelper(node, options, sb.helpers.createBoolean);
6749 break;
6750
6751 case SyntaxKind.GreaterThanToken:
6752 sb.emitHelper(node, options, sb.helpers.lessThan({
6753 leftFirst: false,
6754 left: right,
6755 right: left
6756 }));
6757 sb.emitHelper(node, options, sb.helpers.createBoolean);
6758 break;
6759
6760 case SyntaxKind.GreaterThanEqualsToken:
6761 sb.emitHelper(node, options, sb.helpers.lessThan({
6762 leftFirst: true,
6763 left,
6764 right
6765 }));
6766 sb.emitOp(node, 'NOT');
6767 sb.emitHelper(node, options, sb.helpers.createBoolean);
6768 break;
6769
6770 case SyntaxKind.ExclamationEqualsToken:
6771 sb.emitHelper(node, options, sb.helpers.equalsEquals({
6772 left,
6773 right
6774 }));
6775 sb.emitOp(node, 'NOT');
6776 sb.emitHelper(node, options, sb.helpers.createBoolean);
6777 break;
6778
6779 case SyntaxKind.EqualsEqualsToken:
6780 sb.emitHelper(node, options, sb.helpers.equalsEquals({
6781 left,
6782 right
6783 }));
6784 sb.emitHelper(node, options, sb.helpers.createBoolean);
6785 break;
6786
6787 case SyntaxKind.AmpersandToken:
6788 visitNumeric();
6789 sb.emitOp(node, 'AND');
6790 sb.emitHelper(node, options, sb.helpers.createNumber);
6791 break;
6792
6793 case SyntaxKind.BarToken:
6794 visitNumeric();
6795 sb.emitOp(node, 'OR');
6796 sb.emitHelper(node, options, sb.helpers.createNumber);
6797 break;
6798
6799 case SyntaxKind.CaretToken:
6800 visitNumeric();
6801 sb.emitOp(node, 'XOR');
6802 sb.emitHelper(node, options, sb.helpers.createNumber);
6803 break;
6804
6805 case SyntaxKind.InKeyword:
6806 sb.reportUnsupported(node);
6807 break;
6808
6809 case SyntaxKind.InstanceOfKeyword:
6810 // [left]
6811 sb.visit(left, options); // [right, left]
6812
6813 sb.visit(right, options); // [left instanceof right]
6814
6815 sb.emitHelper(node, options, sb.helpers.instanceof); // [booleanVal]
6816
6817 sb.emitHelper(node, options, sb.helpers.createBoolean);
6818 break;
6819
6820 case SyntaxKind.CommaToken:
6821 sb.emitOp(node, 'DROP');
6822 break;
6823
6824 case SyntaxKind.AsteriskAsteriskToken:
6825 sb.reportUnsupported(node);
6826 break;
6827
6828 case SyntaxKind.EqualsEqualsEqualsToken:
6829 sb.emitHelper(node, options, sb.helpers.equalsEqualsEquals({
6830 left,
6831 right
6832 }));
6833 sb.emitHelper(node, options, sb.helpers.createBoolean);
6834 break;
6835
6836 case SyntaxKind.ExclamationEqualsEqualsToken:
6837 sb.emitHelper(node, options, sb.helpers.equalsEqualsEquals({
6838 left,
6839 right
6840 }));
6841 sb.emitOp(node, 'NOT');
6842 sb.emitHelper(node, options, sb.helpers.createBoolean);
6843 break;
6844
6845 default:
6846 sb.assertUnreachable(kind);
6847 }
6848 }
6849
6850 visitLogicalExpressionOperatorBase(sb, node, kind, left, right, options) {
6851 switch (kind) {
6852 case SyntaxKind.AmpersandAmpersandToken:
6853 {
6854 sb.emitHelper(node, options, sb.helpers.if({
6855 condition: () => {
6856 // [left]
6857 sb.visit(left, sb.pushValueOptions(options));
6858
6859 if (options.pushValue) {
6860 // [left, left]
6861 sb.emitOp(left, 'DUP');
6862 } // [leftBoolean, ?left]
6863
6864
6865 sb.emitHelper(left, sb.pushValueOptions(options), sb.helpers.toBoolean({
6866 type: sb.getType(left)
6867 }));
6868 },
6869 whenTrue: () => {
6870 if (options.pushValue) {
6871 sb.emitOp(node, 'DROP');
6872 }
6873
6874 sb.visit(right, options);
6875 }
6876 }));
6877 break;
6878 }
6879
6880 case SyntaxKind.BarBarToken:
6881 {
6882 sb.emitHelper(node, options, sb.helpers.if({
6883 condition: () => {
6884 // [left]
6885 sb.visit(left, sb.pushValueOptions(options));
6886
6887 if (options.pushValue) {
6888 // [left, left]
6889 sb.emitOp(left, 'DUP');
6890 } // [leftBoolean, ?left]
6891
6892
6893 sb.emitHelper(left, sb.pushValueOptions(options), sb.helpers.toBoolean({
6894 type: sb.getType(left)
6895 }));
6896 },
6897 whenFalse: () => {
6898 if (options.pushValue) {
6899 sb.emitOp(node, 'DROP');
6900 }
6901
6902 sb.visit(right, options);
6903 }
6904 }));
6905 break;
6906 }
6907
6908 default:
6909 sb.assertUnreachable(kind);
6910 }
6911 }
6912
6913}
6914
6915class BooleanLiteralCompiler extends NodeCompiler {
6916 constructor(...args) {
6917 var _temp;
6918
6919 return _temp = super(...args), _defineProperty(this, "value", void 0), _temp;
6920 }
6921
6922 visitNode(sb, expr, options) {
6923 if (options.pushValue) {
6924 sb.emitPushBoolean(expr, this.value);
6925 sb.emitHelper(expr, options, sb.helpers.createBoolean);
6926 }
6927 }
6928
6929}
6930class TrueBooleanLiteralCompiler extends BooleanLiteralCompiler {
6931 constructor(...args) {
6932 var _temp2;
6933
6934 return _temp2 = super(...args), _defineProperty(this, "kind", SyntaxKind.TrueKeyword), _defineProperty(this, "value", true), _temp2;
6935 }
6936
6937}
6938class FalseBooleanLiteralCompiler extends BooleanLiteralCompiler {
6939 constructor(...args) {
6940 var _temp3;
6941
6942 return _temp3 = super(...args), _defineProperty(this, "kind", SyntaxKind.FalseKeyword), _defineProperty(this, "value", false), _temp3;
6943 }
6944
6945}
6946
6947class SimpleSysCallType {
6948 constructor() {
6949 _defineProperty(this, "name", void 0);
6950 }
6951
6952 toSignature() {
6953 return this.name;
6954 }
6955
6956}
6957
6958class VoidClass extends SimpleSysCallType {
6959 constructor(...args) {
6960 var _temp;
6961
6962 return _temp = super(...args), _defineProperty(this, "name", 'void'), _temp;
6963 }
6964
6965 isOnlyType(sb, node, type) {
6966 return false;
6967 }
6968
6969 isType(sb, node, type) {
6970 return false;
6971 }
6972
6973 isRuntimeType(sb, node, options) {
6974 throw new Error('Should not check void at runtime');
6975 }
6976
6977 handleArgument(sb, node, options, type) {
6978 throw new Error('void should not be an argument');
6979 }
6980
6981 handleResult(sb, node, options, type, native = false) {
6982 sb.emitHelper(node, options, sb.helpers.createUndefined);
6983 }
6984
6985}
6986
6987const VoidValue = new VoidClass();
6988
6989class NumberClass extends SimpleSysCallType {
6990 constructor(...args) {
6991 var _temp2;
6992
6993 return _temp2 = super(...args), _defineProperty(this, "name", 'number'), _temp2;
6994 }
6995
6996 isOnlyType(sb, node, type) {
6997 return isOnlyNumber(type);
6998 }
6999
7000 isType(sb, node, type) {
7001 return isNumber(type);
7002 }
7003
7004 isRuntimeType(sb, node, options) {
7005 sb.emitHelper(node, options, sb.helpers.isNumber);
7006 }
7007
7008 handleArgument(sb, node, options, type, native = false) {
7009 if (!native) {
7010 sb.emitHelper(node, options, sb.helpers.getNumber);
7011 }
7012 }
7013
7014 handleResult(sb, node, options, type, native = false) {
7015 if (!native) {
7016 sb.emitHelper(node, options, sb.helpers.createNumber);
7017 }
7018 }
7019
7020}
7021
7022const NumberValue = new NumberClass();
7023
7024class StringClass extends SimpleSysCallType {
7025 constructor(...args) {
7026 var _temp3;
7027
7028 return _temp3 = super(...args), _defineProperty(this, "name", 'string'), _temp3;
7029 }
7030
7031 isOnlyType(sb, node, type) {
7032 return isOnlyString(type);
7033 }
7034
7035 isType(sb, node, type) {
7036 return isString(type);
7037 }
7038
7039 isRuntimeType(sb, node, options) {
7040 sb.emitHelper(node, options, sb.helpers.isString);
7041 }
7042
7043 handleArgument(sb, node, options, type, native = false) {
7044 if (!native) {
7045 sb.emitHelper(node, options, sb.helpers.getString);
7046 }
7047 }
7048
7049 handleResult(sb, node, options, type, native = false) {
7050 if (!native) {
7051 sb.emitHelper(node, options, sb.helpers.createString);
7052 }
7053 }
7054
7055}
7056
7057const StringValue = new StringClass();
7058
7059class BooleanClass extends SimpleSysCallType {
7060 constructor(...args) {
7061 var _temp4;
7062
7063 return _temp4 = super(...args), _defineProperty(this, "name", 'boolean'), _temp4;
7064 }
7065
7066 isOnlyType(sb, node, type) {
7067 return isOnlyBoolean(type);
7068 }
7069
7070 isType(sb, node, type) {
7071 return isBoolean(type);
7072 }
7073
7074 isRuntimeType(sb, node, options) {
7075 sb.emitHelper(node, options, sb.helpers.isBoolean);
7076 }
7077
7078 handleArgument(sb, node, options, type, native = false) {
7079 if (!native) {
7080 sb.emitHelper(node, options, sb.helpers.getBoolean);
7081 }
7082 }
7083
7084 handleResult(sb, node, options, type, native = false) {
7085 if (!native) {
7086 sb.emitHelper(node, options, sb.helpers.createBoolean);
7087 }
7088 }
7089
7090}
7091
7092const BooleanValue = new BooleanClass();
7093
7094class BlockchainInterface extends SimpleSysCallType {
7095 constructor(name) {
7096 super();
7097
7098 _defineProperty(this, "name", void 0);
7099
7100 this.name = name;
7101 }
7102
7103 isOnlyType(sb, node, type) {
7104 return sb.isOnlyGlobal(node, type, this.name);
7105 }
7106
7107 isType(sb, node, type) {
7108 return sb.isGlobal(node, type, this.name);
7109 }
7110
7111 isRuntimeType(sb, node, options) {
7112 sb.emitHelper(node, options, sb.helpers.isBlockchainInterface({
7113 name: this.name
7114 }));
7115 }
7116
7117 handleArgument(sb, node, options, type, native = false) {
7118 if (native) {
7119 throw new Error('BlockchainInterface should not be serialized/deserialized from storage');
7120 }
7121
7122 sb.emitHelper(node, options, sb.helpers.unwrapBlockchainInterface);
7123 }
7124
7125 handleResult(sb, node, options, type, native = false) {
7126 if (native) {
7127 throw new Error('BlockchainInterface should not be serialized/deserialized from storage');
7128 }
7129
7130 sb.emitHelper(node, options, sb.helpers.wrapBlockchainInterface({
7131 name: this.name
7132 }));
7133 }
7134
7135}
7136
7137const AccountValue = new BlockchainInterface('AccountBase');
7138const AssetValue = new BlockchainInterface('AssetBase');
7139const AttributeValue = new BlockchainInterface('AttributeBase');
7140const BlockValue = new BlockchainInterface('BlockBase');
7141const ContractValue = new BlockchainInterface('ContractBase');
7142const HeaderValue = new BlockchainInterface('HeaderBase');
7143const InputValue = new BlockchainInterface('InputBase');
7144const OutputValue = new BlockchainInterface('OutputBase');
7145const TransactionValue = new BlockchainInterface('TransactionBase');
7146const ValidatorValue = new BlockchainInterface('ValidatorBase');
7147const StorageContextValue = new BlockchainInterface('StorageContextBase');
7148const StorageIteratorValue = new BlockchainInterface('StorageIteratorBase');
7149const BLOCKCHAIN_INTERFACES = [AccountValue, AssetValue, AttributeValue, BlockValue, ContractValue, HeaderValue, InputValue, OutputValue, TransactionValue, ValidatorValue, StorageContextValue, StorageIteratorValue].map(value => value.name);
7150
7151class BufferClass extends SimpleSysCallType {
7152 constructor(...args) {
7153 var _temp5;
7154
7155 return _temp5 = super(...args), _defineProperty(this, "name", 'Buffer'), _temp5;
7156 }
7157
7158 isOnlyType(sb, node, type) {
7159 return sb.isOnlyGlobal(node, type, this.name);
7160 }
7161
7162 isType(sb, node, type) {
7163 return sb.isGlobal(node, type, this.name);
7164 }
7165
7166 isRuntimeType(sb, node, options) {
7167 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
7168 property: this.name
7169 }));
7170 sb.emitHelper(node, options, sb.helpers.instanceof);
7171 }
7172
7173 handleArgument(sb, node, options, type, native = false) {
7174 sb.emitHelper(node, options, sb.helpers.unwrapBuffer);
7175
7176 if (native) {
7177 serializeType(sb, node, options, SerializableType.Buffer);
7178 }
7179 }
7180
7181 handleResult(sb, node, options, type, native = false) {
7182 if (native) {
7183 deserializeType(sb, node, options);
7184 }
7185
7186 sb.emitHelper(node, options, sb.helpers.wrapBuffer);
7187 }
7188
7189}
7190
7191const BufferValue = new BufferClass();
7192
7193class ArrayValue extends SimpleSysCallType {
7194 constructor(valueType) {
7195 super();
7196
7197 _defineProperty(this, "name", void 0);
7198
7199 _defineProperty(this, "valueType", void 0);
7200
7201 this.name = `Array<${valueType.name}>`;
7202 this.valueType = typeof valueType === 'function' ? valueType : () => valueType;
7203 }
7204
7205 isOnlyType(sb, node, type) {
7206 return isOnlyArray(type) && !isOnlyTuple(type) && type != null && this.valueType().isOnlyType(sb, node, type.getArrayType());
7207 }
7208
7209 isType(sb, node, type) {
7210 return isArray(type) && !isTuple(type) && type != null && this.valueType().isType(sb, node, type.getArrayType());
7211 }
7212
7213 isRuntimeType(sb, node, options) {
7214 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
7215 property: 'Array'
7216 }));
7217 sb.emitHelper(node, options, sb.helpers.instanceof);
7218 }
7219
7220 handleArgument(sb, node, options, type, native = false) {
7221 sb.emitHelper(node, options, sb.helpers.unwrapArray);
7222 sb.emitHelper(node, options, sb.helpers.arrMap({
7223 map: () => {
7224 this.valueType().handleArgument(sb, node, options, type == null ? type : type.getArrayType(), native);
7225 }
7226 }));
7227
7228 if (native) {
7229 serializeType(sb, node, options, SerializableType.Array);
7230 }
7231 }
7232
7233 handleResult(sb, node, options, type, native = false) {
7234 if (native) {
7235 deserializeType(sb, node, options);
7236 }
7237
7238 sb.emitHelper(node, options, sb.helpers.arrMap({
7239 map: () => {
7240 this.valueType().handleResult(sb, node, options, type == null ? type : type.getArrayType(), native);
7241 }
7242 }));
7243 sb.emitHelper(node, options, sb.helpers.wrapArray);
7244 }
7245
7246}
7247
7248class TupleValue extends SimpleSysCallType {
7249 constructor(valueType) {
7250 super();
7251
7252 _defineProperty(this, "name", void 0);
7253
7254 _defineProperty(this, "valueType", void 0);
7255
7256 this.name = 'any';
7257 this.valueType = typeof valueType === 'function' ? valueType : () => valueType;
7258 }
7259
7260 isOnlyType(sb, node, type) {
7261 return isOnlyTuple(type) && type != null && type.getTupleElements().every(tupleType => this.valueType().isOnlyType(sb, node, tupleType));
7262 }
7263
7264 isType(sb, node, type) {
7265 return isTuple(type) && type != null && type.getTupleElements().every(tupleType => this.valueType().isType(sb, node, tupleType));
7266 }
7267
7268 isRuntimeType(sb, node, options) {
7269 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
7270 property: 'Array'
7271 }));
7272 sb.emitHelper(node, options, sb.helpers.instanceof);
7273 }
7274
7275 handleArgument(sb, node, options, type, native = false) {
7276 throw new Error('Not Implemented');
7277 }
7278
7279 handleResult(sb, node, options, type, native = false) {
7280 if (type == null) {
7281 sb.reportError(node, 'Syscall return type must be explicitly casted to expected type.', DiagnosticCode.UNKNOWN_TYPE);
7282 } else {
7283 // [length, ...value]
7284 sb.emitOp(node, 'UNPACK'); // [...value]
7285
7286 sb.emitOp(node, 'DROP'); // [0, ...value]
7287
7288 sb.emitPushInt(node, 0); // [arr, ...value]
7289
7290 sb.emitOp(node, 'NEWARRAY');
7291
7292 for (const tupleType of type.getTupleElements()) {
7293 // [arr, arr, ...value]
7294 sb.emitOp(node, 'DUP'); // [value, arr, arr, ...value]
7295
7296 sb.emitOp(node, 'ROT'); // [val, arr, arr, ...value]
7297
7298 this.valueType().handleResult(sb, node, options, tupleType, native); // [arr, ...value]
7299
7300 sb.emitOp(node, 'APPEND');
7301 } // [arrayObjectValue]
7302
7303
7304 sb.emitHelper(node, options, sb.helpers.wrapArray);
7305 }
7306 }
7307
7308}
7309
7310class UnionValue extends SimpleSysCallType {
7311 constructor(valueTypes) {
7312 super();
7313
7314 _defineProperty(this, "name", void 0);
7315
7316 _defineProperty(this, "valueTypes", void 0);
7317
7318 this.name = valueTypes.map(valueType => valueType.name).join(' | ');
7319 this.valueTypes = valueTypes;
7320 }
7321
7322 isOnlyType(sb, node, type) {
7323 return isUnion(type) && type != null && type.getUnionTypes().every(unionType => this.valueTypes.some(valueType => valueType.isOnlyType(sb, node, unionType))) || !isUnion(type) && type != null && this.valueTypes.some(valueType => valueType.isOnlyType(sb, node, type));
7324 }
7325
7326 isType(sb, node, type) {
7327 return isUnion(type) && type != null && type.getUnionTypes().every(unionType => this.valueTypes.some(valueType => valueType.isType(sb, node, unionType))) || !isUnion(type) && type != null && this.valueTypes.some(valueType => valueType.isType(sb, node, type));
7328 }
7329
7330 isRuntimeType(sb, node, options) {
7331 throw new Error('Union should not be checked at runtime');
7332 }
7333
7334 handleArgument(sb, node, options, type, native = false) {
7335 const foundType = this.valueTypes.find(valueType => valueType.isOnlyType(sb, node, type));
7336
7337 if (foundType == null) {
7338 if (native) {
7339 sb.emitHelper(node, options, sb.helpers.genericSerialize);
7340 } else {
7341 sb.emitHelper(node, options, sb.helpers.forType({
7342 types: this.valueTypes.map(valueType => ({
7343 isType: innerType => valueType.isType(sb, node, innerType),
7344 isRuntimeType: innerOptions => valueType.isRuntimeType(sb, node, innerOptions),
7345 process: innerOptions => valueType.handleArgument(sb, node, innerOptions, type, native)
7346 }))
7347 }));
7348 }
7349 } else {
7350 foundType.handleArgument(sb, node, options, type, native);
7351 }
7352 }
7353
7354 handleResult(sb, node, options, type, native = false) {
7355 const foundType = this.valueTypes.find(valueType => valueType.isOnlyType(sb, node, type));
7356
7357 if (foundType == null) {
7358 if (native) {
7359 sb.emitHelper(node, options, sb.helpers.genericDeserialize);
7360 } else {
7361 sb.reportError(node, 'Syscall return type must be explicitly casted to expected type.', DiagnosticCode.UNKNOWN_TYPE);
7362 }
7363 } else {
7364 foundType.handleResult(sb, node, options, type, native);
7365 }
7366 }
7367
7368}
7369
7370const StorageKey = new UnionValue([BufferValue, StringValue]);
7371const StorageValue = new UnionValue([BufferValue, NumberValue, StringValue, BooleanValue]);
7372class TypeAlias {
7373 constructor(name, declaration) {
7374 this.name = name;
7375 this.declaration = declaration;
7376 this.name = name;
7377 this.declaration = declaration;
7378 }
7379
7380 toSignature() {
7381 return this.name;
7382 }
7383
7384 toDeclaration() {
7385 return this.declaration;
7386 }
7387
7388}
7389const SerializableValueArrayAlias = new TypeAlias('SerializableValueArray', 'interface SerializableValueArray extends Array<SerializableValue> { }');
7390const SerializableValueObjectAlias = new TypeAlias('SerializableValueObject', `interface SerializableValueObject {
7391 [key: string]: SerializableValue;
7392}`);
7393const SerializableValueAlias = new TypeAlias('SerializableValue', 'type SerializableValue = undefined | number | string | boolean | Buffer | ' + `${SerializableValueArrayAlias.toSignature()} | ${SerializableValueObjectAlias.toSignature()}`);
7394
7395class Serializable extends SimpleSysCallType {
7396 constructor(shouldSerialize = false, shouldHandleNull = false) {
7397 super();
7398 this.shouldSerialize = shouldSerialize;
7399 this.shouldHandleNull = shouldHandleNull;
7400
7401 _defineProperty(this, "name", void 0);
7402
7403 this.name = SerializableValueAlias.toSignature();
7404 }
7405
7406 get type() {
7407 return new UnionValue([BooleanValue, StringValue, NumberValue, BufferValue, new ArrayValue(() => this.type)]);
7408 }
7409
7410 toDeclaration() {
7411 return SerializableValueAlias.toDeclaration();
7412 }
7413
7414 isOnlyType(sb, node, type) {
7415 return this.type.isOnlyType(sb, node, type);
7416 }
7417
7418 isType(sb, node, type) {
7419 return this.type.isType(sb, node, type);
7420 }
7421
7422 isRuntimeType(sb, node, options) {
7423 this.type.isRuntimeType(sb, node, options);
7424 }
7425
7426 handleArgument(sb, node, options, type) {
7427 this.type.handleArgument(sb, node, options, type, true);
7428
7429 if (this.shouldSerialize) {
7430 sb.emitSysCall(node, 'Neo.Runtime.Serialize');
7431 }
7432 }
7433
7434 handleResult(sb, node, options, typeIn) {
7435 let type = typeIn;
7436
7437 if (type != null && this.shouldHandleNull && type.isUnionType() && type.getUnionTypes().some(unionType => isOnlyUndefined(unionType))) {
7438 type = type.getUnionTypes().find(unionType => !isOnlyUndefined(unionType));
7439 }
7440
7441 const handleValue = () => {
7442 if (this.shouldSerialize) {
7443 sb.emitSysCall(node, 'Neo.Runtime.Deserialize');
7444 }
7445
7446 this.type.handleResult(sb, node, options, type, true);
7447 };
7448
7449 if (this.shouldHandleNull) {
7450 sb.emitHelper(node, options, sb.helpers.if({
7451 condition: () => {
7452 // [value, value]
7453 sb.emitOp(node, 'DUP'); // [length, value]
7454
7455 sb.emitOp(node, 'SIZE'); // [0, length, value]
7456
7457 sb.emitPushInt(node, 0); // [length === 0, value]
7458
7459 sb.emitOp(node, 'NUMEQUAL');
7460 },
7461 whenTrue: () => {
7462 // []
7463 sb.emitOp(node, 'DROP'); // [val]
7464
7465 sb.emitHelper(node, options, sb.helpers.createUndefined);
7466 },
7467 whenFalse: () => {
7468 handleValue();
7469 }
7470 }));
7471 } else {
7472 handleValue();
7473 }
7474 }
7475
7476 addSerialize() {
7477 return new Serializable(true, this.shouldHandleNull);
7478 }
7479
7480 handleNull() {
7481 return new Serializable(this.shouldSerialize, true);
7482 }
7483
7484}
7485
7486const SerializableValue = new Serializable();
7487class SysCallArgument {
7488 constructor(name, type) {
7489 _defineProperty(this, "name", void 0);
7490
7491 _defineProperty(this, "type", void 0);
7492
7493 this.name = name;
7494 this.type = type;
7495 }
7496
7497 handleArgument(sb, node, options, type) {
7498 this.type.handleArgument(sb, node, options, type);
7499 }
7500
7501 toSignature() {
7502 return `${this.name}: ${this.type.toSignature()}`;
7503 }
7504
7505}
7506class SimpleSysCall {
7507 constructor(options) {
7508 _defineProperty(this, "name", void 0);
7509
7510 _defineProperty(this, "args", void 0);
7511
7512 _defineProperty(this, "returnType", void 0);
7513
7514 this.name = options.name;
7515 this.args = options.args || [];
7516 this.returnType = options.returnType || VoidValue;
7517 }
7518
7519 toDeclaration() {
7520 const args = [`name: '${this.name}'`].concat(this.args.map(arg => arg.toSignature()));
7521 return `function syscall(${args.join(', ')}): ${this.returnType.toSignature()};`;
7522 }
7523
7524 handleCall(sb, node, optionsIn) {
7525 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn));
7526 const args = [...node.getArguments().slice(1)].reverse();
7527
7528 for (const [idx, arg] of args.entries()) {
7529 sb.visit(arg, options);
7530 this.args[args.length - idx - 1].handleArgument(sb, arg, options, sb.getType(arg));
7531 }
7532
7533 sb.emitSysCall(node, this.name);
7534
7535 if (optionsIn.pushValue) {
7536 this.returnType.handleResult(sb, node, options, optionsIn.cast);
7537 } else if (this.returnType !== VoidValue) {
7538 sb.emitOp(node, 'DROP');
7539 }
7540 }
7541
7542}
7543const SYSCALLS = {
7544 'Neo.Runtime.GetTrigger': new SimpleSysCall({
7545 name: 'Neo.Runtime.GetTrigger',
7546 returnType: NumberValue
7547 }),
7548 'Neo.Runtime.CheckWitness': new SimpleSysCall({
7549 name: 'Neo.Runtime.CheckWitness',
7550 args: [new SysCallArgument('witness', BufferValue)],
7551 returnType: BooleanValue
7552 }),
7553 'Neo.Runtime.Notify': (() => {
7554 const name = 'Neo.Runtime.Notify';
7555 const valueType = new UnionValue([BufferValue, NumberValue, StringValue, BooleanValue]);
7556 const arrayType = new ArrayValue(valueType);
7557 const returnType = VoidValue;
7558 return {
7559 name,
7560
7561 toDeclaration() {
7562 const sig = arrayType.toSignature();
7563 return `function syscall(name: '${name}', ...args: ${sig}): ${returnType.toSignature()};`;
7564 },
7565
7566 handleCall(sb, node, optionsIn) {
7567 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn));
7568 const args = [...node.getArguments().slice(1)].reverse();
7569
7570 for (const arg of args) {
7571 sb.visit(arg, options);
7572 valueType.handleArgument(sb, arg, options, sb.getType(arg));
7573 } // [length, ...]
7574
7575
7576 sb.emitPushInt(node, args.length); // [arr]
7577
7578 sb.emitOp(node, 'PACK');
7579 sb.emitSysCall(node, name);
7580
7581 if (optionsIn.pushValue) {
7582 returnType.handleResult(sb, node, options, optionsIn.cast);
7583 }
7584 }
7585
7586 };
7587 })(),
7588 'Neo.Runtime.Log': new SimpleSysCall({
7589 name: 'Neo.Runtime.Log',
7590 args: [new SysCallArgument('value', StringValue)]
7591 }),
7592 'Neo.Runtime.GetTime': new SimpleSysCall({
7593 name: 'Neo.Runtime.GetTime',
7594 returnType: NumberValue
7595 }),
7596 'Neo.Runtime.Serialize': new SimpleSysCall({
7597 name: 'Neo.Runtime.Serialize',
7598 args: [new SysCallArgument('value', SerializableValue)],
7599 returnType: BufferValue
7600 }),
7601 'Neo.Runtime.Deserialize': new SimpleSysCall({
7602 name: 'Neo.Runtime.Deserialize',
7603 args: [new SysCallArgument('value', BufferValue)],
7604 returnType: SerializableValue
7605 }),
7606 'Neo.Blockchain.GetHeight': new SimpleSysCall({
7607 name: 'Neo.Blockchain.GetHeight',
7608 returnType: NumberValue
7609 }),
7610 'Neo.Blockchain.GetHeader': new SimpleSysCall({
7611 name: 'Neo.Blockchain.GetHeader',
7612 args: [new SysCallArgument('hashOrIndex', new UnionValue([BufferValue, NumberValue]))],
7613 returnType: HeaderValue
7614 }),
7615 'Neo.Blockchain.GetBlock': new SimpleSysCall({
7616 name: 'Neo.Blockchain.GetBlock',
7617 args: [new SysCallArgument('hashOrIndex', new UnionValue([BufferValue, NumberValue]))],
7618 returnType: BlockValue
7619 }),
7620 'Neo.Blockchain.GetTransaction': new SimpleSysCall({
7621 name: 'Neo.Blockchain.GetTransaction',
7622 args: [new SysCallArgument('hash', BufferValue)],
7623 returnType: TransactionValue
7624 }),
7625 'Neo.Blockchain.GetAccount': new SimpleSysCall({
7626 name: 'Neo.Blockchain.GetAccount',
7627 args: [new SysCallArgument('hash', BufferValue)],
7628 returnType: AccountValue
7629 }),
7630 'Neo.Blockchain.GetValidators': new SimpleSysCall({
7631 name: 'Neo.Blockchain.GetValidators',
7632 returnType: new ArrayValue(BufferValue)
7633 }),
7634 'Neo.Blockchain.GetAsset': new SimpleSysCall({
7635 name: 'Neo.Blockchain.GetAsset',
7636 args: [new SysCallArgument('hash', BufferValue)],
7637 returnType: AssetValue
7638 }),
7639 'Neo.Blockchain.GetContract': new SimpleSysCall({
7640 name: 'Neo.Blockchain.GetContract',
7641 args: [new SysCallArgument('hash', BufferValue)],
7642 returnType: ContractValue
7643 }),
7644 'Neo.Header.GetHash': new SimpleSysCall({
7645 name: 'Neo.Header.GetHash',
7646 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7647 returnType: BufferValue
7648 }),
7649 'Neo.Header.GetVersion': new SimpleSysCall({
7650 name: 'Neo.Header.GetVersion',
7651 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7652 returnType: NumberValue
7653 }),
7654 'Neo.Header.GetPrevHash': new SimpleSysCall({
7655 name: 'Neo.Header.GetPrevHash',
7656 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7657 returnType: BufferValue
7658 }),
7659 'Neo.Header.GetIndex': new SimpleSysCall({
7660 name: 'Neo.Header.GetIndex',
7661 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7662 returnType: NumberValue
7663 }),
7664 'Neo.Header.GetMerkleRoot': new SimpleSysCall({
7665 name: 'Neo.Header.GetMerkleRoot',
7666 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7667 returnType: BufferValue
7668 }),
7669 'Neo.Header.GetTimestamp': new SimpleSysCall({
7670 name: 'Neo.Header.GetTimestamp',
7671 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7672 returnType: NumberValue
7673 }),
7674 'Neo.Header.GetConsensusData': new SimpleSysCall({
7675 name: 'Neo.Header.GetConsensusData',
7676 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7677 returnType: NumberValue
7678 }),
7679 'Neo.Header.GetNextConsensus': new SimpleSysCall({
7680 name: 'Neo.Header.GetNextConsensus',
7681 args: [new SysCallArgument('blockOrHeader', new UnionValue([BlockValue, HeaderValue]))],
7682 returnType: BufferValue
7683 }),
7684 'Neo.Block.GetTransactionCount': new SimpleSysCall({
7685 name: 'Neo.Block.GetTransactionCount',
7686 args: [new SysCallArgument('block', BlockValue)],
7687 returnType: NumberValue
7688 }),
7689 'Neo.Block.GetTransactions': new SimpleSysCall({
7690 name: 'Neo.Block.GetTransactions',
7691 args: [new SysCallArgument('block', BlockValue)],
7692 returnType: new ArrayValue(TransactionValue)
7693 }),
7694 'Neo.Block.GetTransaction': new SimpleSysCall({
7695 name: 'Neo.Block.GetTransaction',
7696 args: [new SysCallArgument('block', BlockValue), new SysCallArgument('index', NumberValue)],
7697 returnType: TransactionValue
7698 }),
7699 'Neo.Transaction.GetHash': new SimpleSysCall({
7700 name: 'Neo.Transaction.GetHash',
7701 args: [new SysCallArgument('transaction', TransactionValue)],
7702 returnType: BufferValue
7703 }),
7704 'Neo.Transaction.GetType': new SimpleSysCall({
7705 name: 'Neo.Transaction.GetType',
7706 args: [new SysCallArgument('transaction', TransactionValue)],
7707 returnType: NumberValue
7708 }),
7709 'Neo.Transaction.GetAttributes': new SimpleSysCall({
7710 name: 'Neo.Transaction.GetAttributes',
7711 args: [new SysCallArgument('transaction', TransactionValue)],
7712 returnType: new ArrayValue(AttributeValue)
7713 }),
7714 'Neo.Transaction.GetInputs': new SimpleSysCall({
7715 name: 'Neo.Transaction.GetInputs',
7716 args: [new SysCallArgument('transaction', TransactionValue)],
7717 returnType: new ArrayValue(InputValue)
7718 }),
7719 'Neo.Transaction.GetOutputs': new SimpleSysCall({
7720 name: 'Neo.Transaction.GetOutputs',
7721 args: [new SysCallArgument('transaction', TransactionValue)],
7722 returnType: new ArrayValue(OutputValue)
7723 }),
7724 'Neo.Transaction.GetReferences': new SimpleSysCall({
7725 name: 'Neo.Transaction.GetReferences',
7726 args: [new SysCallArgument('transaction', TransactionValue)],
7727 returnType: new ArrayValue(OutputValue)
7728 }),
7729 'Neo.Transaction.GetUnspentCoins': new SimpleSysCall({
7730 name: 'Neo.Transaction.GetUnspentCoins',
7731 args: [new SysCallArgument('transaction', TransactionValue)],
7732 returnType: new ArrayValue(OutputValue)
7733 }),
7734 'Neo.InvocationTransaction.GetScript': new SimpleSysCall({
7735 name: 'Neo.InvocationTransaction.GetScript',
7736 args: [new SysCallArgument('transaction', TransactionValue)],
7737 returnType: BufferValue
7738 }),
7739 'Neo.Attribute.GetUsage': new SimpleSysCall({
7740 name: 'Neo.Attribute.GetUsage',
7741 args: [new SysCallArgument('attribute', AttributeValue)],
7742 returnType: NumberValue
7743 }),
7744 'Neo.Attribute.GetData': new SimpleSysCall({
7745 name: 'Neo.Attribute.GetData',
7746 args: [new SysCallArgument('attribute', AttributeValue)],
7747 returnType: BufferValue
7748 }),
7749 'Neo.Input.GetHash': new SimpleSysCall({
7750 name: 'Neo.Input.GetHash',
7751 args: [new SysCallArgument('input', InputValue)],
7752 returnType: BufferValue
7753 }),
7754 'Neo.Input.GetIndex': new SimpleSysCall({
7755 name: 'Neo.Input.GetIndex',
7756 args: [new SysCallArgument('input', InputValue)],
7757 returnType: NumberValue
7758 }),
7759 'Neo.Output.GetAssetId': new SimpleSysCall({
7760 name: 'Neo.Output.GetAssetId',
7761 args: [new SysCallArgument('output', OutputValue)],
7762 returnType: BufferValue
7763 }),
7764 'Neo.Output.GetValue': new SimpleSysCall({
7765 name: 'Neo.Output.GetValue',
7766 args: [new SysCallArgument('output', OutputValue)],
7767 returnType: NumberValue
7768 }),
7769 'Neo.Output.GetScriptHash': new SimpleSysCall({
7770 name: 'Neo.Output.GetScriptHash',
7771 args: [new SysCallArgument('output', OutputValue)],
7772 returnType: BufferValue
7773 }),
7774 'Neo.Account.GetScriptHash': new SimpleSysCall({
7775 name: 'Neo.Account.GetScriptHash',
7776 args: [new SysCallArgument('account', AccountValue)],
7777 returnType: BufferValue
7778 }),
7779 'Neo.Account.GetVotes': new SimpleSysCall({
7780 name: 'Neo.Account.GetVotes',
7781 args: [new SysCallArgument('account', AccountValue)],
7782 returnType: new ArrayValue(BufferValue)
7783 }),
7784 'Neo.Account.GetBalance': new SimpleSysCall({
7785 name: 'Neo.Account.GetBalance',
7786 args: [new SysCallArgument('account', AccountValue), new SysCallArgument('assetHash', BufferValue)],
7787 returnType: NumberValue
7788 }),
7789 'Neo.Asset.GetAssetId': new SimpleSysCall({
7790 name: 'Neo.Asset.GetAssetId',
7791 args: [new SysCallArgument('asset', AssetValue)],
7792 returnType: BufferValue
7793 }),
7794 'Neo.Asset.GetAssetType': new SimpleSysCall({
7795 name: 'Neo.Asset.GetAssetType',
7796 args: [new SysCallArgument('asset', AssetValue)],
7797 returnType: NumberValue
7798 }),
7799 'Neo.Asset.GetAmount': new SimpleSysCall({
7800 name: 'Neo.Asset.GetAmount',
7801 args: [new SysCallArgument('asset', AssetValue)],
7802 returnType: NumberValue
7803 }),
7804 'Neo.Asset.GetAvailable': new SimpleSysCall({
7805 name: 'Neo.Asset.GetAvailable',
7806 args: [new SysCallArgument('asset', AssetValue)],
7807 returnType: NumberValue
7808 }),
7809 'Neo.Asset.GetPrecision': new SimpleSysCall({
7810 name: 'Neo.Asset.GetPrecision',
7811 args: [new SysCallArgument('asset', AssetValue)],
7812 returnType: NumberValue
7813 }),
7814 'Neo.Asset.GetOwner': new SimpleSysCall({
7815 name: 'Neo.Asset.GetOwner',
7816 args: [new SysCallArgument('asset', AssetValue)],
7817 returnType: BufferValue
7818 }),
7819 'Neo.Asset.GetAdmin': new SimpleSysCall({
7820 name: 'Neo.Asset.GetAdmin',
7821 args: [new SysCallArgument('asset', AssetValue)],
7822 returnType: BufferValue
7823 }),
7824 'Neo.Asset.GetIssuer': new SimpleSysCall({
7825 name: 'Neo.Asset.GetIssuer',
7826 args: [new SysCallArgument('asset', AssetValue)],
7827 returnType: BufferValue
7828 }),
7829 'Neo.Contract.GetScript': new SimpleSysCall({
7830 name: 'Neo.Contract.GetScript',
7831 args: [new SysCallArgument('contract', ContractValue)],
7832 returnType: BufferValue
7833 }),
7834 'Neo.Storage.GetContext': new SimpleSysCall({
7835 name: 'Neo.Storage.GetContext',
7836 returnType: StorageContextValue
7837 }),
7838 'Neo.Storage.Get': new SimpleSysCall({
7839 name: 'Neo.Storage.Get',
7840 args: [new SysCallArgument('context', StorageContextValue), new SysCallArgument('key', StorageKey)],
7841 returnType: SerializableValue.addSerialize().handleNull()
7842 }),
7843 'Neo.Storage.Find': new SimpleSysCall({
7844 name: 'Neo.Storage.Find',
7845 args: [new SysCallArgument('context', StorageContextValue), new SysCallArgument('prefix', StorageKey)],
7846 returnType: StorageIteratorValue
7847 }),
7848 'Neo.Iterator.Next': new SimpleSysCall({
7849 name: 'Neo.Iterator.Next',
7850 args: [new SysCallArgument('iterator', StorageIteratorValue)],
7851 returnType: BooleanValue
7852 }),
7853 'Neo.Iterator.Key': new SimpleSysCall({
7854 name: 'Neo.Iterator.Key',
7855 args: [new SysCallArgument('iterator', StorageIteratorValue)],
7856 returnType: StorageKey
7857 }),
7858 'Neo.Iterator.Value': new SimpleSysCall({
7859 name: 'Neo.Iterator.Value',
7860 args: [new SysCallArgument('iterator', StorageIteratorValue)],
7861 returnType: StorageValue
7862 }),
7863 'Neo.Account.SetVotes': new SimpleSysCall({
7864 name: 'Neo.Account.SetVotes',
7865 args: [new SysCallArgument('account', AccountValue), new SysCallArgument('votes', new ArrayValue(BufferValue))]
7866 }),
7867 'Neo.Validator.Register': new SimpleSysCall({
7868 name: 'Neo.Validator.Register',
7869 args: [new SysCallArgument('publicKey', BufferValue)],
7870 returnType: ValidatorValue
7871 }),
7872 'Neo.Asset.Create': new SimpleSysCall({
7873 name: 'Neo.Asset.Create',
7874 args: [new SysCallArgument('assetType', NumberValue), new SysCallArgument('assetName', StringValue), new SysCallArgument('amount', NumberValue), new SysCallArgument('precision', NumberValue), new SysCallArgument('owner', BufferValue), new SysCallArgument('admin', BufferValue), new SysCallArgument('issuer', BufferValue)],
7875 returnType: AssetValue
7876 }),
7877 'Neo.Asset.Renew': new SimpleSysCall({
7878 name: 'Neo.Asset.Renew',
7879 args: [new SysCallArgument('asset', AssetValue), new SysCallArgument('years', NumberValue)],
7880 returnType: NumberValue
7881 }),
7882 'Neo.Contract.Create': new SimpleSysCall({
7883 name: 'Neo.Contract.Create',
7884 args: [new SysCallArgument('script', BufferValue), new SysCallArgument('parameterList', BufferValue), new SysCallArgument('returnType', NumberValue), new SysCallArgument('properties', NumberValue), new SysCallArgument('contractName', StringValue), new SysCallArgument('codeVersion', StringValue), new SysCallArgument('author', StringValue), new SysCallArgument('email', StringValue), new SysCallArgument('description', StringValue)],
7885 returnType: ContractValue
7886 }),
7887 'Neo.Contract.Migrate': new SimpleSysCall({
7888 name: 'Neo.Contract.Migrate',
7889 args: [new SysCallArgument('script', BufferValue), new SysCallArgument('parameterList', BufferValue), new SysCallArgument('returnType', NumberValue), new SysCallArgument('properties', NumberValue), new SysCallArgument('contractName', StringValue), new SysCallArgument('codeVersion', StringValue), new SysCallArgument('author', StringValue), new SysCallArgument('email', StringValue), new SysCallArgument('description', StringValue)],
7890 returnType: ContractValue
7891 }),
7892 'Neo.Contract.GetStorageContext': new SimpleSysCall({
7893 name: 'Neo.Contract.GetStorageContext',
7894 args: [new SysCallArgument('contract', ContractValue)],
7895 returnType: StorageContextValue
7896 }),
7897 'Neo.Contract.Destroy': new SimpleSysCall({
7898 name: 'Neo.Contract.Destroy'
7899 }),
7900 'Neo.Storage.Put': new SimpleSysCall({
7901 name: 'Neo.Storage.Put',
7902 args: [new SysCallArgument('context', StorageContextValue), new SysCallArgument('key', StorageKey), new SysCallArgument('value', SerializableValue.addSerialize())]
7903 }),
7904 'Neo.Storage.Delete': new SimpleSysCall({
7905 name: 'Neo.Storage.Delete',
7906 args: [new SysCallArgument('context', StorageContextValue), new SysCallArgument('key', StorageKey)]
7907 }),
7908 'System.ExecutionEngine.GetScriptContainer': new SimpleSysCall({
7909 name: 'System.ExecutionEngine.GetScriptContainer',
7910 returnType: TransactionValue
7911 }),
7912 'System.ExecutionEngine.GetExecutingScriptHash': new SimpleSysCall({
7913 name: 'System.ExecutionEngine.GetExecutingScriptHash',
7914 returnType: BufferValue
7915 }),
7916 'System.ExecutionEngine.GetCallingScriptHash': new SimpleSysCall({
7917 name: 'System.ExecutionEngine.GetCallingScriptHash',
7918 returnType: BufferValue
7919 }),
7920 'System.ExecutionEngine.GetEntryScriptHash': new SimpleSysCall({
7921 name: 'System.ExecutionEngine.GetEntryScriptHash',
7922 returnType: BufferValue
7923 }),
7924 'Neo.Runtime.Return': (() => {
7925 const name = 'Neo.Runtime.Return';
7926 const valueType = new UnionValue([BufferValue, NumberValue, StringValue, BooleanValue]);
7927 const returnType = VoidValue;
7928 return {
7929 name,
7930
7931 toDeclaration() {
7932 const sig = valueType.toSignature();
7933 return `function syscall(name: '${name}', value: ${sig}): ${returnType.toSignature()};`;
7934 },
7935
7936 handleCall(sb, node, optionsIn) {
7937 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn));
7938 const arg = node.getArguments()[1];
7939 sb.visit(arg, options);
7940 valueType.handleArgument(sb, arg, options, sb.getType(arg));
7941 }
7942
7943 };
7944 })(),
7945 'Neo.Runtime.GetArgument': (() => {
7946 const name = 'Neo.Runtime.GetArgument';
7947 const valueType = NumberValue;
7948 const returnType = new UnionValue([BufferValue, BooleanValue, NumberValue, StringValue, new ArrayValue(() => returnType), new TupleValue(() => returnType)]);
7949 return {
7950 name,
7951
7952 toDeclaration() {
7953 const sig = valueType.toSignature();
7954 return `function syscall(name: '${name}', idx: ${sig}): any;`;
7955 },
7956
7957 handleCall(sb, node, optionsIn) {
7958 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn));
7959 const arg = node.getArguments()[1];
7960 sb.visit(arg, options);
7961 sb.emitHelper(arg, options, sb.helpers.getArgument({
7962 type: sb.getType(arg)
7963 }));
7964
7965 if (optionsIn.pushValue) {
7966 returnType.handleResult(sb, node, optionsIn, optionsIn.cast);
7967 } else {
7968 sb.emitOp(node, 'DROP');
7969 }
7970 }
7971
7972 };
7973 })()
7974};
7975
7976class CallExpressionCompiler extends NodeCompiler {
7977 constructor(...args) {
7978 var _temp;
7979
7980 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.CallExpression), _temp;
7981 }
7982
7983 visitNode(sb, expr, optionsIn) {
7984 const func = expr.getExpression();
7985
7986 if (TypeGuards.isIdentifier(func) && sb.isGlobalSymbol(func, sb.getSymbol(func), 'syscall')) {
7987 this.handleSysCall(sb, expr, optionsIn);
7988 return;
7989 }
7990
7991 const options = sb.pushValueOptions(sb.noCastOptions(optionsIn)); // [argsarr]
7992
7993 sb.emitHelper(expr, options, sb.helpers.args);
7994
7995 if (TypeGuards.isSuperExpression(func)) {
7996 this.handleSuperConstruct(sb, expr, options);
7997 return;
7998 }
7999
8000 let bindThis;
8001
8002 if (TypeGuards.isElementAccessExpression(func) || TypeGuards.isPropertyAccessExpression(func)) {
8003 bindThis = true;
8004 const lhs = func.getExpression();
8005
8006 if (TypeGuards.isSuperExpression(lhs)) {
8007 // [thisValue, argsarr]
8008 sb.scope.getThis(sb, lhs, options); // [superPrototype, thisValue, argsarr]
8009
8010 sb.visit(lhs, options);
8011 } else {
8012 // [expr, argsarr]
8013 sb.visit(lhs, options); // [expr, expr, argsarr]
8014
8015 sb.emitOp(func, 'DUP');
8016 }
8017
8018 if (TypeGuards.isElementAccessExpression(func)) {
8019 // [objectVal, expr, argsarr]
8020 sb.emitHelper(func, options, sb.helpers.elementAccess);
8021 } else {
8022 // [name, expr, expr, argsarr]
8023 sb.emitPushString(func.getNameNode(), func.getName()); // [objectVal, expr, argsarr]
8024
8025 sb.emitHelper(expr, options, sb.helpers.getPropertyObjectProperty);
8026 }
8027 } else {
8028 bindThis = false; // [objectVal, argsarr]
8029
8030 sb.visit(func, options);
8031 }
8032
8033 sb.emitHelper(expr, options, sb.helpers.invokeCall({
8034 bindThis
8035 }));
8036
8037 if (!optionsIn.pushValue) {
8038 sb.emitOp(expr, 'DROP');
8039 }
8040 }
8041
8042 handleSysCall(sb, node, options) {
8043 const sysCallName = node.getArguments()[0];
8044
8045 const reportError = () => {
8046 sb.reportError(node, 'First argument to syscall must be a string literal corresponding to a NEO syscall.', DiagnosticCode.INVALID_SYS_CALL);
8047 };
8048
8049 if (sysCallName == null || !TypeGuards.isStringLiteral(sysCallName)) {
8050 reportError();
8051 return;
8052 }
8053
8054 const sysCallKey = sysCallName.getLiteralValue();
8055 const sysCall = SYSCALLS[sysCallKey];
8056
8057 if (sysCall == null) {
8058 reportError();
8059 } else {
8060 sysCall.handleCall(sb, node, options);
8061 }
8062 }
8063
8064 handleSuperConstruct(sb, node, options) {
8065 const superClass = options.superClass;
8066
8067 if (superClass == null) {
8068 throw new Error('Something went wrong, expected super class to be defined.');
8069 } // [thisValue, argsarr]
8070
8071
8072 sb.scope.getThis(sb, node, options); // [ctor, thisValue, argsarr]
8073
8074 sb.scope.get(sb, node, options, superClass); // []
8075
8076 sb.emitHelper(node, options, sb.helpers.invokeConstruct());
8077 }
8078
8079}
8080
8081class CommaListExpressionCompiler extends NodeCompiler {
8082 constructor(...args) {
8083 var _temp;
8084
8085 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.CommaListExpression), _temp;
8086 }
8087
8088 visitNode(sb, expr, options) {
8089 sb.reportUnsupported(expr);
8090 }
8091
8092}
8093
8094class ConditionalExpressionCompiler extends NodeCompiler {
8095 constructor(...args) {
8096 var _temp;
8097
8098 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ConditionalExpression), _temp;
8099 }
8100
8101 visitNode(sb, expr, options) {
8102 sb.emitHelper(expr, options, sb.helpers.if({
8103 condition: () => {
8104 // [val]
8105 sb.visit(expr.getCondition(), sb.pushValueOptions(options)); // [boolean]
8106
8107 sb.emitHelper(expr.getCondition(), sb.pushValueOptions(options), sb.helpers.toBoolean({
8108 type: sb.getType(expr.getCondition())
8109 }));
8110 },
8111 whenTrue: () => {
8112 sb.visit(expr.getWhenTrue(), options);
8113 },
8114 whenFalse: () => {
8115 sb.visit(expr.getWhenFalse(), options);
8116 }
8117 }));
8118 }
8119
8120}
8121
8122class DeleteExpressionCompiler extends NodeCompiler {
8123 constructor(...args) {
8124 var _temp;
8125
8126 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.DeleteExpression), _temp;
8127 }
8128
8129 visitNode(sb, expr, options) {
8130 sb.reportUnsupported(expr);
8131 }
8132
8133}
8134
8135class ElementAccessExpressionCompiler extends NodeCompiler {
8136 constructor(...args) {
8137 var _temp;
8138
8139 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ElementAccessExpression), _temp;
8140 }
8141
8142 visitNode(sb, expr, options) {
8143 const value = expr.getExpression(); // [val]
8144
8145 sb.visit(value, sb.pushValueOptions(sb.noSetValueOptions(options))); // [val]
8146
8147 sb.emitHelper(expr, options, sb.helpers.elementAccess);
8148 }
8149
8150}
8151
8152class FunctionExpressionCompiler extends NodeCompiler {
8153 constructor(...args) {
8154 var _temp;
8155
8156 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.FunctionExpression), _temp;
8157 }
8158
8159 visitNode(sb, expr, options) {
8160 sb.reportUnsupported(expr);
8161 }
8162
8163}
8164
8165class IdentifierCompiler extends NodeCompiler {
8166 constructor(...args) {
8167 var _temp;
8168
8169 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.Identifier), _temp;
8170 }
8171
8172 visitNode(sb, expr, options) {
8173 if (options.setValue) {
8174 sb.scope.set(sb, expr, sb.noSetValueOptions(options), expr.getText());
8175 }
8176
8177 if (options.pushValue) {
8178 if (expr.compilerNode.originalKeywordKind != null && expr.compilerNode.originalKeywordKind === SyntaxKind.UndefinedKeyword) {
8179 sb.emitHelper(expr, options, sb.helpers.createUndefined);
8180 } else {
8181 sb.scope.get(sb, expr, options, expr.getText());
8182 }
8183 }
8184 }
8185
8186}
8187
8188class ImportExpressionCompiler extends NodeCompiler {
8189 constructor(...args) {
8190 var _temp;
8191
8192 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ImportKeyword), _temp;
8193 }
8194
8195 visitNode(sb, expr, options) {
8196 sb.reportUnsupported(expr);
8197 }
8198
8199}
8200
8201class MetaPropertyCompiler extends NodeCompiler {
8202 constructor(...args) {
8203 var _temp;
8204
8205 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.MetaProperty), _temp;
8206 }
8207
8208 visitNode(sb, expr, options) {
8209 sb.reportUnsupported(expr);
8210 }
8211
8212}
8213
8214class NewExpressionCompiler extends NodeCompiler {
8215 constructor(...args) {
8216 var _temp;
8217
8218 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NewExpression), _temp;
8219 }
8220
8221 visitNode(sb, expr, optionsIn) {
8222 const options = sb.pushValueOptions(optionsIn); // [argsarr]
8223
8224 sb.emitHelper(expr, options, sb.helpers.args); // [objectVal, argsarr]
8225
8226 sb.visit(expr.getExpression(), options); // [thisVal]
8227
8228 sb.emitHelper(expr, options, sb.helpers.new());
8229 }
8230
8231}
8232
8233class NonNullExpressionCompiler extends NodeCompiler {
8234 constructor(...args) {
8235 var _temp;
8236
8237 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NonNullExpression), _temp;
8238 }
8239
8240 visitNode(sb, expr, options) {
8241 sb.reportUnsupported(expr);
8242 }
8243
8244}
8245
8246class NoSubstitutionTemplateLiteralCompiler extends NodeCompiler {
8247 constructor(...args) {
8248 var _temp;
8249
8250 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NoSubstitutionTemplateLiteral), _temp;
8251 }
8252
8253 visitNode(sb, expr, options) {
8254 sb.reportUnsupported(expr);
8255 }
8256
8257}
8258
8259class NullLiteralCompiler extends NodeCompiler {
8260 constructor(...args) {
8261 var _temp;
8262
8263 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NullKeyword), _temp;
8264 }
8265
8266 visitNode(sb, expr, options) {
8267 if (options.pushValue) {
8268 sb.emitHelper(expr, options, sb.helpers.createNull);
8269 }
8270 }
8271
8272}
8273
8274class NumericLiteralCompiler extends NodeCompiler {
8275 constructor(...args) {
8276 var _temp;
8277
8278 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NumericLiteral), _temp;
8279 }
8280
8281 visitNode(sb, expr, options) {
8282 if (options.pushValue) {
8283 sb.emitPushInt(expr, expr.getLiteralValue());
8284 sb.emitHelper(expr, options, sb.helpers.createNumber);
8285 }
8286 }
8287
8288}
8289
8290class ObjectLiteralExpressionCompiler extends NodeCompiler {
8291 constructor(...args) {
8292 var _temp;
8293
8294 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ObjectLiteralExpression), _temp;
8295 }
8296
8297 visitNode(sb, node, optionsIn) {
8298 const options = sb.pushValueOptions(optionsIn); // [objectVal]
8299
8300 sb.emitHelper(node, options, sb.helpers.createObject);
8301 node.getProperties().forEach(prop => {
8302 // [objectVal, objectVal]
8303 sb.emitOp(node, 'DUP');
8304
8305 if (TypeGuards.isPropertyAssignment(prop) || TypeGuards.isShorthandPropertyAssignment(prop) || TypeGuards.isMethodDeclaration(prop)) {
8306 // [propString, objectVal, objectVal]
8307 sb.emitPushString(prop, prop.getName());
8308
8309 if (TypeGuards.isPropertyAssignment(prop)) {
8310 // [val, propString, objectVal, objectVal]
8311 sb.visit(prop.getInitializerOrThrow(), options);
8312 } else if (TypeGuards.isShorthandPropertyAssignment(prop)) {
8313 // [val, propString, objectVal, objectVal]
8314 sb.visit(prop.getNameNode(), options);
8315 } else if (TypeGuards.isMethodDeclaration(prop)) {
8316 // [callArr, propString, objectVal, objectVal]
8317 sb.emitHelper(prop, options, sb.helpers.createCallArray); // [callObj, propString, objectVal, objectVal]
8318
8319 sb.emitHelper(prop, options, sb.helpers.createFunctionObject({
8320 property: InternalFunctionProperties.CALL
8321 }));
8322 } else {
8323 sb.reportUnsupported(prop);
8324 } // [objectVal]
8325
8326
8327 sb.emitHelper(prop, options, sb.helpers.setDataPropertyObjectProperty);
8328 } else {
8329 sb.reportUnsupported(prop);
8330 }
8331 });
8332
8333 if (!optionsIn.pushValue) {
8334 sb.emitOp(node, 'DROP');
8335 }
8336 }
8337
8338}
8339
8340class OmittedExpressionCompiler extends NodeCompiler {
8341 constructor(...args) {
8342 var _temp;
8343
8344 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.OmittedExpression), _temp;
8345 }
8346
8347 visitNode(sb, expr, options) {
8348 sb.reportUnsupported(expr);
8349 }
8350
8351}
8352
8353class ParenthesizedExpressionCompiler extends NodeCompiler {
8354 constructor(...args) {
8355 var _temp;
8356
8357 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ParenthesizedExpression), _temp;
8358 }
8359
8360 visitNode(sb, expr, options) {
8361 sb.visit(expr.getExpression(), options);
8362 }
8363
8364}
8365
8366class PartiallyEmittedExpressionCompiler extends NodeCompiler {
8367 constructor(...args) {
8368 var _temp;
8369
8370 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.PartiallyEmittedExpression), _temp;
8371 }
8372
8373 visitNode(sb, expr, options) {
8374 sb.reportUnsupported(expr);
8375 }
8376
8377}
8378
8379class PostfixUnaryExpressionCompiler extends NodeCompiler {
8380 constructor(...args) {
8381 var _temp;
8382
8383 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.PostfixUnaryExpression), _temp;
8384 }
8385
8386 visitNode(sb, expr, options) {
8387 sb.visit(expr.getOperand(), sb.noSetValueOptions(sb.pushValueOptions(options)));
8388 const token = expr.getOperatorToken();
8389
8390 switch (token) {
8391 case SyntaxKind.PlusPlusToken:
8392 case SyntaxKind.MinusMinusToken:
8393 this.visitAssignment(sb, token, expr, options);
8394 break;
8395
8396 default:
8397 sb.assertUnreachable(token);
8398 }
8399 }
8400
8401 visitAssignment(sb, token, expr, options) {
8402 if (options.pushValue) {
8403 sb.emitOp(expr, 'DUP');
8404 }
8405
8406 switch (token) {
8407 case SyntaxKind.PlusPlusToken:
8408 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.toNumber({
8409 type: sb.getType(expr)
8410 }));
8411 sb.emitOp(expr, 'INC');
8412 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.createNumber);
8413 break;
8414
8415 case SyntaxKind.MinusMinusToken:
8416 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.toNumber({
8417 type: sb.getType(expr)
8418 }));
8419 sb.emitOp(expr, 'DEC');
8420 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.createNumber);
8421 break;
8422
8423 default:
8424 sb.assertUnreachable(token);
8425 }
8426
8427 sb.visit(expr.getOperand(), sb.noPushValueOptions(sb.setValueOptions(options)));
8428 }
8429
8430}
8431
8432class PrefixUnaryExpressionCompiler extends NodeCompiler {
8433 constructor(...args) {
8434 var _temp;
8435
8436 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.PrefixUnaryExpression), _temp;
8437 }
8438
8439 visitNode(sb, expr, options) {
8440 const token = expr.getOperatorToken();
8441
8442 switch (token) {
8443 case SyntaxKind.PlusPlusToken:
8444 case SyntaxKind.MinusMinusToken:
8445 this.visitAssignment(sb, token, expr, options);
8446 break;
8447
8448 case SyntaxKind.PlusToken:
8449 case SyntaxKind.MinusToken:
8450 case SyntaxKind.TildeToken:
8451 case SyntaxKind.ExclamationToken:
8452 this.visitValue(sb, token, expr, options);
8453 break;
8454
8455 default:
8456 sb.assertUnreachable(token);
8457 }
8458 }
8459
8460 visitAssignment(sb, token, expr, options) {
8461 sb.visit(expr.getOperand(), sb.noSetValueOptions(sb.pushValueOptions(options)));
8462
8463 switch (token) {
8464 case SyntaxKind.PlusPlusToken:
8465 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.toNumber({
8466 type: sb.getType(expr)
8467 }));
8468 sb.emitOp(expr, 'INC');
8469 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.createNumber);
8470 break;
8471
8472 case SyntaxKind.MinusMinusToken:
8473 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.toNumber({
8474 type: sb.getType(expr)
8475 }));
8476 sb.emitOp(expr, 'DEC');
8477 sb.emitHelper(expr, sb.pushValueOptions(options), sb.helpers.createNumber);
8478 break;
8479
8480 default:
8481 sb.assertUnreachable(token);
8482 }
8483
8484 sb.visit(expr.getOperand(), sb.setValueOptions(options));
8485 }
8486
8487 visitValue(sb, token, expr, options) {
8488 const operand = expr.getOperand();
8489 sb.visit(operand, sb.noSetValueOptions(sb.pushValueOptions(options)));
8490
8491 if (!options.pushValue) {
8492 sb.emitOp(expr, 'DROP');
8493 return;
8494 }
8495
8496 switch (token) {
8497 case SyntaxKind.PlusToken:
8498 sb.emitHelper(expr, options, sb.helpers.toNumber({
8499 type: sb.getType(expr)
8500 }));
8501 sb.emitHelper(expr, options, sb.helpers.createNumber);
8502 break;
8503
8504 case SyntaxKind.MinusToken:
8505 sb.emitHelper(expr, options, sb.helpers.toNumber({
8506 type: sb.getType(expr)
8507 }));
8508 sb.emitOp(expr, 'NEGATE');
8509 sb.emitHelper(expr, options, sb.helpers.createNumber);
8510 break;
8511
8512 case SyntaxKind.TildeToken:
8513 sb.emitHelper(expr, options, sb.helpers.toNumber({
8514 type: sb.getType(expr)
8515 }));
8516 sb.emitOp(expr, 'INVERT');
8517 sb.emitHelper(expr, options, sb.helpers.createNumber);
8518 break;
8519
8520 case SyntaxKind.ExclamationToken:
8521 sb.emitHelper(operand, options, sb.helpers.toBoolean({
8522 type: sb.getType(operand)
8523 }));
8524 sb.emitOp(expr, 'NOT');
8525 sb.emitHelper(operand, options, sb.helpers.createBoolean);
8526 break;
8527
8528 default:
8529 sb.assertUnreachable(token);
8530 }
8531 }
8532
8533}
8534
8535class PropertyAccessExpressionCompiler extends NodeCompiler {
8536 constructor(...args) {
8537 var _temp;
8538
8539 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.PropertyAccessExpression), _temp;
8540 }
8541
8542 visitNode(sb, expr, optionsIn) {
8543 const options = sb.pushValueOptions(sb.noSetValueOptions(optionsIn));
8544 const expression = expr.getExpression(); // [val]
8545
8546 sb.visit(expression, options); // [objectVal]
8547
8548 sb.emitHelper(expression, options, sb.helpers.toObject({
8549 type: sb.getType(expression)
8550 }));
8551
8552 if (optionsIn.setValue) {
8553 if (optionsIn.pushValue) {
8554 // [objectVal, value, objectVal]
8555 sb.emitOp(expression, 'TUCK');
8556 } // [name, objectVal, value, objectVal]
8557
8558
8559 sb.emitPushString(expr, expr.getName()); // [value, name, objectVal, objectVal]
8560
8561 sb.emitOp(expr, 'ROT'); // [objectVal]
8562
8563 sb.emitHelper(expr, options, sb.helpers.setPropertyObjectProperty);
8564 }
8565
8566 if (optionsIn.pushValue || !optionsIn.setValue) {
8567 // [name, objectVal]
8568 sb.emitPushString(expr, expr.getName()); // [value]
8569
8570 sb.emitHelper(expr, options, sb.helpers.getPropertyObjectProperty);
8571
8572 if (!optionsIn.pushValue) {
8573 sb.emitOp(expr, 'DROP');
8574 }
8575 }
8576 }
8577
8578}
8579
8580class RegularExpressionLiteralCompiler extends NodeCompiler {
8581 constructor(...args) {
8582 var _temp;
8583
8584 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.RegularExpressionLiteral), _temp;
8585 }
8586
8587 visitNode(sb, expr, options) {
8588 sb.reportUnsupported(expr);
8589 }
8590
8591}
8592
8593class SpreadElementCompiler extends NodeCompiler {
8594 constructor(...args) {
8595 var _temp;
8596
8597 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.SpreadElement), _temp;
8598 }
8599
8600 visitNode(sb, expr, options) {
8601 sb.reportUnsupported(expr);
8602 }
8603
8604}
8605
8606class StringLiteralCompiler extends NodeCompiler {
8607 constructor(...args) {
8608 var _temp;
8609
8610 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.StringLiteral), _temp;
8611 }
8612
8613 visitNode(sb, expr, options) {
8614 if (options.pushValue) {
8615 sb.emitPushString(expr, expr.getLiteralValue());
8616 sb.emitHelper(expr, options, sb.helpers.createString);
8617 }
8618 }
8619
8620}
8621
8622class SuperExpressionCompiler extends NodeCompiler {
8623 constructor(...args) {
8624 var _temp;
8625
8626 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.SuperKeyword), _temp;
8627 }
8628
8629 visitNode(sb, expr, options) {
8630 if (options.pushValue) {
8631 const superClass = options.superClass;
8632
8633 if (superClass == null) {
8634 throw new Error('Something went wrong, expected super class to be defined.');
8635 } // [superClass]
8636
8637
8638 sb.scope.get(sb, expr, options, superClass); // ['prototype', superClass]
8639
8640 sb.emitPushString(expr, 'prototype'); // [superPrototype]
8641
8642 sb.emitHelper(expr, options, sb.helpers.getPropertyObjectProperty);
8643 }
8644 }
8645
8646}
8647
8648class TaggedTemplateExpressionCompiler extends NodeCompiler {
8649 constructor(...args) {
8650 var _temp;
8651
8652 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.TaggedTemplateExpression), _temp;
8653 }
8654
8655 visitNode(sb, expr, options) {
8656 sb.reportUnsupported(expr);
8657 }
8658
8659}
8660
8661class ThisExpressionCompiler extends NodeCompiler {
8662 constructor(...args) {
8663 var _temp;
8664
8665 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ThisKeyword), _temp;
8666 }
8667
8668 visitNode(sb, expr, options) {
8669 if (options.pushValue) {
8670 sb.scope.getThis(sb, expr, options);
8671 }
8672 }
8673
8674}
8675
8676class TypeAssertionCompiler extends NodeCompiler {
8677 constructor(...args) {
8678 var _temp;
8679
8680 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.TypeAssertionExpression), _temp;
8681 }
8682
8683 visitNode(sb, expr, options) {
8684 sb.reportUnsupported(expr);
8685 }
8686
8687}
8688
8689class TypeOfExpressionCompiler extends NodeCompiler {
8690 constructor(...args) {
8691 var _temp;
8692
8693 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.TypeOfExpression), _temp;
8694 }
8695
8696 visitNode(sb, expr, options) {
8697 sb.reportUnsupported(expr);
8698 }
8699
8700}
8701
8702class VoidExpressionCompiler extends NodeCompiler {
8703 constructor(...args) {
8704 var _temp;
8705
8706 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.VoidExpression), _temp;
8707 }
8708
8709 visitNode(sb, expr, options) {
8710 if (options.pushValue) {
8711 sb.emitHelper(expr, options, sb.helpers.createUndefined);
8712 }
8713 }
8714
8715}
8716
8717class YieldExpressionCompiler extends NodeCompiler {
8718 constructor(...args) {
8719 var _temp;
8720
8721 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.YieldExpression), _temp;
8722 }
8723
8724 visitNode(sb, expr, options) {
8725 sb.reportUnsupported(expr);
8726 }
8727
8728}
8729
8730var expression = [ArrayLiteralExpressionCompiler, ArrowFunctionCompiler, AsExpressionCompiler, AwaitExpressionCompiler, BinaryExpressionCompiler, TrueBooleanLiteralCompiler, FalseBooleanLiteralCompiler, CallExpressionCompiler, CommaListExpressionCompiler, ConditionalExpressionCompiler, DeleteExpressionCompiler, ElementAccessExpressionCompiler, FunctionExpressionCompiler, IdentifierCompiler, ImportExpressionCompiler, MetaPropertyCompiler, NewExpressionCompiler, NonNullExpressionCompiler, NoSubstitutionTemplateLiteralCompiler, NullLiteralCompiler, NumericLiteralCompiler, ObjectLiteralExpressionCompiler, OmittedExpressionCompiler, ParenthesizedExpressionCompiler, PartiallyEmittedExpressionCompiler, PostfixUnaryExpressionCompiler, PrefixUnaryExpressionCompiler, PropertyAccessExpressionCompiler, RegularExpressionLiteralCompiler, SpreadElementCompiler, StringLiteralCompiler, SuperExpressionCompiler, TaggedTemplateExpressionCompiler, ThisExpressionCompiler, TypeAssertionCompiler, TypeOfExpressionCompiler, VoidExpressionCompiler, YieldExpressionCompiler];
8731
8732class SourceFileCompiler extends NodeCompiler {
8733 constructor(...args) {
8734 var _temp;
8735
8736 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.SourceFile), _temp;
8737 }
8738
8739 visitNode(sb, node, options) {
8740 node.getImportDeclarations().forEach(decl => {
8741 sb.visit(decl, options);
8742 });
8743 sb.emitHelper(node, options, sb.helpers.processStatements({
8744 createScope: false
8745 }));
8746 node.getExportDeclarations().forEach(decl => {
8747 sb.visit(decl, options);
8748 });
8749 node.getExportAssignments().forEach(assignment => {
8750 sb.visit(assignment, options);
8751 });
8752 }
8753
8754}
8755
8756var file = [SourceFileCompiler];
8757
8758class BlockCompiler extends NodeCompiler {
8759 constructor(...args) {
8760 var _temp;
8761
8762 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.Block), _temp;
8763 }
8764
8765 visitNode(sb, expr, options) {
8766 sb.emitHelper(expr, options, sb.helpers.processStatements({
8767 createScope: true
8768 }));
8769 }
8770
8771}
8772
8773class BreakStatementCompiler extends NodeCompiler {
8774 constructor(...args) {
8775 var _temp;
8776
8777 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.BreakStatement), _temp;
8778 }
8779
8780 visitNode(sb, node, options) {
8781 const label = node.getLabel();
8782
8783 if (label != null) {
8784 sb.reportUnsupported(label);
8785 }
8786
8787 if (options.breakPC == null) {
8788 sb.reportError(node, 'Something went wrong. Expected a break jump location.', DiagnosticCode.SOMETHING_WENT_WRONG);
8789 } else {
8790 sb.emitPushInt(node, BREAK_COMPLETION);
8791 sb.emitJmp(node, 'JMP', options.breakPC);
8792 }
8793 }
8794
8795}
8796
8797class CaseBlockCompiler extends NodeCompiler {
8798 constructor(...args) {
8799 var _temp;
8800
8801 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.CaseBlock), _temp;
8802 }
8803
8804 visitNode(sb, node, options) {
8805 node.getClauses().forEach(clause => {
8806 sb.visit(clause, options);
8807 });
8808 }
8809
8810}
8811
8812class CaseClauseCompiler extends NodeCompiler {
8813 constructor(...args) {
8814 var _temp;
8815
8816 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.CaseClause), _temp;
8817 }
8818
8819 visitNode(sb, node, options) {
8820 sb.reportUnsupported(node);
8821 }
8822
8823}
8824
8825class CatchClauseCompiler extends NodeCompiler {
8826 constructor(...args) {
8827 var _temp;
8828
8829 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.CatchClause), _temp;
8830 }
8831
8832 visitNode(sb, node, options) {
8833 const variable = node.getVariableDeclaration();
8834
8835 if (variable == null) {
8836 sb.visit(node.getBlock(), options);
8837 } else {
8838 sb.withScope(node, options, innerOptions => {
8839 sb.visit(variable, innerOptions);
8840 sb.visit(node.getBlock(), innerOptions);
8841 });
8842 }
8843 }
8844
8845}
8846
8847class ContinueStatementCompiler extends NodeCompiler {
8848 constructor(...args) {
8849 var _temp;
8850
8851 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ContinueStatement), _temp;
8852 }
8853
8854 visitNode(sb, node, options) {
8855 const label = node.getLabel();
8856
8857 if (label != null) {
8858 sb.reportUnsupported(label);
8859 }
8860
8861 if (options.continuePC == null) {
8862 sb.reportError(node, 'Something went wrong. Expected a continue jump location.', DiagnosticCode.SOMETHING_WENT_WRONG);
8863 } else {
8864 sb.emitPushInt(node, CONTINUE_COMPLETION);
8865 sb.emitJmp(node, 'JMP', options.continuePC);
8866 }
8867 }
8868
8869}
8870
8871class DebuggerStatementCompiler extends NodeCompiler {
8872 constructor(...args) {
8873 var _temp;
8874
8875 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.DebuggerStatement), _temp;
8876 }
8877
8878 visitNode(sb, node, options) {
8879 sb.reportUnsupported(node);
8880 }
8881
8882}
8883
8884class DefaultClauseCompiler extends NodeCompiler {
8885 constructor(...args) {
8886 var _temp;
8887
8888 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.DefaultClause), _temp;
8889 }
8890
8891 visitNode(sb, node, options) {
8892 sb.emitOp(node, 'DROP');
8893 sb.emitHelper(node, options, sb.helpers.processStatements({
8894 createScope: false
8895 }));
8896 }
8897
8898}
8899
8900class DoStatementCompiler extends NodeCompiler {
8901 constructor(...args) {
8902 var _temp;
8903
8904 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.DoStatement), _temp;
8905 }
8906
8907 visitNode(sb, node, options) {
8908 sb.withProgramCounter(pc => {
8909 sb.withProgramCounter(innerPC => {
8910 sb.visit(node.getStatement(), sb.breakPCOptions(sb.continuePCOptions(options, innerPC.getLast()), pc.getLast()));
8911 });
8912 sb.emitHelper(node.getExpression(), options, sb.helpers.if({
8913 condition: () => {
8914 sb.visit(node.getExpression(), sb.pushValueOptions(options));
8915 },
8916 whenTrue: () => {
8917 sb.emitJmp(node, 'JMP', pc.getFirst());
8918 }
8919 }));
8920 });
8921 }
8922
8923}
8924
8925class EmptyStatementCompiler extends NodeCompiler {
8926 constructor(...args) {
8927 var _temp;
8928
8929 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.EmptyStatement), _temp;
8930 }
8931
8932 visitNode(sb, node, options) {// tslint:disable-line
8933 }
8934
8935}
8936
8937class ExpressionStatementCompiler extends NodeCompiler {
8938 constructor(...args) {
8939 var _temp;
8940
8941 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ExpressionStatement), _temp;
8942 }
8943
8944 visitNode(sb, node, options) {
8945 sb.visit(node.getExpression(), sb.noPushValueOptions(options));
8946 }
8947
8948}
8949
8950class ForInStatementCompiler extends NodeCompiler {
8951 constructor(...args) {
8952 var _temp;
8953
8954 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ForInStatement), _temp;
8955 }
8956
8957 visitNode(sb, node, options) {
8958 sb.reportUnsupported(node);
8959 }
8960
8961}
8962
8963class ForOfStatementCompiler extends NodeCompiler {
8964 constructor(...args) {
8965 var _temp;
8966
8967 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ForOfStatement), _temp;
8968 }
8969
8970 visitNode(sb, node, options) {
8971 sb.reportUnsupported(node);
8972 }
8973
8974}
8975
8976class ForStatementCompiler extends NodeCompiler {
8977 constructor(...args) {
8978 var _temp;
8979
8980 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ForStatement), _temp;
8981 }
8982
8983 visitNode(sb, node, options) {
8984 let initializer;
8985 const exprInitializer = node.getInitializer();
8986
8987 if (exprInitializer != null) {
8988 initializer = () => {
8989 sb.visit(exprInitializer, sb.noPushValueOptions(options));
8990 };
8991 }
8992
8993 let condition;
8994 const exprCondition = node.getCondition();
8995
8996 if (exprCondition != null) {
8997 condition = () => {
8998 sb.visit(exprCondition, sb.pushValueOptions(options));
8999 sb.emitHelper(exprCondition, sb.pushValueOptions(options), sb.helpers.toBoolean({
9000 type: sb.getType(exprCondition)
9001 }));
9002 };
9003 }
9004
9005 let incrementor;
9006 const exprIncrementor = node.getIncrementor();
9007
9008 if (exprIncrementor != null) {
9009 incrementor = () => {
9010 sb.visit(exprIncrementor, sb.noPushValueOptions(options));
9011 };
9012 }
9013
9014 sb.emitHelper(node, options, sb.helpers.forLoop({
9015 initializer,
9016 condition,
9017 incrementor,
9018 each: innerOptions => {
9019 sb.visit(node.getStatement(), sb.noPushValueOptions(innerOptions));
9020 }
9021 }));
9022 }
9023
9024}
9025
9026class IfStatementCompiler extends NodeCompiler {
9027 constructor(...args) {
9028 var _temp;
9029
9030 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.IfStatement), _temp;
9031 }
9032
9033 visitNode(sb, node, options) {
9034 const condition = () => {
9035 const cond = node.getExpression();
9036 sb.visit(cond, sb.pushValueOptions(options));
9037 sb.emitHelper(cond, sb.pushValueOptions(options), sb.helpers.toBoolean({
9038 type: sb.getType(cond)
9039 }));
9040 };
9041
9042 const whenTrue = () => {
9043 sb.visit(node.getThenStatement(), options);
9044 };
9045
9046 let whenFalse;
9047 const nodeWhenFalse = node.getElseStatement();
9048
9049 if (nodeWhenFalse != null) {
9050 whenFalse = () => {
9051 sb.visit(nodeWhenFalse, options);
9052 };
9053 }
9054
9055 sb.emitHelper(node, options, sb.helpers.if({
9056 condition,
9057 whenTrue,
9058 whenFalse
9059 }));
9060 }
9061
9062}
9063
9064class LabeledStatementCompiler extends NodeCompiler {
9065 constructor(...args) {
9066 var _temp;
9067
9068 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.LabeledStatement), _temp;
9069 }
9070
9071 visitNode(sb, node, options) {
9072 sb.reportUnsupported(node);
9073 }
9074
9075}
9076
9077class NotEmittedStatementCompiler extends NodeCompiler {
9078 constructor(...args) {
9079 var _temp;
9080
9081 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.NotEmittedStatement), _temp;
9082 }
9083
9084 visitNode(sb, node, options) {
9085 sb.reportUnsupported(node);
9086 }
9087
9088}
9089
9090class ReturnStatementCompiler extends NodeCompiler {
9091 constructor(...args) {
9092 var _temp;
9093
9094 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ReturnStatement), _temp;
9095 }
9096
9097 visitNode(sb, node, options) {
9098 const expr = node.getExpression();
9099
9100 if (expr == null) {
9101 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createUndefined);
9102 } else {
9103 sb.visit(expr, sb.pushValueOptions(options));
9104 }
9105
9106 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createNormalCompletion);
9107 sb.emitOp(node, 'RET');
9108 }
9109
9110}
9111
9112class SwitchStatementCompiler extends NodeCompiler {
9113 constructor(...args) {
9114 var _temp;
9115
9116 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.SwitchStatement), _temp;
9117 }
9118
9119 visitNode(sb, node, options) {
9120 sb.withProgramCounter(pc => {
9121 sb.visit(node.getExpression(), sb.pushValueOptions(options));
9122 sb.visit(node.getCaseBlock(), sb.breakPCOptions(options, pc.getLast()));
9123 });
9124 }
9125
9126}
9127
9128class ThrowStatementCompiler extends NodeCompiler {
9129 constructor(...args) {
9130 var _temp;
9131
9132 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ThrowStatement), _temp;
9133 }
9134
9135 visitNode(sb, node, options) {
9136 const expr = node.getExpression();
9137 sb.visit(expr, sb.pushValueOptions(options));
9138 sb.emitHelper(node, options, sb.helpers.throw);
9139 }
9140
9141}
9142
9143class TryStatementCompiler extends NodeCompiler {
9144 constructor(...args) {
9145 var _temp;
9146
9147 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.TryStatement), _temp;
9148 }
9149
9150 visitNode(sb, node, options) {
9151 const catchClause = node.getCatchClause();
9152
9153 if (catchClause == null) {
9154 sb.visit(node.getTryBlock(), options);
9155 } else {
9156 sb.withProgramCounter(pc => {
9157 sb.withProgramCounter(innerPC => {
9158 sb.visit(node.getTryBlock(), sb.catchPCOptions(options, innerPC.getLast()));
9159 sb.emitJmp(node, 'JMP', pc.getLast());
9160 });
9161 sb.visit(catchClause, options);
9162 });
9163 }
9164
9165 const finallyBlock = node.getFinallyBlock();
9166
9167 if (finallyBlock != null) {
9168 sb.reportUnsupported(finallyBlock);
9169 }
9170 }
9171
9172}
9173
9174class VariableStatementCompiler extends NodeCompiler {
9175 constructor(...args) {
9176 var _temp;
9177
9178 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.VariableStatement), _temp;
9179 }
9180
9181 visitNode(sb, node, optionsIn) {
9182 sb.visit(node.getDeclarationList(), optionsIn);
9183
9184 if (node.isNamedExport()) {
9185 const options = sb.pushValueOptions(optionsIn); // [exports]
9186
9187 sb.emitHelper(node, options, sb.helpers.getCurrentModule);
9188 node.getDeclarationList().getDeclarations().forEach(decl => {
9189 // [exports, exports]
9190 sb.emitOp(node, 'DUP'); // [val, exports, exports]
9191
9192 sb.scope.get(sb, node, options, decl.getName()); // [exports]
9193
9194 sb.emitHelper(node, options, sb.helpers.export({
9195 name: decl.getName()
9196 }));
9197 }); // []
9198
9199 sb.emitOp(node, 'DROP');
9200 }
9201 }
9202
9203}
9204
9205class WhileStatementCompiler extends NodeCompiler {
9206 constructor(...args) {
9207 var _temp;
9208
9209 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.WhileStatement), _temp;
9210 }
9211
9212 visitNode(sb, node, options) {
9213 sb.withProgramCounter(pc => {
9214 sb.visit(node.getExpression(), sb.pushValueOptions(options));
9215 sb.emitJmp(node, 'JMPIFNOT', pc.getLast());
9216 sb.visit(node.getStatement(), sb.breakPCOptions(sb.continuePCOptions(options, pc.getFirst()), pc.getLast()));
9217 sb.emitJmp(node, 'JMP', pc.getFirst());
9218 });
9219 }
9220
9221}
9222
9223class WithStatementCompiler extends NodeCompiler {
9224 constructor(...args) {
9225 var _temp;
9226
9227 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.WithStatement), _temp;
9228 }
9229
9230 visitNode(sb, node, options) {
9231 sb.reportUnsupported(node);
9232 }
9233
9234}
9235
9236var statement = [BlockCompiler, BreakStatementCompiler, CaseBlockCompiler, CaseClauseCompiler, CatchClauseCompiler, ContinueStatementCompiler, DebuggerStatementCompiler, DefaultClauseCompiler, DoStatementCompiler, EmptyStatementCompiler, ExpressionStatementCompiler, ForInStatementCompiler, ForOfStatementCompiler, ForStatementCompiler, IfStatementCompiler, LabeledStatementCompiler, NotEmittedStatementCompiler, ReturnStatementCompiler, SwitchStatementCompiler, ThrowStatementCompiler, TryStatementCompiler, VariableStatementCompiler, WhileStatementCompiler, WithStatementCompiler];
9237
9238const MAX_JUMP = 32767;
9239const JUMP_OFFSET = 20000;
9240
9241class CodePoint {
9242 constructor() {
9243 _defineProperty(this, "length", void 0);
9244
9245 _defineProperty(this, "sources", new Set());
9246
9247 _defineProperty(this, "pcInternal", void 0);
9248
9249 _defineProperty(this, "prevInternal", void 0);
9250
9251 _defineProperty(this, "nextInternal", void 0);
9252 }
9253
9254 get pc() {
9255 return this.resolvePC();
9256 }
9257
9258 resolvePC() {
9259 if (this.pcInternal == null) {
9260 this.pcInternal = 0;
9261
9262 if (this.prev == null) {
9263 this.pcInternal = 0;
9264 } else {
9265 this.pcInternal = this.prev.pc + this.prev.length;
9266 }
9267 }
9268
9269 return this.pcInternal;
9270 }
9271
9272 resetPC() {
9273 if (this.pcInternal != null) {
9274 this.pcInternal = undefined;
9275 let next = this.next;
9276
9277 while (next != null) {
9278 next.pcInternal = undefined;
9279 next = next.next;
9280 }
9281 }
9282 }
9283
9284 get totalLength() {
9285 let length = this.length;
9286 let next = this.next;
9287
9288 while (next != null) {
9289 length += next.length;
9290 next = next.next;
9291 }
9292
9293 return length;
9294 }
9295
9296 get prev() {
9297 return this.prevInternal;
9298 }
9299
9300 set prev(prev) {
9301 this.resetPC();
9302 this.prevInternal = prev;
9303 }
9304
9305 get next() {
9306 return this.nextInternal;
9307 }
9308
9309 set next(next) {
9310 this.nextInternal = next;
9311 }
9312
9313 insertJumps(targets) {
9314 let self = this;
9315 let skipJump = false;
9316 let ret = this;
9317
9318 while (self != null) {
9319 const target = targets[0];
9320
9321 if (target == null) {
9322 return ret;
9323 }
9324
9325 let length = 0;
9326
9327 if (self.next != null && !skipJump) {
9328 length = 3;
9329 }
9330
9331 let next = self.next;
9332 let nextSkipJump = false;
9333
9334 if (target.isMax && self.pc + self.length + length > target.pc + target.getPostOffset() || !target.isMax && self.pc >= target.pc + target.getPostOffset() - length) {
9335 next = self;
9336
9337 if (skipJump) {
9338 const resolved = target.resolve();
9339 self.insertBefore(resolved);
9340
9341 if (self === this) {
9342 ret = resolved;
9343 }
9344 } else {
9345 const resolved = target.resolve();
9346 const jump = new JumpCodePoint('JMP', self);
9347 self.insertBefore(jump);
9348 jump.insertAfter(resolved);
9349
9350 if (self === this) {
9351 ret = resolved;
9352 }
9353 }
9354
9355 nextSkipJump = true;
9356 targets.shift();
9357 }
9358
9359 self = next;
9360 skipJump = nextSkipJump;
9361 }
9362
9363 if (targets.length > 0) {
9364 throw new Error(`Failed to insert all targets. Something went wrong. Remaining: ${targets.length}`);
9365 }
9366
9367 return ret;
9368 }
9369
9370 insertBefore(point) {
9371 if (this.prev != null) {
9372 this.prev.next = point;
9373 point.prev = this.prev;
9374 }
9375
9376 this.prev = point;
9377 point.next = this;
9378 }
9379
9380 insertAfter(point) {
9381 if (this.next != null) {
9382 this.next.prev = point;
9383 point.next = this.next;
9384 }
9385
9386 this.next = point;
9387 point.prev = this;
9388 }
9389
9390 replace(point) {
9391 if (this.prev != null) {
9392 this.prev.next = point;
9393 point.prevInternal = this.prev;
9394 }
9395
9396 if (this.next != null) {
9397 if (point.length === this.length) {
9398 this.next.prevInternal = point;
9399 } else {
9400 this.next.prev = point;
9401 }
9402
9403 point.next = this.next;
9404 }
9405 }
9406
9407}
9408
9409class JumpCodePoint extends CodePoint {
9410 constructor(type, targetInternal) {
9411 super();
9412 this.type = type;
9413 this.targetInternal = targetInternal;
9414
9415 _defineProperty(this, "length", 3);
9416 }
9417
9418 get target() {
9419 if (this.targetInternal == null) {
9420 throw new Error('Target not set');
9421 }
9422
9423 return this.targetInternal;
9424 }
9425
9426 set target(target) {
9427 this.targetInternal = target;
9428 }
9429
9430 get isForwardJump() {
9431 return this.target.pc > this.pc;
9432 }
9433
9434 get isReverseJump() {
9435 return this.target.pc < this.pc;
9436 }
9437
9438 get offset() {
9439 if (this.target.pc === this.pc) {
9440 throw new Error('Something went wrong. Found equal target pc and current pc.');
9441 }
9442
9443 return this.target.pc - this.pc;
9444 }
9445
9446}
9447
9448class BufferCodePoint extends CodePoint {
9449 constructor(value) {
9450 super();
9451 this.value = value;
9452
9453 _defineProperty(this, "length", void 0);
9454
9455 this.length = value.length;
9456 }
9457
9458}
9459
9460class NewJump {
9461 constructor(pc, isMax, target) {
9462 this.pc = pc;
9463 this.isMax = isMax;
9464 this.target = target;
9465
9466 _defineProperty(this, "length", 3);
9467
9468 _defineProperty(this, "sourceInternal", void 0);
9469
9470 _defineProperty(this, "internalPostOffset", void 0);
9471 }
9472
9473 get source() {
9474 if (this.sourceInternal == null) {
9475 throw new Error('NewJump source is not set');
9476 }
9477
9478 return this.sourceInternal;
9479 }
9480
9481 set source(source) {
9482 this.sourceInternal = source;
9483 }
9484
9485 resolve() {
9486 const jump = new JumpCodePoint('JMP', this.target);
9487 this.source.target = jump;
9488
9489 if (this.target instanceof NewJump) {
9490 this.target.source = jump;
9491 } else {
9492 this.target.sources.add(jump);
9493 }
9494
9495 if (this.source instanceof JumpCodePoint) {
9496 jump.sources.add(this.source);
9497 }
9498
9499 return jump;
9500 }
9501
9502 get isForwardJump() {
9503 return this.isMax;
9504 }
9505
9506 get isReverseJump() {
9507 return !this.isMax;
9508 }
9509
9510 get offset() {
9511 if (this.target.pc === this.pc) {
9512 throw new Error('Something went wrong. Found equal target pc and current pc.');
9513 }
9514
9515 return this.target.pc - this.pc;
9516 }
9517
9518 getPostOffset() {
9519 if (this.internalPostOffset == null) {
9520 throw new Error('Not resolved');
9521 }
9522
9523 return this.internalPostOffset;
9524 }
9525
9526 resolvePostOffset(targets) {
9527 const sourcePC = this.source.pc;
9528
9529 if (this.isMax) {
9530 this.internalPostOffset = targets.filter(target => sourcePC < target.pc && target.pc < this.pc).reduce(acc => acc - 6, 0);
9531 } else {
9532 this.internalPostOffset = targets.filter(target => this.pc < target.pc && target.pc < sourcePC).reduce(acc => acc + 6, 0);
9533 }
9534 }
9535
9536}
9537
9538class JumpResolver {
9539 process(bytecode) {
9540 let first = this.getCodePoint(bytecode);
9541 let newTargets = [];
9542
9543 do {
9544 this.resolvePC(first);
9545 const result = this.processOne(first);
9546 first = result[0];
9547 newTargets = result[1];
9548
9549 const sortedNewTargets = _.sortBy(newTargets, target => target.pc);
9550
9551 sortedNewTargets.forEach(target => target.resolvePostOffset(sortedNewTargets));
9552 first = first.insertJumps(sortedNewTargets);
9553 } while (newTargets.length > 0);
9554
9555 this.resolvePC(first);
9556 let current = first;
9557 const out = [];
9558
9559 while (current != null) {
9560 if (current instanceof JumpCodePoint) {
9561 const pc = new KnownProgramCounter(current.target.pc);
9562
9563 if (current.type === 'CALL') {
9564 out.push(new Call(pc));
9565 } else {
9566 out.push(new Jmp(current.type, pc));
9567 }
9568 } else if (current instanceof BufferCodePoint) {
9569 out.push(current.value);
9570 } else {
9571 throw new Error('Something went wrong.');
9572 }
9573
9574 current = current.next;
9575 }
9576
9577 return out;
9578 }
9579
9580 processOne(codePoint) {
9581 const newTargets = [];
9582 let ret = codePoint;
9583 let value = codePoint;
9584
9585 while (value != null) {
9586 if (value instanceof JumpCodePoint) {
9587 const result = this.getTarget(value);
9588
9589 if (result == null) {
9590 value = value.next;
9591 } else {
9592 const [newValue, newValueTargets] = result;
9593 value.replace(newValue);
9594
9595 if (value === codePoint) {
9596 ret = newValue;
9597 }
9598
9599 newTargets.push(...newValueTargets);
9600 value = newValue.next;
9601 }
9602 } else {
9603 value = value.next;
9604 }
9605 }
9606
9607 return [ret, newTargets];
9608 }
9609
9610 getTarget(value) {
9611 if (value.isForwardJump && value.offset > MAX_JUMP || value.isReverseJump && value.offset < -MAX_JUMP) {
9612 const isMax = value.isForwardJump;
9613 const newOffset = isMax ? JUMP_OFFSET : -JUMP_OFFSET;
9614
9615 if (value.target instanceof NewJump) {
9616 throw new Error('Something went wrong. Unexpected jump target.');
9617 }
9618
9619 const newValueTargets = this.getNewTarget(new NewJump(value.pc + newOffset, isMax, value.target));
9620 const newValueTarget = newValueTargets[0];
9621 const newValue = new JumpCodePoint(value.type, newValueTarget);
9622 newValueTarget.source = newValue;
9623 value.target.sources.delete(value);
9624 [...value.sources].forEach(source => {
9625 source.target = newValue;
9626 newValue.sources.add(source);
9627 });
9628 return [newValue, newValueTargets];
9629 }
9630
9631 return undefined;
9632 }
9633
9634 getNewTarget(value) {
9635 if (value.isForwardJump && value.offset > MAX_JUMP || value.isReverseJump && value.offset < -MAX_JUMP) {
9636 const isMax = value.isForwardJump;
9637 const newOffset = isMax ? JUMP_OFFSET : -JUMP_OFFSET;
9638
9639 if (value.target instanceof NewJump) {
9640 throw new Error('Something went wrong. Unexpected jump target.');
9641 }
9642
9643 const newValueTarget = new NewJump(value.pc + newOffset, isMax, value.target);
9644 value.target = newValueTarget;
9645 newValueTarget.source = value;
9646 const newTargets = this.getNewTarget(newValueTarget);
9647 return [value].concat(newTargets);
9648 }
9649
9650 return [value];
9651 }
9652
9653 getCodePoint(bytecode) {
9654 const sources = {};
9655 const codePoints = {};
9656 const firstBytecode = bytecode[0];
9657 let first;
9658
9659 if (firstBytecode instanceof Jump) {
9660 const jumpCodePoint = new JumpCodePoint(firstBytecode.op);
9661 sources[firstBytecode.pc.getPC()] = [jumpCodePoint];
9662 first = jumpCodePoint;
9663 } else {
9664 first = new BufferCodePoint(firstBytecode);
9665 }
9666
9667 codePoints[0] = first;
9668 let pc = first.length;
9669 let prev = first;
9670
9671 for (const value of bytecode.slice(1)) {
9672 let codePoint;
9673
9674 if (value instanceof Jump) {
9675 const targetPC = value.pc.getPC();
9676 let jumpCodePoint;
9677
9678 if (targetPC < pc) {
9679 jumpCodePoint = new JumpCodePoint(value.op, codePoints[targetPC]);
9680 codePoints[targetPC].sources.add(jumpCodePoint);
9681 } else {
9682 jumpCodePoint = new JumpCodePoint(value.op);
9683
9684 if (sources[targetPC] == null) {
9685 sources[targetPC] = [];
9686 }
9687
9688 sources[targetPC].push(jumpCodePoint);
9689 }
9690
9691 codePoint = jumpCodePoint;
9692 } else {
9693 codePoint = new BufferCodePoint(value);
9694 }
9695
9696 const pcSources = sources[pc];
9697
9698 if (pcSources != null) {
9699 delete sources[pc];
9700 pcSources.forEach(source => {
9701 source.target = codePoint;
9702 codePoint.sources.add(source);
9703 });
9704 }
9705
9706 codePoints[pc] = codePoint;
9707 pc += codePoint.length;
9708 codePoint.prev = prev;
9709 prev.next = codePoint;
9710 prev = codePoint;
9711 }
9712
9713 return first;
9714 }
9715
9716 resolvePC(codePoint) {
9717 codePoint.resetPC();
9718 let current = codePoint;
9719
9720 while (current != null) {
9721 current.resolvePC();
9722 current = current.next;
9723 }
9724 }
9725
9726}
9727
9728const compilers = [declarations, decorator, expression, file, statement];
9729class BaseScriptBuilder {
9730 constructor(context, helpers, ast, sourceFile, allHelpers = []) {
9731 this.context = context;
9732 this.helpers = helpers;
9733 this.ast = ast;
9734 this.sourceFile = sourceFile;
9735 this.allHelpers = allHelpers;
9736
9737 _defineProperty(this, "jumpTable", new JumpTable());
9738
9739 _defineProperty(this, "currentScope", void 0);
9740
9741 _defineProperty(this, "compilers", void 0);
9742
9743 _defineProperty(this, "bytecode", void 0);
9744
9745 _defineProperty(this, "pc", void 0);
9746
9747 _defineProperty(this, "jumpTablePC", new DeferredProgramCounter());
9748
9749 _defineProperty(this, "capturedBytecode", undefined);
9750
9751 _defineProperty(this, "nodes", new Map());
9752
9753 _defineProperty(this, "moduleMap", {});
9754
9755 _defineProperty(this, "reverseModuleMap", {});
9756
9757 _defineProperty(this, "exportMap", {});
9758
9759 _defineProperty(this, "nextModuleIndex", 0);
9760
9761 _defineProperty(this, "currentModuleIndex", 0);
9762
9763 this.bytecode = [];
9764 this.pc = 0;
9765 this.currentScope = undefined;
9766 this.compilers = compilers.reduce((acc, kindCompilers) => acc.concat(kindCompilers), []).reduce((acc, KindCompiler) => {
9767 const kindCompiler = new KindCompiler();
9768
9769 if (acc[kindCompiler.kind] != null) {
9770 throw new Error(`Found duplicate compiler for kind ${kindCompiler.kind}`);
9771 }
9772
9773 acc[kindCompiler.kind] = kindCompiler;
9774 return acc;
9775 }, {});
9776 }
9777
9778 get scope() {
9779 if (this.currentScope == null) {
9780 throw new Error('Scope has not been set');
9781 }
9782
9783 return this.currentScope;
9784 }
9785
9786 get moduleIndex() {
9787 return this.currentModuleIndex;
9788 }
9789
9790 process() {
9791 const sourceFile = this.sourceFile;
9792 const {
9793 bytecode
9794 } = this.capture(() => {
9795 this.moduleMap[sourceFile.getFilePath()] = this.nextModuleIndex;
9796 this.reverseModuleMap[this.nextModuleIndex] = sourceFile.getFilePath();
9797 this.currentModuleIndex = this.nextModuleIndex;
9798 this.nextModuleIndex += 1;
9799 this.currentScope = this.createScope(sourceFile, 0, undefined);
9800 this.nodes.set(sourceFile, 0);
9801 const options = {};
9802 this.currentScope.emit(this, sourceFile, options, innerOptions => {
9803 // []
9804 this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.setGlobalObject); // [globalObjectVal]
9805
9806 this.scope.getGlobal(this, sourceFile, this.pushValueOptions(options)); // []
9807
9808 this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.addEmptyModule); // []
9809
9810 this.allHelpers.forEach(helper => {
9811 helper.emitGlobal(this, sourceFile, innerOptions);
9812 });
9813 this.visit(sourceFile, innerOptions);
9814 });
9815 });
9816 this.withProgramCounter(pc => {
9817 this.emitJmp(sourceFile, 'JMP', pc.getLast());
9818 this.jumpTablePC.setPC(pc.getCurrent());
9819 this.jumpTable.emitTable(this, sourceFile);
9820 });
9821 this.emitBytecode(bytecode);
9822 }
9823
9824 getFinalBytecode() {
9825 const bytecode = new JumpResolver().process(this.bytecode.map(([_$$1, value]) => value));
9826 let pc = 0;
9827 const buffers = bytecode.map(valueIn => {
9828 let value = valueIn;
9829
9830 if (value instanceof Jump) {
9831 const offsetPC = new BN(value.pc.getPC()).sub(new BN(pc)); // @ts-ignore
9832
9833 const jumpPC = offsetPC.toTwos(16);
9834 const byteCodeBuffer = BYTECODE_TO_BYTECODE_BUFFER[OPCODE_TO_BYTECODE[value.op]];
9835
9836 if (byteCodeBuffer == null) {
9837 throw new Error('Something went wrong, could not find bytecode buffer');
9838 }
9839
9840 value = Buffer.concat([byteCodeBuffer, jumpPC.toArrayLike(Buffer, 'le', 2)]);
9841 }
9842
9843 pc += value.length;
9844 return value;
9845 });
9846 return Buffer.concat(buffers);
9847 }
9848
9849 visit(node, options) {
9850 const compiler = this.compilers[node.compilerNode.kind];
9851
9852 if (compiler == null) {
9853 this.reportUnsupported(node);
9854 } else {
9855 compiler.visitNode(this, node, options);
9856 }
9857 }
9858
9859 withScope(node, options, func) {
9860 let index = this.nodes.get(node);
9861
9862 if (index == null) {
9863 index = 0;
9864 } else {
9865 index += 1;
9866 }
9867
9868 this.nodes.set(node, index);
9869 const currentScope = this.currentScope;
9870 this.currentScope = this.createScope(node, index, currentScope);
9871 this.currentScope.emit(this, node, options, func);
9872 this.currentScope = currentScope;
9873 }
9874
9875 withProgramCounter(func) {
9876 const pc = new ProgramCounterHelper(() => this.pc);
9877 func(pc);
9878 pc.setLast();
9879 }
9880
9881 emitOp(node, code, buffer) {
9882 const bytecode = OPCODE_TO_BYTECODE[code];
9883
9884 if (bytecode == null) {
9885 throw new UnknownOpError(code);
9886 }
9887
9888 this.emitOpByte(node, bytecode, buffer);
9889 }
9890
9891 emitPushInt(node, valueIn) {
9892 const value = new BN(valueIn);
9893
9894 if (value.eq(utils.NEGATIVE_ONE)) {
9895 return this.emitOp(node, 'PUSHM1');
9896 } else if (value.eq(utils.ZERO)) {
9897 return this.emitPush(node, utils.toSignedBuffer(value));
9898 } else if (value.gt(utils.ZERO) && value.lt(utils.SIXTEEN)) {
9899 return this.emitOpByte(node, OPCODE_TO_BYTECODE.PUSH1 - 1 + value.toNumber());
9900 }
9901
9902 return this.emitPush(node, utils.toSignedBuffer(value));
9903 }
9904
9905 emitPushBoolean(node, value) {
9906 this.emitOp(node, value ? 'PUSH1' : 'PUSH0');
9907 }
9908
9909 emitPushString(node, value) {
9910 return this.emitPush(node, this.toBuffer(value));
9911 }
9912
9913 emitJmp(node, code, pc) {
9914 this.emitJump(node, new Jmp(code, pc));
9915 }
9916
9917 emitHelper(node, options, helper) {
9918 helper.emit(this, node, options);
9919 }
9920
9921 emitBytecode(bytecode) {
9922 const pc = this.pc;
9923 bytecode.forEach(([node, code]) => {
9924 if (code instanceof Call) {
9925 this.emitJump(node, code);
9926 } else if (code instanceof Jmp) {
9927 this.emitJump(node, code.plus(pc));
9928 } else if (code instanceof Jump) {
9929 throw new Error('Something went wrong.');
9930 } else {
9931 this.emitRaw(node, code);
9932 }
9933 });
9934 }
9935
9936 emitCall(node) {
9937 this.emitJump(node, new Call(this.jumpTablePC));
9938 }
9939
9940 emitSysCall(node, name) {
9941 const sysCallBuffer = Buffer.from(name, 'ascii');
9942 const writer = new BinaryWriter();
9943 writer.writeVarBytesLE(sysCallBuffer);
9944 this.emitOp(node, 'SYSCALL', writer.toBuffer());
9945 }
9946
9947 loadModule(sourceFile) {
9948 const options = {};
9949 let moduleIndex = this.moduleMap[sourceFile.getFilePath()];
9950
9951 if (moduleIndex == null) {
9952 moduleIndex = this.nextModuleIndex;
9953 this.nextModuleIndex += 1;
9954 this.moduleMap[sourceFile.getFilePath()] = moduleIndex;
9955 this.reverseModuleMap[moduleIndex] = sourceFile.getFilePath();
9956 const currentScope = this.currentScope;
9957 this.currentScope = this.createScope(sourceFile, 0, undefined);
9958 const currentModuleIndex = this.currentModuleIndex;
9959 this.currentModuleIndex = moduleIndex; // [globalObjectVal]
9960
9961 this.scope.getGlobal(this, sourceFile, this.pushValueOptions(options)); // [globalObjectVal, globalObjectVal]
9962
9963 this.emitOp(sourceFile, 'DUP'); // [globalObjectVal]
9964
9965 this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.addEmptyModule);
9966 this.currentScope.emit(this, sourceFile, options, innerOptions => {
9967 // []
9968 this.scope.setGlobal(this, sourceFile, options);
9969 this.visit(sourceFile, innerOptions);
9970 });
9971 this.currentScope = currentScope;
9972 this.currentModuleIndex = currentModuleIndex;
9973 } // [globalObjectVal]
9974
9975
9976 this.scope.getGlobal(this, sourceFile, this.pushValueOptions(options)); // [exports]
9977
9978 this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.getModule({
9979 moduleIndex
9980 }));
9981 }
9982
9983 capture(func) {
9984 const originalCapturedBytecode = this.capturedBytecode;
9985 this.capturedBytecode = [];
9986 const originalPC = this.pc;
9987 this.pc = 0;
9988 func();
9989 const capturedBytecode = this.capturedBytecode;
9990 this.capturedBytecode = originalCapturedBytecode;
9991 const capturedLength = this.pc;
9992 this.pc = originalPC;
9993 return {
9994 length: capturedLength,
9995 bytecode: capturedBytecode
9996 };
9997 }
9998
9999 toBuffer(value) {
10000 return Buffer.from(value, 'utf8');
10001 }
10002
10003 plainOptions(options) {
10004 return _objectSpread({}, options, {
10005 pushValue: false,
10006 setValue: false,
10007 catchPC: undefined
10008 });
10009 }
10010
10011 pushValueOptions(options) {
10012 return _objectSpread({}, options, {
10013 pushValue: true
10014 });
10015 }
10016
10017 noPushValueOptions(options) {
10018 return _objectSpread({}, options, {
10019 pushValue: false
10020 });
10021 }
10022
10023 setValueOptions(options) {
10024 return _objectSpread({}, options, {
10025 setValue: true
10026 });
10027 }
10028
10029 noSetValueOptions(options) {
10030 return _objectSpread({}, options, {
10031 setValue: false
10032 });
10033 }
10034
10035 noValueOptions(options) {
10036 return _objectSpread({}, options, {
10037 pushValue: false,
10038 setValue: false
10039 });
10040 }
10041
10042 breakPCOptions(options, pc) {
10043 return _objectSpread({}, options, {
10044 breakPC: pc
10045 });
10046 }
10047
10048 continuePCOptions(options, pc) {
10049 return _objectSpread({}, options, {
10050 continuePC: pc
10051 });
10052 }
10053
10054 catchPCOptions(options, pc) {
10055 return _objectSpread({}, options, {
10056 catchPC: pc
10057 });
10058 }
10059
10060 castOptions(options, cast) {
10061 return _objectSpread({}, options, {
10062 cast
10063 });
10064 }
10065
10066 noCastOptions(options) {
10067 return _objectSpread({}, options, {
10068 cast: undefined
10069 });
10070 }
10071
10072 superClassOptions(options, superClass) {
10073 return _objectSpread({}, options, {
10074 superClass
10075 });
10076 }
10077
10078 noSuperClassOptions(options) {
10079 return _objectSpread({}, options, {
10080 superClass: undefined
10081 });
10082 }
10083
10084 reportError(node, message, code) {
10085 this.context.reportError(node, message, code);
10086 }
10087
10088 reportUnsupported(node) {
10089 this.context.reportUnsupported(node);
10090 }
10091
10092 getType(node, required = false) {
10093 return this.context.getType(node, required);
10094 }
10095
10096 getSymbol(node, required = false) {
10097 return this.context.getSymbol(node, required);
10098 }
10099
10100 isOnlyGlobal(node, type, name) {
10101 return this.context.isOnlyGlobal(node, type, name);
10102 }
10103
10104 isGlobal(node, type, name) {
10105 return this.context.isGlobal(node, type, name);
10106 }
10107
10108 isGlobalSymbol(node, symbol, name) {
10109 return this.context.isGlobalSymbol(node, symbol, name);
10110 }
10111
10112 hasExport(sourceFile, name) {
10113 return (this.exportMap[sourceFile.getFilePath()] || new Set()).has(name);
10114 }
10115
10116 addExport(name) {
10117 const filePath = this.assertNotNull(this.reverseModuleMap[this.currentModuleIndex]);
10118 let fileExports = this.exportMap[filePath];
10119
10120 if (fileExports == null) {
10121 fileExports = new Set();
10122 this.exportMap[filePath] = fileExports;
10123 }
10124
10125 fileExports.add(name);
10126 }
10127
10128 assertUnreachable(value) {
10129 throw new Error('Should not be reached.');
10130 }
10131
10132 assertNotNull(value) {
10133 return this.context.assertNotNull(value);
10134 }
10135
10136 filterNotNull(value) {
10137 return value != null;
10138 }
10139
10140 emitPush(node, value) {
10141 if (value.length <= OPCODE_TO_BYTECODE.PUSHBYTES75) {
10142 this.emitOpByte(node, value.length, value);
10143 } else if (value.length < 0x100) {
10144 this.emitOp(node, 'PUSHDATA1', new ScriptBuilder().emitUInt8(value.length).emit(value).build());
10145 } else if (value.length < 0x10000) {
10146 this.emitOp(node, 'PUSHDATA2', new ScriptBuilder().emitUInt16LE(value.length).emit(value).build());
10147 } else if (value.length < 0x100000000) {
10148 this.emitOp(node, 'PUSHDATA4', new ScriptBuilder().emitUInt32LE(value.length).emit(value).build());
10149 } else {
10150 throw new Error('Value too large.');
10151 }
10152 }
10153
10154 emitOpByte(node, byteCodeIn, buffer) {
10155 const byteCode = `${byteCodeIn == null ? '' : byteCodeIn}`;
10156 const byteCodeBuffer = BYTECODE_TO_BYTECODE_BUFFER[byteCode];
10157
10158 if (byteCodeBuffer == null) {
10159 throw new UnknownOpError(byteCode);
10160 }
10161
10162 let value = byteCodeBuffer;
10163
10164 if (buffer != null) {
10165 value = Buffer.concat([byteCodeBuffer, buffer]);
10166 }
10167
10168 this.emitRaw(node, value);
10169 }
10170
10171 emitRaw(node, value) {
10172 this.push(node, value);
10173 this.pc += value.length;
10174 }
10175
10176 emitJump(node, jump) {
10177 this.push(node, jump);
10178 this.pc += 3;
10179 }
10180
10181 push(node, value) {
10182 if (this.capturedBytecode != null) {
10183 this.capturedBytecode.push([node, value]);
10184 } else {
10185 this.bytecode.push([node, value]);
10186 }
10187 }
10188
10189}
10190
10191class IdentifierName {
10192 constructor(value) {
10193 this.value = value;
10194
10195 _defineProperty(this, "nameBrand", 0);
10196 }
10197
10198}
10199
10200class ResolvedScope {
10201 constructor(variableCount, parent) {
10202 this.variableCount = variableCount;
10203 this.parent = parent;
10204
10205 _defineProperty(this, "position", 0);
10206
10207 _defineProperty(this, "variables", {});
10208
10209 _defineProperty(this, "uniqueVariables", new Map());
10210
10211 _defineProperty(this, "scopeLength", void 0);
10212
10213 _defineProperty(this, "addScope", void 0);
10214
10215 _defineProperty(this, "scopeCount", void 0);
10216
10217 if (this.parent == null) {
10218 this.addScope = true;
10219 this.scopeCount = 1;
10220 this.scopeLength = 1;
10221 } else {
10222 this.addScope = variableCount > 0;
10223 this.scopeCount = this.addScope ? 1 : 0;
10224 this.scopeLength = this.parent.scopeLength + this.scopeCount;
10225 }
10226 }
10227
10228 add(name) {
10229 const identifier = new IdentifierName(name);
10230 const existing = this.variables[name];
10231
10232 if (existing != null) {
10233 return identifier;
10234 }
10235
10236 this.variables[identifier.value] = this.position;
10237 this.position += 1;
10238
10239 if (this.position > this.variableCount) {
10240 throw new Error(`Something went wrong. Name: ${name} Position: ${this.position} Count: ${this.variableCount}`);
10241 }
10242
10243 return identifier;
10244 }
10245
10246 addUnique() {
10247 const name = {
10248 nameBrand: 0
10249 };
10250 this.uniqueVariables.set(name, this.position);
10251 this.position += 1;
10252
10253 if (this.position > this.variableCount) {
10254 throw new Error(`Something went wrong. Position: ${this.position} Count: ${this.variableCount}`);
10255 }
10256
10257 return name;
10258 } // [value]
10259
10260
10261 set(sb, node, optionsIn, name, scopeLength = this.scopeLength, scopePosition = 0) {
10262 const options = sb.pushValueOptions(optionsIn);
10263 const position = this.getPosition(name);
10264
10265 if (position == null) {
10266 if (this.parent == null) {
10267 sb.reportError(node, `Unknown reference: ${name}`, DiagnosticCode.REFERENCE_ERROR);
10268 } else {
10269 this.parent.set(sb, node, options, name, scopeLength, scopePosition + this.scopeCount);
10270 }
10271 } else {
10272 // [normal]
10273 sb.emitHelper(node, options, sb.helpers.createNormalCompletion); // [scope, normal]
10274
10275 this.loadScope(sb, node, scopeLength, scopePosition); // [position, scope, normal]
10276
10277 sb.emitPushInt(node, position); // [normal, position, scope]
10278
10279 sb.emitOp(node, 'ROT'); // []
10280
10281 sb.emitOp(node, 'SETITEM');
10282 }
10283 }
10284
10285 get(sb, node, options, name, scopeLength = this.scopeLength, scopePosition = 0) {
10286 const position = this.getPosition(name);
10287
10288 if (position == null) {
10289 if (this.parent == null) {
10290 if (typeof name === 'string' && sb.helpers.globalProperties.has(name)) {
10291 // [val]
10292 sb.emitHelper(node, options, sb.helpers.getGlobalProperty({
10293 property: name
10294 }));
10295 } else {
10296 sb.reportError(node, `Unknown reference: ${name}`, DiagnosticCode.REFERENCE_ERROR);
10297 }
10298 } else {
10299 this.parent.get(sb, node, options, name, scopeLength, scopePosition + this.scopeCount);
10300 }
10301 } else {
10302 this.loadScope(sb, node, scopeLength, scopePosition);
10303 sb.emitPushInt(node, position);
10304 sb.emitOp(node, 'PICKITEM');
10305 sb.emitHelper(node, options, sb.helpers.pickCompletionVal);
10306 }
10307 }
10308
10309 getThis(sb, node, options) {
10310 // [[scopes, this]]
10311 this.loadAll(sb, node); // [1, [scopes, this]]
10312
10313 sb.emitPushInt(node, 1); // [this]
10314
10315 sb.emitOp(node, 'PICKITEM');
10316 }
10317
10318 setThis(sb, node, options) {
10319 // [[scopes, this], val]
10320 this.loadAll(sb, node); // [1, [scopes, this], val]
10321
10322 sb.emitPushInt(node, 1); // [val, 1, [scopes, this]]
10323
10324 sb.emitOp(node, 'ROT'); // []
10325
10326 sb.emitOp(node, 'SETITEM');
10327 }
10328
10329 getGlobal(sb, node, options) {
10330 if (this.parent == null) {
10331 // [[scopes, this, global]]
10332 this.loadAll(sb, node); // [2, [scopes, this, global]]
10333
10334 sb.emitPushInt(node, 2); // [this]
10335
10336 sb.emitOp(node, 'PICKITEM');
10337 } else {
10338 this.parent.getGlobal(sb, node, options);
10339 }
10340 }
10341
10342 setGlobal(sb, node, options) {
10343 if (this.parent == null) {
10344 // [[scopes, this, global], val]
10345 this.loadAll(sb, node); // [[scopes, this, global], val, [scopes, this, global]]
10346
10347 sb.emitOp(node, 'TUCK'); // [val, [scopes, this, global], val, [scopes, this, global]]
10348
10349 sb.emitOp(node, 'OVER'); // [2, val, [scopes, this, global], val, [scopes, this, global]]
10350
10351 sb.emitPushInt(node, 2); // [val, 2, [scopes, this, global], val, [scopes, this, global]]
10352
10353 sb.emitOp(node, 'SWAP'); // [val, [scopes, this, global]]
10354
10355 sb.emitOp(node, 'SETITEM'); // [1, val, [scopes, this, global]]
10356
10357 sb.emitPushInt(node, 1); // [val, 1, [scopes, this, global]]
10358
10359 sb.emitOp(node, 'SWAP'); // []
10360
10361 sb.emitOp(node, 'SETITEM');
10362 } else {
10363 this.parent.setGlobal(sb, node, options);
10364 }
10365 }
10366
10367 hasBinding(name) {
10368 return this.variables[name] != null || this.parent != null && this.parent.hasBinding(name);
10369 }
10370
10371 pushAll(sb, node, options) {
10372 sb.emitOp(node, 'DUPFROMALTSTACK');
10373 }
10374
10375 emit(sb, node, options, func) {
10376 if (this.addScope) {
10377 this.surround(sb, node, options, func);
10378 } else {
10379 func(options);
10380 }
10381 }
10382
10383 surround(sb, node, options, func) {
10384 if (this.parent == null) {
10385 // [global]
10386 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createUndefined); // [this, global]
10387
10388 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createUndefined); // [0, this, global]
10389
10390 sb.emitPushInt(node, 0); // [scopes, this, global]
10391
10392 sb.emitOp(node, 'NEWSTRUCT'); // [3, scopes, this, global]
10393
10394 sb.emitPushInt(node, 3); // [[scopes, this, global]]
10395
10396 sb.emitOp(node, 'PACK'); // [[scopes, this, global], [scopes, this, global]]
10397
10398 sb.emitOp(node, 'DUP'); // [[scopes, this, global]]
10399
10400 sb.emitOp(node, 'TOALTSTACK');
10401 } else {
10402 // [[scopes, this]]
10403 sb.emitOp(node, 'DUPFROMALTSTACK');
10404 } // [0, [scopes, this]]
10405
10406
10407 sb.emitPushInt(node, 0); // [scopes]
10408
10409 sb.emitOp(node, 'PICKITEM'); // [0, scopes]
10410
10411 sb.emitPushInt(node, 0); // [scope, scopes]
10412
10413 sb.emitOp(node, 'NEWARRAY'); // [idx, scope, scopes]
10414
10415 sb.emitPushInt(node, 0);
10416 sb.withProgramCounter(loopPC => {
10417 // [idx, idx, scope, scopes]
10418 sb.emitOp(node, 'DUP'); // [count, idx, idx, scope, scopes]
10419
10420 sb.emitPushInt(node, this.variableCount); // [idx < count, idx, scope, scopes]
10421
10422 sb.emitOp(node, 'LT'); // [idx, scope, scopes]
10423
10424 sb.emitJmp(node, 'JMPIFNOT', loopPC.getLast()); // [scope, idx, scope, scopes]
10425
10426 sb.emitOp(node, 'OVER'); // [errorString, scope, idx, scope, scopes]
10427
10428 sb.emitPushString(node, 'Referenced variable before it was defined'); // [error, scope, idx, scope, scopes]
10429
10430 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createString); // [throw, scope, idx, scope, scopes]
10431
10432 sb.emitHelper(node, sb.pushValueOptions(options), sb.helpers.createThrowCompletion); // [idx, scope, scopes]
10433
10434 sb.emitOp(node, 'APPEND'); // [idx, scope, scopes]
10435
10436 sb.emitOp(node, 'INC'); // [idx, scope, scopes]
10437
10438 sb.emitJmp(node, 'JMP', loopPC.getFirst());
10439 }); // [scope, scopes]
10440
10441 sb.emitOp(node, 'DROP'); // []
10442
10443 sb.emitOp(node, 'APPEND');
10444 const {
10445 breakPC,
10446 continuePC,
10447 catchPC
10448 } = options;
10449 const nonLocal = breakPC != null || continuePC != null || catchPC != null;
10450 sb.withProgramCounter(pc => {
10451 let innerOptions = options;
10452
10453 if (breakPC != null) {
10454 innerOptions = sb.breakPCOptions(innerOptions, pc.getLast());
10455 }
10456
10457 if (continuePC != null) {
10458 innerOptions = sb.continuePCOptions(innerOptions, pc.getLast());
10459 }
10460
10461 if (catchPC != null) {
10462 innerOptions = sb.catchPCOptions(innerOptions, pc.getLast());
10463 }
10464
10465 func(innerOptions);
10466
10467 if (nonLocal) {
10468 sb.emitPushInt(node, NORMAL_COMPLETION);
10469 }
10470 });
10471
10472 if (this.parent == null) {
10473 // [[scopes, undefined]]
10474 sb.emitOp(node, 'FROMALTSTACK');
10475 sb.emitOp(node, 'DROP');
10476 } else {
10477 // [[scopes, undefined]]
10478 sb.emitOp(node, 'DUPFROMALTSTACK'); // [0, [scopes, undefined]]
10479
10480 sb.emitPushInt(node, 0); // [scopes]
10481
10482 sb.emitOp(node, 'PICKITEM'); // [scopes, scopes]
10483
10484 sb.emitOp(node, 'DUP'); // [size, scopes]
10485
10486 sb.emitOp(node, 'ARRAYSIZE'); // [size - 1, scopes]
10487
10488 sb.emitOp(node, 'DEC'); // []
10489
10490 sb.emitOp(node, 'REMOVE');
10491 }
10492
10493 this.emitNonLocal(sb, node, BREAK_COMPLETION, breakPC);
10494 this.emitNonLocal(sb, node, CONTINUE_COMPLETION, continuePC);
10495 this.emitNonLocal(sb, node, CATCH_COMPLETION, catchPC);
10496
10497 if (nonLocal) {
10498 sb.emitOp(node, 'DROP');
10499 }
10500 }
10501
10502 emitNonLocal(sb, node, completion, pc) {
10503 if (pc != null) {
10504 sb.withProgramCounter(innerPC => {
10505 sb.emitOp(node, 'DUP');
10506 sb.emitPushInt(node, completion);
10507 sb.emitOp(node, 'NUMEQUAL');
10508 sb.emitJmp(node, 'JMPIF', pc);
10509 });
10510 }
10511 }
10512
10513 getPosition(name) {
10514 if (typeof name === 'string') {
10515 return this.variables[name];
10516 } else if (name instanceof IdentifierName) {
10517 return this.variables[name.value];
10518 }
10519
10520 return this.uniqueVariables.get(name);
10521 }
10522
10523 loadScope(sb, node, scopeLength, scopePosition) {
10524 this.loadAll(sb, node); // [0,[scopes, this]]
10525
10526 sb.emitPushInt(node, 0); // [scopes]
10527
10528 sb.emitOp(node, 'PICKITEM'); // [scopeIndex, scopes]
10529
10530 sb.emitPushInt(node, scopeLength - scopePosition - 1); // [scope]
10531
10532 sb.emitOp(node, 'PICKITEM');
10533 }
10534
10535 loadAll(sb, node) {
10536 // [[scopes, this]]
10537 sb.emitOp(node, 'DUPFROMALTSTACK');
10538 }
10539
10540}
10541
10542class CapturingScope {
10543 constructor(node, index, parent) {
10544 this.node = node;
10545 this.index = index;
10546 this.parent = parent;
10547
10548 _defineProperty(this, "variableCount", 0);
10549
10550 _defineProperty(this, "bindings", new Set());
10551 }
10552
10553 add(name) {
10554 this.variableCount += 1;
10555 this.bindings.add(name);
10556 return {
10557 nameBrand: 0
10558 };
10559 }
10560
10561 addUnique() {
10562 this.variableCount += 1;
10563 return {
10564 nameBrand: 0
10565 };
10566 }
10567
10568 set(sb, node) {
10569 sb.emitOp(node, 'NOP');
10570 }
10571
10572 get(sb, node) {
10573 sb.emitOp(node, 'NOP');
10574 }
10575
10576 getThis(sb, node) {
10577 sb.emitOp(node, 'NOP');
10578 }
10579
10580 setThis(sb, node) {
10581 sb.emitOp(node, 'NOP');
10582 }
10583
10584 getGlobal(sb, node) {
10585 sb.emitOp(node, 'NOP');
10586 }
10587
10588 setGlobal(sb, node) {
10589 sb.emitOp(node, 'NOP');
10590 }
10591
10592 hasBinding(name) {
10593 return this.bindings.has(name) || this.parent != null && this.parent.hasBinding(name);
10594 }
10595
10596 pushAll(sb, node) {
10597 sb.emitOp(node, 'NOP');
10598 }
10599
10600 emit(sb, node, options, func) {
10601 sb.emitOp(node, 'NOP');
10602 func(options);
10603 sb.emitOp(node, 'NOP');
10604 }
10605
10606 resolve(parent) {
10607 return new ResolvedScope(this.variableCount, parent);
10608 }
10609
10610}
10611
10612class ScopeCapturingScriptBuilder extends BaseScriptBuilder {
10613 constructor(...args) {
10614 var _temp;
10615
10616 return _temp = super(...args), _defineProperty(this, "scopes", []), _defineProperty(this, "resolvedScopes", new Map()), _temp;
10617 }
10618
10619 process() {
10620 super.process();
10621 this.resolveScopes();
10622 }
10623
10624 getScopes() {
10625 return this.resolvedScopes;
10626 }
10627
10628 createScope(node, index, parent) {
10629 const scope = new CapturingScope(node, index, parent);
10630 this.scopes.push(scope);
10631 return scope;
10632 }
10633
10634 resolveScopes() {
10635 this.scopes.forEach(scope => {
10636 this.resolveScope(scope);
10637 });
10638 }
10639
10640 resolveScope(scope) {
10641 let forNode = this.resolvedScopes.get(scope.node);
10642
10643 if (forNode == null) {
10644 forNode = new Map();
10645 this.resolvedScopes.set(scope.node, forNode);
10646 }
10647
10648 let resolved = forNode.get(scope.index);
10649
10650 if (resolved == null) {
10651 const parent = scope.parent;
10652
10653 if (parent == null) {
10654 resolved = scope.resolve();
10655 } else {
10656 resolved = scope.resolve(this.resolveScope(parent));
10657 }
10658
10659 forNode.set(scope.index, resolved);
10660 }
10661
10662 return resolved;
10663 }
10664
10665}
10666
10667class EmittingScriptBuilder extends BaseScriptBuilder {
10668 constructor({
10669 context,
10670 scopes,
10671 helpers,
10672 ast,
10673 sourceFile,
10674 allHelpers
10675 }) {
10676 super(context, helpers, ast, sourceFile, allHelpers);
10677
10678 _defineProperty(this, "scopes", void 0);
10679
10680 this.scopes = scopes;
10681 }
10682
10683 createScope(node, index) {
10684 return this.assertNotNull(this.assertNotNull(this.scopes.get(node)).get(index));
10685 }
10686
10687}
10688
10689class HelperCapturingScriptBuilder extends ScopeCapturingScriptBuilder {
10690 constructor(...args) {
10691 var _temp;
10692
10693 return _temp = super(...args), _defineProperty(this, "capturedHelpersSet", new Set()), _defineProperty(this, "capturedHelpers", []), _temp;
10694 }
10695
10696 getHelpers() {
10697 return [...this.capturedHelpers];
10698 }
10699
10700 emitHelper(node, options, helper) {
10701 if (!this.capturedHelpersSet.has(helper)) {
10702 this.capturedHelpersSet.add(helper);
10703 this.capturedHelpers.push(helper);
10704 helper.emitGlobal(this, node, options);
10705 }
10706
10707 helper.emit(this, node, options);
10708 }
10709
10710}
10711
10712class CompilerDiagnostic {
10713 constructor(node, messageText, code, category) {
10714 this.node = node;
10715 this.messageText = messageText;
10716 this.code = code;
10717 this.category = category;
10718 }
10719
10720 get file() {
10721 return this.node.getSourceFile().compilerNode;
10722 }
10723
10724 get start() {
10725 return this.node.getStart();
10726 }
10727
10728 get length() {
10729 return this.node.getWidth();
10730 }
10731
10732 get source() {
10733 return this.node.getText();
10734 }
10735
10736}
10737
10738class Context {
10739 constructor(globals, libs, libAliases) {
10740 this.globals = globals;
10741 this.libs = libs;
10742 this.libAliases = libAliases;
10743
10744 _defineProperty(this, "diagnostics", []);
10745 }
10746
10747 reportError(node, message, code) {
10748 this.diagnostics.push(new CompilerDiagnostic(node, message, code, DiagnosticCategory.Error));
10749 }
10750
10751 reportWarning(node, message, code) {
10752 this.diagnostics.push(new CompilerDiagnostic(node, message, code, DiagnosticCategory.Warning));
10753 }
10754
10755 reportUnsupported(node) {
10756 this.reportError(node, 'Unsupported syntax', DiagnosticCode.UNSUPPORTED_SYNTAX);
10757 }
10758
10759 reportTypeError(node) {
10760 this.reportError(node, 'Could not infer type. Please add an explicit type annotation.', DiagnosticCode.UNKNOWN_TYPE);
10761 }
10762
10763 reportTypeWarning(node) {
10764 this.reportWarning(node, 'Could not infer type. Deoptimized implementation will be used. Add an explicit type annotation ' + 'to optimize the output.', DiagnosticCode.UNKNOWN_TYPE);
10765 }
10766
10767 getType(node, required = false) {
10768 let type = this.getNotAnyType(node.getType());
10769
10770 if (type == null && TypeGuards.isExpression(node)) {
10771 type = this.getNotAnyType(node.getContextualType());
10772 }
10773
10774 if (type == null) {
10775 if (required) {
10776 this.reportTypeError(node);
10777 } else {
10778 this.reportTypeWarning(node);
10779 }
10780 }
10781
10782 return type;
10783 }
10784
10785 getTypeOfSymbol(symbol, node, required = false) {
10786 if (symbol == null) {
10787 return undefined;
10788 }
10789
10790 const type = this.getNotAnyType(symbol.getTypeAtLocation(node));
10791
10792 if (type == null) {
10793 if (required) {
10794 this.reportTypeError(node);
10795 } else {
10796 this.reportTypeWarning(node);
10797 }
10798 }
10799
10800 return type;
10801 }
10802
10803 getSymbol(node, required = false) {
10804 const symbol = node.getSymbol();
10805
10806 if (symbol == null) {
10807 const message = 'Could not determine source symbol.';
10808
10809 if (required) {
10810 this.reportError(node, message, DiagnosticCode.UNKNOWN_SYMBOL);
10811 } else {
10812 this.reportWarning(node, message, DiagnosticCode.UNKNOWN_SYMBOL);
10813 }
10814
10815 return undefined;
10816 }
10817
10818 const aliased = symbol.getAliasedSymbol();
10819
10820 if (aliased != null) {
10821 return aliased;
10822 }
10823
10824 return symbol;
10825 }
10826
10827 getSymbolForType(node, type, required = false) {
10828 if (type == null) {
10829 return undefined;
10830 }
10831
10832 const symbol = type.getSymbol();
10833
10834 if (symbol == null) {
10835 const message = `Could not determine source symbol for type: ${type.getText()}.`;
10836
10837 if (required) {
10838 this.reportError(node, message, DiagnosticCode.UNKNOWN_SYMBOL);
10839 } else {
10840 this.reportWarning(node, message, DiagnosticCode.UNKNOWN_SYMBOL);
10841 }
10842
10843 return undefined;
10844 }
10845
10846 const aliased = symbol.getAliasedSymbol();
10847
10848 if (aliased != null) {
10849 return aliased;
10850 }
10851
10852 return symbol;
10853 }
10854
10855 assertUnreachable(value) {
10856 throw new Error('Should not be reached.');
10857 }
10858
10859 assertNotNull(value) {
10860 if (value == null) {
10861 throw new Error('Something went wrong. Unexpected null.');
10862 }
10863
10864 return value;
10865 }
10866
10867 isOnlyGlobal(node, type, name) {
10868 return this.isSymbolic(type) && this.isGlobalSymbol(node, this.getSymbolForType(node, type), name);
10869 }
10870
10871 isGlobal(node, type, name) {
10872 return this.isSymbolic(type) && this.isGlobalSymbol(node, this.getSymbolForType(node, type), name);
10873 }
10874
10875 isGlobalSymbol(node, symbol, name) {
10876 return symbol === this.globals[name];
10877 }
10878
10879 isOnlyLib(node, type, name) {
10880 return this.isSymbolic(type) && this.isLibSymbol(node, this.getSymbolForType(node, type), name);
10881 }
10882
10883 isLibSymbol(node, symbol, name) {
10884 return symbol === this.libs[name];
10885 }
10886
10887 isLibAlias(identifier, name) {
10888 if (identifier == null) {
10889 return false;
10890 }
10891
10892 return this.libAliases[name].has(identifier);
10893 }
10894
10895 isSymbolic(type) {
10896 return type == null || !isLiteral(type) && !isPrimitive(type) && !isTuple(type) && !isUnion(type) && !isIntersection(type);
10897 }
10898
10899 getNotAnyType(type) {
10900 // tslint:disable-next-line no-bitwise
10901 if (type == null || (type.getFlags() & TypeFlags.Any) !== 0) {
10902 return undefined;
10903 }
10904
10905 return type;
10906 }
10907
10908}
10909
10910// tslint:disable ban-types no-bitwise
10911
10912const findInterfaceFile = (ast, name) => {
10913 const files = ast.getSourceFiles();
10914 return files.find(file => {
10915 if (!file.isDeclarationFile()) {
10916 return false;
10917 }
10918
10919 let bufferInterface = file.getInterface(name);
10920 const globalNamespace = file.getNamespace('global');
10921 let isGlobalAugmentation = false;
10922
10923 if (bufferInterface == null && globalNamespace != null) {
10924 bufferInterface = globalNamespace.getInterface(name);
10925 isGlobalAugmentation = true;
10926 }
10927
10928 if (bufferInterface == null) {
10929 return false;
10930 }
10931
10932 return isGlobalAugmentation || (bufferInterface.compilerNode.flags & ts.NodeFlags.GlobalAugmentation) !== 0;
10933 });
10934};
10935
10936const getGlobals = ast => {
10937 let bufferFile = findInterfaceFile(ast, 'Buffer');
10938
10939 if (bufferFile == null) {
10940 bufferFile = ast.addExistingSourceFileIfExists(require.resolve('@types/node/index.d.ts'));
10941 }
10942
10943 if (bufferFile == null) {
10944 throw new Error('Could not find Buffer');
10945 }
10946
10947 const buffer = bufferFile.getInterfaceOrThrow('Buffer');
10948 const typeChecker = ast.getTypeChecker().compilerObject; // @ts-ignore
10949
10950 const array = new Symbol$1( // @ts-ignore
10951 ast.global, typeChecker.createArrayType(typeChecker.getAnyType()).symbol).getDeclaredType();
10952 let neoFile = findInterfaceFile(ast, 'AccountBase');
10953
10954 if (neoFile == null) {
10955 ast.addExistingSourceFiles(path__default.join(path__default.dirname(require.resolve('@neo-one/smart-contract')), '**', '*.ts'));
10956 }
10957
10958 neoFile = findInterfaceFile(ast, 'AccountBase');
10959
10960 if (neoFile == null) {
10961 throw new Error('Could not find NEO type definition file');
10962 }
10963
10964 const neoGlobal = neoFile.getNamespaceOrThrow('global');
10965 return {
10966 Array: array.getSymbolOrThrow(),
10967 Buffer: buffer.getSymbolOrThrow(),
10968 process: bufferFile.getVariableDeclarationOrThrow('process').getSymbolOrThrow(),
10969 AccountBase: neoGlobal.getInterfaceOrThrow('AccountBase').getSymbolOrThrow(),
10970 AssetBase: neoGlobal.getInterfaceOrThrow('AssetBase').getSymbolOrThrow(),
10971 AttributeBase: neoGlobal.getInterfaceOrThrow('AttributeBase').getSymbolOrThrow(),
10972 BlockBase: neoGlobal.getInterfaceOrThrow('BlockBase').getSymbolOrThrow(),
10973 ContractBase: neoGlobal.getInterfaceOrThrow('ContractBase').getSymbolOrThrow(),
10974 HeaderBase: neoGlobal.getInterfaceOrThrow('HeaderBase').getSymbolOrThrow(),
10975 InputBase: neoGlobal.getInterfaceOrThrow('InputBase').getSymbolOrThrow(),
10976 OutputBase: neoGlobal.getInterfaceOrThrow('OutputBase').getSymbolOrThrow(),
10977 TransactionBase: neoGlobal.getInterfaceOrThrow('TransactionBase').getSymbolOrThrow(),
10978 ValidatorBase: neoGlobal.getInterfaceOrThrow('ValidatorBase').getSymbolOrThrow(),
10979 StorageContextBase: neoGlobal.getInterfaceOrThrow('StorageContextBase').getSymbolOrThrow(),
10980 StorageIteratorBase: neoGlobal.getInterfaceOrThrow('StorageIteratorBase').getSymbolOrThrow(),
10981 syscall: neoGlobal.getFunctionOrThrow('syscall').getSymbolOrThrow()
10982 };
10983};
10984
10985const findLibFile = ast => {
10986 const files = ast.getSourceFiles();
10987 return files.find(file => file.getClass('MapStorage') != null);
10988};
10989
10990const getLibs = ast => {
10991 let libFileIn = findLibFile(ast);
10992
10993 if (libFileIn == null) {
10994 ast.addExistingSourceFiles(path__default.join(path__default.dirname(require.resolve('@neo-one/smart-contract')), '**', '*.ts'));
10995 }
10996
10997 libFileIn = findLibFile(ast);
10998
10999 if (libFileIn == null) {
11000 throw new Error('Could not find NEO lib file');
11001 }
11002
11003 const libFile = libFileIn;
11004 return {
11005 get SmartContract() {
11006 return libFile.getClassOrThrow('SmartContract').getSymbolOrThrow();
11007 },
11008
11009 get MapStorage() {
11010 return libFile.getClassOrThrow('MapStorage').getSymbolOrThrow();
11011 },
11012
11013 get SetStorage() {
11014 return libFile.getClassOrThrow('SetStorage').getSymbolOrThrow();
11015 },
11016
11017 get Fixed() {
11018 return libFile.getTypeAliasOrThrow('Fixed').getSymbolOrThrow();
11019 },
11020
11021 get constant() {
11022 return libFile.getFunctionOrThrow('constant').getSymbolOrThrow();
11023 },
11024
11025 get verify() {
11026 return libFile.getFunctionOrThrow('verify').getSymbolOrThrow();
11027 }
11028
11029 };
11030};
11031const getLibAliases = ast => {
11032 let libFileIn = findLibFile(ast);
11033
11034 if (libFileIn == null) {
11035 ast.addExistingSourceFiles(path__default.join(path__default.dirname(require.resolve('@neo-one/smart-contract')), '**', '*.ts'));
11036 }
11037
11038 libFileIn = findLibFile(ast);
11039
11040 if (libFileIn == null) {
11041 throw new Error('Could not find NEO lib file');
11042 }
11043
11044 const libFile = libFileIn;
11045 return {
11046 get Address() {
11047 return new Set(libFile.getTypeAliasOrThrow('Address').getReferencingNodes());
11048 },
11049
11050 get Hash256() {
11051 return new Set(libFile.getTypeAliasOrThrow('Hash256').getReferencingNodes());
11052 },
11053
11054 get Signature() {
11055 return new Set(libFile.getTypeAliasOrThrow('Signature').getReferencingNodes());
11056 },
11057
11058 get PublicKey() {
11059 return new Set(libFile.getTypeAliasOrThrow('PublicKey').getReferencingNodes());
11060 }
11061
11062 };
11063};
11064
11065const compile = ({
11066 ast,
11067 sourceFile,
11068 context: contextIn
11069}) => {
11070 const context = contextIn || new Context(getGlobals(ast), getLibs(ast), getLibAliases(ast));
11071 const helpers = createHelpers();
11072 const helperScriptBuilder = new HelperCapturingScriptBuilder(context, helpers, ast, sourceFile);
11073 helperScriptBuilder.process();
11074 const scopeScriptBuilder = new ScopeCapturingScriptBuilder(context, helpers, ast, sourceFile, helperScriptBuilder.getHelpers());
11075 scopeScriptBuilder.process();
11076 const emittingScriptBuilder = new EmittingScriptBuilder({
11077 context,
11078 scopes: scopeScriptBuilder.getScopes(),
11079 ast,
11080 sourceFile,
11081 helpers,
11082 allHelpers: helperScriptBuilder.getHelpers()
11083 });
11084 emittingScriptBuilder.process();
11085 return {
11086 code: emittingScriptBuilder.getFinalBytecode(),
11087 context
11088 };
11089};
11090
11091// tslint:disable ban-types
11092
11093const findRoot = async (dir, filename) => {
11094 let start = dir;
11095
11096 if (typeof start === 'string') {
11097 if (start[start.length - 1] !== sep) {
11098 start += sep;
11099 }
11100
11101 start = start.split(sep);
11102 }
11103
11104 if (!start.length) {
11105 throw new Error('tsconfig.json not found in path');
11106 }
11107
11108 start.pop();
11109 const currentDir = start.join(sep);
11110 const file = join(currentDir, filename);
11111 const exists = await pathExists(file);
11112
11113 if (exists) {
11114 return file;
11115 }
11116
11117 return findRoot(start, filename);
11118};
11119
11120const makeAst = async dir => {
11121 const tsConfigFilePath = await findRoot(dir, 'tsconfig.json');
11122 const res = ts.readConfigFile(tsConfigFilePath, value => readFileSync(value, 'utf8'));
11123 const parseConfigHost = {
11124 fileExists: existsSync,
11125 readDirectory: ts.sys.readDirectory,
11126 readFile: ts.sys.readFile,
11127 useCaseSensitiveFileNames: true
11128 };
11129 const parsed = ts.parseJsonConfigFileContent(res.config, parseConfigHost, dirname(tsConfigFilePath));
11130 return new Ast({
11131 compilerOptions: parsed.options
11132 });
11133};
11134const getAst = async dir => {
11135 const ast = await makeAst(dir);
11136 ast.addExistingSourceFiles(join(dir, '**', '*.ts')); // For some reason this forces Ast to resolve references. Do not remove.
11137
11138 ast.getPreEmitDiagnostics();
11139 return ast;
11140};
11141
11142const compileScript = async scriptPath => {
11143 const ast = await getAst(path__default.dirname(scriptPath));
11144 const sourceFile = ast.getSourceFileOrThrow(scriptPath);
11145 return compile({
11146 ast,
11147 sourceFile
11148 });
11149};
11150
11151class NodeTranspiler {
11152 constructor() {
11153 _defineProperty(this, "kind", void 0);
11154 }
11155
11156}
11157
11158const DEPLOY_METHOD = 'deploy';
11159class ClassDeclarationTranspiler extends NodeTranspiler {
11160 constructor(...args) {
11161 var _temp;
11162
11163 return _temp = super(...args), _defineProperty(this, "kind", SyntaxKind.ClassDeclaration), _temp;
11164 }
11165
11166 visitNode(transpiler, node) {
11167 if (transpiler.isSmartContract(node)) {
11168 this.transpileSmartContract(transpiler, node);
11169 }
11170 }
11171
11172 transpileSmartContract(transpiler, node) {
11173 transpiler.visit(node.getBaseClass());
11174 this.transpileDeploy(transpiler, node);
11175 }
11176
11177 transpileDeploy(transpiler, node) {
11178 const existingDeploy = node.getMethod(DEPLOY_METHOD);
11179
11180 if (existingDeploy != null) {
11181 transpiler.reportError(existingDeploy, 'The deploy method is reserved in SmartContract instances.', DiagnosticCode.UNSUPPORTED_SYNTAX);
11182 return;
11183 }
11184
11185 const ctor = node.getConstructors().find(ctorDecl => ctorDecl.isImplementation());
11186 let bodyText = '';
11187 let parameters = [];
11188
11189 if (ctor == null) {
11190 const baseDeploy = this.getBaseDeploy(transpiler, node);
11191
11192 if (baseDeploy != null) {
11193 bodyText = `
11194 super.deploy(${baseDeploy.getParameters().map(param => param.getName()).join(', ')});
11195 `;
11196 parameters = baseDeploy.getParameters();
11197 }
11198 } else {
11199 const firstStatement = ctor.getStatements()[0];
11200
11201 if (firstStatement != null && TypeGuards.isExpressionStatement(firstStatement)) {
11202 const callExpr = firstStatement.getExpression();
11203
11204 if (TypeGuards.isCallExpression(callExpr)) {
11205 const lhsrExpr = callExpr.getExpression();
11206
11207 if (TypeGuards.isSuperExpression(lhsrExpr)) {
11208 firstStatement.replaceWithText(`super.deploy(${callExpr.getArguments().map(arg => arg.getText()).join(', ')});`);
11209 }
11210 }
11211 }
11212
11213 bodyText = ctor.getStatements().map(statement => statement.getText()).join('\n');
11214 parameters = ctor.getParameters();
11215 }
11216
11217 const deploy = node.addMethod({
11218 name: DEPLOY_METHOD,
11219 returnType: 'boolean',
11220 bodyText,
11221 parameters: parameters.map(param => {
11222 const initializer = param.getInitializer();
11223 let type = param.getType().getText();
11224 const typeNode = param.getTypeNode();
11225
11226 if (typeNode != null) {
11227 type = typeNode.getText();
11228 }
11229
11230 return {
11231 name: param.getNameOrThrow(),
11232 type,
11233 initializer: initializer == null ? undefined : initializer.getText(),
11234 hasQuestionToken: param.hasQuestionToken(),
11235 isRestParameter: param.isRestParameter()
11236 };
11237 }),
11238 scope: Scope.Public
11239 });
11240 node.getInstanceProperties().forEach(property => {
11241 if (TypeGuards.isPropertyDeclaration(property) && !property.isAbstract() || TypeGuards.isParameterDeclaration(property)) {
11242 const name = TypeGuards.isPropertyDeclaration(property) ? property.getName() : property.getNameOrThrow();
11243 const type = property.getType();
11244 const typeNode = property.getTypeNode();
11245
11246 if (type == null || typeNode == null) {
11247 transpiler.reportError(property, 'Could not determine type of property.', DiagnosticCode.UNKNOWN_TYPE);
11248 } else if (isOnlyPrimitive(type) || transpiler.isFixedType(property, type) || transpiler.isOnlyGlobal(property, type, 'Buffer')) {
11249 if (TypeGuards.isParameterDeclaration(property)) {
11250 deploy.addStatements(`
11251 this.${property.getName()} = ${property.getName()};
11252 `);
11253 }
11254
11255 const init = property.getInitializer();
11256 let addAccessors = true;
11257
11258 if (TypeGuards.isPropertyDeclaration(property) && init != null) {
11259 if (property.isReadonly()) {
11260 addAccessors = false;
11261 } else {
11262 deploy.addStatements(`
11263 this.${property.getName()} = ${init.getText()};
11264 `);
11265 }
11266 }
11267
11268 if (addAccessors) {
11269 node.addGetAccessor({
11270 name,
11271 returnType: typeNode.getText(),
11272 bodyText: `
11273 return syscall('Neo.Storage.Get', syscall('Neo.Storage.GetContext'), '${name}') as ${typeNode.getText()};
11274 `,
11275 scope: property.getScope()
11276 });
11277 node.addSetAccessor({
11278 name,
11279 parameters: [{
11280 name,
11281 type: typeNode.getText()
11282 }],
11283 bodyText: `
11284 syscall('Neo.Storage.Put', syscall('Neo.Storage.GetContext'), '${name}', ${name});
11285 `,
11286 scope: property.getScope()
11287 });
11288 property.remove();
11289 }
11290 } else if (transpiler.isOnlyLib(property, type, 'MapStorage')) {
11291 property.setInitializer(`new MapStorage(syscall('Neo.Runtime.Serialize', '${name}'))`);
11292 } else if (transpiler.isOnlyLib(property, type, 'SetStorage')) {
11293 property.setInitializer(`new SetStorage(syscall('Neo.Runtime.Serialize', '${name}'))`);
11294 } else {
11295 transpiler.reportError(property, 'Unsupported SmartContract property.', DiagnosticCode.UNSUPPORTED_SYNTAX);
11296 }
11297 }
11298 });
11299 deploy.addStatements(`
11300 return true;
11301 `);
11302
11303 if (ctor != null) {
11304 ctor.remove();
11305 }
11306 }
11307
11308 getBaseDeploy(transpiler, node) {
11309 const baseClass = node.getBaseClass();
11310
11311 if (baseClass == null) {
11312 return undefined;
11313 }
11314
11315 const deploy = baseClass.getInstanceMethod('deploy');
11316
11317 if (deploy == null) {
11318 return this.getBaseDeploy(transpiler, baseClass);
11319 }
11320
11321 return deploy;
11322 }
11323
11324}
11325
11326var declarations$1 = [ClassDeclarationTranspiler];
11327
11328const isPublic = (node // tslint:disable-next-line no-bitwise
11329) => (node.getCombinedModifierFlags() & ts.ModifierFlags.Public) !== 0;
11330
11331const transpilers = [declarations$1];
11332class NEOTranspiler {
11333 constructor(context, ast, smartContract) {
11334 this.context = context;
11335 this.ast = ast;
11336 this.smartContract = smartContract;
11337
11338 _defineProperty(this, "transpilers", void 0);
11339
11340 this.transpilers = transpilers.reduce((acc, kindCompilers) => acc.concat(kindCompilers), []).reduce((acc, KindCompiler) => {
11341 const kindCompiler = new KindCompiler();
11342
11343 if (acc[kindCompiler.kind] != null) {
11344 throw new Error(`Found duplicate compiler for kind ${kindCompiler.kind}`);
11345 }
11346
11347 acc[kindCompiler.kind] = kindCompiler;
11348 return acc;
11349 }, {});
11350 }
11351
11352 process() {
11353 const file = this.smartContract.getSourceFile();
11354 this.visit(file);
11355 const smartContract = file.getClassOrThrow(this.smartContract.getNameOrThrow());
11356 const methods = smartContract.getType().getProperties().map(symbol => this.processProperty(symbol)).reduce((acc, values) => acc.concat(values), []);
11357 const verifySwitches = [];
11358 const applicationSwitches = [];
11359 const functions = [];
11360
11361 for (const [method, func] of methods) {
11362 const name = TypeGuards.isParameterDeclaration(method) ? method.getNameOrThrow() : method.getName();
11363 let methodSwitch;
11364
11365 if (TypeGuards.isMethodDeclaration(method)) {
11366 let argsStatement = '';
11367 let args = '';
11368
11369 if (method.getParameters().length > 0) {
11370 const argsTypes = method.getParameters().map(param => this.getTypeText(param, this.getType(param))).join(',');
11371 argsStatement = `const args = syscall('Neo.Runtime.GetArgument', 1) as [${argsTypes}];\n`;
11372 args = method.getParameters().map((param, idx) => `args[${idx}]`).join(', ');
11373 }
11374
11375 let call = `contract.${name}(${args})`;
11376
11377 if (!isVoid(method.getReturnType())) {
11378 call = `syscall('Neo.Runtime.Return', ${call})`;
11379 }
11380
11381 methodSwitch = `
11382 if (method === '${name}') {
11383 ${argsStatement}${call};
11384 }
11385 `;
11386 } else if (TypeGuards.isGetAccessorDeclaration(method) || TypeGuards.isPropertyDeclaration(method) || TypeGuards.isParameterDeclaration(method)) {
11387 methodSwitch = `
11388 if (method === '${name}') {
11389 syscall('Neo.Runtime.Return', contract.${name});
11390 }
11391 `;
11392 } else {
11393 const param = method.getParameters()[0];
11394 const typeText = this.getTypeText(param, this.getType(param));
11395 methodSwitch = `
11396 if (method === 'set${name[0].toUpperCase()}${name.slice(1)}') {
11397 contract.${name} = (syscall('Neo.Runtime.GetArgument', 1) as [${typeText}])[0];
11398 }
11399 `;
11400 }
11401
11402 applicationSwitches.push(methodSwitch);
11403
11404 if (func.verify) {
11405 verifySwitches.push(methodSwitch);
11406 }
11407
11408 functions.push(func);
11409 }
11410
11411 const applicationFallback = applicationSwitches.length === 0 ? 'throw new Error(' : ` else {
11412 throw new Error('Unknown method');
11413 }`;
11414 let verifyFallback = `
11415 if (!syscall('Neo.Runtime.CheckWitness', contract.owner)) {
11416 throw new Error('Invalid witness');
11417 }
11418 `;
11419
11420 if (verifySwitches.length > 0) {
11421 verifyFallback = `else {
11422 ${verifyFallback}
11423 }`;
11424 }
11425
11426 const statements = `
11427 const contract = new ${this.smartContract.getName()}();
11428 const method = syscall('Neo.Runtime.GetArgument', 0) as string;
11429 if (syscall('Neo.Runtime.GetTrigger') === 0x10) {
11430 ${applicationSwitches.join(' else ')}
11431 ${applicationFallback}
11432 } else if (syscall('Neo.Runtime.GetTrigger') === 0x00) {
11433 ${verifySwitches.join(' else ')}
11434 ${verifyFallback}
11435 } else {
11436 throw new Error('Unsupported trigger');
11437 }
11438 `;
11439 file.addStatements(statements);
11440 return {
11441 ast: this.ast,
11442 sourceFile: file,
11443 abi: {
11444 functions
11445 },
11446 context: this.context
11447 };
11448 }
11449
11450 visit(node) {
11451 if (node == null) {
11452 return;
11453 }
11454
11455 const transpiler = this.transpilers[node.compilerNode.kind];
11456
11457 if (transpiler == null) {
11458 node.getChildren().forEach(child => {
11459 this.visit(child);
11460 });
11461 } else {
11462 transpiler.visitNode(this, node);
11463 }
11464 }
11465
11466 isSmartContract(node) {
11467 return node === this.smartContract || node.getDerivedClasses().some(derived => this.isSmartContract(derived));
11468 }
11469
11470 getType(node) {
11471 return this.context.getType(node);
11472 }
11473
11474 getTypeOfSymbol(symbol, node) {
11475 return this.context.getTypeOfSymbol(symbol, node);
11476 }
11477
11478 getSymbol(node) {
11479 return this.context.getSymbol(node);
11480 }
11481
11482 isOnlyGlobal(node, type, name) {
11483 return this.context.isOnlyGlobal(node, type, name);
11484 }
11485
11486 isLibSymbol(node, symbol, name) {
11487 return this.context.isLibSymbol(node, symbol, name);
11488 }
11489
11490 isOnlyLib(node, type, name) {
11491 return this.context.isOnlyLib(node, type, name);
11492 }
11493
11494 isLibAlias(identifier, name) {
11495 return this.context.isLibAlias(identifier, name);
11496 }
11497
11498 isFixedType(node, type) {
11499 if (type == null) {
11500 return false;
11501 }
11502
11503 return this.isLibSymbol(node, type.getAliasSymbol() || type.getSymbol(), 'Fixed');
11504 }
11505
11506 reportError(node, message, code) {
11507 this.context.reportError(node, message, code);
11508 }
11509
11510 reportUnsupported(node) {
11511 this.context.reportUnsupported(node);
11512 }
11513
11514 assertNotNull(value) {
11515 return this.context.assertNotNull(value);
11516 }
11517
11518 filterNotNull(value) {
11519 return value != null;
11520 }
11521
11522 processProperty(symbol) {
11523 const decls = symbol.getDeclarations().filter(symbolDecl => !TypeGuards.isMethodDeclaration(symbolDecl) || symbolDecl.isImplementation());
11524
11525 if (!(decls.length === 1 || decls.length === 2 && decls.some(accessor => TypeGuards.isGetAccessorDeclaration(accessor)) && decls.some(accessor => TypeGuards.isSetAccessorDeclaration(accessor)))) {
11526 this.reportError(symbol.getDeclarations()[0], 'Invalid contract function. Resolved to multiple implementation declarations.', DiagnosticCode.INVALID_CONTRACT_METHOD);
11527 return [];
11528 }
11529
11530 const decl = decls[0];
11531
11532 if (!(TypeGuards.isMethodDeclaration(decl) || TypeGuards.isPropertyDeclaration(decl) || TypeGuards.isGetAccessorDeclaration(decl) || TypeGuards.isSetAccessorDeclaration(decl) || TypeGuards.isParameterDeclaration(decl))) {
11533 return [];
11534 }
11535
11536 const name = symbol.getName();
11537 const type = this.getTypeOfSymbol(symbol, decl);
11538
11539 if (type == null) {
11540 return [];
11541 }
11542
11543 if (TypeGuards.isGetAccessorDeclaration(decl) || TypeGuards.isSetAccessorDeclaration(decl)) {
11544 const getDecl = TypeGuards.isGetAccessorDeclaration(decl) ? decl : decl.getGetAccessor();
11545 const setDecl = TypeGuards.isSetAccessorDeclaration(decl) ? decl : decl.getSetAccessor();
11546 const result = [];
11547
11548 if (getDecl != null && isPublic(getDecl)) {
11549 result.push([getDecl, {
11550 name,
11551 constant: true,
11552 verify: this.hasVerify(getDecl),
11553 returnType: this.toABIReturn(getDecl, type, this.getIdentifier(getDecl.getReturnTypeNode())) || {
11554 type: 'ByteArray'
11555 }
11556 }]);
11557 }
11558
11559 if (setDecl != null && isPublic(setDecl)) {
11560 result.push([setDecl, {
11561 name,
11562 constant: false,
11563 verify: this.hasVerify(setDecl),
11564 parameters: [_objectSpread({
11565 name: setDecl.getParameters()[0].getNameOrThrow()
11566 }, this.toABIReturn(setDecl, type, this.getIdentifier(setDecl.getParameters()[0].getTypeNode())) || {
11567 type: 'ByteArray'
11568 })],
11569 returnType: {
11570 type: 'Void'
11571 }
11572 }]);
11573 }
11574
11575 return result;
11576 }
11577
11578 if (!isPublic(decl)) {
11579 return [];
11580 }
11581
11582 const verify = this.hasVerify(decl);
11583
11584 if (TypeGuards.isMethodDeclaration(decl)) {
11585 const callSignatures = type.getCallSignatures();
11586
11587 if (callSignatures.length !== 1) {
11588 this.reportError(decl, 'Invalid contract function. Resolved to multiple call signatures.', DiagnosticCode.INVALID_CONTRACT_METHOD);
11589 return [];
11590 }
11591
11592 const callSignature = callSignatures[0];
11593 const parameters = callSignature.getParameters().map(parameter => this.toABIParameter(parameter)).filter(this.filterNotNull);
11594 const returnType = this.toABIReturn(decl, callSignature.getReturnType(), this.getIdentifier(decl.getReturnTypeNode()));
11595 const constant = this.hasDecorator(decl, 'constant');
11596 const func = {
11597 name,
11598 constant,
11599 verify,
11600 parameters,
11601 returnType: returnType || {
11602 type: 'ByteArray'
11603 }
11604 };
11605 return [[decl, func]];
11606 } else {
11607 const returnType = this.toABIReturn(decl, type, this.getIdentifier(decl.getTypeNode()));
11608 const func = {
11609 name,
11610 constant: true,
11611 verify,
11612 returnType: returnType || {
11613 type: 'ByteArray'
11614 }
11615 };
11616 return [[decl, func]];
11617 }
11618 }
11619
11620 hasVerify(decl) {
11621 return this.hasDecorator(decl, 'verify');
11622 }
11623
11624 hasDecorator(decl, name) {
11625 return decl.getDecorators().some(decorator => this.isOnlyLib(decorator.getExpression(), this.getType(decorator.getExpression()), name));
11626 }
11627
11628 toABIParameter(param) {
11629 const decl = this.assertNotNull(param.getDeclarations()[0]);
11630 const id = TypeGuards.isParameterDeclaration(decl) ? this.getIdentifier(decl.getTypeNode()) : undefined;
11631 const type = this.toABIReturn(decl, this.getTypeOfSymbol(param, decl), id);
11632
11633 if (type == null) {
11634 return undefined;
11635 }
11636
11637 return _objectSpread({}, type, {
11638 name: param.getName()
11639 });
11640 }
11641
11642 toABIReturn(node, resolvedType, typeIdentifier) {
11643 if (resolvedType == null && typeIdentifier == null) {
11644 this.reportError(node, 'Could not detect ABI, unknown type.', DiagnosticCode.UNKNOWN_TYPE);
11645 return undefined;
11646 }
11647
11648 if (isOnlyBoolean(resolvedType)) {
11649 return {
11650 type: 'Boolean'
11651 };
11652 } else if (this.isLibAlias(typeIdentifier, 'Address')) {
11653 return {
11654 type: 'Hash160'
11655 };
11656 } else if (this.isLibAlias(typeIdentifier, 'Hash256')) {
11657 return {
11658 type: 'Hash256'
11659 };
11660 } else if (this.isLibAlias(typeIdentifier, 'Signature')) {
11661 return {
11662 type: 'Signature'
11663 };
11664 } else if (this.isLibAlias(typeIdentifier, 'PublicKey')) {
11665 return {
11666 type: 'PublicKey'
11667 };
11668 } else if (isVoid(resolvedType)) {
11669 return {
11670 type: 'Void'
11671 };
11672 } else if (isOnlyString(resolvedType)) {
11673 return {
11674 type: 'String'
11675 };
11676 } else if (isOnlyNumberLiteral(resolvedType)) {
11677 return {
11678 type: 'Integer',
11679 decimals: 0
11680 };
11681 } else if (this.isFixedType(node, resolvedType) && resolvedType != null) {
11682 const decimals = this.getFixedDecimals(resolvedType);
11683 return {
11684 type: 'Integer',
11685 decimals
11686 };
11687 } else if (isOnlyNumber(resolvedType)) {
11688 return {
11689 type: 'Integer',
11690 decimals: 0
11691 };
11692 } else if (isOnlyArray(resolvedType) && resolvedType != null) {
11693 const value = this.toABIReturn(node, resolvedType.getTypeArguments()[0]);
11694
11695 if (value != null) {
11696 return {
11697 type: 'Array',
11698 value
11699 };
11700 }
11701 } else if (this.isOnlyGlobal(node, resolvedType, 'Buffer')) {
11702 return {
11703 type: 'ByteArray'
11704 };
11705 } else {
11706 this.reportError(node, 'Invalid contract type.', DiagnosticCode.INVALID_CONTRACT_TYPE);
11707 }
11708
11709 return undefined;
11710 }
11711
11712 getFixedDecimals(type) {
11713 return type.getUnionTypes()[1].getIntersectionTypes()[1].compilerType.value;
11714 }
11715
11716 getIdentifier(node) {
11717 return node == null ? node : node.getFirstChildByKind(SyntaxKind.Identifier);
11718 }
11719
11720 getTypeText(node, type) {
11721 let typeText = 'any';
11722
11723 if (type == null) {
11724 this.reportError(node, 'Unknown type', DiagnosticCode.UNKNOWN_TYPE);
11725 } else if (this.isFixedType(node, type)) {
11726 typeText = 'number';
11727 } else {
11728 typeText = type.getText();
11729 }
11730
11731 return typeText;
11732 }
11733
11734}
11735
11736const transpile = ({
11737 ast,
11738 smartContract,
11739 context: contextIn
11740}) => {
11741 const context = contextIn || new Context(getGlobals(ast), getLibs(ast), getLibAliases(ast));
11742 const transpiler = new NEOTranspiler(context, ast, smartContract);
11743 return transpiler.process();
11744};
11745
11746const compileContract = async ({
11747 dir,
11748 filePath,
11749 name
11750}) => {
11751 const ast = await getAst(dir);
11752 const smartContract = ast.getSourceFileOrThrow(filePath).getClassOrThrow(name);
11753 const {
11754 ast: transpiledAst,
11755 sourceFile,
11756 abi,
11757 context
11758 } = transpile({
11759 ast,
11760 smartContract
11761 });
11762 const {
11763 code,
11764 context: finalContext
11765 } = compile({
11766 ast: transpiledAst,
11767 sourceFile,
11768 context
11769 });
11770 return {
11771 code,
11772 diagnostics: finalContext.diagnostics,
11773 abi
11774 };
11775};
11776
11777const executeScript = async (monitor, ast, sourceFile, prelude = Buffer.alloc(0, 0)) => {
11778 const blockchain = await Blockchain.create({
11779 log: () => {// tslint:disable-next-line
11780 },
11781 settings: test,
11782 storage: levelUpStorage({
11783 context: {
11784 messageMagic: test.messageMagic
11785 },
11786 db: levelup( // @ts-ignore
11787 memdown())
11788 }),
11789 vm,
11790 monitor
11791 });
11792 const {
11793 code: compiledCode,
11794 context
11795 } = compile({
11796 ast,
11797 sourceFile
11798 });
11799 const error = context.diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error)[0];
11800
11801 if (error != null) {
11802 throw new Error(`Compilation error: ${error.messageText} at ${error.source}`);
11803 }
11804
11805 const result = await blockchain.invokeScript(Buffer.concat([prelude, compiledCode]), monitor);
11806 return result;
11807};
11808
11809const scan = async dir => {
11810 const ast = await getAst(dir);
11811 const libs = getLibs(ast);
11812 const smartContract = libs.SmartContract.getDeclarations()[0];
11813 return smartContract.getDerivedClasses().reduce((acc, derived) => {
11814 if (!derived.isAbstract()) {
11815 const file = derived.getSourceFile().getFilePath();
11816
11817 if (acc[file] == null) {
11818 acc[file] = [];
11819 }
11820
11821 acc[file].push(derived.getNameOrThrow());
11822 }
11823
11824 return acc;
11825 }, {});
11826};
11827
11828const findContract = async (dir, name) => {
11829 const contracts = await scan(dir);
11830 const found = Object.entries(contracts).map(([path, contractNames]) => ({
11831 path,
11832 contractNames: contractNames.filter(contractName => name === contractName)
11833 })).filter(({
11834 contractNames
11835 }) => contractNames.length > 0);
11836
11837 if (found.length > 1) {
11838 throw new Error(`Found multiple contracts with name ${name}`);
11839 } else if (found.length === 0) {
11840 throw new Error(`Cound not find contract with name ${name}`);
11841 }
11842
11843 return {
11844 filePath: found[0].path,
11845 name
11846 };
11847};
11848
11849export { compile, compileScript, compileContract, executeScript, findContract, scan };
11850//# sourceMappingURL=index.es.js.map