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.
@@ -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
- [TYPES.bytestring]: [ // duplicate of string
605
- ...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
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: def
678
- }, intOut ? Valtype.i32 : valtypeBinary)
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.undefined]: [
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
- }, intOut ? Valtype.i32 : valtypeBinary)
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 Prefs.bytestring ? TYPES.bytestring : TYPES.string;
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, allowFallThrough = false) => {
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
- return bc[known] ?? bc.default;
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 (allowFallThrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`);
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
- for (let i = 0; i < bcArr.length; i++) {
2756
- const x = bcArr[i][0];
2757
- if (x === 'default') continue;
2758
-
2759
- if (allowFallThrough) {
2760
- let types = [];
2761
- let wasm;
2762
- while (i < bcArr.length) {
2763
- if (bcArr[i][0] === 'default') continue;
2764
- types.push(bcArr[i][0]);
2765
- // look for an empty array, essentially acting as an additional type for our typecheck
2766
- const bodyWasm = bcArr[i][1];
2767
- if (bodyWasm.length != 0) {
2768
- wasm = bodyWasm;
2769
- break;
2770
- }
2771
- i++;
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
- // create the consequent
2787
- [ Opcodes.if, Blocktype.void, `TYPESWITCH|${types.map(t => TYPE_NAMES[t]).join(',')}` ],
2788
- ...wasm,
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(bcArr[i][0], Valtype.i32),
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 (bc.default) out.push(...bc.default);
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]: makeString(scope, 'number', false, '#typeof_result'),
3705
- [TYPES.boolean]: makeString(scope, 'boolean', false, '#typeof_result'),
3706
- [TYPES.string]: makeString(scope, 'string', false, '#typeof_result'),
3707
- [TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
3708
- [TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
3709
- [TYPES.symbol]: makeString(scope, 'symbol', false, '#typeof_result'),
3710
- [TYPES.bytestring]: makeString(scope, 'string', false, '#typeof_result'),
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: makeString(scope, 'object', false, '#typeof_result'),
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
- ...setVar,
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 ret = typeSwitch(scope, getNodeType(scope, decl.discriminant.arguments[0]), () => {
4450
- const ret = [];
4451
- for (const [type, consequent] of cases) {
4452
- const o = generate(scope, { type: 'BlockStatement', body: consequent });
4453
- ret.push([type, o]);
4454
- }
4455
- return ret;
4456
- }, Blocktype.void, true);
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 ret;
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 = Prefs.bytestring;
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;
@@ -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 = ['--bytestring', '--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'];
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 = [ 'bytestring', 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused', 'data', 'passiveData', 'rmUnusedTypes' ];
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
 
@@ -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
- if (Prefs.bytestring) {
310
- this[TYPES.bytestring] = {
311
- at: (pointer, length, wIndex, wType, iTmp, _, arrayShell) => {
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
- ...wIndex,
319
- Opcodes.i32_to_u,
320
- [ Opcodes.local_tee, iTmp ],
313
+ return [
314
+ // setup new/out array and use pointer for store later
315
+ ...newOut,
321
316
 
322
- // if index < 0: access index + array length
323
- ...number(0, Valtype.i32),
324
- [ Opcodes.i32_lt_s ],
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
- // if still < 0 or >= length: return undefined
333
- [ Opcodes.local_get, iTmp ],
334
- ...number(0, Valtype.i32),
335
- [ Opcodes.i32_lt_s ],
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
- [ Opcodes.local_get, iTmp ],
338
- ...length.getCachedI32(),
339
- [ Opcodes.i32_ge_s ],
340
- [ Opcodes.i32_or ],
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
- [ Opcodes.if, Blocktype.void ],
343
- ...number(UNDEFINED),
344
- [ Opcodes.br, 1 ],
345
- [ Opcodes.end ],
336
+ [ Opcodes.local_get, iTmp ],
337
+ ...length.getCachedI32(),
338
+ [ Opcodes.i32_ge_s ],
339
+ [ Opcodes.i32_or ],
346
340
 
347
- [ Opcodes.local_get, iTmp ],
341
+ [ Opcodes.if, Blocktype.void ],
342
+ ...number(UNDEFINED),
343
+ [ Opcodes.br, 1 ],
344
+ [ Opcodes.end ],
348
345
 
349
- ...pointer,
350
- [ Opcodes.i32_add ],
346
+ [ Opcodes.local_get, iTmp ],
351
347
 
352
- // load current string ind {arg}
353
- [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
348
+ ...pointer,
349
+ [ Opcodes.i32_add ],
354
350
 
355
- // store to new string ind 0
356
- [ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
351
+ // load current string ind {arg}
352
+ [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
357
353
 
358
- // return new string (pointer)
359
- ...newPointer,
360
- Opcodes.i32_from_u
361
- ];
362
- },
354
+ // store to new string ind 0
355
+ [ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
363
356
 
364
- // todo: out of bounds properly
365
- charAt: (pointer, length, wIndex, wType, _1, _2, arrayShell) => {
366
- const [ newOut, newPointer ] = arrayShell(1, 'i8');
357
+ // return new string (pointer)
358
+ ...newPointer,
359
+ Opcodes.i32_from_u
360
+ ];
361
+ },
367
362
 
368
- return [
369
- // setup new/out array and use pointer for later
370
- ...newOut,
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
- ...wIndex,
373
- Opcodes.i32_to,
367
+ return [
368
+ // setup new/out array and use pointer for later
369
+ ...newOut,
374
370
 
375
- ...pointer,
376
- [ Opcodes.i32_add ],
371
+ ...wIndex,
372
+ Opcodes.i32_to,
377
373
 
378
- // load current string ind {arg}
379
- [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
374
+ ...pointer,
375
+ [ Opcodes.i32_add ],
380
376
 
381
- // store to new string ind 0
382
- [ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
377
+ // load current string ind {arg}
378
+ [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
383
379
 
384
- // return new string (page)
385
- ...newPointer,
386
- Opcodes.i32_from_u
387
- ];
388
- },
380
+ // store to new string ind 0
381
+ [ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
389
382
 
390
- charCodeAt: (pointer, length, wIndex, wType, iTmp) => [
391
- ...wIndex,
392
- Opcodes.i32_to,
383
+ // return new string (page)
384
+ ...newPointer,
385
+ Opcodes.i32_from_u
386
+ ];
387
+ },
393
388
 
394
- ...(zeroChecks.charcodeat ? [] : [
395
- [ Opcodes.local_set, iTmp ],
389
+ charCodeAt: (pointer, length, wIndex, wType, iTmp) => [
390
+ ...wIndex,
391
+ Opcodes.i32_to,
396
392
 
397
- // index < 0
398
- ...(noUnlikelyChecks ? [] : [
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
- // index >= length
396
+ // index < 0
397
+ ...(noUnlikelyChecks ? [] : [
405
398
  [ Opcodes.local_get, iTmp ],
406
- ...length.getCachedI32(),
407
- [ Opcodes.i32_ge_s ],
399
+ ...number(0, Valtype.i32),
400
+ [ Opcodes.i32_lt_s ],
401
+ ]),
408
402
 
409
- ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
410
- [ Opcodes.if, Blocktype.void ],
411
- ...number(valtype === 'i32' ? -1 : NaN),
412
- [ Opcodes.br, 1 ],
413
- [ Opcodes.end ],
403
+ // index >= length
404
+ [ Opcodes.local_get, iTmp ],
405
+ ...length.getCachedI32(),
406
+ [ Opcodes.i32_ge_s ],
414
407
 
415
- [ Opcodes.local_get, iTmp ],
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
- ...pointer,
419
- [ Opcodes.i32_add ],
414
+ [ Opcodes.local_get, iTmp ],
415
+ ]),
420
416
 
421
- // load current string ind {arg}
422
- [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
423
- Opcodes.i32_from_u
424
- ]
425
- };
426
-
427
- this[TYPES.bytestring].at.local = Valtype.i32;
428
- this[TYPES.bytestring].at.returnType = TYPES.bytestring;
429
- this[TYPES.bytestring].charAt.returnType = TYPES.bytestring;
430
- this[TYPES.bytestring].charCodeAt.returnType = TYPES.number;
431
- this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
432
- this[TYPES.bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.37.3+36b86e571",
4
+ "version": "0.37.5+c797bd00d",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.37.3+36b86e571';
3
+ globalThis.version = '0.37.5+c797bd00d';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {