UNPKG

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