porffor 0.2.0-fde989a → 0.14.0-4057a18e9

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.
Files changed (60) hide show
  1. package/CONTRIBUTING.md +256 -0
  2. package/LICENSE +20 -20
  3. package/README.md +131 -86
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +216 -0
  7. package/compiler/2c.js +2 -53
  8. package/compiler/{sections.js → assemble.js} +84 -21
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +18 -0
  11. package/compiler/builtins/array.ts +145 -0
  12. package/compiler/builtins/base64.ts +76 -0
  13. package/compiler/builtins/boolean.ts +18 -0
  14. package/compiler/builtins/crypto.ts +120 -0
  15. package/compiler/builtins/date.ts +2067 -0
  16. package/compiler/builtins/escape.ts +141 -0
  17. package/compiler/builtins/function.ts +5 -0
  18. package/compiler/builtins/int.ts +145 -0
  19. package/compiler/builtins/number.ts +529 -0
  20. package/compiler/builtins/object.ts +4 -0
  21. package/compiler/builtins/porffor.d.ts +60 -0
  22. package/compiler/builtins/set.ts +187 -0
  23. package/compiler/builtins/string.ts +1080 -0
  24. package/compiler/builtins.js +436 -283
  25. package/compiler/{codeGen.js → codegen.js} +1027 -482
  26. package/compiler/decompile.js +2 -3
  27. package/compiler/embedding.js +22 -22
  28. package/compiler/encoding.js +94 -10
  29. package/compiler/expression.js +1 -1
  30. package/compiler/generated_builtins.js +1625 -0
  31. package/compiler/index.js +25 -36
  32. package/compiler/log.js +6 -3
  33. package/compiler/opt.js +55 -41
  34. package/compiler/parse.js +38 -30
  35. package/compiler/precompile.js +120 -0
  36. package/compiler/prefs.js +27 -0
  37. package/compiler/prototype.js +31 -46
  38. package/compiler/types.js +38 -0
  39. package/compiler/wasmSpec.js +33 -8
  40. package/compiler/wrap.js +88 -70
  41. package/package.json +9 -5
  42. package/porf +2 -0
  43. package/rhemyn/compile.js +46 -27
  44. package/rhemyn/parse.js +322 -320
  45. package/rhemyn/test/parse.js +58 -58
  46. package/runner/compare.js +33 -34
  47. package/runner/debug.js +117 -0
  48. package/runner/index.js +78 -11
  49. package/runner/profiler.js +75 -0
  50. package/runner/repl.js +40 -13
  51. package/runner/sizes.js +37 -37
  52. package/runner/version.js +10 -8
  53. package/compiler/builtins/base64.js +0 -92
  54. package/filesize.cmd +0 -2
  55. package/runner/info.js +0 -89
  56. package/runner/profile.js +0 -46
  57. package/runner/results.json +0 -1
  58. package/runner/transform.js +0 -15
  59. package/tmp.c +0 -661
  60. package/util/enum.js +0 -20
@@ -0,0 +1,27 @@
1
+ const onByDefault = [ 'bytestring', 'aotPointerOpt', 'treeshakeWasmImports', 'alwaysMemory' ];
2
+
3
+ let cache = {};
4
+ const obj = new Proxy({}, {
5
+ get(_, p) {
6
+ // intentionally misses with undefined values cached
7
+ if (cache[p]) return cache[p];
8
+
9
+ return cache[p] = (() => {
10
+ // fooBar -> foo-bar
11
+ const name = p[0] === '_' ? p : p.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);
12
+ const prefix = name.length === 1 ? '-' : '--';
13
+ if (process.argv.includes(prefix + name)) return true;
14
+ if (process.argv.includes(prefix + 'no-' + name)) return false;
15
+
16
+ const valArg = process.argv.find(x => x.startsWith(`${prefix}${name}=`));
17
+ if (valArg) return valArg.slice(name.length + 1 + prefix.length);
18
+
19
+ if (onByDefault.includes(p)) return true;
20
+ return undefined;
21
+ })();
22
+ }
23
+ });
24
+
25
+ obj.uncache = () => cache = {};
26
+
27
+ export default obj;
@@ -1,34 +1,20 @@
1
- import { Opcodes, Blocktype, Valtype, ValtypeSize, PageSize } from "./wasmSpec.js";
2
- import { number } from "./embedding.js";
3
- import { unsignedLEB128 } from "./encoding.js";
4
- import { UNDEFINED } from "./builtins.js";
5
-
6
- // todo: do not duplicate this
7
- const TYPES = {
8
- number: 0x00,
9
- boolean: 0x01,
10
- string: 0x02,
11
- undefined: 0x03,
12
- object: 0x04,
13
- function: 0x05,
14
- symbol: 0x06,
15
- bigint: 0x07,
16
-
17
- // these are not "typeof" types but tracked internally
18
- _array: 0x10,
19
- _regexp: 0x11,
20
- _bytestring: 0x12
21
- };
1
+ import { Opcodes, Blocktype, Valtype, ValtypeSize } from './wasmSpec.js';
2
+ import { number } from './embedding.js';
3
+ import { unsignedLEB128 } from './encoding.js';
4
+ import { UNDEFINED } from './builtins.js';
5
+ import { TYPES } from './types.js';
6
+ import Prefs from './prefs.js';
22
7
 
