porffor 0.2.0-f2bbe1f → 0.2.0-f647e42

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 (53) hide show
  1. package/CONTRIBUTING.md +239 -0
  2. package/LICENSE +20 -20
  3. package/README.md +154 -89
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +237 -0
  7. package/compiler/2c.js +317 -72
  8. package/compiler/{sections.js → assemble.js} +63 -15
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +19 -0
  11. package/compiler/builtins/array.ts +145 -0
  12. package/compiler/builtins/base64.ts +151 -0
  13. package/compiler/builtins/crypto.ts +120 -0
  14. package/compiler/builtins/date.ts +1858 -0
  15. package/compiler/builtins/escape.ts +141 -0
  16. package/compiler/builtins/int.ts +147 -0
  17. package/compiler/builtins/number.ts +527 -0
  18. package/compiler/builtins/porffor.d.ts +59 -0
  19. package/compiler/builtins/string.ts +1055 -0
  20. package/compiler/builtins/tostring.ts +45 -0
  21. package/compiler/builtins.js +449 -269
  22. package/compiler/{codeGen.js → codegen.js} +1153 -418
  23. package/compiler/decompile.js +0 -1
  24. package/compiler/embedding.js +22 -22
  25. package/compiler/encoding.js +108 -10
  26. package/compiler/generated_builtins.js +1454 -0
  27. package/compiler/index.js +36 -34
  28. package/compiler/log.js +6 -3
  29. package/compiler/opt.js +51 -36
  30. package/compiler/parse.js +33 -23
  31. package/compiler/precompile.js +128 -0
  32. package/compiler/prefs.js +27 -0
  33. package/compiler/prototype.js +177 -37
  34. package/compiler/types.js +37 -0
  35. package/compiler/wasmSpec.js +30 -7
  36. package/compiler/wrap.js +56 -40
  37. package/package.json +9 -5
  38. package/porf +4 -0
  39. package/rhemyn/compile.js +46 -27
  40. package/rhemyn/parse.js +322 -320
  41. package/rhemyn/test/parse.js +58 -58
  42. package/runner/compare.js +34 -34
  43. package/runner/debug.js +122 -0
  44. package/runner/index.js +91 -11
  45. package/runner/profiler.js +102 -0
  46. package/runner/repl.js +42 -9
  47. package/runner/sizes.js +37 -37
  48. package/compiler/builtins/base64.js +0 -92
  49. package/runner/info.js +0 -89
  50. package/runner/profile.js +0 -46
  51. package/runner/results.json +0 -1
  52. package/runner/transform.js +0 -15
  53. package/util/enum.js +0 -20
@@ -2,29 +2,16 @@ import { Opcodes, Blocktype, Valtype, ValtypeSize, PageSize } from "./wasmSpec.j
2
2
  import { number } from "./embedding.js";
3
3
  import { unsignedLEB128 } from "./encoding.js";
4
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
- };
5
+ import Prefs from './prefs.js';
6
+ import { TYPES } from './types.js';
21
7
 
22
8
  // todo: turn these into built-ins once arrays and these become less hacky
23
9
 
24
10
  export const PrototypeFuncs = function() {
25
- const noUnlikelyChecks = process.argv.includes('-funsafe-no-unlikely-proto-checks');
26
- let zeroChecks = process.argv.find(x => x.startsWith('-funsafe-zero-proto-checks='));
27
- 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; }, {});
28
15
  else zeroChecks = {};
29
16
 
