porffor 0.2.0-767de65 → 0.2.0-812b38c

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.
@@ -1,4 +1,4 @@
1
- // @porf -funsafe-no-unlikely-proto-checks -valtype=i32
1
+ // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
2
 
3
3
  import type {} from './porffor';
4
4
 
@@ -1,4 +1,4 @@
1
- // @porf -funsafe-no-unlikely-proto-checks
1
+ // @porf --funsafe-no-unlikely-proto-checks
2
2
 
3
3
  // radix: number|any for rawType check
4
4
  // export const parseInt = (input: string|bytestring, radix: number|any): f64 => {
@@ -1,4 +1,4 @@
1
- // // @porf -funsafe-no-unlikely-proto-checks
1
+ // @porf --funsafe-no-unlikely-proto-checks
2
2
 
3
3
  // radix: number|any for rawType check
4
4
  export const __Number_prototype_toString = (_this: number, radix: number|any) => {
@@ -1,4 +1,4 @@
1
- // @porf -funsafe-no-unlikely-proto-checks -valtype=i32
1
+ // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
2
 
3
3
  export const __String_fromCharCode = (code: i32) => {
4
4
  // todo: support >1 arg
@@ -1,4 +1,4 @@
1
- // // @porf -funsafe-no-unlikely-proto-checks -valtype=i32
1
+ // // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
2
 
3
3
  export const __Boolean_prototype_toString = (_this: boolean) => {
4
4
  let out: bytestring = '';
@@ -23,6 +23,12 @@ export const importedFuncs = [
23
23
  params: 0,
24
24
  returns: 1
25
25
  },
26
+ {
27
+ name: 'timeOrigin',
28
+ import: 'u',
29
+ params: 0,
30
+ returns: 1
31
+ },
26
32
  {
27
33
  name: 'profile1',
28
34
  import: 'y',
@@ -140,6 +146,10 @@ export const BuiltinVars = function() {
140
146
  for (const x in TYPES) {
141
147
  this['__Porffor_TYPES_' + x] = number(TYPES[x]);
142
148
  }
149
+
150
+ this.__performance_timeOrigin = [
151
+ [ Opcodes.call, importedFuncs.timeOrigin ]
152
+ ];
143
153
  };
144
154
 
145
155
  export const BuiltinFuncs = function() {
@@ -206,7 +216,7 @@ export const BuiltinFuncs = function() {
206
216
  };
207
217
 
208
218
 
209
- this.__console_log = {
219
+ this.__Porffor_print = {
210
220
  params: [ valtypeBinary, Valtype.i32 ],
211
221
  typedParams: true,
212
222
  locals: [ Valtype.i32, Valtype.i32 ],
@@ -358,10 +368,7 @@ export const BuiltinFuncs = function() {
358
368
  [ Opcodes.local_get, 0 ],
359
369
  [ Opcodes.call, importedFuncs.print ],
360
370
  ]
361
- }, Blocktype.void),
362
-
363
- ...char('\n'),
364
- [ Opcodes.call, importedFuncs.printChar ]
371
+ }, Blocktype.void)
365
372
  ]
366
373
  };
367
374
 
@@ -210,7 +210,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
210
210
  return int;
211
211
  });
212
212
 
213
- out.push([ ...inst, ...immediates ]);
213
+ out.push([ ...inst, ...immediates.flatMap(x => signedLEB128(x)) ]);
214
214
  }
215
215
 
216
216
  return out;
@@ -1273,6 +1273,18 @@ const getNodeType = (scope, node) => {
1273
1273
  return TYPES.number;
1274
1274
  }
1275
1275
 
1276
+ if (node.type === 'NewExpression' && builtinFuncs[name + '$constructor']) {
1277
+ if (builtinFuncs[name + '$constructor'].typedReturns) {
1278
+ if (scope.locals['#last_type']) return getLastType(scope);
1279
+
1280
+ // presume
1281
+ // todo: warn here?
1282
+ return TYPES.number;
1283
+ }
1284
+
1285
+ return builtinFuncs[name + '$constructor'].returnType ?? TYPES.number;
1286
+ }
1287
+
1276
1288
  const func = funcs.find(x => x.name === name);
