porffor 0.0.0-44bc2d8 → 0.0.0-48403fd
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.
- package/README.md +50 -15
- package/c +0 -0
- package/c.exe +0 -0
- package/compiler/2c.js +354 -0
- package/compiler/builtins.js +14 -12
- package/compiler/codeGen.js +859 -332
- package/compiler/decompile.js +21 -5
- package/compiler/embedding.js +9 -5
- package/compiler/encoding.js +4 -2
- package/compiler/index.js +56 -5
- package/compiler/opt.js +337 -251
- package/compiler/parse.js +1 -0
- package/compiler/prototype.js +172 -34
- package/compiler/sections.js +46 -5
- package/compiler/wasmSpec.js +3 -0
- package/compiler/wrap.js +11 -5
- package/cool.exe +0 -0
- package/fib.js +10 -0
- package/g +0 -0
- package/g.exe +0 -0
- package/hi.c +37 -0
- package/out +0 -0
- package/out.exe +0 -0
- package/package.json +1 -1
- package/r.js +39 -0
- package/rhemyn/README.md +37 -0
- package/rhemyn/compile.js +214 -0
- package/rhemyn/parse.js +321 -0
- package/rhemyn/test/parse.js +59 -0
- package/runner/index.js +54 -34
- package/runner/info.js +37 -2
- package/runner/repl.js +4 -11
- package/runner/results.json +1 -0
- package/runner/transform.js +2 -1
- package/runner/version.js +10 -0
- package/tmp.c +61 -0
- package/t.js +0 -31
package/compiler/decompile.js
CHANGED
@@ -18,6 +18,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
|
|
18
18
|
if (justLocals.length > 0) out += ` local ${justLocals.map(x => invValtype[x.type]).join(' ')}\n`;
|
19
19
|
|
20
20
|
let i = 0, lastInst;
|
21
|
+
let byte = 0;
|
21
22
|
for (let inst of wasm.concat(name ? [ [ Opcodes.end ] ] : [])) {
|
22
23
|
if (inst[0] === null) continue;
|
23
24
|
|
@@ -33,8 +34,18 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
|
|
33
34
|
if (inst[0] === Opcodes.end || inst[0] === Opcodes.else || inst[0] === Opcodes.catch_all) depth--;
|
34
35
|
|
35
36
|
const opStr = invOpcodes[inst[0]];
|
36
|
-
if (!opStr)
|
37
|
-
|
37
|
+
if (!opStr) {
|
38
|
+
console.log(`decomp: unknown op ${inst[0]?.toString?.(16)}`);
|
39
|
+
// out += `;; failed to decomp\n`;
|
40
|
+
continue;
|
41
|
+
}
|
42
|
+
|
43
|
+
// out += '0x' + byte.toString(10).padStart(2, '0');
|
44
|
+
byte += inst.length;
|
45
|
+
|
46
|
+
out += ' '.repeat(Math.max(0, depth * 2));
|
47
|
+
|
48
|
+
out += opStr.replace('_', '.').replace('return.', 'return_').replace('call.', 'call_').replace('br.', 'br_');
|
38
49
|
|
39
50
|
if (inst[0] === Opcodes.if || inst[0] === Opcodes.loop || inst[0] === Opcodes.block || inst[0] === Opcodes.else || inst[0] === Opcodes.try || inst[0] === Opcodes.catch_all) depth++;
|
40
51
|
|
@@ -42,9 +53,14 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
|
|
42
53
|
out += ` ${read_ieee754_binary64(inst.slice(1))}`;
|
43
54
|
} else if (inst[0] === Opcodes.i32_const || inst[0] === Opcodes.i64_const) {
|
44
55
|
out += ` ${read_signedLEB128(inst.slice(1))}`;
|
45
|
-
} else if (inst[0] === Opcodes.i32_load || inst[0] === Opcodes.i64_load || inst[0] === Opcodes.f64_load || inst[0] === Opcodes.i32_store || inst[0] === Opcodes.i64_store || inst[0] === Opcodes.f64_store) {
|
46
|
-
out += ` ${inst[1]} ${read_unsignedLEB128(inst.slice(2))}
|
56
|
+
} else if (inst[0] === Opcodes.i32_load || inst[0] === Opcodes.i64_load || inst[0] === Opcodes.f64_load || inst[0] === Opcodes.i32_store || inst[0] === Opcodes.i64_store || inst[0] === Opcodes.f64_store || inst[0] === Opcodes.i32_store16 || inst[0] === Opcodes.i32_load16_u) {
|
57
|
+
out += ` ${inst[1]} ${read_unsignedLEB128(inst.slice(2))}`;
|
47
58
|
} else for (const operand of inst.slice(1)) {
|
59
|
+
if (typeof operand === 'string') {
|
60
|
+
out += ` ;; ${operand}`;
|
61
|
+
continue;
|
62
|
+
}
|
63
|
+
|
48
64
|
if (inst[0] === Opcodes.if || inst[0] === Opcodes.loop || inst[0] === Opcodes.block) {
|
49
65
|
if (operand === Blocktype.void) continue;
|
50
66
|
out += ` ${invValtype[operand]}`;
|
@@ -57,7 +73,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
|
|
57
73
|
out += ` ;; label @${depth}`;
|
58
74
|
}
|
59
75
|
|
60
|
-
if (inst[0] === Opcodes.br) {
|
76
|
+
if (inst[0] === Opcodes.br || inst[0] === Opcodes.br_if) {
|
61
77
|
out += ` ;; goto @${depth - inst[1]}`;
|
62
78
|
}
|
63
79
|
|
package/compiler/embedding.js
CHANGED
@@ -9,11 +9,15 @@ export const number = (n, valtype = valtypeBinary) => {
|
|
9
9
|
}
|
10
10
|
};
|
11
11
|
|
12
|
-
const
|
12
|
+
export const enforceOneByte = arr => [ arr[0] ?? 0 ];
|
13
|
+
export const enforceTwoBytes = arr => [ arr[0] ?? 0, arr[1] ?? 0 ];
|
14
|
+
export const enforceFourBytes = arr => [ arr[0] ?? 0, arr[1] ?? 0, arr[2] ?? 0, arr[3] ?? 0 ];
|
15
|
+
export const enforceEightBytes = arr => [ arr[0] ?? 0, arr[1] ?? 0, arr[2] ?? 0, arr[3] ?? 0, arr[4] ?? 0, arr[5] ?? 0, arr[6] ?? 0, arr[7] ?? 0 ];
|
16
|
+
|
13
17
|
export const i32x4 = (a, b, c, d) => [ [
|
14
18
|
...Opcodes.v128_const,
|
15
|
-
...
|
16
|
-
...
|
17
|
-
...
|
18
|
-
...
|
19
|
+
...enforceFourBytes(signedLEB128(a)),
|
20
|
+
...enforceFourBytes(signedLEB128(b)),
|
21
|
+
...enforceFourBytes(signedLEB128(c)),
|
22
|
+
...enforceFourBytes(signedLEB128(d))
|
19
23
|
] ];
|
package/compiler/encoding.js
CHANGED
@@ -22,15 +22,15 @@ export const encodeLocal = (count, type) => [
|
|
22
22
|
type
|
23
23
|
];
|
24
24
|
|
25
|
+
// todo: this only works with integers within 32 bit range
|
25
26
|
export const signedLEB128 = n => {
|
26
|
-
|
27
|
+
n |= 0;
|
27
28
|
|
28
29
|
// just input for small numbers (for perf as common)
|
29
30
|
if (n >= 0 && n <= 63) return [ n ];
|
30
31
|
if (n >= -64 && n <= 0) return [ 128 + n ];
|
31
32
|
|
32
33
|
const buffer = [];
|
33
|
-
n |= 0;
|
34
34
|
|
35
35
|
while (true) {
|
36
36
|
let byte = n & 0x7f;
|
@@ -50,6 +50,8 @@ export const signedLEB128 = n => {
|
|
50
50
|
};
|
51
51
|
|
52
52
|
export const unsignedLEB128 = n => {
|
53
|
+
n |= 0;
|
54
|
+
|
53
55
|
// just input for small numbers (for perf as common)
|
54
56
|
if (n >= 0 && n <= 127) return [ n ];
|
55
57
|
|
package/compiler/index.js
CHANGED
@@ -4,6 +4,8 @@ import opt from './opt.js';
|
|
4
4
|
import produceSections from './sections.js';
|
5
5
|
import decompile from './decompile.js';
|
6
6
|
import { BuiltinPreludes } from './builtins.js';
|
7
|
+
import toc from './2c.js';
|
8
|
+
|
7
9
|
|
8
10
|
globalThis.decompile = decompile;
|
9
11
|
|
@@ -14,7 +16,9 @@ const bold = x => `\u001b[1m${x}\u001b[0m`;
|
|
14
16
|
const areaColors = {
|
15
17
|
codegen: [ 20, 80, 250 ],
|
16
18
|
opt: [ 250, 20, 80 ],
|
17
|
-
sections: [ 20, 250, 80 ]
|
19
|
+
sections: [ 20, 250, 80 ],
|
20
|
+
alloc: [ 250, 250, 20 ],
|
21
|
+
'2c': [ 20, 250, 250 ]
|
18
22
|
};
|
19
23
|
|
20
24
|
globalThis.log = (area, ...args) => console.log(`\u001b[90m[\u001b[0m${rgb(...areaColors[area], area)}\u001b[90m]\u001b[0m`, ...args);
|
@@ -35,9 +39,16 @@ const logFuncs = (funcs, globals, exceptions) => {
|
|
35
39
|
console.log();
|
36
40
|
};
|
37
41
|
|
42
|
+
const getArg = name => process.argv.find(x => x.startsWith(`-${name}=`))?.slice(name.length + 2);
|
43
|
+
|
44
|
+
const writeFileSync = (typeof process !== 'undefined' ? (await import('node:fs')).writeFileSync : undefined);
|
45
|
+
const execSync = (typeof process !== 'undefined' ? (await import('node:child_process')).execSync : undefined);
|
46
|
+
|
38
47
|
export default (code, flags) => {
|
39
48
|
globalThis.optLog = process.argv.includes('-opt-log');
|
40
49
|
globalThis.codeLog = process.argv.includes('-code-log');
|
50
|
+
globalThis.allocLog = process.argv.includes('-alloc-log');
|
51
|
+
globalThis.regexLog = process.argv.includes('-regex-log');
|
41
52
|
|
42
53
|
for (const x in BuiltinPreludes) {
|
43
54
|
if (code.indexOf(x + '(') !== -1) code = BuiltinPreludes[x] + code;
|
@@ -48,20 +59,60 @@ export default (code, flags) => {
|
|
48
59
|
if (flags.includes('info')) console.log(`1. parsed in ${(performance.now() - t0).toFixed(2)}ms`);
|
49
60
|
|
50
61
|
const t1 = performance.now();
|
51
|
-
const { funcs, globals, tags, exceptions, pages } = codeGen(program);
|
62
|
+
const { funcs, globals, tags, exceptions, pages, data } = codeGen(program);
|
52
63
|
if (flags.includes('info')) console.log(`2. generated code in ${(performance.now() - t1).toFixed(2)}ms`);
|
53
64
|
|
54
65
|
if (process.argv.includes('-funcs')) logFuncs(funcs, globals, exceptions);
|
55
66
|
|
56
67
|
const t2 = performance.now();
|
57
|
-
opt(funcs, globals);
|
68
|
+
opt(funcs, globals, pages);
|
58
69
|
if (flags.includes('info')) console.log(`3. optimized code in ${(performance.now() - t2).toFixed(2)}ms`);
|
59
70
|
|
60
71
|
if (process.argv.includes('-opt-funcs')) logFuncs(funcs, globals, exceptions);
|
61
72
|
|
62
73
|
const t3 = performance.now();
|
63
|
-
const sections = produceSections(funcs, globals, tags, pages, flags);
|
74
|
+
const sections = produceSections(funcs, globals, tags, pages, data, flags);
|
64
75
|
if (flags.includes('info')) console.log(`4. produced sections in ${(performance.now() - t3).toFixed(2)}ms`);
|
65
76
|
|
66
|
-
|
77
|
+
if (allocLog) {
|
78
|
+
const wasmPages = Math.ceil((pages.size * pageSize) / 65536);
|
79
|
+
const bytes = wasmPages * 65536;
|
80
|
+
log('alloc', `\x1B[1mallocated ${bytes / 1024}KiB\x1B[0m for ${pages.size} things using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'}`);
|
81
|
+
console.log([...pages.keys()].map(x => `\x1B[36m - ${x}\x1B[0m`).join('\n') + '\n');
|
82
|
+
}
|
83
|
+
|
84
|
+
const out = { wasm: sections, funcs, globals, tags, exceptions, pages };
|
85
|
+
|
86
|
+
const target = getArg('target') ?? getArg('t') ?? 'wasm';
|
87
|
+
const outFile = getArg('o');
|
88
|
+
|
89
|
+
if (target === 'c') {
|
90
|
+
const c = toc(out);
|
91
|
+
|
92
|
+
if (outFile) {
|
93
|
+
writeFileSync(outFile, c);
|
94
|
+
} else {
|
95
|
+
console.log(c);
|
96
|
+
}
|
97
|
+
|
98
|
+
process.exit();
|
99
|
+
}
|
100
|
+
|
101
|
+
if (target === 'native') {
|
102
|
+
const compiler = getArg('compiler') ?? 'clang';
|
103
|
+
const cO = getArg('cO') ?? 'Ofast';
|
104
|
+
|
105
|
+
const tmpfile = 'tmp.c';
|
106
|
+
const args = [ compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native' ];
|
107
|
+
|
108
|
+
const c = toc(out);
|
109
|
+
writeFileSync(tmpfile, c);
|
110
|
+
|
111
|
+
// obvious command escape is obvious
|
112
|
+
execSync(args.join(' '), { stdio: 'inherit' });
|
113
|
+
|
114
|
+
process.exit();
|
115
|
+
}
|
116
|
+
|
117
|
+
return out;
|
67
118
|
};
|