porffor 0.2.0-aea77ff → 0.2.0-b9abe0d

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/.vscode/launch.json +18 -0
  2. package/LICENSE +20 -20
  3. package/README.md +124 -83
  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 +9 -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 +42 -0
  19. package/compiler/builtins/string.ts +1055 -0
  20. package/compiler/builtins/tostring.ts +45 -0
  21. package/compiler/builtins.js +479 -262
  22. package/compiler/{codeGen.js → codegen.js} +1049 -394
  23. package/compiler/embedding.js +22 -22
  24. package/compiler/encoding.js +108 -10
  25. package/compiler/generated_builtins.js +722 -0
  26. package/compiler/index.js +36 -34
  27. package/compiler/log.js +6 -3
  28. package/compiler/opt.js +51 -36
  29. package/compiler/parse.js +35 -27
  30. package/compiler/precompile.js +123 -0
  31. package/compiler/prefs.js +26 -0
  32. package/compiler/prototype.js +177 -37
  33. package/compiler/types.js +37 -0
  34. package/compiler/wasmSpec.js +29 -7
  35. package/compiler/wrap.js +52 -39
  36. package/package.json +9 -5
  37. package/porf +4 -0
  38. package/rhemyn/compile.js +5 -3
  39. package/rhemyn/parse.js +323 -320
  40. package/rhemyn/test/parse.js +58 -58
  41. package/runner/compare.js +34 -34
  42. package/runner/debug.js +122 -0
  43. package/runner/index.js +49 -10
  44. package/runner/profiler.js +102 -0
  45. package/runner/repl.js +40 -7
  46. package/runner/sizes.js +37 -37
  47. package/test262_changes_from_1afe9b87d2_to_04-09.md +270 -0
  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,26 @@ 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
+
69
88
  memory_grow: 0x40,
70
89
 
71
90
  i32_const: 0x41,
@@ -97,6 +116,8 @@ export const Opcodes = {
97
116
  i32_shl: 0x74,
98
117
  i32_shr_s: 0x75,
99
118
  i32_shr_u: 0x76,
119
+ i32_rotl: 0x77,
120
+ i32_rotr: 0x78,
100
121
 
101
122
  i64_eqz: 0x50,
102
123
  i64_eq: 0x51,
@@ -120,6 +141,7 @@ export const Opcodes = {
120
141
  i64_shr_s: 0x87,
121
142
  i64_shr_u: 0x88,
122
143
  i64_rotl: 0x89,
144
+ i64_rotr: 0x8a,
123
145
 
124
146
  f64_eq: 0x61,
125
147
  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,12 +156,29 @@ 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 : {};
162
163
 
163
- case '_array': {
164
+ case TYPES.string: {
165
+ const pointer = ret;
166
+ const length = new Int32Array(memory.buffer, pointer, 1);
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
+ }
180
+
181
+ case TYPES._array: {
164
182
  const pointer = ret;
165
183
  const length = new Int32Array(memory.buffer, pointer, 1);
166
184
 
@@ -170,20 +188,15 @@ 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
193
  const length = new Int32Array(memory.buffer, pointer, 1);
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;
184
-
185
- // make fake empty func for repl/etc
186
- return {[func.name]() {}}[func.name];
198
+ case TYPES._date: {
199
+ return new Date(ret);
187
200
  }
188
201
 
189
202
  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-aea77ff",
4
+ "version": "0.2.0-b9abe0d",
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 "$@"
package/rhemyn/compile.js CHANGED
@@ -2,6 +2,7 @@ import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from '../compiler/
2
2
  import { number } from '../compiler/embedding.js';
3
3
  import { signedLEB128, unsignedLEB128 } from '../compiler/encoding.js';
4
4
  import parse from './parse.js';
5
+ import Prefs from '../compiler/prefs.js';
5
6
 
6
7
  // local indexes
7
8
  const BasePointer = 0; // base string pointer
@@ -80,7 +81,7 @@ const generate = (node, negated = false, get = true, func = 'test') => {
80
81
  })[func], Valtype.i32)
81
82
  ];
82
83
 
83
- if (globalThis.regexLog) {
84
+ if (Prefs.regexLog) {
84
85
  const underline = x => `\u001b[4m\u001b[1m${x}\u001b[0m`;
85
86
  console.log(`\n${underline('ast')}`);
86
87
  console.log(node);
@@ -159,7 +160,7 @@ const generateSet = (node, negated, get) => {
159
160
  ];
160
161
  }
161
162
 
162
- out = out.concat(new Array(node.body.length - 1).fill(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ]));
163
+ if (node.body.length > 0) out = out.concat(new Array(node.body.length - 1).fill(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ]));
163
164
 
164
165
  return [
165
166
  ...out,
@@ -187,7 +188,8 @@ const generateRange = (node, negated, get) => {
187
188
  };
188
189
 
189
190
  const generateGroup = (node, negated, get) => {
190
-
191
+ // todo
192
+ return [];
191
193
  };
192
194
 
193
195
  export const test = (regex, index = 0, name = 'regex_test_' + regex) => outputFunc(generate(parse(regex), false, true, 'test'), name, index);