1277
1289
 
1278
1290
  if (func) {
@@ -1460,16 +1472,23 @@ const countLeftover = wasm => {
1460
1472
  if (depth === 0)
1461
1473
  if ([Opcodes.throw, Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
1462
1474
  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)) {}
1463
- else if ([Opcodes.local_get, Opcodes.global_get, Opcodes.f64_const, Opcodes.i32_const, Opcodes.i64_const, Opcodes.v128_const].includes(inst[0])) count++;
1475
+ else if ([Opcodes.local_get, Opcodes.global_get, Opcodes.f64_const, Opcodes.i32_const, Opcodes.i64_const, Opcodes.v128_const, Opcodes.memory_size].includes(inst[0])) count++;
1464
1476
  else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.i32_store16, Opcodes.i32_store8].includes(inst[0])) count -= 2;
1465
1477
  else if (Opcodes.memory_copy[0] === inst[0] && Opcodes.memory_copy[1] === inst[1]) count -= 3;
1466
1478
  else if (inst[0] === Opcodes.return) count = 0;
1467
1479
  else if (inst[0] === Opcodes.call) {
1468
1480
  let func = funcs.find(x => x.index === inst[1]);
1469
- if (func) {
1470
- count -= func.params.length;
1471
- } else count--;
1472
- if (func) count += func.returns.length;
1481
+ if (inst[1] === -1) {
1482
+ // todo: count for calling self
1483
+ } else if (!func && inst[1] < importedFuncs.length) {
1484
+ count -= importedFuncs[inst[1]].params;
1485
+ count += importedFuncs[inst[1]].returns;
1486
+ } else {
1487
+ if (func) {
1488
+ count -= func.params.length;
1489
+ } else count--;
1490
+ if (func) count += func.returns.length;
1491
+ }
1473
1492
  } else count--;
1474
1493
 
1475
1494
  // console.log(count, decompile([ inst ]).slice(0, -1));
@@ -1627,18 +1646,25 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1627
1646
  // megahack for /regex/.func()
1628
1647
  const funcName = decl.callee.property.name;
