porffor 0.2.0-eeb45f8 → 0.2.0-f2bbe1f

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 CHANGED
@@ -215,7 +215,7 @@ Basically none right now (other than giving people headaches). Potential ideas:
215
215
  - More in future probably?
216
216
 
217
217
  ## Usage
218
- Basically nothing will work :). See files in `test` and `bench` for examples.
218
+ Basically nothing will work :). See files in `test` for examples.
219
219
 
220
220
  1. Clone repo
221
221
  2. `npm install`
@@ -55,7 +55,7 @@ const todo = msg => {
55
55
  };
56
56
 
57
57
  const isFuncType = type => type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression';
58
- const generate = (scope, decl, global = false, name = undefined, valueUnused = false) => {
58
+ const generate = (scope, decl, global = false, name = undefined) => {
59
59
  switch (decl.type) {
60
60
  case 'BinaryExpression':
61
61
  return generateBinaryExp(scope, decl, global, name);
@@ -86,7 +86,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
86
86
  return generateExp(scope, decl);
87
87
 
88
88
  case 'CallExpression':
89
- return generateCall(scope, decl, global, name, valueUnused);
89
+ return generateCall(scope, decl, global, name);
90
90
 
91
91
  case 'NewExpression':
92
92
  return generateNew(scope, decl, global, name);
@@ -685,15 +685,6 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
685
685
  [ Opcodes.i32_eqz ], */
686
686
  ...(intOut ? [] : [ Opcodes.i32_from_u ])
687
687
  ],
688
- [TYPES._bytestring]: [ // duplicate of string
689
- [ Opcodes.local_get, tmp ],
690
- ...(intIn ? [] : [ Opcodes.i32_to_u ]),
691
-
692
- // get length
693
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
694
-
695
- ...(intOut ? [] : [ Opcodes.i32_from_u ])
696
- ],
697
688
  default: def
698
689
  }, intOut ? Valtype.i32 : valtypeBinary)
699
690
  ];
@@ -721,17 +712,6 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
721
712
  [ Opcodes.i32_eqz ],
722
713
  ...(intOut ? [] : [ Opcodes.i32_from_u ])
723
714
  ],
