porffor 0.2.0-fdf0fc5 → 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.
- package/README.md +9 -2
- package/byg/index.js +3 -24
- package/compiler/2c.js +2 -53
- package/compiler/assemble.js +26 -11
- package/compiler/builtins/annexb_string.js +10 -10
- package/compiler/builtins/annexb_string.ts +3 -3
- package/compiler/builtins/array.ts +2 -6
- package/compiler/builtins/base64.ts +1 -1
- package/compiler/builtins/boolean.ts +0 -2
- package/compiler/builtins/crypto.ts +1 -1
- package/compiler/builtins/date.ts +1 -4
- package/compiler/builtins/escape.ts +1 -1
- package/compiler/builtins/function.ts +0 -2
- package/compiler/builtins/int.ts +0 -2
- package/compiler/builtins/number.ts +3 -8
- package/compiler/builtins/object.ts +0 -2
- package/compiler/builtins/porffor.d.ts +9 -8
- package/compiler/builtins/set.ts +184 -2
- package/compiler/builtins/string.ts +1 -1
- package/compiler/builtins.js +4 -7
- package/compiler/codegen.js +21 -106
- package/compiler/decompile.js +2 -2
- package/compiler/embedding.js +2 -2
- package/compiler/encoding.js +0 -14
- package/compiler/expression.js +1 -1
- package/compiler/generated_builtins.js +303 -204
- package/compiler/index.js +0 -2
- package/compiler/opt.js +7 -7
- package/compiler/parse.js +1 -3
- package/compiler/precompile.js +17 -25
- package/compiler/prototype.js +5 -5
- package/compiler/wasmSpec.js +5 -0
- package/compiler/wrap.js +69 -56
- package/package.json +1 -1
- package/runner/compare.js +0 -1
- package/runner/debug.js +1 -6
- package/runner/profiler.js +15 -42
- package/runner/repl.js +3 -9
- package/runner/sizes.js +2 -2
- package/runner/version.js +10 -8
package/compiler/index.js
CHANGED
@@ -89,8 +89,6 @@ export default (code, flags) => {
|
|
89
89
|
else compiler = [ compiler ];
|
90
90
|
|
91
91
|
const tmpfile = 'porffor_tmp.c';
|
92
|
-
// const args = [ compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-ffunction-sections', '-fdata-sections', '-Wl', '-fno-ident', '-fno-exceptions', '-ffast-math' ];
|
93
|
-
// const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-ffast-math', '-fno-exceptions', '-target', 'x86_64-linux' ];
|
94
92
|
const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-ffast-math', '-fno-exceptions' ];
|
95
93
|
|
96
94
|
const c = toc(out);
|
package/compiler/opt.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
import { Opcodes, Valtype } from
|
2
|
-
import { number } from
|
3
|
-
import { read_signedLEB128, read_ieee754_binary64 } from
|
4
|
-
import { log } from
|
1
|
+
import { Opcodes, Valtype } from './wasmSpec.js';
|
2
|
+
import { number } from './embedding.js';
|
3
|
+
import { read_signedLEB128, read_ieee754_binary64 } from './encoding.js';
|
4
|
+
import { log } from './log.js';
|
5
5
|
import Prefs from './prefs.js';
|
6
6
|
|
7
7
|
const performWasmOp = (op, a, b) => {
|
@@ -172,14 +172,14 @@ export default (funcs, globals, pages, tags, exceptions) => {
|
|
172
172
|
}
|
173
173
|
}
|
174
174
|
|
175
|
-
if (inst[inst.length - 1] === 'string_only' && !pages.hasAnyString) {
|
175
|
+
if (inst[inst.length - 1] === 'string_only' && !pages.hasAnyString && !Prefs.noRmUnusedTypes) {
|
176
176
|
// remove this inst
|
177
177
|
wasm.splice(i, 1);
|
178
178
|
if (i > 0) i--;
|
179
179
|
inst = wasm[i];
|
180
180
|
}
|
181
181
|
|
182
|
-
if (inst[inst.length - 1] === 'string_only|start' && !pages.hasAnyString) {
|
182
|
+
if (inst[inst.length - 1] === 'string_only|start' && !pages.hasAnyString&& !Prefs.noRmUnusedTypes) {
|
183
183
|
let j = i;
|
184
184
|
for (; j < wasm.length; j++) {
|
185
185
|
const op = wasm[j];
|
@@ -193,7 +193,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
|
|
193
193
|
inst = wasm[i];
|
194
194
|
}
|
195
195
|
|
196
|
-
if (inst[0] === Opcodes.if && typeof inst[2] === 'string') {
|
196
|
+
if (inst[0] === Opcodes.if && typeof inst[2] === 'string' && !Prefs.noRmUnusedTypes) {
|
197
197
|
// remove unneeded typeswitch checks
|
198
198
|
|
199
199
|
const type = inst[2].split('|')[1];
|
package/compiler/parse.js
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
import { log } from
|
1
|
+
import { log } from './log.js';
|
2
2
|
import Prefs from './prefs.js';
|
3
3
|
|
4
|
-
// import { parse } from 'acorn';
|
5
|
-
|
6
4
|
// deno compat
|
7
5
|
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
8
6
|
const textEncoder = new TextEncoder();
|
package/compiler/precompile.js
CHANGED
@@ -7,9 +7,6 @@ import { join } from 'node:path';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
8
8
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
9
9
|
|
10
|
-
// import porfParse from './parse.js';
|
11
|
-
// import porfCodegen from './codeGen.js';
|
12
|
-
|
13
10
|
const argv = process.argv.slice();
|
14
11
|
|
15
12
|
const compile = async (file, [ _funcs, _globals ]) => {
|
@@ -21,17 +18,12 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
21
18
|
first = source.slice(0, source.indexOf('\n'));
|
22
19
|
}
|
23
20
|
|
24
|
-
let args = ['--bytestring', '--todo-time=compile', '--no-aot-pointer-opt', '--no-treeshake-wasm-imports', '--scoped-page-names', '--parse-types', '--opt-types'];
|
21
|
+
let args = ['--bytestring', '--todo-time=compile', '--no-aot-pointer-opt', '--no-treeshake-wasm-imports', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--parse-types', '--opt-types'];
|
25
22
|
if (first.startsWith('// @porf')) {
|
26
23
|
args = args.concat(first.slice('// @porf '.length).split(' '));
|
27
24
|
}
|
28
25
|
process.argv = argv.concat(args);
|
29
26
|
|
30
|
-
// const porfParse = (await import(`./parse.js?_=${Date.now()}`)).default;
|
31
|
-
// const porfCodegen = (await import(`./codeGen.js?_=${Date.now()}`)).default;
|
32
|
-
|
33
|
-
// let { funcs, globals, data } = porfCodegen(porfParse(source, ['module']));
|
34
|
-
|
35
27
|
const porfCompile = (await import(`./index.js?_=${Date.now()}`)).default;
|
36
28
|
|
37
29
|
let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
|
@@ -78,7 +70,14 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
78
70
|
allocated.add(pageName);
|
79
71
|
|
80
72
|
y.splice(0, 10, 'alloc', pageName, x.pages.get(pageName).type, valtypeBinary);
|
81
|
-
|
73
|
+
}
|
74
|
+
|
75
|
+
if (y[0] === Opcodes.i32_const && n[0] === Opcodes.throw) {
|
76
|
+
const id = y[1];
|
77
|
+
y.splice(0, 10, 'throw', exceptions[id].constructor, exceptions[id].message);
|
78
|
+
|
79
|
+
// remove throw inst
|
80
|
+
x.wasm.splice(i + 1, 1);
|
82
81
|
}
|
83
82
|
}
|
84
83
|
}
|
@@ -98,31 +97,24 @@ const precompile = async () => {
|
|
98
97
|
await compile(join(dir, file), [ funcs, globals ]);
|
99
98
|
}
|
100
99
|
|
101
|
-
// const a = funcs.find(x => x.name === '__ecma262_ToUTCDTSF');
|
102
|
-
// console.log(Object.values(a.locals).slice(a.params.length));
|
103
|
-
|
104
|
-
// ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
|
105
|
-
// ${x.used && x.used.length > 0 ? ` used: ${JSON.stringify(x.used)},` : ''}
|
106
|
-
|
107
100
|
return `// autogenerated by compiler/precompile.js
|
108
101
|
import { number } from './embedding.js';
|
109
102
|
|
110
103
|
export const BuiltinFuncs = function() {
|
111
|
-
${funcs.map(x =>
|
112
|
-
|
104
|
+
${funcs.map(x => {
|
105
|
+
const wasm = JSON.stringify(x.wasm.filter(x => x.length && x[0] != null)).replace(/\["alloc","(.*?)","(.*?)",(.*?)\]/g, (_, reason, type, valtype) => `...number(allocPage(scope, '${reason}', '${type}') * pageSize, ${valtype})`).replace(/\[16,"(.*?)"]/g, (_, name) => `[16, builtin('${name}')]`).replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(scope, '${constructor}', \`${message}\`)`);
|
106
|
+
return ` this.${x.name} = {
|
107
|
+
wasm: (scope, {${wasm.includes('allocPage(') ? 'allocPage,' : ''}${wasm.includes('builtin(') ? 'builtin,' : ''}${wasm.includes('internalThrow(') ? 'internalThrow,' : ''}}) => ${wasm},
|
113
108
|
params: ${JSON.stringify(x.params)},
|
114
109
|
typedParams: true,
|
115
110
|
returns: ${JSON.stringify(x.returns)},
|
116
111
|
${x.returnType != null ? `returnType: ${JSON.stringify(x.returnType)}` : 'typedReturns: true'},
|
117
112
|
locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length).map(x => x.type))},
|
118
113
|
localNames: ${JSON.stringify(Object.keys(x.locals))},
|
119
|
-
${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)}
|
120
|
-
|
121
|
-
|
114
|
+
${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)}` : ''}
|
115
|
+
};`.replaceAll('\n\n', '\n').replaceAll('\n\n', '\n')
|
116
|
+
}).join('\n')}
|
122
117
|
};`;
|
123
118
|
};
|
124
119
|
|
125
|
-
|
126
|
-
// console.log(code);
|
127
|
-
|
128
|
-
fs.writeFileSync(join(__dirname, 'generated_builtins.js'), code);
|
120
|
+
fs.writeFileSync(join(__dirname, 'generated_builtins.js'), await precompile());
|
package/compiler/prototype.js
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
import { Opcodes, Blocktype, Valtype, ValtypeSize
|
2
|
-
import { number } from
|
3
|
-
import { unsignedLEB128 } from
|
4
|
-
import { UNDEFINED } from
|
5
|
-
import Prefs from './prefs.js';
|
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';
|
6
5
|
import { TYPES } from './types.js';
|
6
|
+
import Prefs from './prefs.js';
|
7
7
|
|
8
8
|
// todo: turn these into built-ins once arrays and these become less hacky
|
9
9
|
|
package/compiler/wasmSpec.js
CHANGED
package/compiler/wrap.js
CHANGED
@@ -1,12 +1,76 @@
|
|
1
1
|
import compile from './index.js';
|
2
2
|
import decompile from './decompile.js';
|
3
3
|
import { encodeVector, encodeLocal } from './encoding.js';
|
4
|
-
import Prefs from './prefs.js';
|
5
|
-
import { log } from './log.js';
|
6
4
|
import { TYPES } from './types.js';
|
5
|
+
import { log } from './log.js';
|
6
|
+
import Prefs from './prefs.js';
|
7
7
|
|
8
8
|
const bold = x => `\u001b[1m${x}\u001b[0m`;
|
9
9
|
|
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
|
+
}
|
72
|
+
};
|
73
|
+
|
10
74
|
export default async (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
|
11
75
|
const times = [];
|
12
76
|
|
@@ -148,62 +212,11 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
148
212
|
|
149
213
|
exports[func.name] = function() {
|
150
214
|
try {
|
151
|
-
const
|
152
|
-
|
153
|
-
if (_ret == null) return undefined;
|
154
|
-
|
155
|
-
const [ ret, type ] = _ret;
|
156
|
-
|
157
|
-
// if (ret >= typeBase && ret <= typeBase + 8) return ret > (typeBase + 7) ? 'object' : TYPES[ret];
|
158
|
-
|
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];
|
215
|
+
const ret = exp.apply(this, arguments);
|
167
216
|
|
168
|
-
|
169
|
-
}
|
217
|
+
if (ret == null) return undefined;
|
170
218
|
|
171
|
-
|
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: {
|
182
|
-
const pointer = ret;
|
183
|
-
const length = (new Int32Array(memory.buffer, pointer, 1))[0];
|
184
|
-
|
185
|
-
// have to slice because of memory alignment
|
186
|
-
const buf = memory.buffer.slice(pointer + 4, pointer + 4 + 8 * length);
|
187
|
-
|
188
|
-
return Array.from(new Float64Array(buf));
|
189
|
-
}
|
190
|
-
|
191
|
-
case TYPES.bytestring: {
|
192
|
-
const pointer = ret;
|
193
|
-
const length = (new Int32Array(memory.buffer, pointer, 1))[0];
|
194
|
-
|
195
|
-
return Array.from(new Uint8Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
|
196
|
-
}
|
197
|
-
|
198
|
-
case TYPES.date: {
|
199
|
-
const pointer = ret;
|
200
|
-
const value = (new Float64Array(memory.buffer, pointer, 1))[0];
|
201
|
-
|
202
|
-
return new Date(value);
|
203
|
-
}
|
204
|
-
|
205
|
-
default: return ret;
|
206
|
-
}
|
219
|
+
return porfToJSValue(memory, funcs, ret[0], ret[1])
|
207
220
|
} catch (e) {
|
208
221
|
if (e.is && e.is(exceptTag)) {
|
209
222
|
const exceptId = e.getArg(exceptTag, 0);
|
package/package.json
CHANGED
package/runner/compare.js
CHANGED
package/runner/debug.js
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
import compile from '../compiler/wrap.js';
|
4
|
-
import fs from 'node:fs';
|
5
|
-
|
6
4
|
import Byg from '../byg/index.js';
|
5
|
+
import fs from 'node:fs';
|
7
6
|
|
8
7
|
const file = process.argv.slice(2).find(x => x[0] !== '-');
|
9
8
|
let source = fs.readFileSync(file, 'utf8');
|
@@ -19,7 +18,6 @@ source = source.replace(/^\s*(function|const)\s*([a-zA-Z0-9]+)(\s*=\s*)?\([^)]*\
|
|
19
18
|
|
20
19
|
const lines = source.split('\n');
|
21
20
|
for (let i = 0; i < lines.length; i++) {
|
22
|
-
// lines[line] = lines[line].replace(/^[^\n}]*;$/, _ => `profile(${line});${_}`);
|
23
21
|
if (lines[i].trim().replace('}', '') !== '') lines[i] = `profile1(Porffor.wasm.i32.const(${i}));` + lines[i];
|
24
22
|
}
|
25
23
|
source = lines.join('\n');
|
@@ -35,8 +33,6 @@ const byg = Byg({
|
|
35
33
|
}
|
36
34
|
});
|
37
35
|
|
38
|
-
// console.log(source);
|
39
|
-
|
40
36
|
let stepIn = false, stepOut = false;
|
41
37
|
const callStack = [];
|
42
38
|
|
@@ -72,7 +68,6 @@ try {
|
|
72
68
|
[
|
73
69
|
{
|
74
70
|
x: termWidth - 1 - 40 - 6,
|
75
|
-
// y: () => termHeight - 20 - 1 - 4,
|
76
71
|
y: () => 4,
|
77
72
|
width: 40,
|
78
73
|
height: 20,
|
package/runner/profiler.js
CHANGED
@@ -3,22 +3,12 @@
|
|
3
3
|
import compile from '../compiler/wrap.js';
|
4
4
|
import fs from 'node:fs';
|
5
5
|
|
6
|
-
import Prefs from '../compiler/prefs.js';
|
7
|
-
|
8
|
-
// const fast = Prefs.profiler === 'fast';
|
9
|
-
const fast = !Prefs.experimentalProfiler;
|
10
|
-
|
11
6
|
const file = process.argv.slice(2).find(x => x[0] !== '-');
|
12
7
|
let source = fs.readFileSync(file, 'utf8');
|
13
8
|
|
14
9
|
let profileId = 0;
|
15
|
-
|
16
|
-
// source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile(Porffor.wasm.i32.const(${profileId++}));${_}profile(Porffor.wasm.i32.const(${profileId++}));`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
|
17
|
-
source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile1(Porffor.wasm.i32.const(${profileId}));${_}profile2(Porffor.wasm.i32.const(${profileId++}));`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
|
10
|
+
source = source.replace(/^[^\n}]*;$/mg, _ => `profile1(Porffor.wasm.i32.const(${profileId}));${_}profile2(Porffor.wasm.i32.const(${profileId++}));`)
|
18
11
|
|
19
|
-
// console.log(source);
|
20
|
-
|
21
|
-
// let tmp = new Array(profileId).fill(0);
|
22
12
|
let tmp = new Array(profileId).fill(0);
|
23
13
|
let times = new Array(profileId).fill(0);
|
24
14
|
let samples = 0;
|
@@ -31,31 +21,19 @@ let last = 0;
|
|
31
21
|
|
32
22
|
try {
|
33
23
|
const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
|
34
|
-
y:
|
24
|
+
y: n => {
|
35
25
|
tmp[n] = performance.now();
|
36
|
-
}
|
37
|
-
z:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
// if (n % 3 === 2) {
|
48
|
-
// tmp[n] += (performance.now() - tmp[n - 1]) - (tmp[n - 1] - tmp[n - 2]);
|
49
|
-
// samples++;
|
50
|
-
|
51
|
-
// if (performance.now() > last) {
|
52
|
-
// process.stdout.write(`\r${spinner[spin++ % 4]} running: collected ${samples} samples...`);
|
53
|
-
// last = performance.now() + 100;
|
54
|
-
// }
|
55
|
-
// } else {
|
56
|
-
// tmp[n] = performance.now();
|
57
|
-
// }
|
58
|
-
// }
|
26
|
+
},
|
27
|
+
z: n => {
|
28
|
+
const t = performance.now();
|
29
|
+
times[n] += t - tmp[n];
|
30
|
+
|
31
|
+
samples++;
|
32
|
+
if (t > last) {
|
33
|
+
process.stdout.write(`\r${spinner[spin++ % 4]} running: collected ${samples} samples...`);
|
34
|
+
last = t + 100;
|
35
|
+
}
|
36
|
+
}
|
59
37
|
});
|
60
38
|
|
61
39
|
const start = performance.now();
|
@@ -64,14 +42,11 @@ try {
|
|
64
42
|
|
65
43
|
const total = performance.now() - start;
|
66
44
|
|
67
|
-
console.log(`\
|
45
|
+
console.log(`\ntotal: ${total}ms\nsamples: ${samples}\n\n\n` + source.split('\n').map(x => {
|
68
46
|
let time = 0;
|
69
47
|
if (x.startsWith('profile')) {
|
70
|
-
// const id = parseInt(x.slice(8, x.indexOf(')')));
|
71
|
-
// const id = parseInt(x.slice(31, x.indexOf(')') + 1));
|
72
48
|
const id = parseInt(x.slice(32, x.indexOf(')')));
|
73
|
-
|
74
|
-
time = fast ? times[id] : tmp[id + 2];
|
49
|
+
time = times[id]
|
75
50
|
}
|
76
51
|
|
77
52
|
let color = [ 0, 0, 0 ];
|
@@ -85,8 +60,6 @@ try {
|
|
85
60
|
|
86
61
|
const ansiColor = `2;${color[0]};${color[1]};${color[2]}m`;
|
87
62
|
|
88
|
-
// const line = x.replace(/profile\([0-9]+\);/g, '');
|
89
|
-
// const line = x.replace(/profile\(Porffor.wasm.i32.const\([0-9]+\)\);/g, '');
|
90
63
|
const line = x.replace(/profile[0-9]\(Porffor.wasm.i32.const\([0-9]+\)\);/g, '');
|
91
64
|
|
92
65
|
if (percents) return `\x1b[48;${ansiColor}\x1b[97m${time ? ((time * 100).toFixed(0).padStart(4, ' ') + '%') : ' '}\x1b[0m\x1b[38;${ansiColor}▌\x1b[0m ${line}`;
|
package/runner/repl.js
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
import compile from '../compiler/wrap.js';
|
2
|
-
import
|
3
|
-
|
4
|
-
// import repl from 'node:repl';
|
5
|
-
// import repl from '../../node-repl-polyfill/index.js';
|
2
|
+
import version from './version.js';
|
6
3
|
|
7
4
|
let repl;
|
8
5
|
try {
|
@@ -17,8 +14,6 @@ try {
|
|
17
14
|
repl = (await import('node-repl-polyfill')).default;
|
18
15
|
}
|
19
16
|
|
20
|
-
// process.argv.push('-O0'); // disable opts
|
21
|
-
|
22
17
|
globalThis.valtype = 'f64';
|
23
18
|
|
24
19
|
const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
|
@@ -32,7 +27,7 @@ if (host.startsWith('Node')) host = '\x1B[92m' + host;
|
|
32
27
|
if (host.startsWith('Deno')) host = '\x1B[97m' + host;
|
33
28
|
if (host.startsWith('Bun')) host = '\x1B[93m' + host;
|
34
29
|
|
35
|
-
console.log(`Welcome to \x1B[1m\x1B[35mPorffor\x1B[0m \x1B[90m(${
|
30
|
+
console.log(`Welcome to \x1B[1m\x1B[35mPorffor\x1B[0m \x1B[90m(${version})\x1B[0m running on \x1B[1m${host.replace('/', ' \x1B[0m\x1B[90m(')})\x1B[0m`);
|
36
31
|
console.log(`\x1B[90musing opt ${process.argv.find(x => x.startsWith('-O')) ?? '-O1'}, parser ${parser}, valtype ${valtype}\x1B[0m`);
|
37
32
|
console.log();
|
38
33
|
|
@@ -81,11 +76,10 @@ const run = async (source, _context, _filename, callback, run = true) => {
|
|
81
76
|
let toRun = (prev ? (prev + `;\nprint(-0x1337);\n`) : '') + source.trim();
|
82
77
|
|
83
78
|
let shouldPrint = !prev;
|
84
|
-
const { exports,
|
79
|
+
const { exports, pages } = await compile(toRun, [], {}, str => {
|
85
80
|
if (shouldPrint) process.stdout.write(str);
|
86
81
|
if (str === '-4919') shouldPrint = true;
|
87
82
|
});
|
88
|
-
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
89
83
|
|
90
84
|
if (run && exports.$) {
|
91
85
|
lastMemory = exports.$;
|
package/runner/sizes.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import fs from 'node:fs';
|
2
1
|
import compile from '../compiler/index.js';
|
2
|
+
import fs from 'node:fs';
|
3
3
|
|
4
4
|
// deno compat
|
5
5
|
const textEncoder = new TextEncoder();
|
@@ -18,7 +18,7 @@ const perform = async (file, args) => {
|
|
18
18
|
console.log(label, ' '.repeat(40 - label.length), `${size}b`);
|
19
19
|
};
|
20
20
|
|
21
|
-
const argsValtypes = [ '--valtype=i32', '--valtype=
|
21
|
+
const argsValtypes = [ '--valtype=i32', '--valtype=f64' ];
|
22
22
|
const argsOptlevels = [ '-O0', '-O1', '-O2', '-O3' ];
|
23
23
|
|
24
24
|
for (const file of [ 'bench/prime_basic.js', 'bench/fib_iter.js', 'test/math_1.js', 'test/math_3.js', 'test/while_1.js', 'test/for_2.js', 'test/unary_3.js', 'test/updateexp_1.js', 'test/eq_3.js', 'test/empty.js' ]) {
|
package/runner/version.js
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
import
|
1
|
+
import { readFileSync } from 'node:fs';
|
2
2
|
|
3
|
-
let
|
4
|
-
|
5
|
-
rev = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version.split('-')[1].slice(0, 7);
|
6
|
-
} catch {
|
7
|
-
rev = fs.readFileSync(new URL('../.git/refs/heads/main', import.meta.url), 'utf8').trim().slice(0, 7);
|
8
|
-
}
|
3
|
+
export let version = 'unknown';
|
4
|
+
export let rev = 'unknown';
|
9
5
|
|
10
|
-
|
6
|
+
const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
7
|
+
version = packageJson.version.split('-')[0];
|
8
|
+
rev = packageJson.version.split('-')[1];
|
9
|
+
|
10
|
+
if (!rev) rev = readFileSync(new URL('../.git/refs/heads/main', import.meta.url), 'utf8').trim().slice(0, 9);
|
11
|
+
|
12
|
+
export default `${version}-${rev}`;
|