porffor 0.2.0-623cdf0 → 0.2.0-6aff0fa

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.
@@ -32,17 +32,16 @@ export const Opcodes = {
32
32
  throw: 0x08,
33
33
  rethrow: 0x09,
34
34
 
35
- call: 0x10,
36
- call_indirect: 0x11,
37
- return_call: 0x12,
38
- return_call_indirect: 0x13,
39
-
40
35
  end: 0x0b,
41
36
  br: 0x0c,
42
37
  br_if: 0x0d,
43
38
  br_table: 0x0e,
44
39
  return: 0x0f,
40
+
45
41
  call: 0x10,
42
+ call_indirect: 0x11,
43
+ return_call: 0x12,
44
+ return_call_indirect: 0x13,
46
45
 
47
46
  drop: 0x1a,
48
47
 
@@ -62,13 +61,21 @@ export const Opcodes = {
62
61
  i32_load16_s: 0x2e,
63
62
  i32_load16_u: 0x2f,
64
63
 
65
- i32_store8: 0x3a,
66
- i32_store16: 0x3b,
64
+ i64_load8_s: 0x30,
65
+ i64_load8_u: 0x31,
66
+ i64_load16_s: 0x32,
67
+ i64_load16_u: 0x33,
67
68
 
68
69
  i32_store: 0x36,
69
70
  i64_store: 0x37,
70
71
  f64_store: 0x39,
71
72
 
73
+ i32_store8: 0x3a,
74
+ i32_store16: 0x3b,
75
+
76
+ i64_store8: 0x3c,
77
+ i64_store16: 0x3d,
78
+
72
79
  memory_grow: 0x40,
73
80
 
74
81
  i32_const: 0x41,
package/compiler/wrap.js CHANGED
@@ -1,7 +1,8 @@
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';
5
6
 
6
7
  const bold = x => `\u001b[1m${x}\u001b[0m`;
7
8
 
@@ -31,7 +32,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
31
32
 
32
33
  if (source.includes('export function')) flags.push('module');
33
34
 
34
- // fs.writeFileSync('out.wasm', Buffer.from(wasm));
35
+ // (await import('node:fs')).writeFileSync('out.wasm', Buffer.from(wasm));
35
36
 
36
37
  times.push(performance.now() - t1);
37
38
  if (flags.includes('info')) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
@@ -40,7 +41,13 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
40
41
 
41
42
  let instance;
42
43
  try {
43
- 0, { instance } = await WebAssembly.instantiate(wasm, {
44
+ let wasmEngine = WebAssembly;
45
+ if (Prefs.asur) {
46
+ log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
47
+ wasmEngine = await import('../asur/index.js');
48
+ }
49
+
50
+ 0, { instance } = await wasmEngine.instantiate(wasm, {
44
51
  '': {
45
52
  p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
46
53
  c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
@@ -191,7 +198,8 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
191
198
  case 'function': {
192
199
  // wasm func index, including all imports
193
200
  const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
194
- if (!func) return ret;
201
+ // if (!func) return ret;
202
+ if (!func) return function () {};
195
203
 
196
204
  // make fake empty func for repl/etc
197
205
  return {[func.name]() {}}[func.name];
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-623cdf0",
4
+ "version": "0.2.0-6aff0fa",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "dependencies": {
package/porf ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ node 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);
package/runner/index.js CHANGED
@@ -3,6 +3,8 @@
3
3
  import compile from '../compiler/wrap.js';
4
4
  import fs from 'node:fs';
5
5
 
6
+ const start = performance.now();
7
+
6
8
  if (process.argv.includes('-compile-hints')) {
7
9
  const v8 = await import('node:v8');
8
10
  v8.setFlagsFromString(`--experimental-wasm-compilation-hints`);
@@ -16,7 +18,13 @@ if (process.argv.includes('-compile-hints')) {
16
18
  }
17
19
 
18
20
  let file = process.argv.slice(2).find(x => x[0] !== '-');
19
- if (['run', 'wasm', 'native', 'c'].includes(file)) {
21
+ if (['run', 'wasm', 'native', 'c', 'profile'].includes(file)) {
22
+ if (file === 'profile') {
23
+ process.argv.splice(process.argv.indexOf(file), 1);
24
+ await import('./profiler.js');
25
+ await new Promise(() => {});
26
+ }
27
+
20
28
  if (['wasm', 'native', 'c'].includes(file)) {
21
29
  process.argv.push(`-target=${file}`);
22
30
  }
@@ -65,4 +73,6 @@ try {
65
73
  } catch (e) {
66
74
  if (cache) process.stdout.write(cache);
67
75
  console.error(process.argv.includes('-i') ? e : `${e.constructor.name}: ${e.message}`);
68
- }
76
+ }
77
+
78
+ if (process.argv.includes('-t')) console.log(`\n\ntotal time: ${(performance.now() - start).toFixed(2)}ms`);
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+
3
+ import compile from '../compiler/wrap.js';
4
+ import fs from 'node:fs';
5
+
6
+ import Prefs from '../compiler/prefs.js';
7
+
8
+ const fast = Prefs.profiler === 'fast';
9
+
10
+ const file = process.argv.slice(2).find(x => x[0] !== '-');
11
+ let source = fs.readFileSync(file, 'utf8');
12
+
13
+ let profileId = 0;
14
+ source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});${_}profile(${profileId++});`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
15
+
16
+ // console.log(source);
17
+
18
+ let tmp = new Array(profileId).fill(0);
19
+ let samples = 0;
20
+
21
+ const percents = process.argv.includes('-%');
22
+
23
+ const spinner = ['-', '\\', '|', '/'];
24
+ let spin = 0;
25
+ let last = 0;
26
+
27
+ try {
28
+ const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
29
+ z: fast ? n => {
30
+ if (n % 2) {
31
+ tmp[n] += performance.now() - tmp[n - 1];
32
+ } else {
33
+ tmp[n] = performance.now();
34
+ }
35
+ } : n => {
36
+ if (n % 3 === 2) {
37
+ tmp[n] += (performance.now() - tmp[n - 1]) - (tmp[n - 1] - tmp[n - 2]);
38
+ samples++;
39
+
40
+ if (performance.now() > last) {
41
+ process.stdout.write(`\r${spinner[spin++ % 4]} running: collected ${samples} samples...`);
42
+ last = performance.now() + 100;
43
+ }
44
+ } else {
45
+ tmp[n] = performance.now();
46
+ }
47
+ }
48
+ });
49
+
50
+ const start = performance.now();
51
+
52
+ exports.main();
53
+
54
+ const total = performance.now() - start;
55
+
56
+ console.log(`\nsamples: ${fast ? 'not measured' : samples}\ntotal: ${total}ms\n\n` + source.split('\n').map(x => {
57
+ let time = 0;
58
+ if (x.startsWith('profile')) {
59
+ const id = parseInt(x.slice(8, x.indexOf(')')));
60
+ time = fast ? tmp[id + 1] : tmp[id + 2];
61
+ }
62
+
63
+ let color = [ 0, 0, 0 ];
64
+ if (time) {
65
+ const relativeTime = Math.sqrt(time / total);
66
+ if (percents) time = relativeTime;
67
+
68
+ color = [ (relativeTime * 250) | 0, (Math.sin(relativeTime * Math.PI) * 50) | 0, 0 ];
69
+ }
70
+
71
+ const ansiColor = `2;${color[0]};${color[1]};${color[2]}m`;
72
+
73
+ if (percents) return `\x1b[48;${ansiColor}\x1b[97m${time ? ((time * 100).toFixed(0).padStart(4, ' ') + '%') : ' '}\x1b[0m\x1b[38;${ansiColor}▌\x1b[0m ${x.replace(/profile\([0-9]+\);/g, '')}`;
74
+
75
+ let digits = 2;
76
+ if (time >= 100) digits = 1;
77
+ if (time >= 1000) digits = 0;
78
+
79
+ return `\x1b[48;${ansiColor}\x1b[97m${time ? time.toFixed(digits).padStart(6, ' ') : ' '}\x1b[0m\x1b[38;${ansiColor}▌\x1b[0m ${x.replace(/profile\([0-9]+\);/g, '')}`;
80
+ }).join('\n'));
81
+ } catch (e) {
82
+ console.error(e);
83
+ }
@@ -1,92 +0,0 @@
1
- var btoa_a = str => {
2
- // todo: throw invalid character for unicode
3
-
4
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
5
- const mask = (1 << 6) - 1;
6
-
7
- let out = '';
8
- let bits = 0, buffer = 0;
9
- for (let i = 0; i < str.length; i++) {
10
- buffer = (buffer << 8) | (0xff & str.charCodeAt(i));
11
- bits += 8;
12
-
13
- while (bits > 6) {
14
- bits -= 6;
15
- out += chars[mask & (buffer >> bits)];
16
- }
17
- }
18
-
19
- if (bits) {
20
- out += chars[mask & (buffer << (6 - bits))]
21
- }
22
-
23
- while ((out.length * 6) & 7) {
24
- out += '=';
25
- }
26
-
27
- return out;
28
- };
29
-
30
- var btoa = function (input) {
31
- // todo: throw invalid character for unicode
32
- const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
33
-
34
- let output = "";
35
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
36
- let i = 0;
37
-
38
- while (i < input.length) {
39
- chr1 = input.charCodeAt(i++);
40
- chr2 = input.charCodeAt(i++);
41
- chr3 = input.charCodeAt(i++);
42
-
43
- enc1 = chr1 >> 2;
44
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
45
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
46
- enc4 = chr3 & 63;
47
-
48
- if (isNaN(chr2)) {
49
- enc3 = enc4 = 64;
50
- } else if (isNaN(chr3)) {
51
- enc4 = 64;
52
- }
53
-
54
- output += keyStr.charAt(enc1);
55
- output += keyStr.charAt(enc2);
56
- output += keyStr.charAt(enc3);
57
- output += keyStr.charAt(enc4);
58
- }
59
-
60
- return output;
61
- };
62
-
63
- var atob_b = function (input) {
64
- const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
65
-
66
- let output = "";
67
- let chr1, chr2, chr3;
68
- let enc1, enc2, enc3, enc4;
69
- let i = 0;
70
-
71
- while (i < input.length) {
72
- enc1 = keyStr.indexOf(input.charAt(i++));
73
- enc2 = keyStr.indexOf(input.charAt(i++));
74
- enc3 = keyStr.indexOf(input.charAt(i++));
75
- enc4 = keyStr.indexOf(input.charAt(i++));
76
-
77
- chr1 = (enc1 << 2) | (enc2 >> 4);
78
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
79
- chr3 = ((enc3 & 3) << 6) | enc4;
80
-
81
- output += String.fromCharCode(chr1);
82
-
83
- if (enc3 != 64) {
84
- output += String.fromCharCode(chr2);
85
- }
86
- if (enc4 != 64) {
87
- output += String.fromCharCode(chr3);
88
- }
89
- }
90
-
91
- return output;
92
- };
package/filesize.cmd DELETED
@@ -1,2 +0,0 @@
1
- @echo off
2
- echo %~z1
package/runner/profile.js DELETED
@@ -1,46 +0,0 @@
1
- import compile from '../compiler/index.js';
2
- import fs from 'node:fs';
3
-
4
- let csv = `phase,time\n`;
5
-
6
- csv += `node,${performance.now()}\n`;
7
-
8
- const t0 = performance.now();
9
- const file = process.argv.slice(2).find(x => x[0] !== '-');
10
- const source = fs.readFileSync(file, 'utf8');
11
- csv += `read,${performance.now() - t0}\n`;
12
-
13
- console.log = x => {
14
- if (x.includes(' in ')) {
15
- csv += [ 'parse', 'codegen', 'opt', 'sections' ][parseInt(x[0]) - 1] + ',' + x.split(' in ')[1].slice(0, -2) + '\n';
16
- }
17
- };
18
-
19
- const wasm = compile(source, [ 'info' ]);
20
-
21
- let cache = '';
22
- const print = str => {
23
- cache += str;
24
-
25
- if (str === '\n') {
26
- process.stdout.write(cache);
27
- cache = '';
28
- }
29
- };
30
-
31
- const t1 = performance.now();
32
- const { instance } = await WebAssembly.instantiate(wasm, {
33
- '': {
34
- p: i => print(Number(i).toString()),
35
- c: i => print(String.fromCharCode(Number(i)))
36
- }
37
- });
38
- csv += `inst,${performance.now() - t1}\n`;
39
-
40
- const t2 = performance.now();
41
- instance.exports.m();
42
- print('\n');
43
-
44
- csv += `exec,${performance.now() - t2}`;
45
-
46
- fs.writeFileSync(`profile.csv`, csv);