724
- [TYPES._bytestring]: [ // duplicate of string
725
- [ Opcodes.local_get, tmp ],
726
- ...(intIn ? [] : [ Opcodes.i32_to_u ]),
727
-
728
- // get length
729
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
730
-
731
- // if length == 0
732
- [ Opcodes.i32_eqz ],
733
- ...(intOut ? [] : [ Opcodes.i32_from_u ])
734
- ],
735
715
  default: [
736
716
  // if value == 0
737
717
  [ Opcodes.local_get, tmp ],
@@ -1064,8 +1044,7 @@ const TYPES = {
1064
1044
 
1065
1045
  // these are not "typeof" types but tracked internally
1066
1046
  _array: 0x10,
1067
- _regexp: 0x11,
1068
- _bytestring: 0x12
1047
+ _regexp: 0x11
1069
1048
  };
1070
1049
 
1071
1050
  const TYPE_NAMES = {
@@ -1079,8 +1058,7 @@ const TYPE_NAMES = {
1079
1058
  [TYPES.bigint]: 'BigInt',
1080
1059
 
1081
1060
  [TYPES._array]: 'Array',
1082
- [TYPES._regexp]: 'RegExp',
1083
- [TYPES._bytestring]: 'ByteString'
1061
+ [TYPES._regexp]: 'RegExp'
1084
1062
  };
1085
1063
 
1086
1064
  const getType = (scope, _name) => {
@@ -1133,8 +1111,6 @@ const getNodeType = (scope, node) => {
1133
1111
  if (node.type === 'Literal') {
1134
1112
  if (node.regex) return TYPES._regexp;
1135
1113
 
1136
- if (typeof node.value === 'string' && byteStringable(node.value)) return TYPES._bytestring;
1137
-
1138
1114
  return TYPES[typeof node.value];
1139
1115
  }
1140
1116
 
@@ -1148,15 +1124,6 @@ const getNodeType = (scope, node) => {
1148
1124
 
1149
1125
  if (node.type === 'CallExpression' || node.type === 'NewExpression') {
1150
1126
  const name = node.callee.name;
1151
- if (!name) {
1152
- // iife
1153
- if (scope.locals['#last_type']) return [ getLastType(scope) ];
1154
-
1155
- // presume
1156
- // todo: warn here?
1157
- return TYPES.number;
1158
- }
1159
-
1160
1127
  const func = funcs.find(x => x.name === name);
1161
1128
 
1162
1129
  if (func) {
@@ -1251,7 +1218,7 @@ const getNodeType = (scope, node) => {
1251
1218
  if (node.operator === '!') return TYPES.boolean;
1252
1219
  if (node.operator === 'void') return TYPES.undefined;
1253
1220
  if (node.operator === 'delete') return TYPES.boolean;
1254
- if (node.operator === 'typeof') return process.argv.includes('-bytestring') ? TYPES._bytestring : TYPES.string;
1221
+ if (node.operator === 'typeof') return TYPES.string;
1255
1222
 
1256
1223
  return TYPES.number;
1257
1224
  }
@@ -1260,9 +1227,7 @@ const getNodeType = (scope, node) => {
1260
1227
  // hack: if something.length, number type
1261
1228
  if (node.property.name === 'length') return TYPES.number;
1262
1229
 
1263
- if (scope.locals['#last_type']) return [ getLastType(scope) ];
1264
-
1265
- // presume
1230
+ // we cannot guess
1266
1231
  return TYPES.number;
1267
1232
  }
1268
1233
 
@@ -1334,9 +1299,9 @@ const countLeftover = wasm => {
1334
1299
 
1335
1300
  if (depth === 0)
1336
1301
  if ([Opcodes.throw,Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
1337
- else if ([null, Opcodes.i32_eqz, Opcodes.i64_eqz, Opcodes.f64_ceil, Opcodes.f64_floor, Opcodes.f64_trunc, Opcodes.f64_nearest, Opcodes.f64_sqrt, Opcodes.local_tee, Opcodes.i32_wrap_i64, Opcodes.i64_extend_i32_s, Opcodes.i64_extend_i32_u, Opcodes.f32_demote_f64, Opcodes.f64_promote_f32, Opcodes.f64_convert_i32_s, Opcodes.f64_convert_i32_u, Opcodes.i32_clz, Opcodes.i32_ctz, Opcodes.i32_popcnt, Opcodes.f64_neg, Opcodes.end, Opcodes.i32_trunc_sat_f64_s[0], Opcodes.i32x4_extract_lane, Opcodes.i16x8_extract_lane, Opcodes.i32_load, Opcodes.i64_load, Opcodes.f64_load, Opcodes.v128_load, Opcodes.i32_load16_u, Opcodes.i32_load16_s, Opcodes.i32_load8_u, Opcodes.i32_load8_s, Opcodes.memory_grow].includes(inst[0]) && (inst[0] !== 0xfc || inst[1] < 0x0a)) {}
1302
+ else if ([null, Opcodes.i32_eqz, Opcodes.i64_eqz, Opcodes.f64_ceil, Opcodes.f64_floor, Opcodes.f64_trunc, Opcodes.f64_nearest, Opcodes.f64_sqrt, Opcodes.local_tee, Opcodes.i32_wrap_i64, Opcodes.i64_extend_i32_s, Opcodes.i64_extend_i32_u, Opcodes.f32_demote_f64, Opcodes.f64_promote_f32, Opcodes.f64_convert_i32_s, Opcodes.f64_convert_i32_u, Opcodes.i32_clz, Opcodes.i32_ctz, Opcodes.i32_popcnt, Opcodes.f64_neg, Opcodes.end, Opcodes.i32_trunc_sat_f64_s[0], Opcodes.i32x4_extract_lane, Opcodes.i16x8_extract_lane, Opcodes.i32_load, Opcodes.i64_load, Opcodes.f64_load, Opcodes.v128_load, Opcodes.i32_load16_u, Opcodes.i32_load16_s, Opcodes.memory_grow].includes(inst[0]) && (inst[0] !== 0xfc || inst[1] < 0x0a)) {}
1338
1303
  else if ([Opcodes.local_get, Opcodes.global_get, Opcodes.f64_const, Opcodes.i32_const, Opcodes.i64_const, Opcodes.v128_const].includes(inst[0])) count++;
1339
- else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.i32_store16, Opcodes.i32_store8].includes(inst[0])) count -= 2;
1304
+ else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.i32_store16].includes(inst[0])) count -= 2;
1340
1305
  else if (Opcodes.memory_copy[0] === inst[0] && Opcodes.memory_copy[1] === inst[1]) count -= 3;
1341
1306
  else if (inst[0] === Opcodes.return) count = 0;
1342
1307
  else if (inst[0] === Opcodes.call) {
@@ -1362,7 +1327,7 @@ const disposeLeftover = wasm => {
1362
1327
  const generateExp = (scope, decl) => {
1363
1328
  const expression = decl.expression;
1364
1329
 
1365
- const out = generate(scope, expression, undefined, undefined, true);
1330
+ const out = generate(scope, expression);
1366
1331
  disposeLeftover(out);
1367
1332
 
1368
1333
  return out;
@@ -1420,7 +1385,7 @@ const RTArrayUtil = {
1420
1385
  ]
1421
1386
  };
1422
1387
 
1423
- const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1388
+ const generateCall = (scope, decl, _global, _name) => {
1424
1389
  /* const callee = decl.callee;
1425
1390
  const args = decl.arguments;
1426
1391
 
@@ -1539,18 +1504,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1539
1504
  // use local for cached i32 length as commonly used
1540
1505
  const lengthLocal = localTmp(scope, '__proto_length_cache', Valtype.i32);
1541
1506
  const pointerLocal = localTmp(scope, '__proto_pointer_cache', Valtype.i32);
1507
+ const getPointer = [ [ Opcodes.local_get, pointerLocal ] ];
1542
1508
 
1543
1509
  // TODO: long-term, prototypes should be their individual separate funcs
1544
1510
 
1545
- const rawPointer = [
1546
- ...generate(scope, target),
1547
- Opcodes.i32_to_u
1548
- ];
1549
-
1550
- const usePointerCache = !Object.values(protoCands).every(x => x.noPointerCache === true);
1551
- const getPointer = usePointerCache ? [ [ Opcodes.local_get, pointerLocal ] ] : rawPointer;
1552
-
1553
- let allOptUnused = true;
1554
1511
  let lengthI32CacheUsed = false;
1555
1512
  const protoBC = {};
1556
1513
  for (const x in protoCands) {
@@ -1570,7 +1527,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1570
1527
  const protoLocal = protoFunc.local ? localTmp(scope, `__${protoName}_tmp`, protoFunc.local) : -1;
1571
1528
  const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
1572
1529
 
1573
- let optUnused = false;
1574
1530
  const protoOut = protoFunc(getPointer, {
1575
1531
  getCachedI32: () => {
1576
1532
  lengthI32CacheUsed = true;
@@ -1585,15 +1541,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1585
1541
  return makeArray(scope, {
1586
1542
  rawElements: new Array(length)
1587
1543
  }, _global, _name, true, itemType);
1588
- }, () => {
1589
- optUnused = true;
1590
- return unusedValue;
1591
1544
  });
1592
1545
 
1593
- if (!optUnused) allOptUnused = false;
1594
-
1595
1546
  protoBC[x] = [
1596
- [ Opcodes.block, unusedValue && optUnused ? Blocktype.void : valtypeBinary ],
1547
+ [ Opcodes.block, valtypeBinary ],
1597
1548
  ...protoOut,
1598
1549
 
1599
1550
  ...number(protoFunc.returnType ?? TYPES.number, Valtype.i32),
@@ -1602,13 +1553,11 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1602
1553
  ];
1603
1554
  }
1604
1555
 
1605
- // todo: if some cands use optUnused and some don't, we will probably crash
1606
-
1607
1556
  return [
1608
- ...(usePointerCache ? [
1609
- ...rawPointer,
1610
- [ Opcodes.local_set, pointerLocal ],
1611
- ] : []),
1557
+ ...generate(scope, target),
1558
+
1559
+ Opcodes.i32_to_u,
1560
+ [ Opcodes.local_set, pointerLocal ],
1612
1561
 
1613
1562
  ...(!lengthI32CacheUsed ? [] : [
1614
1563
  ...RTArrayUtil.getLengthI32(getPointer),
@@ -1620,7 +1569,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1620
1569
 
1621
1570
  // TODO: error better
1622
1571
  default: internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl`)
1623
- }, allOptUnused && unusedValue ? Blocktype.void : valtypeBinary),
1572
+ }, valtypeBinary),
1624
1573
  ];
1625
1574
  }
1626
1575
  }
@@ -1828,8 +1777,6 @@ const brTable = (input, bc, returns) => {
1828
1777
  };
1829
1778
 
1830
1779
  const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
1831
- if (!process.argv.includes('-bytestring')) delete bc[TYPES._bytestring];
1832
-
1833
1780
  const known = knownType(scope, type);
1834
1781
  if (known != null) {
1835
1782
  return bc[known] ?? bc.default;
@@ -2220,8 +2167,6 @@ const generateUnary = (scope, decl) => {
2220
2167
  [TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
2221
2168
  [TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
2222
2169
 
2223
- [TYPES._bytestring]: makeString(scope, 'string', false, '#typeof_result'),
2224
-
2225
2170
  // object and internal types
2226
2171
  default: makeString(scope, 'object', false, '#typeof_result'),
2227
2172
  });
@@ -2403,14 +2348,13 @@ const generateForOf = (scope, decl) => {
2403
2348
  // // todo: we should only do this for strings but we don't know at compile-time :(
2404
2349
  // hack: this is naughty and will break things!
2405
2350
  let newOut = number(0, Valtype.f64), newPointer = -1;
2406
- if (pages.hasAnyString) {
2351
+ if (pages.hasString) {
2407
2352
  0, [ newOut, newPointer ] = makeArray(scope, {
2408
2353
  rawElements: new Array(1)
2409
2354
  }, isGlobal, leftName, true, 'i16');
2410
2355
  }
2411
2356
 
2412
2357
  // set type for local
2413
- // todo: optimize away counter and use end pointer
2414
2358
  out.push(...typeSwitch(scope, getNodeType(scope, decl.right), {
2415
2359
  [TYPES._array]: [
2416
2360
  ...setType(scope, leftName, TYPES.number),
@@ -2596,8 +2540,6 @@ const allocPage = (reason, type) => {
2596
2540
 
2597
2541
  if (reason.startsWith('array:')) pages.hasArray = true;
2598
2542
  if (reason.startsWith('string:')) pages.hasString = true;
2599
- if (reason.startsWith('bytestring:')) pages.hasByteString = true;
2600
- if (reason.includes('string:')) pages.hasAnyString = true;
2601
2543
 
2602
2544
  const ind = pages.size;
2603
2545
  pages.set(reason, { ind, type });
@@ -2631,8 +2573,7 @@ const StoreOps = {
2631
2573
  f64: Opcodes.f64_store,
2632
2574
 
2633
2575
  // expects i32 input!
2634
- i8: Opcodes.i32_store8,
2635
- i16: Opcodes.i32_store16,
2576
+ i16: Opcodes.i32_store16
2636
2577
  };
2637
2578
 
2638
2579
  let data = [];
@@ -2651,15 +2592,6 @@ const compileBytes = (val, itemType, signed = true) => {
2651
2592
  }
2652
2593
  };
2653
2594
 
2654
- const getAllocType = itemType => {
2655
- switch (itemType) {
2656
- case 'i8': return 'bytestring';
2657
- case 'i16': return 'string';
2658
-
2659
- default: return 'array';
2660
- }
2661
- };
2662
-
2663
2595
  const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false, itemType = valtype) => {
2664
2596
  const out = [];
2665
2597
 
@@ -2669,7 +2601,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
2669
2601
 
2670
2602
  // todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
2671
2603
  const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
2672
- arrays.set(name, allocPage(`${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
2604
+ arrays.set(name, allocPage(`${itemType === 'i16' ? 'string' : 'array'}: ${uniqueName}`, itemType) * pageSize);
2673
2605
  }
2674
2606
 
2675
2607
  const pointer = arrays.get(name);
@@ -2715,7 +2647,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
2715
2647
  out.push(
2716
2648
  ...number(0, Valtype.i32),
2717
2649
  ...(useRawElements ? number(elements[i], Valtype[valtype]) : generate(scope, elements[i])),
2718
- [ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(pointer + ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
2650
+ [ storeOp, Math.log2(ValtypeSize[itemType]) - 1, ...unsignedLEB128(pointer + ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
2719
2651
  );
2720
2652
  }
2721
2653
 
@@ -2725,29 +2657,15 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
2725
2657
  return [ out, pointer ];
2726
2658
  };
2727
2659
 
2728
- const byteStringable = str => {
2729
- if (!process.argv.includes('-bytestring')) return false;
2730
-
2731
- for (let i = 0; i < str.length; i++) {
2732
- if (str.charCodeAt(i) > 0xFF) return false;
2733
- }
2734
-
2735
- return true;
2736
- };
2737
-
2738
2660
  const makeString = (scope, str, global = false, name = '$undeclared') => {
2739
2661
  const rawElements = new Array(str.length);
2740
- let byteStringable = process.argv.includes('-bytestring');
2741
2662
  for (let i = 0; i < str.length; i++) {
2742
- const c = str.charCodeAt(i);
2743
- rawElements[i] = c;
2744
-
2745
- if (byteStringable && c > 0xFF) byteStringable = false;
2663
+ rawElements[i] = str.charCodeAt(i);
2746
2664
  }
2747
2665
 
2748
2666
  return makeArray(scope, {
2749
2667
  rawElements
2750
- }, global, name, false, byteStringable ? 'i8' : 'i16')[0];
2668
+ }, global, name, false, 'i16')[0];
2751
2669
  };
2752
2670
 
2753
2671
  let arrays = new Map();
@@ -2775,13 +2693,10 @@ export const generateMember = (scope, decl, _global, _name) => {
2775
2693
  ];
2776
2694
  }
2777
2695
 
2778
- const object = generate(scope, decl.object);
2779
- const property = generate(scope, decl.property);
2780
-
2781
2696
  // // todo: we should only do this for strings but we don't know at compile-time :(
2782
2697
  // hack: this is naughty and will break things!
2783
2698
  let newOut = number(0, valtypeBinary), newPointer = -1;
2784
- if (pages.hasAnyString) {
2699
+ if (pages.hasString) {
2785
2700
  0, [ newOut, newPointer ] = makeArray(scope, {
2786
2701
  rawElements: new Array(1)
2787
2702
  }, _global, _name, true, 'i16');
@@ -2790,7 +2705,7 @@ export const generateMember = (scope, decl, _global, _name) => {
2790
2705
  return typeSwitch(scope, getNodeType(scope, decl.object), {
2791
2706
  [TYPES._array]: [
2792
2707
  // get index as valtype
2793
- ...property,
2708
+ ...generate(scope, decl.property),
2794
2709
 
2795
2710
  // convert to i32 and turn into byte offset by * valtypeSize (4 for i32, 8 for i64/f64)
2796
2711
  Opcodes.i32_to_u,
@@ -2798,7 +2713,7 @@ export const generateMember = (scope, decl, _global, _name) => {
2798
2713
  [ Opcodes.i32_mul ],
2799
2714
 
2800
2715
  ...(aotPointer ? [] : [
2801
- ...object,
2716
+ ...generate(scope, decl.object),
2802
2717
  Opcodes.i32_to_u,
2803
2718
  [ Opcodes.i32_add ]
2804
2719
  ]),
@@ -2817,14 +2732,14 @@ export const generateMember = (scope, decl, _global, _name) => {
2817
2732
 
2818
2733
  ...number(0, Valtype.i32), // base 0 for store later
2819
2734
 
2820
- ...property,
2821
- Opcodes.i32_to_u,
2735
+ ...generate(scope, decl.property),
2822
2736
 
2737
+ Opcodes.i32_to_u,
2823
2738
  ...number(ValtypeSize.i16, Valtype.i32),
2824
2739
  [ Opcodes.i32_mul ],
2825
2740
 
2826
2741
  ...(aotPointer ? [] : [
2827
- ...object,
2742
+ ...generate(scope, decl.object),
2828
2743
  Opcodes.i32_to_u,
2829
2744
  [ Opcodes.i32_add ]
2830
2745
  ]),
@@ -2841,34 +2756,6 @@ export const generateMember = (scope, decl, _global, _name) => {
2841
2756
  ...number(TYPES.string, Valtype.i32),
2842
2757
  setLastType(scope)
2843
2758
  ],
2844
- [TYPES._bytestring]: [
2845
- // setup new/out array
2846
- ...newOut,
2847
- [ Opcodes.drop ],
2848
-
2849
- ...number(0, Valtype.i32), // base 0 for store later
2850
-
2851
- ...property,
2852
- Opcodes.i32_to_u,
2853
-
2854
- ...(aotPointer ? [] : [
2855
- ...object,
2856
- Opcodes.i32_to_u,
2857
- [ Opcodes.i32_add ]
2858
- ]),
2859
-
2860
- // load current string ind {arg}
2861
- [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
2862
-
2863
- // store to new string ind 0
2864
- [ Opcodes.i32_store8, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
2865
-
2866
- // return new string (page)
2867
- ...number(newPointer),
2868
-
2869
- ...number(TYPES._bytestring, Valtype.i32),
2870
- setLastType(scope)
2871
- ],
2872
2759
 
2873
2760
  default: [ [ Opcodes.unreachable ] ]
2874
2761
  });
@@ -2950,8 +2837,10 @@ const generateFunc = (scope, decl) => {
2950
2837
  const func = {
2951
2838
  name,
2952
2839
  params: Object.values(innerScope.locals).slice(0, params.length * 2).map(x => x.type),
2953
- index: currentFuncIndex++,
2954
- ...innerScope
2840
+ returns: innerScope.returns,
2841
+ locals: innerScope.locals,
2842
+ throws: innerScope.throws,
2843
+ index: currentFuncIndex++
2955
2844
  };
2956
2845
  funcIndex[name] = func.index;
2957
2846
 
package/compiler/opt.js CHANGED
@@ -192,7 +192,6 @@ export default (funcs, globals, pages, tags) => {
192
192
  let missing = false;
193
193
  if (type === 'Array') missing = !pages.hasArray;
194
194
  if (type === 'String') missing = !pages.hasString;
195
- if (type === 'ByteString') missing = !pages.hasByteString;
196
195
 
197
196
  if (missing) {
198
197
  let j = i, depth = 0;
@@ -16,8 +16,7 @@ const TYPES = {
16
16
 
17
17
  // these are not "typeof" types but tracked internally
18
18
  _array: 0x10,
19
- _regexp: 0x11,
20
- _bytestring: 0x12
19
+ _regexp: 0x11
21
20
  };
22
21
 
23
22
  // todo: turn these into built-ins once arrays and these become less hacky
@@ -72,7 +71,7 @@ export const PrototypeFuncs = function() {
72
71
  ],
73
72
 
74
73
  // todo: only for 1 argument
75
- push: (pointer, length, wNewMember, _1, _2, _3, unusedValue) => [
74
+ push: (pointer, length, wNewMember) => [
76
75
  // get memory offset of array at last index (length)
77
76
  ...length.getCachedI32(),
78
77
  ...number(ValtypeSize[valtype], Valtype.i32),
@@ -93,28 +92,22 @@ export const PrototypeFuncs = function() {
93
92
  ...number(1, Valtype.i32),
94
93
  [ Opcodes.i32_add ],
95
94
 
96
- ...(unusedValue() ? [] : [
97
- ...length.setCachedI32(),
98
- ...length.getCachedI32(),
99
- ])
95
+ ...length.setCachedI32(),
96
+ ...length.getCachedI32(),
100
97
  ]),
101
98
 
102
- ...(unusedValue() ? [] : [
103
- ...length.getCachedI32(),
104
- Opcodes.i32_from_u
105
- ])
99
+ ...length.getCachedI32(),
100
+ Opcodes.i32_from_u
106
101
 
107
102
  // ...length.get()
108
103
  ],
109
104
 
110
- pop: (pointer, length, _1, _2, _3, _4, unusedValue) => [
105
+ pop: (pointer, length) => [
111
106
  // if length == 0, noop
112
107
  ...length.getCachedI32(),
113
108
  [ Opcodes.i32_eqz ],
114
109
  [ Opcodes.if, Blocktype.void ],
115
- ...(unusedValue() ? [] : [
116
- ...number(UNDEFINED),
117
- ]),
110
+ ...number(UNDEFINED),
118
111
  [ Opcodes.br, 1 ],
119
112
  [ Opcodes.end ],
120
113
 
@@ -126,23 +119,19 @@ export const PrototypeFuncs = function() {
126
119
  ...number(1, Valtype.i32),
127
120
  [ Opcodes.i32_sub ],
128
121
 
129
- ...(unusedValue() ? [] : [
130
- ...length.setCachedI32(),
131
- ...length.getCachedI32(),
132
- ])
122
+ ...length.setCachedI32(),
123
+ ...length.getCachedI32(),
133
124
  ]),
134
125
 
135
126
  // load last element
136
- ...(unusedValue() ? [] : [
137
- ...length.getCachedI32(),
138
- ...number(ValtypeSize[valtype], Valtype.i32),
139
- [ Opcodes.i32_mul ],
127
+ ...length.getCachedI32(),
128
+ ...number(ValtypeSize[valtype], Valtype.i32),
129
+ [ Opcodes.i32_mul ],
140
130
 
141
- ...pointer,
142
- [ Opcodes.i32_add ],
131
+ ...pointer,
132
+ [ Opcodes.i32_add ],
143
133
 
144
- [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
145
- ])
134
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
146
135
  ],
147
136
 
148
137
  shift: (pointer, length) => [
@@ -483,152 +472,8 @@ export const PrototypeFuncs = function() {
483
472
  this[TYPES.string].at.returnType = TYPES.string;
484
473
  this[TYPES.string].charAt.returnType = TYPES.string;
485
474
  this[TYPES.string].charCodeAt.local = Valtype.i32;
486
- this[TYPES.string].charCodeAt.noPointerCache = zeroChecks.charcodeat;
487
475
 
488
476
  this[TYPES.string].isWellFormed.local = Valtype.i32;
489
477
  this[TYPES.string].isWellFormed.local2 = Valtype.i32;
490
478
  this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
491
-
492
- if (process.argv.includes('-bytestring')) {
493
- this[TYPES._bytestring] = {
494
- at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
495
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
496
-
497
- return [
498
- // setup new/out array
499
- ...newOut,
500
- [ Opcodes.drop ],
501
-
502
- ...number(0, Valtype.i32), // base 0 for store later
503
-
504
- ...wIndex,
505
- Opcodes.i32_to_u,
506
- [ Opcodes.local_tee, iTmp ],
507
-
508
- // if index < 0: access index + array length
509
- ...number(0, Valtype.i32),
510
- [ Opcodes.i32_lt_s ],
511
- [ Opcodes.if, Blocktype.void ],
512
- [ Opcodes.local_get, iTmp ],
513
- ...length.getCachedI32(),
514
- [ Opcodes.i32_add ],
515
- [ Opcodes.local_set, iTmp ],
516
- [ Opcodes.end ],
517
-
518
- // if still < 0 or >= length: return undefined
519
- [ Opcodes.local_get, iTmp ],
520
- ...number(0, Valtype.i32),
521
- [ Opcodes.i32_lt_s ],
522
-
523
- [ Opcodes.local_get, iTmp ],
524
- ...length.getCachedI32(),
525
- [ Opcodes.i32_ge_s ],
526
- [ Opcodes.i32_or ],
527
-
528
- [ Opcodes.if, Blocktype.void ],
529
- ...number(UNDEFINED),
530
- [ Opcodes.br, 1 ],
531
- [ Opcodes.end ],
532
-
533
- [ Opcodes.local_get, iTmp ],
534
-
535
- ...pointer,
536
- [ Opcodes.i32_add ],
537
-
538
- // load current string ind {arg}
539
- [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
540
-
541
- // store to new string ind 0
542
- [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
543
-
544
- // return new string (pointer)
545
- ...number(newPointer)
546
- ];
547
- },
548
-
549
- // todo: out of bounds properly
550
- charAt: (pointer, length, wIndex, _1, _2, arrayShell) => {
551
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
552
-
553
- return [
554
- // setup new/out array
555
- ...newOut,
556
- [ Opcodes.drop ],
557
-
558
- ...number(0, Valtype.i32), // base 0 for store later
559
-
560
- ...wIndex,
561
-
562
- Opcodes.i32_to,
563
-
564
- ...pointer,
565
- [ Opcodes.i32_add ],
566
-
567
- // load current string ind {arg}
568
- [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
569
-
570
- // store to new string ind 0
571
- [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
572
-
573
- // return new string (page)
574
- ...number(newPointer)
575
- ];
576
- },
577
-
578
- charCodeAt: (pointer, length, wIndex, iTmp) => {
579
- return [
580
- ...wIndex,
581
- Opcodes.i32_to,
582
-
583
- ...(zeroChecks.charcodeat ? [] : [
584
- [ Opcodes.local_set, iTmp ],
585
-
586
- // index < 0
587
- ...(noUnlikelyChecks ? [] : [
588
- [ Opcodes.local_get, iTmp ],
589
- ...number(0, Valtype.i32),
590
- [ Opcodes.i32_lt_s ],
591
- ]),
592
-
593
- // index >= length
594
- [ Opcodes.local_get, iTmp ],
595
- ...length.getCachedI32(),
596
- [ Opcodes.i32_ge_s ],
597
-
598
- ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
599
- [ Opcodes.if, Blocktype.void ],
600
- ...number(NaN),
601
- [ Opcodes.br, 1 ],
602
- [ Opcodes.end ],
603
-
604
- [ Opcodes.local_get, iTmp ],
605
- ]),
606
-
607
- ...pointer,
608
- [ Opcodes.i32_add ],
609
-
610
- // load current string ind {arg}
611
- [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
612
- Opcodes.i32_from_u
613
- ];
614
- },
615
-
616
- isWellFormed: () => {
617
- return [
618
- // we know it must be true as it is a bytestring lol
619
- ...number(1)
620
- ]
621
- }
622
- };
623
-
624
- this[TYPES._bytestring].at.local = Valtype.i32;
625
- this[TYPES._bytestring].at.returnType = TYPES._bytestring;
626
- this[TYPES._bytestring].charAt.returnType = TYPES._bytestring;
627
- this[TYPES._bytestring].charCodeAt.local = Valtype.i32;
628
- this[TYPES._bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
629
-
630
- this[TYPES._bytestring].isWellFormed.local = Valtype.i32;
631
- this[TYPES._bytestring].isWellFormed.local2 = Valtype.i32;
632
- this[TYPES._bytestring].isWellFormed.returnType = TYPES.boolean;
633
- }
634
479
  };
@@ -57,12 +57,9 @@ export const Opcodes = {
57
57
  i64_load: 0x29,
58
58
  f64_load: 0x2b,
59
59
 
60
- i32_load8_s: 0x2c,
61
- i32_load8_u: 0x2d,
62
60
  i32_load16_s: 0x2e,
63
61
  i32_load16_u: 0x2f,
64
62
 
65
- i32_store8: 0x3a,
66
63
  i32_store16: 0x3b,
67
64
 
68
65
  i32_store: 0x36,
package/compiler/wrap.js CHANGED
@@ -19,8 +19,7 @@ const TYPES = {
19
19
 
20
20
  // internal
21
21
  [internalTypeBase]: '_array',
22
- [internalTypeBase + 1]: '_regexp',
23
- [internalTypeBase + 2]: '_bytestring'
22
+ [internalTypeBase + 1]: '_regexp'
24
23
  };
25
24
 
26
25
  export default async (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
@@ -49,9 +48,6 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
49
48
  }
50
49
  });
51
50
  } catch (e) {
52
- // only backtrace for runner, not test262/etc
53
- if (!process.argv[1].includes('/runner')) throw e;
54
-
55
51
  const funcInd = parseInt(e.message.match(/function #([0-9]+) /)[1]);
56
52
  const blobOffset = parseInt(e.message.split('@')[1]);
57
53
 
@@ -181,13 +177,6 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
181
177
  return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
182
178
  }
183
179
 
184
- case '_bytestring': {
185
- const pointer = ret;
186
- const length = new Int32Array(memory.buffer, pointer, 1);
187
-
188
- return Array.from(new Uint8Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
189
- }
190
-
191
180
  case 'function': {
192
181
  // wasm func index, including all imports
193
182
  const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
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.2.0-eeb45f8",
4
+ "version": "0.2.0-f2bbe1f",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "dependencies": {