30
17
  this[TYPES._array] = {
@@ -71,7 +58,7 @@ export const PrototypeFuncs = function() {
71
58
  ],
72
59
 
73
60
  // todo: only for 1 argument
74
- push: (pointer, length, wNewMember) => [
61
+ push: (pointer, length, wNewMember, _1, _2, _3, unusedValue) => [
75
62
  // get memory offset of array at last index (length)
76
63
  ...length.getCachedI32(),
77
64
  ...number(ValtypeSize[valtype], Valtype.i32),
@@ -92,22 +79,28 @@ export const PrototypeFuncs = function() {
92
79
  ...number(1, Valtype.i32),
93
80
  [ Opcodes.i32_add ],
94
81
 
95
- ...length.setCachedI32(),
96
- ...length.getCachedI32(),
82
+ ...(unusedValue() ? [] : [
83
+ ...length.setCachedI32(),
84
+ ...length.getCachedI32(),
85
+ ])
97
86
  ]),
98
87
 
99
- ...length.getCachedI32(),
100
- Opcodes.i32_from_u
88
+ ...(unusedValue() ? [] : [
89
+ ...length.getCachedI32(),
90
+ Opcodes.i32_from_u
91
+ ])
101
92
 
102
93
  // ...length.get()
103
94
  ],
104
95
 
105
- pop: (pointer, length) => [
96
+ pop: (pointer, length, _1, _2, _3, _4, unusedValue) => [
106
97
  // if length == 0, noop
107
98
  ...length.getCachedI32(),
108
99
  [ Opcodes.i32_eqz ],
109
100
  [ Opcodes.if, Blocktype.void ],
110
- ...number(UNDEFINED),
101
+ ...(unusedValue() ? [] : [
102
+ ...number(UNDEFINED),
103
+ ]),
111
104
  [ Opcodes.br, 1 ],
112
105
  [ Opcodes.end ],
113
106
 
@@ -119,25 +112,29 @@ export const PrototypeFuncs = function() {
119
112
  ...number(1, Valtype.i32),
120
113
  [ Opcodes.i32_sub ],
121
114
 
122
- ...length.setCachedI32(),
123
- ...length.getCachedI32(),
115
+ ...(unusedValue() ? [] : [
116
+ ...length.setCachedI32(),
117
+ ...length.getCachedI32(),
118
+ ])
124
119
  ]),
125
120
 
126
121
  // load last element
127
- ...length.getCachedI32(),
128
- ...number(ValtypeSize[valtype], Valtype.i32),
129
- [ Opcodes.i32_mul ],
122
+ ...(unusedValue() ? [] : [
123
+ ...length.getCachedI32(),
124
+ ...number(ValtypeSize[valtype], Valtype.i32),
125
+ [ Opcodes.i32_mul ],
130
126
 
131
- ...pointer,
132
- [ Opcodes.i32_add ],
127
+ ...pointer,
128
+ [ Opcodes.i32_add ],
133
129
 
134
- [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
130
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
131
+ ])
135
132
  ],
136
133
 
137
134
  shift: (pointer, length) => [
138
135
  // if length == 0, noop
139
136
  ...length.getCachedI32(),
140
- Opcodes.i32_eqz,
137
+ [ Opcodes.i32_eqz ],
141
138
  [ Opcodes.if, Blocktype.void ],
142
139
  ...number(UNDEFINED),
143
140
  [ Opcodes.br, 1 ],
@@ -331,8 +328,8 @@ export const PrototypeFuncs = function() {
331
328
  ...number(0, Valtype.i32), // base 0 for store later
332
329
 
333
330
  ...wIndex,
334
-
335
331
  Opcodes.i32_to,
332
+
336
333
  ...number(ValtypeSize.i16, Valtype.i32),
337
334
  [ Opcodes.i32_mul ],
338
335
 
@@ -372,7 +369,7 @@ export const PrototypeFuncs = function() {
372
369
 
373
370
  ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
374
371
  [ Opcodes.if, Blocktype.void ],
375
- ...number(NaN),
372
+ ...number(valtype === 'i32' ? -1 : NaN),
376
373
  [ Opcodes.br, 1 ],
377
374
  [ Opcodes.end ],
378
375
 
@@ -472,8 +469,151 @@ export const PrototypeFuncs = function() {
472
469
  this[TYPES.string].at.returnType = TYPES.string;
473
470
  this[TYPES.string].charAt.returnType = TYPES.string;
474
471
  this[TYPES.string].charCodeAt.local = Valtype.i32;
472
+ this[TYPES.string].charCodeAt.noPointerCache = zeroChecks.charcodeat;
475
473
 
476
474
  this[TYPES.string].isWellFormed.local = Valtype.i32;
477
475
  this[TYPES.string].isWellFormed.local2 = Valtype.i32;
478
476
  this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
477
+
478
+ if (Prefs.bytestring) {
479
+ this[TYPES._bytestring] = {
480
+ at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
481
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
482
+
483
+ return [
484
+ // setup new/out array
485
+ ...newOut,
486
+ [ Opcodes.drop ],
487
+
488
+ ...number(0, Valtype.i32), // base 0 for store later
489
+
490
+ ...wIndex,
491
+ Opcodes.i32_to_u,
492
+ [ Opcodes.local_tee, iTmp ],
493
+
494
+ // if index < 0: access index + array length
495
+ ...number(0, Valtype.i32),
496
+ [ Opcodes.i32_lt_s ],
497
+ [ Opcodes.if, Blocktype.void ],
498
+ [ Opcodes.local_get, iTmp ],
499
+ ...length.getCachedI32(),
500
+ [ Opcodes.i32_add ],
501
+ [ Opcodes.local_set, iTmp ],
502
+ [ Opcodes.end ],
503
+
504
+ // if still < 0 or >= length: return undefined
505
+ [ Opcodes.local_get, iTmp ],
506
+ ...number(0, Valtype.i32),
507
+ [ Opcodes.i32_lt_s ],
508
+
509
+ [ Opcodes.local_get, iTmp ],
510
+ ...length.getCachedI32(),
511
+ [ Opcodes.i32_ge_s ],
512
+ [ Opcodes.i32_or ],
513
+
514
+ [ Opcodes.if, Blocktype.void ],
515
+ ...number(UNDEFINED),
516
+ [ Opcodes.br, 1 ],
517
+ [ Opcodes.end ],
518
+
519
+ [ Opcodes.local_get, iTmp ],
520
+
521
+ ...pointer,
522
+ [ Opcodes.i32_add ],
523
+
524
+ // load current string ind {arg}
525
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
526
+
527
+ // store to new string ind 0
528
+ [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
529
+
530
+ // return new string (pointer)
531
+ ...number(newPointer)
532
+ ];
533
+ },
534
+
535
+ // todo: out of bounds properly
536
+ charAt: (pointer, length, wIndex, _1, _2, arrayShell) => {
537
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
538
+
539
+ return [
540
+ // setup new/out array
541
+ ...newOut,
542
+ [ Opcodes.drop ],
543
+
544
+ ...number(0, Valtype.i32), // base 0 for store later
545
+
546
+ ...wIndex,
547
+ Opcodes.i32_to,
548
+
549
+ ...pointer,
550
+ [ Opcodes.i32_add ],
551
+
552
+ // load current string ind {arg}
553
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
554
+
555
+ // store to new string ind 0
556
+ [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
557
+
558
+ // return new string (page)
559
+ ...number(newPointer)
560
+ ];
561
+ },
562
+
563
+ charCodeAt: (pointer, length, wIndex, iTmp) => {
564
+ return [
565
+ ...wIndex,
566
+ Opcodes.i32_to,
567
+
568
+ ...(zeroChecks.charcodeat ? [] : [
569
+ [ Opcodes.local_set, iTmp ],
570
+
571
+ // index < 0
572
+ ...(noUnlikelyChecks ? [] : [
573
+ [ Opcodes.local_get, iTmp ],
574
+ ...number(0, Valtype.i32),
575
+ [ Opcodes.i32_lt_s ],
576
+ ]),
577
+
578
+ // index >= length
579
+ [ Opcodes.local_get, iTmp ],
580
+ ...length.getCachedI32(),
581
+ [ Opcodes.i32_ge_s ],
582
+
583
+ ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
584
+ [ Opcodes.if, Blocktype.void ],
585
+ ...number(valtype === 'i32' ? -1 : NaN),
586
+ [ Opcodes.br, 1 ],
587
+ [ Opcodes.end ],
588
+
589
+ [ Opcodes.local_get, iTmp ],
590
+ ]),
591
+
592
+ ...pointer,
593
+ [ Opcodes.i32_add ],
594
+
595
+ // load current string ind {arg}
596
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
597
+ Opcodes.i32_from_u
598
+ ];
599
+ },
600
+
601
+ isWellFormed: () => {
602
+ return [
603
+ // we know it must be true as it is a bytestring lol
604
+ ...number(1)
605
+ ]
606
+ }
607
+ };
608
+
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;
614
+
615
+ this[TYPES._bytestring].isWellFormed.local = Valtype.i32;
616
+ this[TYPES._bytestring].isWellFormed.local2 = Valtype.i32;
617
+ this[TYPES._bytestring].isWellFormed.returnType = TYPES.boolean;
618
+ }
479
619
  };
@@ -0,0 +1,37 @@
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');
@@ -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');
@@ -32,17 +41,16 @@ export const Opcodes = {
32
41
  throw: 0x08,
33
42
  rethrow: 0x09,
34
43
 
35
- call: 0x10,
36
- call_indirect: 0x11,
37
- return_call: 0x12,
38
- return_call_indirect: 0x13,
39
-
40
44
  end: 0x0b,
41
45
  br: 0x0c,
42
46
  br_if: 0x0d,
43
47
  br_table: 0x0e,
44
48
  return: 0x0f,
49
+
45
50
  call: 0x10,
51
+ call_indirect: 0x11,
52
+ return_call: 0x12,
53
+ return_call_indirect: 0x13,
46
54
 
47
55
  drop: 0x1a,
48
56
 
@@ -57,15 +65,27 @@ export const Opcodes = {
57
65
  i64_load: 0x29,
58
66
  f64_load: 0x2b,
59
67
 
68
+ i32_load8_s: 0x2c,
69
+ i32_load8_u: 0x2d,
60
70
  i32_load16_s: 0x2e,
61
71
  i32_load16_u: 0x2f,
62
72
 
63
- i32_store16: 0x3b,
73
+ i64_load8_s: 0x30,
74
+ i64_load8_u: 0x31,
75
+ i64_load16_s: 0x32,
76
+ i64_load16_u: 0x33,
64
77
 
65
78
  i32_store: 0x36,
66
79
  i64_store: 0x37,
67
80
  f64_store: 0x39,
68
81
 
82
+ i32_store8: 0x3a,
83
+ i32_store16: 0x3b,
84
+
85
+ i64_store8: 0x3c,
86
+ i64_store16: 0x3d,
87
+
88
+ memory_size: 0x3f,
69
89
  memory_grow: 0x40,
70
90
 
71
91
  i32_const: 0x41,
@@ -97,6 +117,8 @@ export const Opcodes = {
97
117
  i32_shl: 0x74,
98
118
  i32_shr_s: 0x75,
99
119
  i32_shr_u: 0x76,
120
+ i32_rotl: 0x77,
121
+ i32_rotr: 0x78,
100
122
 
101
123
  i64_eqz: 0x50,
102
124
  i64_eq: 0x51,
@@ -120,6 +142,7 @@ export const Opcodes = {
120
142
  i64_shr_s: 0x87,
121
143
  i64_shr_u: 0x88,
122
144
  i64_rotl: 0x89,
145
+ i64_rotr: 0x8a,
123
146
 
124
147
  f64_eq: 0x61,
125
148
  f64_ne: 0x62,
package/compiler/wrap.js CHANGED
@@ -1,55 +1,56 @@
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 Prefs from './prefs.js';
5
+ import { log } from './log.js';
6
+ import { TYPES } from './types.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
- };
24
-
25
10
  export default async (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
26
11
  const times = [];
27
12
 
28
13
  const t1 = performance.now();
29
14
  const { wasm, funcs, globals, tags, exceptions, pages, c } = compile(source, flags);
30
15
 
16
+ globalThis.porfDebugInfo = { funcs, globals };
17
+
31
18
  if (source.includes('export function')) flags.push('module');
32
19
 
33
- // fs.writeFileSync('out.wasm', Buffer.from(wasm));
20
+ // (await import('node:fs')).writeFileSync('out.wasm', Buffer.from(wasm));
34
21
 
35
22
  times.push(performance.now() - t1);
36
- if (flags.includes('info')) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
23
+ if (Prefs.profileCompiler) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
37
24
 
38
25
  const t2 = performance.now();
39
26
 
40
27
  let instance;
41
28
  try {
42
- 0, { instance } = await WebAssembly.instantiate(wasm, {
29
+ let wasmEngine = WebAssembly;
30
+ if (Prefs.asur) {
31
+ log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
32
+ wasmEngine = await import('../asur/index.js');
33
+ }
34
+
35
+ 0, { instance } = await wasmEngine.instantiate(wasm, {
43
36
  '': {
44
37
  p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
45
38
  c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
46
- t: _ => performance.now(),
39
+ t: () => performance.now(),
40
+ u: () => performance.timeOrigin,
41
+ y: () => {},
42
+ z: () => {},
47
43
  ...customImports
48
44
  }
49
45
  });
50
46
  } catch (e) {
51
- const funcInd = parseInt(e.message.match(/function #([0-9]+) /)[1]);
52
- const blobOffset = parseInt(e.message.split('@')[1]);
47
+ // only backtrace for runner, not test262/etc
48
+ if (!process.argv[1].includes('/runner')) throw e;
49
+
50
+ const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
51
+ const blobOffset = parseInt(e.message.split('@')?.[1]);
52
+
53
+ if (!funcInd) throw e;
53
54
 
54
55
  // convert blob offset -> function wasm offset.
55
56
  // this is not good code and is somewhat duplicated
@@ -127,7 +128,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
127
128
  }
128
129
 
129
130
  times.push(performance.now() - t2);
130
- if (flags.includes('info')) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
131
+ if (Prefs.profileCompiler) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
131
132
 
132
133
  const exports = {};
133
134
 
@@ -155,14 +156,31 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
155
156
 
156
157
  // if (ret >= typeBase && ret <= typeBase + 8) return ret > (typeBase + 7) ? 'object' : TYPES[ret];
157
158
 
158
- switch (TYPES[type]) {
159
- case 'boolean': return Boolean(ret);
160
- case 'undefined': return undefined;
161
- case 'object': return ret === 0 ? null : {};
159
+ switch (type) {
160
+ case TYPES.boolean: return Boolean(ret);
161
+ case TYPES.undefined: return undefined;
162
+ case TYPES.object: return ret === 0 ? null : {};
163
+
164
+ case TYPES.string: {
165
+ const pointer = ret;
166
+ const length = (new Int32Array(memory.buffer, pointer, 1))[0];
167
+
168
+ return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
169
+ }
170
+
171
+ case TYPES.function: {
172
+ // wasm func index, including all imports
173
+ const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
174
+ // if (!func) return ret;
175
+ if (!func) return function () {};
176
+
177
+ // make fake empty func for repl/etc
178
+ return {[func.name]() {}}[func.name];
179
+ }
162
180
 
163
- case '_array': {
181
+ case TYPES._array: {
164
182
  const pointer = ret;
165
- const length = new Int32Array(memory.buffer, pointer, 1);
183
+ const length = (new Int32Array(memory.buffer, pointer, 1))[0];
166
184
 
167
185
  // have to slice because of memory alignment
168
186
  const buf = memory.buffer.slice(pointer + 4, pointer + 4 + 8 * length);
@@ -170,20 +188,18 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
170
188
  return Array.from(new Float64Array(buf));
171
189
  }
172
190
 
173
- case 'string': {
191
+ case TYPES._bytestring: {
174
192
  const pointer = ret;
175
- const length = new Int32Array(memory.buffer, pointer, 1);
193
+ const length = (new Int32Array(memory.buffer, pointer, 1))[0];
176
194
 
177
- return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
195
+ return Array.from(new Uint8Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
178
196
  }
179
197
 
180
- case 'function': {
181
- // wasm func index, including all imports
182
- const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
183
- if (!func) return ret;
198
+ case TYPES._date: {
199
+ const pointer = ret;
200
+ const value = (new Float64Array(memory.buffer, pointer, 1))[0];
184
201
 
185
- // make fake empty func for repl/etc
186
- return {[func.name]() {}}[func.name];
202
+ return new Date(value);
187
203
  }
188
204
 
189
205
  default: return ret;
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-f2bbe1f",
4
+ "version": "0.2.0-f647e42",
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 ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ node runner/index.js "$@"
3
+ # deno run -A runner/index.js "$@"
4
+ # bun runner/index.js "$@"