1629
1648
  if (decl.callee.object.regex && Object.hasOwn(Rhemyn, funcName)) {
1630
- const func = Rhemyn[funcName](decl.callee.object.regex.pattern, currentFuncIndex++);
1649
+ const regex = decl.callee.object.regex.pattern;
1650
+ const rhemynName = `regex_${funcName}_${regex}`;
1651
+
1652
+ if (!funcIndex[rhemynName]) {
1653
+ const func = Rhemyn[funcName](regex, currentFuncIndex++, rhemynName);
1631
1654
 
1632
- funcIndex[func.name] = func.index;
1633
- funcs.push(func);
1655
+ funcIndex[func.name] = func.index;
1656
+ funcs.push(func);
1657
+ }
1634
1658
 
1659
+ const idx = funcIndex[rhemynName];
1635
1660
  return [
1636
1661
  // make string arg
1637
1662
  ...generate(scope, decl.arguments[0]),
1663
+ Opcodes.i32_to_u,
1664
+ ...getNodeType(scope, decl.arguments[0]),
1638
1665
 
1639
1666
  // call regex func
1640
- Opcodes.i32_to_u,
1641
- [ Opcodes.call, func.index ],
1667
+ [ Opcodes.call, idx ],
1642
1668
  Opcodes.i32_from_u,
1643
1669
 
1644
1670
  ...number(TYPES.boolean, Valtype.i32),
@@ -1678,6 +1704,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1678
1704
 
1679
1705
  protoBC[type] = generateCall(scope, {
1680
1706
  callee: {
1707
+ type: 'Identifier',
1681
1708
  name: x
1682
1709
  },
1683
1710
  arguments: [ target, ...decl.arguments ],
@@ -1826,28 +1853,28 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1826
1853
  if (idx === undefined && name.startsWith('__Porffor_wasm_')) {
1827
1854
  const wasmOps = {
1828
1855
  // pointer, align, offset
1829
- i32_load: { imms: 2, args: 1, returns: 1 },
1856
+ i32_load: { imms: 2, args: [ true ], returns: 1 },
1830
1857
  // pointer, value, align, offset
1831
- i32_store: { imms: 2, args: 2, returns: 0 },
1858
+ i32_store: { imms: 2, args: [ true, true ], returns: 0 },
1832
1859
  // pointer, align, offset
1833
- i32_load8_u: { imms: 2, args: 1, returns: 1 },
1860
+ i32_load8_u: { imms: 2, args: [ true ], returns: 1 },
1834
1861
  // pointer, value, align, offset
1835
- i32_store8: { imms: 2, args: 2, returns: 0 },
1862
+ i32_store8: { imms: 2, args: [ true, true ], returns: 0 },
1836
1863
  // pointer, align, offset
1837
- i32_load16_u: { imms: 2, args: 1, returns: 1 },
1864
+ i32_load16_u: { imms: 2, args: [ true ], returns: 1 },
1838
1865
  // pointer, value, align, offset
1839
- i32_store16: { imms: 2, args: 2, returns: 0 },
1866
+ i32_store16: { imms: 2, args: [ true, true ], returns: 0 },
1840
1867
 
1841
1868
  // pointer, align, offset
1842
- f64_load: { imms: 2, args: 1, returns: 1 },
1869
+ f64_load: { imms: 2, args: [ true ], returns: 0 }, // 0 due to not i32
1843
1870
  // pointer, value, align, offset
1844
- f64_store: { imms: 2, args: 2, returns: 0 },
1871
+ f64_store: { imms: 2, args: [ true, false ], returns: 0 },
1845
1872
 
1846
1873
  // value
1847
- i32_const: { imms: 1, args: 0, returns: 1 },
1874
+ i32_const: { imms: 1, args: [], returns: 1 },
1848
1875
 
1849
1876
  // a, b
1850
- i32_or: { imms: 0, args: 2, returns: 1 },
1877
+ i32_or: { imms: 0, args: [ true, true ], returns: 1 },
1851
1878
  };
1852
1879
 
1853
1880
  const opName = name.slice('__Porffor_wasm_'.length);
@@ -1856,13 +1883,13 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1856
1883
  const op = wasmOps[opName];
1857
1884
 
1858
1885
  const argOut = [];
1859
- for (let i = 0; i < op.args; i++) argOut.push(
1886
+ for (let i = 0; i < op.args.length; i++) argOut.push(
1860
1887
  ...generate(scope, decl.arguments[i]),
1861
- Opcodes.i32_to
1888
+ ...(op.args[i] ? [ Opcodes.i32_to ] : [])
1862
1889
  );
1863
1890
 
1864
1891
  // literals only
1865
- const imms = decl.arguments.slice(op.args).map(x => x.value);
1892
+ const imms = decl.arguments.slice(op.args.length).map(x => x.value);
1866
1893
 
1867
1894
  return [
1868
1895
  ...argOut,
@@ -1937,7 +1964,20 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1937
1964
  const generateNew = (scope, decl, _global, _name) => {
1938
1965
  // hack: basically treat this as a normal call for builtins for now
1939
1966
  const name = mapName(decl.callee.name);
1967
+
1940
1968
  if (internalConstrs[name] && !internalConstrs[name].notConstr) return internalConstrs[name].generate(scope, decl, _global, _name);
1969
+
1970
+ if (builtinFuncs[name + '$constructor']) {
1971
+ // custom ...$constructor override builtin func
1972
+ return generateCall(scope, {
1973
+ ...decl,
1974
+ callee: {
1975
+ type: 'Identifier',
1976
+ name: name + '$constructor'
1977
+ }
1978
+ }, _global, _name);
1979
+ }
1980
+
1941
1981
  if (!builtinFuncs[name]) return todo(scope, `new statement is not supported yet`); // return todo(scope, `new statement is not supported yet (new ${unhackName(name)})`);
1942
1982
 
1943
1983
  return generateCall(scope, decl, _global, _name);
@@ -2128,8 +2168,8 @@ const addVarMetadata = (scope, name, global = false, metadata = {}) => {
2128
2168
 
2129
2169
  const typeAnnoToPorfType = x => {
2130
2170
  if (!x) return null;
2131
- if (TYPES[x] != null) return TYPES[x];
2132
- if (TYPES['_' + x] != null) return TYPES['_' + x];
2171
+ if (TYPES[x.toLowerCase()] != null) return TYPES[x.toLowerCase()];
2172
+ if (TYPES['_' + x.toLowerCase()] != null) return TYPES['_' + x.toLowerCase()];
2133
2173
 
2134
2174
  switch (x) {
2135
2175
  case 'i32':
@@ -2194,7 +2234,7 @@ const generateVar = (scope, decl) => {
2194
2234
  }
2195
2235
 
2196
2236
  const typed = typedInput && x.id.typeAnnotation;
2197
- let idx = allocVar(scope, name, global, !typed);
2237
+ let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(x.id).type != null));
2198
2238
 
2199
2239
  if (typed) {
2200
2240
  addVarMetadata(scope, name, global, extractTypeAnnotation(x.id));
@@ -3473,6 +3513,8 @@ const internalConstrs = {
3473
3513
  );
3474
3514
  }
3475
3515
 
3516
+ out.push(Opcodes.i32_from_u);
3517
+
3476
3518
  return out;
3477
3519
  },
3478
3520
  type: TYPES.boolean,
@@ -3491,6 +3533,8 @@ const internalConstrs = {
3491
3533
  );
3492
3534
  }
3493
3535
 
3536
+ out.push(Opcodes.i32_from_u);
3537
+
3494
3538
  return out;
3495
3539
  },
3496
3540
  type: TYPES.boolean,
@@ -3545,6 +3589,39 @@ const internalConstrs = {
3545
3589
  type: TYPES.number,
3546
3590
  notConstr: true,
3547
3591
  length: 2
3592
+ },
3593
+
3594
+ __console_log: {
3595
+ generate: (scope, decl) => {
3596
+ const out = [];
3597
+
3598
+ for (let i = 0; i < decl.arguments.length; i++) {
3599
+ out.push(
3600
+ ...generateCall(scope, {
3601
+ callee: {
3602
+ type: 'Identifier',
3603
+ name: '__Porffor_print'
3604
+ },
3605
+ arguments: [ decl.arguments[i] ]
3606
+ }),
3607
+
3608
+ // print space
3609
+ ...number(32),
3610
+ [ Opcodes.call, importedFuncs.printChar ]
3611
+ );
3612
+ }
3613
+
3614
+ // print newline
3615
+ out.push(
3616
+ ...number(10),
3617
+ [ Opcodes.call, importedFuncs.printChar ]
3618
+ );
3619
+
3620
+ return out;
3621
+ },
3622
+ type: TYPES.undefined,
3623
+ notConstr: true,
3624
+ length: 0
3548
3625
  }
3549
3626
  };
3550
3627
 
@@ -3579,7 +3656,7 @@ export default program => {
3579
3656
 
3580
3657
  globalThis.valtype = 'f64';
3581
3658
 
3582
- const valtypeOpt = process.argv.find(x => x.startsWith('-valtype='));
3659
+ const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
3583
3660
  if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
3584
3661
 
3585
3662
  globalThis.valtypeBinary = Valtype[valtype];
@@ -3587,7 +3664,7 @@ export default program => {
3587
3664
  const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
3588
3665
 
3589
3666
  globalThis.pageSize = PageSize;
3590
- const pageSizeOpt = process.argv.find(x => x.startsWith('-page-size='));
3667
+ const pageSizeOpt = process.argv.find(x => x.startsWith('--page-size='));
3591
3668
  if (pageSizeOpt) pageSize = parseInt(pageSizeOpt.split('=')[1]) * 1024;
3592
3669
 
3593
3670
  // set generic opcodes for current valtype
@@ -110,7 +110,6 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
110
110
 
111
111
  out += '\n';
112
112
  lastInst = inst;
113
- i++;
114
113
  }
115
114
 
116
115
  return highlightAsm(out);