porffor 0.37.3 → 0.37.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/compiler/builtins.js +1 -1
- package/compiler/builtins_precompiled.js +207 -207
- package/compiler/codegen.js +105 -138
- package/compiler/precompile.js +1 -1
- package/compiler/prefs.js +1 -1
- package/compiler/prototype.js +97 -99
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -588,8 +588,8 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMod
|
|
588
588
|
...wasm,
|
589
589
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
590
590
|
|
591
|
-
...typeSwitch(scope, type,
|
592
|
-
[TYPES.string]
|
591
|
+
...typeSwitch(scope, type, [
|
592
|
+
[ [ TYPES.string, TYPES.bytestring ], [
|
593
593
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
594
594
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
595
595
|
|
@@ -600,18 +600,9 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMod
|
|
600
600
|
/* [ Opcodes.i32_eqz ],
|
601
601
|
[ Opcodes.i32_eqz ], */
|
602
602
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
603
|
-
],
|
604
|
-
[
|
605
|
-
|
606
|
-
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
607
|
-
|
608
|
-
// get length
|
609
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
610
|
-
|
611
|
-
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
612
|
-
],
|
613
|
-
default: def
|
614
|
-
}, intOut ? Valtype.i32 : valtypeBinary)
|
603
|
+
] ],
|
604
|
+
[ 'default', def ]
|
605
|
+
], intOut ? Valtype.i32 : valtypeBinary)
|
615
606
|
];
|
616
607
|
};
|
617
608
|
|
@@ -651,19 +642,8 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMode
|
|
651
642
|
...wasm,
|
652
643
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
653
644
|
|
654
|
-
...typeSwitch(scope, type,
|
655
|
-
[TYPES.string]
|
656
|
-
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
657
|
-
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
658
|
-
|
659
|
-
// get length
|
660
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
661
|
-
|
662
|
-
// if length == 0
|
663
|
-
[ Opcodes.i32_eqz ],
|
664
|
-
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
665
|
-
],
|
666
|
-
[TYPES.bytestring]: [ // duplicate of string
|
645
|
+
...typeSwitch(scope, type, [
|
646
|
+
[ [ TYPES.string, TYPES.bytestring ], [
|
667
647
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
668
648
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
669
649
|
|
@@ -673,9 +653,9 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMode
|
|
673
653
|
// if length == 0
|
674
654
|
[ Opcodes.i32_eqz ],
|
675
655
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
676
|
-
],
|
677
|
-
default
|
678
|
-
|
656
|
+
] ],
|
657
|
+
[ 'default', def ]
|
658
|
+
], intOut ? Valtype.i32 : valtypeBinary)
|
679
659
|
];
|
680
660
|
};
|
681
661
|
|
@@ -687,30 +667,25 @@ const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
687
667
|
...wasm,
|
688
668
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
689
669
|
|
690
|
-
...typeSwitch(scope, type,
|
691
|
-
[TYPES.empty]
|
670
|
+
...typeSwitch(scope, type, [
|
671
|
+
[ [ TYPES.empty, TYPES.undefined ], [
|
692
672
|
// empty
|
693
673
|
...(!useTmp ? [ [ Opcodes.drop ] ] : []),
|
694
674
|
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
695
|
-
],
|
696
|
-
[TYPES.
|
697
|
-
// undefined
|
698
|
-
...(!useTmp ? [ [ Opcodes.drop ] ] : []),
|
699
|
-
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
700
|
-
],
|
701
|
-
[TYPES.object]: [
|
675
|
+
] ],
|
676
|
+
[ TYPES.object, [
|
702
677
|
// object, null if == 0
|
703
678
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
704
679
|
|
705
680
|
...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
706
681
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
707
|
-
],
|
708
|
-
default
|
682
|
+
] ],
|
683
|
+
[ 'default', [
|
709
684
|
// not
|
710
685
|
...(!useTmp ? [ [ Opcodes.drop ] ] : []),
|
711
686
|
...number(0, intOut ? Valtype.i32 : valtypeBinary)
|
712
|
-
]
|
713
|
-
|
687
|
+
] ]
|
688
|
+
], intOut ? Valtype.i32 : valtypeBinary)
|
714
689
|
];
|
715
690
|
};
|
716
691
|
|
@@ -1382,7 +1357,7 @@ const getNodeType = (scope, node) => {
|
|
1382
1357
|
if (node.operator === '!') return TYPES.boolean;
|
1383
1358
|
if (node.operator === 'void') return TYPES.undefined;
|
1384
1359
|
if (node.operator === 'delete') return TYPES.boolean;
|
1385
|
-
if (node.operator === 'typeof') return
|
1360
|
+
if (node.operator === 'typeof') return TYPES.bytestring;
|
1386
1361
|
|
1387
1362
|
return TYPES.number;
|
1388
1363
|
}
|
@@ -2717,95 +2692,83 @@ const brTable = (input, bc, returns) => {
|
|
2717
2692
|
|
2718
2693
|
let typeswitchDepth = 0;
|
2719
2694
|
|
2720
|
-
const typeSwitch = (scope, type, bc, returns = valtypeBinary,
|
2721
|
-
if (!Prefs.bytestring) delete bc[TYPES.bytestring];
|
2722
|
-
|
2695
|
+
const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = false) => {
|
2723
2696
|
const known = knownType(scope, type);
|
2724
2697
|
if (known != null) {
|
2725
|
-
|
2698
|
+
if (Array.isArray(bc)) {
|
2699
|
+
let def;
|
2700
|
+
for (const [ type, wasm ] of bc) {
|
2701
|
+
if (type === 'default') {
|
2702
|
+
def = wasm;
|
2703
|
+
continue;
|
2704
|
+
}
|
2705
|
+
|
2706
|
+
if (Array.isArray(type)) {
|
2707
|
+
if (type.includes(known)) return wasm;
|
2708
|
+
} else if (type === known) return wasm;
|
2709
|
+
}
|
2710
|
+
|
2711
|
+
return def;
|
2712
|
+
} else {
|
2713
|
+
return bc[known] ?? bc.default;
|
2714
|
+
}
|
2726
2715
|
}
|
2727
2716
|
|
2728
2717
|
if (Prefs.typeswitchBrtable) {
|
2729
|
-
if (
|
2718
|
+
if (fallthrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`);
|
2730
2719
|
return brTable(type, bc, returns);
|
2731
2720
|
}
|
2732
2721
|
|
2733
|
-
typeswitchDepth
|
2734
|
-
|
2735
|
-
let bcArr = bc;
|
2736
|
-
// hack?: we do this so that typeswitchDepth can be properly handled
|
2737
|
-
if (typeof bcArr === 'function') {
|
2738
|
-
bcArr = bcArr();
|
2739
|
-
}
|
2740
|
-
// hack: we need to preserve insertion order for fall through so all objects are converted to entries
|
2741
|
-
if (!Array.isArray(bcArr)) {
|
2742
|
-
bcArr = Object.entries(bc);
|
2743
|
-
} else {
|
2744
|
-
bc = Object.fromEntries(bcArr);
|
2745
|
-
}
|
2746
|
-
|
2747
|
-
|
2748
|
-
const tmp = localTmp(scope, `#typeswitch_tmp${typeswitchDepth}${Prefs.typeswitchUniqueTmp ? uniqId() : ''}`, Valtype.i32);
|
2722
|
+
const tmp = localTmp(scope, `#typeswitch_tmp${++typeswitchDepth}${Prefs.typeswitchUniqueTmp ? uniqId() : ''}`, Valtype.i32);
|
2749
2723
|
const out = [
|
2750
2724
|
...type,
|
2751
2725
|
[ Opcodes.local_set, tmp ],
|
2752
2726
|
[ Opcodes.block, returns ]
|
2753
2727
|
];
|
2754
2728
|
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
}
|
2773
|
-
// if we found any types,
|
2774
|
-
if (types.length > 0) {
|
2775
|
-
for (let j = 0; j < types.length; j++) {
|
2776
|
-
// create the type tests
|
2777
|
-
out.push(
|
2778
|
-
[ Opcodes.local_get, tmp ],
|
2779
|
-
...number(types[j], Valtype.i32),
|
2780
|
-
[ Opcodes.i32_eq ]
|
2781
|
-
);
|
2782
|
-
// for every test but the first, or them together
|
2783
|
-
if (j != 0) out.push([ Opcodes.i32_or ]);
|
2784
|
-
}
|
2729
|
+
if (typeof bc === 'function') bc = bc();
|
2730
|
+
|
2731
|
+
let def;
|
2732
|
+
if (!Array.isArray(bc)) {
|
2733
|
+
def = bc.default;
|
2734
|
+
bc = Object.entries(bc);
|
2735
|
+
}
|
2736
|
+
|
2737
|
+
for (let i = 0; i < bc.length; i++) {
|
2738
|
+
let [ type, wasm ] = bc[i];
|
2739
|
+
if (type === 'default') {
|
2740
|
+
def = wasm;
|
2741
|
+
continue;
|
2742
|
+
}
|
2743
|
+
|
2744
|
+
if (Array.isArray(type)) {
|
2745
|
+
for (let j = 0; j < type.length; j++) {
|
2785
2746
|
out.push(
|
2786
|
-
|
2787
|
-
[
|
2788
|
-
|
2789
|
-
// we don't need an `br 1` here because depth[-1] should be 'switch', and that's the only place this is used right now
|
2790
|
-
[ Opcodes.end ]
|
2747
|
+
[ Opcodes.local_get, tmp ],
|
2748
|
+
...number(type[j], Valtype.i32),
|
2749
|
+
[ Opcodes.i32_eq ]
|
2791
2750
|
);
|
2751
|
+
|
2752
|
+
if (j > 0) out.push([ Opcodes.i32_or ]);
|
2792
2753
|
}
|
2793
2754
|
} else {
|
2794
|
-
// if type == x
|
2795
2755
|
out.push(
|
2796
2756
|
[ Opcodes.local_get, tmp ],
|
2797
|
-
...number(
|
2798
|
-
[ Opcodes.i32_eq ]
|
2799
|
-
[ Opcodes.if, Blocktype.void, `TYPESWITCH|${TYPE_NAMES[x]}` ],
|
2800
|
-
...bcArr[i][1],
|
2801
|
-
[ Opcodes.br, 1 ],
|
2802
|
-
[ Opcodes.end ]
|
2757
|
+
...number(type, Valtype.i32),
|
2758
|
+
[ Opcodes.i32_eq ]
|
2803
2759
|
);
|
2804
2760
|
}
|
2761
|
+
|
2762
|
+
out.push(
|
2763
|
+
[ Opcodes.if, Blocktype.void, `TYPESWITCH|${Array.isArray(type) ? type.map(t => TYPE_NAMES[t]).join(',') : TYPE_NAMES[type]}` ],
|
2764
|
+
...wasm,
|
2765
|
+
...(fallthrough ? [] : [ [ Opcodes.br, 1 ] ]),
|
2766
|
+
[ Opcodes.end ]
|
2767
|
+
);
|
2805
2768
|
}
|
2806
2769
|
|
2807
2770
|
// default
|
2808
|
-
if (
|
2771
|
+
if (def) out.push(...def);
|
2809
2772
|
else if (returns !== Blocktype.void) out.push(...number(0, returns));
|
2810
2773
|
|
2811
2774
|
out.push([ Opcodes.end, 'TYPESWITCH_end' ]);
|
@@ -2888,8 +2851,6 @@ const extractTypeAnnotation = decl => {
|
|
2888
2851
|
const typeName = type;
|
2889
2852
|
type = typeAnnoToPorfType(type);
|
2890
2853
|
|
2891
|
-
if (type === TYPES.bytestring && !Prefs.bytestring) type = TYPES.string;
|
2892
|
-
|
2893
2854
|
// if (decl.name) console.log(decl.name, { type, elementType });
|
2894
2855
|
|
2895
2856
|
return { type, typeName, elementType };
|
@@ -3700,19 +3661,18 @@ const generateUnary = (scope, decl) => {
|
|
3700
3661
|
const out = toGenerate ? generate(scope, decl.argument) : [];
|
3701
3662
|
disposeLeftover(out);
|
3702
3663
|
|
3703
|
-
out.push(...typeSwitch(scope, overrideType ?? getNodeType(scope, decl.argument),
|
3704
|
-
[TYPES.number
|
3705
|
-
[TYPES.boolean
|
3706
|
-
[TYPES.string
|
3707
|
-
[TYPES.undefined]
|
3708
|
-
[TYPES.function
|
3709
|
-
[TYPES.symbol
|
3710
|
-
[TYPES.bytestring
|
3711
|
-
[TYPES.empty]: makeString(scope, 'undefined', false, '#typeof_result'),
|
3664
|
+
out.push(...typeSwitch(scope, overrideType ?? getNodeType(scope, decl.argument), [
|
3665
|
+
[ TYPES.number, makeString(scope, 'number', false, '#typeof_result') ],
|
3666
|
+
[ TYPES.boolean, makeString(scope, 'boolean', false, '#typeof_result') ],
|
3667
|
+
[ TYPES.string, makeString(scope, 'string', false, '#typeof_result') ],
|
3668
|
+
[ [ TYPES.undefined, TYPES.empty ], makeString(scope, 'undefined', false, '#typeof_result') ],
|
3669
|
+
[ TYPES.function, makeString(scope, 'function', false, '#typeof_result') ],
|
3670
|
+
[ TYPES.symbol, makeString(scope, 'symbol', false, '#typeof_result') ],
|
3671
|
+
[ TYPES.bytestring, makeString(scope, 'string', false, '#typeof_result') ],
|
3712
3672
|
|
3713
3673
|
// object and internal types
|
3714
|
-
default
|
3715
|
-
|
3674
|
+
[ 'default', makeString(scope, 'object', false, '#typeof_result') ],
|
3675
|
+
]));
|
3716
3676
|
|
3717
3677
|
return out;
|
3718
3678
|
}
|
@@ -4030,7 +3990,7 @@ const generateForOf = (scope, decl) => {
|
|
4030
3990
|
Opcodes.i32_from_u,
|
4031
3991
|
[ Opcodes.local_set, tmp ],
|
4032
3992
|
|
4033
|
-
|
3993
|
+
...setVar,
|
4034
3994
|
|
4035
3995
|
[ Opcodes.block, Blocktype.void ],
|
4036
3996
|
[ Opcodes.block, Blocktype.void ],
|
@@ -4423,9 +4383,7 @@ const generateSwitch = (scope, decl) => {
|
|
4423
4383
|
|
4424
4384
|
depth.push('switch');
|
4425
4385
|
|
4426
|
-
if (
|
4427
|
-
decl.discriminant.type === 'CallExpression' && decl.discriminant.callee.type === 'Identifier' && decl.discriminant.callee.name === '__Porffor_rawType'
|
4428
|
-
) {
|
4386
|
+
if (decl.discriminant.type === 'CallExpression' && decl.discriminant.callee.type === 'Identifier' && decl.discriminant.callee.name === '__Porffor_rawType') {
|
4429
4387
|
const cases = []
|
4430
4388
|
let canTypeCheck = true;
|
4431
4389
|
for (const x of decl.cases) {
|
@@ -4437,8 +4395,9 @@ const generateSwitch = (scope, decl) => {
|
|
4437
4395
|
} else if (x.test.type === 'Identifier' && x.test.name.startsWith('__Porffor_TYPES_')) {
|
4438
4396
|
type = TYPES[x.test.name.slice('__Porffor_TYPES_'.length)];
|
4439
4397
|
}
|
4398
|
+
|
4440
4399
|
if (type !== undefined) {
|
4441
|
-
cases.push([type, x.consequent]);
|
4400
|
+
cases.push([ type, x.consequent ]);
|
4442
4401
|
} else {
|
4443
4402
|
canTypeCheck = false;
|
4444
4403
|
break;
|
@@ -4446,16 +4405,26 @@ const generateSwitch = (scope, decl) => {
|
|
4446
4405
|
}
|
4447
4406
|
|
4448
4407
|
if (canTypeCheck) {
|
4449
|
-
const
|
4450
|
-
|
4451
|
-
|
4452
|
-
const
|
4453
|
-
|
4454
|
-
|
4455
|
-
|
4456
|
-
|
4408
|
+
const out = typeSwitch(scope,
|
4409
|
+
getNodeType(scope, decl.discriminant.arguments[0]),
|
4410
|
+
() => {
|
4411
|
+
const bc = [];
|
4412
|
+
let types = [];
|
4413
|
+
for (const [ type, consequent ] of cases) {
|
4414
|
+
types.push(type);
|
4415
|
+
|
4416
|
+
if (consequent.length !== 0) {
|
4417
|
+
const o = generate(scope, { type: 'BlockStatement', body: consequent });
|
4418
|
+
bc.push([ types, o ]);
|
4419
|
+
types = [];
|
4420
|
+
}
|
4421
|
+
}
|
4422
|
+
|
4423
|
+
return bc;
|
4424
|
+
}, Blocktype.void, true);
|
4425
|
+
|
4457
4426
|
depth.pop();
|
4458
|
-
return
|
4427
|
+
return out;
|
4459
4428
|
}
|
4460
4429
|
}
|
4461
4430
|
|
@@ -5030,8 +4999,6 @@ const loadArray = (scope, array, index) => {
|
|
5030
4999
|
};
|
5031
5000
|
|
5032
5001
|
const byteStringable = str => {
|
5033
|
-
if (!Prefs.bytestring) return false;
|
5034
|
-
|
5035
5002
|
for (let i = 0; i < str.length; i++) {
|
5036
5003
|
if (str.charCodeAt(i) > 0xFF) return false;
|
5037
5004
|
}
|
@@ -5041,7 +5008,7 @@ const byteStringable = str => {
|
|
5041
5008
|
|
5042
5009
|
const makeString = (scope, str, global = false, name = '$undeclared', forceBytestring = undefined) => {
|
5043
5010
|
const rawElements = new Array(str.length);
|
5044
|
-
let byteStringable =
|
5011
|
+
let byteStringable = true;
|
5045
5012
|
for (let i = 0; i < str.length; i++) {
|
5046
5013
|
const c = str.charCodeAt(i);
|
5047
5014
|
rawElements[i] = c;
|
package/compiler/precompile.js
CHANGED
@@ -25,7 +25,7 @@ const compile = async (file, _funcs) => {
|
|
25
25
|
first = source.slice(0, source.indexOf('\n'));
|
26
26
|
}
|
27
27
|
|
28
|
-
let args = ['--
|
28
|
+
let args = ['--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data'];
|
29
29
|
if (first.startsWith('// @porf')) {
|
30
30
|
args = first.slice('// @porf '.length).split(' ').concat(args);
|
31
31
|
}
|
package/compiler/prefs.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
const onByDefault = [ '
|
1
|
+
const onByDefault = [ 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused', 'data', 'passiveData', 'rmUnusedTypes' ];
|
2
2
|
|
3
3
|
const nameToKey = x => x.replace(/[a-z]\-[a-z]/g, y => `${y[0]}${y[2].toUpperCase()}`);
|
4
4
|
|
package/compiler/prototype.js
CHANGED
@@ -306,129 +306,127 @@ export const PrototypeFuncs = function() {
|
|
306
306
|
this[TYPES.string].charCodeAt.local = Valtype.i32;
|
307
307
|
this[TYPES.string].charCodeAt.noPointerCache = zeroChecks.charcodeat;
|
308
308
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
const [ newOut, newPointer ] = arrayShell(1, 'i8');
|
313
|
-
|
314
|
-
return [
|
315
|
-
// setup new/out array and use pointer for store later
|
316
|
-
...newOut,
|
309
|
+
this[TYPES.bytestring] = {
|
310
|
+
at: (pointer, length, wIndex, wType, iTmp, _, arrayShell) => {
|
311
|
+
const [ newOut, newPointer ] = arrayShell(1, 'i8');
|
317
312
|
|
318
|
-
|
319
|
-
|
320
|
-
|
313
|
+
return [
|
314
|
+
// setup new/out array and use pointer for store later
|
315
|
+
...newOut,
|
321
316
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
[ Opcodes.if, Blocktype.void ],
|
326
|
-
[ Opcodes.local_get, iTmp ],
|
327
|
-
...length.getCachedI32(),
|
328
|
-
[ Opcodes.i32_add ],
|
329
|
-
[ Opcodes.local_set, iTmp ],
|
330
|
-
[ Opcodes.end ],
|
317
|
+
...wIndex,
|
318
|
+
Opcodes.i32_to_u,
|
319
|
+
[ Opcodes.local_tee, iTmp ],
|
331
320
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
321
|
+
// if index < 0: access index + array length
|
322
|
+
...number(0, Valtype.i32),
|
323
|
+
[ Opcodes.i32_lt_s ],
|
324
|
+
[ Opcodes.if, Blocktype.void ],
|
325
|
+
[ Opcodes.local_get, iTmp ],
|
326
|
+
...length.getCachedI32(),
|
327
|
+
[ Opcodes.i32_add ],
|
328
|
+
[ Opcodes.local_set, iTmp ],
|
329
|
+
[ Opcodes.end ],
|
336
330
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
331
|
+
// if still < 0 or >= length: return undefined
|
332
|
+
[ Opcodes.local_get, iTmp ],
|
333
|
+
...number(0, Valtype.i32),
|
334
|
+
[ Opcodes.i32_lt_s ],
|
341
335
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
336
|
+
[ Opcodes.local_get, iTmp ],
|
337
|
+
...length.getCachedI32(),
|
338
|
+
[ Opcodes.i32_ge_s ],
|
339
|
+
[ Opcodes.i32_or ],
|
346
340
|
|
347
|
-
|
341
|
+
[ Opcodes.if, Blocktype.void ],
|
342
|
+
...number(UNDEFINED),
|
343
|
+
[ Opcodes.br, 1 ],
|
344
|
+
[ Opcodes.end ],
|
348
345
|
|
349
|
-
|
350
|
-
[ Opcodes.i32_add ],
|
346
|
+
[ Opcodes.local_get, iTmp ],
|
351
347
|
|
352
|
-
|
353
|
-
|
348
|
+
...pointer,
|
349
|
+
[ Opcodes.i32_add ],
|
354
350
|
|
355
|
-
|
356
|
-
|
351
|
+
// load current string ind {arg}
|
352
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
357
353
|
|
358
|
-
|
359
|
-
|
360
|
-
Opcodes.i32_from_u
|
361
|
-
];
|
362
|
-
},
|
354
|
+
// store to new string ind 0
|
355
|
+
[ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
|
363
356
|
|
364
|
-
|
365
|
-
|
366
|
-
|
357
|
+
// return new string (pointer)
|
358
|
+
...newPointer,
|
359
|
+
Opcodes.i32_from_u
|
360
|
+
];
|
361
|
+
},
|
367
362
|
|
368
|
-
|
369
|
-
|
370
|
-
|
363
|
+
// todo: out of bounds properly
|
364
|
+
charAt: (pointer, length, wIndex, wType, _1, _2, arrayShell) => {
|
365
|
+
const [ newOut, newPointer ] = arrayShell(1, 'i8');
|
371
366
|
|
372
|
-
|
373
|
-
|
367
|
+
return [
|
368
|
+
// setup new/out array and use pointer for later
|
369
|
+
...newOut,
|
374
370
|
|
375
|
-
|
376
|
-
|
371
|
+
...wIndex,
|
372
|
+
Opcodes.i32_to,
|
377
373
|
|
378
|
-
|
379
|
-
|
374
|
+
...pointer,
|
375
|
+
[ Opcodes.i32_add ],
|
380
376
|
|
381
|
-
|
382
|
-
|
377
|
+
// load current string ind {arg}
|
378
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
383
379
|
|
384
|
-
|
385
|
-
|
386
|
-
Opcodes.i32_from_u
|
387
|
-
];
|
388
|
-
},
|
380
|
+
// store to new string ind 0
|
381
|
+
[ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
|
389
382
|
|
390
|
-
|
391
|
-
...
|
392
|
-
Opcodes.
|
383
|
+
// return new string (page)
|
384
|
+
...newPointer,
|
385
|
+
Opcodes.i32_from_u
|
386
|
+
];
|
387
|
+
},
|
393
388
|
|
394
|
-
|
395
|
-
|
389
|
+
charCodeAt: (pointer, length, wIndex, wType, iTmp) => [
|
390
|
+
...wIndex,
|
391
|
+
Opcodes.i32_to,
|
396
392
|
|
397
|
-
|
398
|
-
|
399
|
-
[ Opcodes.local_get, iTmp ],
|
400
|
-
...number(0, Valtype.i32),
|
401
|
-
[ Opcodes.i32_lt_s ],
|
402
|
-
]),
|
393
|
+
...(zeroChecks.charcodeat ? [] : [
|
394
|
+
[ Opcodes.local_set, iTmp ],
|
403
395
|
|
404
|
-
|
396
|
+
// index < 0
|
397
|
+
...(noUnlikelyChecks ? [] : [
|
405
398
|
[ Opcodes.local_get, iTmp ],
|
406
|
-
...
|
407
|
-
[ Opcodes.
|
399
|
+
...number(0, Valtype.i32),
|
400
|
+
[ Opcodes.i32_lt_s ],
|
401
|
+
]),
|
408
402
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
[ Opcodes.end ],
|
403
|
+
// index >= length
|
404
|
+
[ Opcodes.local_get, iTmp ],
|
405
|
+
...length.getCachedI32(),
|
406
|
+
[ Opcodes.i32_ge_s ],
|
414
407
|
|
415
|
-
|
416
|
-
]
|
408
|
+
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
409
|
+
[ Opcodes.if, Blocktype.void ],
|
410
|
+
...number(valtype === 'i32' ? -1 : NaN),
|
411
|
+
[ Opcodes.br, 1 ],
|
412
|
+
[ Opcodes.end ],
|
417
413
|
|
418
|
-
|
419
|
-
|
414
|
+
[ Opcodes.local_get, iTmp ],
|
415
|
+
]),
|
420
416
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
417
|
+
...pointer,
|
418
|
+
[ Opcodes.i32_add ],
|
419
|
+
|
420
|
+
// load current string ind {arg}
|
421
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
422
|
+
Opcodes.i32_from_u
|
423
|
+
]
|
424
|
+
};
|
425
|
+
|
426
|
+
this[TYPES.bytestring].at.local = Valtype.i32;
|
427
|
+
this[TYPES.bytestring].at.returnType = TYPES.bytestring;
|
428
|
+
this[TYPES.bytestring].charAt.returnType = TYPES.bytestring;
|
429
|
+
this[TYPES.bytestring].charCodeAt.returnType = TYPES.number;
|
430
|
+
this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
|
431
|
+
this[TYPES.bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
|
434
432
|
};
|
package/package.json
CHANGED