23
8
  // todo: turn these into built-ins once arrays and these become less hacky
24
9
 
25
10
  export const PrototypeFuncs = function() {
26
- const noUnlikelyChecks = process.argv.includes('-funsafe-no-unlikely-proto-checks');
27
- let zeroChecks = process.argv.find(x => x.startsWith('-funsafe-zero-proto-checks='));
28
- if (zeroChecks) zeroChecks = zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
11
+ const noUnlikelyChecks = Prefs.funsafeNoUnlikelyProtoChecks;
12
+
13
+ let zeroChecks;
14
+ if (Prefs.zeroChecks) zeroChecks = Prefs.zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
29
15
  else zeroChecks = {};
30
16
 
31
- this[TYPES._array] = {
17
+ this[TYPES.array] = {
32
18
  // lX = local accessor of X ({ get, set }), iX = local index of X, wX = wasm ops of X
33
19
  at: (pointer, length, wIndex, iTmp) => [
34
20
  ...wIndex,
@@ -148,7 +134,7 @@ export const PrototypeFuncs = function() {
148
134
  shift: (pointer, length) => [
149
135
  // if length == 0, noop
150
136
  ...length.getCachedI32(),
151
- Opcodes.i32_eqz,
137
+ [ Opcodes.i32_eqz ],
152
138
  [ Opcodes.if, Blocktype.void ],
153
139
  ...number(UNDEFINED),
154
140
  [ Opcodes.br, 1 ],
@@ -267,10 +253,10 @@ export const PrototypeFuncs = function() {
267
253
  ]
268
254
  };
269
255
 
270
- this[TYPES._array].at.local = Valtype.i32;
271
- this[TYPES._array].push.noArgRetLength = true;
272
- this[TYPES._array].fill.local = valtypeBinary;
273
- this[TYPES._array].fill.returnType = TYPES._array;
256
+ this[TYPES.array].at.local = Valtype.i32;
257
+ this[TYPES.array].push.noArgRetLength = true;
258
+ this[TYPES.array].fill.local = valtypeBinary;
259
+ this[TYPES.array].fill.returnType = TYPES.array;
274
260
 
275
261
  this[TYPES.string] = {
276
262
  at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
@@ -342,8 +328,8 @@ export const PrototypeFuncs = function() {
342
328
  ...number(0, Valtype.i32), // base 0 for store later
343
329
 
344
330
  ...wIndex,
345
-
346
331
  Opcodes.i32_to,
332
+
347
333
  ...number(ValtypeSize.i16, Valtype.i32),
348
334
  [ Opcodes.i32_mul ],
349
335
 
@@ -383,7 +369,7 @@ export const PrototypeFuncs = function() {
383
369
 
384
370
  ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
385
371
  [ Opcodes.if, Blocktype.void ],
386
- ...number(NaN),
372
+ ...number(valtype === 'i32' ? -1 : NaN),
387
373
  [ Opcodes.br, 1 ],
388
374
  [ Opcodes.end ],
389
375
 
@@ -489,10 +475,10 @@ export const PrototypeFuncs = function() {
489
475
  this[TYPES.string].isWellFormed.local2 = Valtype.i32;
490
476
  this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
491
477
 
492
- if (process.argv.includes('-bytestring')) {
493
- this[TYPES._bytestring] = {
478
+ if (Prefs.bytestring) {
479
+ this[TYPES.bytestring] = {
494
480
  at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
495
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
481
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
496
482
 
497
483
  return [
498
484
  // setup new/out array
@@ -548,7 +534,7 @@ export const PrototypeFuncs = function() {
548
534
 
549
535
  // todo: out of bounds properly
550
536
  charAt: (pointer, length, wIndex, _1, _2, arrayShell) => {
551
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
537
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
552
538
 
553
539
  return [
554
540
  // setup new/out array
@@ -558,7 +544,6 @@ export const PrototypeFuncs = function() {
558
544
  ...number(0, Valtype.i32), // base 0 for store later
559
545
 
560
546
  ...wIndex,
561
-
562
547
  Opcodes.i32_to,
563
548
 
564
549
  ...pointer,
@@ -597,7 +582,7 @@ export const PrototypeFuncs = function() {
597
582
 
598
583
  ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
599
584
  [ Opcodes.if, Blocktype.void ],
600
- ...number(NaN),
585
+ ...number(valtype === 'i32' ? -1 : NaN),
601
586
  [ Opcodes.br, 1 ],
602
587
  [ Opcodes.end ],
603
588
 
@@ -621,14 +606,14 @@ export const PrototypeFuncs = function() {
621
606
  }
622
607
  };
623
608
 
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;
609
+ this[TYPES.bytestring].at.local = Valtype.i32;
610
+ this[TYPES.bytestring].at.returnType = TYPES.bytestring;
611
+ this[TYPES.bytestring].charAt.returnType = TYPES.bytestring;
612
+ this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
613
+ this[TYPES.bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
629
614
 
630
- this[TYPES._bytestring].isWellFormed.local = Valtype.i32;
631
- this[TYPES._bytestring].isWellFormed.local2 = Valtype.i32;
632
- this[TYPES._bytestring].isWellFormed.returnType = TYPES.boolean;
615
+ this[TYPES.bytestring].isWellFormed.local = Valtype.i32;
616
+ this[TYPES.bytestring].isWellFormed.local2 = Valtype.i32;
617
+ this[TYPES.bytestring].isWellFormed.returnType = TYPES.boolean;
633
618
  }
634
619
  };
@@ -0,0 +1,38 @@
1
+ export const TYPES = {
2
+ number: 0x00,
3
+ boolean: 0x01,
4
+ string: 0x02,
5
+ undefined: 0x03,
6
+ object: 0x04,
7
+ function: 0x05,
8
+ symbol: 0x06,
9
+ bigint: 0x07
10
+ };
11
+
12
+ export const TYPE_NAMES = {
13
+ [TYPES.number]: 'Number',
14
+ [TYPES.boolean]: 'Boolean',
15
+ [TYPES.string]: 'String',
16
+ [TYPES.undefined]: 'undefined',
17
+ [TYPES.object]: 'Object',
18
+ [TYPES.function]: 'Function',
19
+ [TYPES.symbol]: 'Symbol',
20
+ [TYPES.bigint]: 'BigInt'
21
+ };
22
+
23
+ export const INTERNAL_TYPE_BASE = 0x10;
24
+ let internalTypeIndex = INTERNAL_TYPE_BASE;
25
+ const registerInternalType = name => {
26
+ const n = internalTypeIndex++;
27
+ TYPES[name.toLowerCase()] = n;
28
+ TYPE_NAMES[n] = name;
29
+ };
30
+
31
+ // note: when adding a new internal type, please also add a deserializer to wrap.js
32
+ // (it is okay to add a throw todo deserializer for wips)
33
+
34
+ registerInternalType('Array');
35
+ registerInternalType('RegExp');
36
+ registerInternalType('ByteString');
37
+ registerInternalType('Date');
38
+ registerInternalType('Set');
@@ -1,4 +1,13 @@
1
- import { enumify } from "../util/enum.js";
1
+ const enumify = (...args) => {
2
+ const obj = {};
3
+
4
+ for (let i = 0; i < args.length; i++) {
5
+ obj[i] = args[i];
6
+ obj[args[i]] = i;
7
+ }
8
+
9
+ return obj;
10
+ };
2
11
 
3
12
  export const Section = enumify('custom', 'type', 'import', 'func', 'table', 'memory', 'global', 'export', 'start', 'element', 'code', 'data', 'data_count', 'tag');
4
13
  export const ExportDesc = enumify('func', 'table', 'mem', 'global', 'tag');
@@ -12,6 +21,11 @@ export const Valtype = {
12
21
  v128: 0x7b
13
22
  };
14
23
 
24
+ export const Reftype = {
25
+ funcref: 0x70,
26
+ externref: 0x6f
27
+ };
28
+
15
29
  export const Blocktype = {
16
30
  void: 0x40,
17
31
  };
@@ -32,17 +46,16 @@ export const Opcodes = {
32
46
  throw: 0x08,
33
47
  rethrow: 0x09,
34
48
 
35
- call: 0x10,
36
- call_indirect: 0x11,
37
- return_call: 0x12,
38
- return_call_indirect: 0x13,
39
-
40
49
  end: 0x0b,
41
50
  br: 0x0c,
42
51
  br_if: 0x0d,
43
52
  br_table: 0x0e,
44
53
  return: 0x0f,
54
+
45
55
  call: 0x10,
56
+ call_indirect: 0x11,
57
+ return_call: 0x12,
58
+ return_call_indirect: 0x13,
46
59
 
47
60
  drop: 0x1a,
48
61
 
@@ -62,13 +75,22 @@ export const Opcodes = {
62
75
  i32_load16_s: 0x2e,
63
76
  i32_load16_u: 0x2f,
64
77
 
65
- i32_store8: 0x3a,
66
- i32_store16: 0x3b,
78
+ i64_load8_s: 0x30,
79
+ i64_load8_u: 0x31,
80
+ i64_load16_s: 0x32,
81
+ i64_load16_u: 0x33,
67
82
 
68
83
  i32_store: 0x36,
69
84
  i64_store: 0x37,
70
85
  f64_store: 0x39,
71
86
 
87
+ i32_store8: 0x3a,
88
+ i32_store16: 0x3b,
89
+
90
+ i64_store8: 0x3c,
91
+ i64_store16: 0x3d,
92
+
93
+ memory_size: 0x3f,
72
94
  memory_grow: 0x40,
73
95
 
74
96
  i32_const: 0x41,
@@ -100,6 +122,8 @@ export const Opcodes = {
100
122
  i32_shl: 0x74,
101
123
  i32_shr_s: 0x75,
102
124
  i32_shr_u: 0x76,
125
+ i32_rotl: 0x77,
126
+ i32_rotr: 0x78,
103
127
 
104
128
  i64_eqz: 0x50,
105
129
  i64_eq: 0x51,
@@ -123,6 +147,7 @@ export const Opcodes = {
123
147
  i64_shr_s: 0x87,
124
148
  i64_shr_u: 0x88,
125
149
  i64_rotl: 0x89,
150
+ i64_rotr: 0x8a,
126
151
 
127
152
  f64_eq: 0x61,
128
153
  f64_ne: 0x62,
package/compiler/wrap.js CHANGED
@@ -1,26 +1,74 @@
1
1
  import compile from './index.js';
2
2
  import decompile from './decompile.js';
3
3
  import { encodeVector, encodeLocal } from './encoding.js';
4
- // import fs from 'node:fs';
4
+ import { TYPES } from './types.js';
5
+ import { log } from './log.js';
6
+ import Prefs from './prefs.js';
5
7
 
6
8
  const bold = x => `\u001b[1m${x}\u001b[0m`;
7
9
 
8
- const typeBase = 0x00;
9
- const internalTypeBase = 0x10;
10
- const TYPES = {
11
- [typeBase]: 'number',
12
- [typeBase + 1]: 'boolean',
13
- [typeBase + 2]: 'string',
14
- [typeBase + 3]: 'undefined',
15
- [typeBase + 4]: 'object',
16
- [typeBase + 5]: 'function',
17
- [typeBase + 6]: 'symbol',
18
- [typeBase + 7]: 'bigint',
19
-
20
- // internal
21
- [internalTypeBase]: '_array',
22
- [internalTypeBase + 1]: '_regexp',
23
- [internalTypeBase + 2]: '_bytestring'
10
+ const porfToJSValue = (memory, funcs, value, type) => {
11
+ switch (type) {
12
+ case TYPES.boolean: return Boolean(value);
13
+ case TYPES.undefined: return undefined;
14
+ case TYPES.object: return value === 0 ? null : {};
15
+
16
+ case TYPES.function: {
17
+ // wasm func index, including all imports
18
+ const func = funcs.find(x => (x.originalIndex ?? x.index) === value);
19
+ // if (!func) return value;
20
+ if (!func) return function () {};
21
+
22
+ // make fake empty func for repl/etc
23
+ return {[func.name]() {}}[func.name];
24
+ }
25
+
26
+ case TYPES.string: {
27
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
28
+ return Array.from(new Uint16Array(memory.buffer, value + 4, length)).map(x => String.fromCharCode(x)).join('');
29
+ }
30
+
31
+ case TYPES.bytestring: {
32
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
33
+ return Array.from(new Uint8Array(memory.buffer, value + 4, length)).map(x => String.fromCharCode(x)).join('');
34
+ }
35
+
36
+ case TYPES.array: {
37
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
38
+
39
+ // have to slice because of memory alignment (?)
40
+ const buf = memory.buffer.slice(value + 4, value + 4 + 8 * length);
41
+ return Array.from(new Float64Array(buf, 0, length));
42
+ }
43
+
44
+ case TYPES.date: {
45
+ const t = (new Float64Array(memory.buffer, value, 1))[0];
46
+ return new Date(t);
47
+ }
48
+
49
+ case TYPES.set: {
50
+ const size = (new Int32Array(memory.buffer, value, 1))[0];
51
+
52
+ const out = new Set();
53
+ for (let i = 0; i < size; i++) {
54
+ const offset = value + 4 + (i * 9);
55
+
56
+ // have to slice because of memory alignment (?)
57
+ const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
58
+ const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
59
+
60
+ // console.log(`reading value at index ${i}...`)
61
+ // console.log(' memory:', Array.from(new Uint8Array(memory.buffer, offset, 9)).map(x => x.toString(16).padStart(2, '0')).join(' '));
62
+ // console.log(' read:', { value: v, type: t }, '\n');
63
+
64
+ out.add(porfToJSValue(memory, funcs, v, t));
65
+ }
66
+
67
+ return out;
68
+ }
69
+
70
+ default: return value;
71
+ }
24
72
  };
25
73
 
26
74
  export default async (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
@@ -29,22 +77,33 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
29
77
  const t1 = performance.now();
30
78
  const { wasm, funcs, globals, tags, exceptions, pages, c } = compile(source, flags);
31
79
 
80
+ globalThis.porfDebugInfo = { funcs, globals };
81
+
32
82
  if (source.includes('export function')) flags.push('module');
33
83
 
34
- // fs.writeFileSync('out.wasm', Buffer.from(wasm));
84
+ // (await import('node:fs')).writeFileSync('out.wasm', Buffer.from(wasm));
35
85
 
36
86
  times.push(performance.now() - t1);
37
- if (flags.includes('info')) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
87
+ if (Prefs.profileCompiler) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
38
88
 
39
89
  const t2 = performance.now();
40
90
 
41
91
  let instance;
42
92
  try {
43
- 0, { instance } = await WebAssembly.instantiate(wasm, {
93
+ let wasmEngine = WebAssembly;
94
+ if (Prefs.asur) {
95
+ log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
96
+ wasmEngine = await import('../asur/index.js');
97
+ }
98
+
99
+ 0, { instance } = await wasmEngine.instantiate(wasm, {
44
100
  '': {
45
101
  p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
46
102
  c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
47
- t: _ => performance.now(),
103
+ t: () => performance.now(),
104
+ u: () => performance.timeOrigin,
105
+ y: () => {},
106
+ z: () => {},
48
107
  ...customImports
49
108
  }
50
109
  });
@@ -52,8 +111,10 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
52
111
  // only backtrace for runner, not test262/etc
53
112
  if (!process.argv[1].includes('/runner')) throw e;
54
113
 
55
- const funcInd = parseInt(e.message.match(/function #([0-9]+) /)[1]);
56
- const blobOffset = parseInt(e.message.split('@')[1]);
114
+ const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
115
+ const blobOffset = parseInt(e.message.split('@')?.[1]);
116
+
117
+ if (!funcInd) throw e;
57
118
 
58
119
  // convert blob offset -> function wasm offset.
59
120
  // this is not good code and is somewhat duplicated
@@ -131,7 +192,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
131
192
  }
132
193
 
133
194
  times.push(performance.now() - t2);
134
- if (flags.includes('info')) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
195
+ if (Prefs.profileCompiler) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
135
196
 
136
197
  const exports = {};
137
198
 
@@ -151,54 +212,11 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
151
212
 
152
213
  exports[func.name] = function() {
153
214
  try {
154
- const _ret = exp.apply(this, arguments);
155
-
156
- if (_ret == null) return undefined;
157
-
158
- const [ ret, type ] = _ret;
159
-
160
- // if (ret >= typeBase && ret <= typeBase + 8) return ret > (typeBase + 7) ? 'object' : TYPES[ret];
161
-
162
- switch (TYPES[type]) {
163
- case 'boolean': return Boolean(ret);
164
- case 'undefined': return undefined;
165
- case 'object': return ret === 0 ? null : {};
215
+ const ret = exp.apply(this, arguments);
166
216
 
167
- case '_array': {
168
- const pointer = ret;
169
- const length = new Int32Array(memory.buffer, pointer, 1);
217
+ if (ret == null) return undefined;
170
218
 
171
- // have to slice because of memory alignment
172
- const buf = memory.buffer.slice(pointer + 4, pointer + 4 + 8 * length);
173
-
174
- return Array.from(new Float64Array(buf));
175
- }
176
-
177
- case 'string': {
178
- const pointer = ret;
179
- const length = new Int32Array(memory.buffer, pointer, 1);
180
-
181
- return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
182
- }
183
-
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
- case 'function': {
192
- // wasm func index, including all imports
193
- const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
194
- if (!func) return ret;
195
-
196
- // make fake empty func for repl/etc
197
- return {[func.name]() {}}[func.name];
198
- }
199
-
200
- default: return ret;
201
- }
219
+ return porfToJSValue(memory, funcs, ret[0], ret[1])
202
220
  } catch (e) {
203
221
  if (e.is && e.is(exceptTag)) {
204
222
  const exceptId = e.getArg(exceptTag, 0);
package/package.json CHANGED
@@ -1,21 +1,25 @@
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-fde989a",
4
+ "version": "0.14.0-4057a18e9",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
+ "scripts": {
8
+ "precompile": "node ./compiler/precompile.js"
9
+ },
7
10
  "dependencies": {
8
- "acorn": "^8.9.0"
11
+ "acorn": "^8.11.3",
12
+ "node-repl-polyfill": "^0.1.1"
9
13
  },
10
14
  "optionalDependencies": {
11
- "@babel/parser": "^7.23.6",
15
+ "@babel/parser": "^7.24.4",
12
16
  "hermes-parser": "^0.18.2",
13
17
  "meriyah": "^4.3.9"
14
18
  },
15
19
  "bin": {
16
20
  "porf": "./runner/index.js"
17
21
  },
18
- "main": "./runner/index.js",
22
+ "main": "./compiler/wrap.js",
19
23
  "type": "module",
20
24
  "repository": {
21
25
  "type": "git",
@@ -25,4 +29,4 @@
25
29
  "url": "https://github.com/CanadaHonk/porffor/issues"
26
30
  },
27
31
  "homepage": "https://porffor.goose.icu"
28
- }
32
+ }
package/porf CHANGED
@@ -1,2 +1,4 @@
1
1
  #!/bin/sh
2
2
  node runner/index.js "$@"
3
+ # deno run -A runner/index.js "$@"
4
+ # bun runner/index.js "$@"