porffor 0.25.0 → 0.25.2
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/CONTRIBUTING.md +2 -3
- package/compiler/builtins.js +1 -1
- package/compiler/builtins_objects.js +104 -41
- package/compiler/builtins_precompiled.js +148 -148
- package/compiler/codegen.js +29 -15
- package/compiler/precompile.js +3 -2
- package/compiler/wrap.js +4 -1
- package/package.json +1 -1
- package/runner/index.js +5 -3
- package/todo.txt +0 -2
package/compiler/codegen.js
CHANGED
@@ -1189,7 +1189,7 @@ const generateBinaryExp = (scope, decl, _global, _name) => {
|
|
1189
1189
|
const asmFuncToAsm = (scope, func) => {
|
1190
1190
|
return func(scope, {
|
1191
1191
|
TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage, internalThrow,
|
1192
|
-
getNodeType, generateIdent,
|
1192
|
+
getNodeType, generate, generateIdent,
|
1193
1193
|
builtin: n => {
|
1194
1194
|
let idx = funcIndex[n] ?? importedFuncs[n];
|
1195
1195
|
if (idx == null && builtinFuncs[n]) {
|
@@ -1772,10 +1772,10 @@ const RTArrayUtil = {
|
|
1772
1772
|
]
|
1773
1773
|
};
|
1774
1774
|
|
1775
|
-
const createNewTarget = (scope, decl, idx) => {
|
1775
|
+
const createNewTarget = (scope, decl, idx = 0) => {
|
1776
1776
|
if (decl._new) {
|
1777
1777
|
return [
|
1778
|
-
...number(idx),
|
1778
|
+
...(typeof idx === 'number' ? number(idx) : idx),
|
1779
1779
|
...number(TYPES.function, Valtype.i32)
|
1780
1780
|
];
|
1781
1781
|
}
|
@@ -1786,7 +1786,7 @@ const createNewTarget = (scope, decl, idx) => {
|
|
1786
1786
|
];
|
1787
1787
|
};
|
1788
1788
|
|
1789
|
-
const createThisArg = (scope, decl,
|
1789
|
+
const createThisArg = (scope, decl, knownThis = undefined) => {
|
1790
1790
|
if (knownThis) {
|
1791
1791
|
// todo: check compliance
|
1792
1792
|
return knownThis;
|
@@ -2248,6 +2248,12 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2248
2248
|
];
|
2249
2249
|
}
|
2250
2250
|
|
2251
|
+
const newTargetWasm = decl._newTargetWasm ?? createNewTarget(scope, decl, [
|
2252
|
+
[ Opcodes.local_get, funcLocal ],
|
2253
|
+
Opcodes.i32_from_u
|
2254
|
+
]);
|
2255
|
+
const thisWasm = decl._thisWasm ?? createThisArg(scope, decl, knownThis);
|
2256
|
+
|
2251
2257
|
const gen = argc => {
|
2252
2258
|
const argsOut = [];
|
2253
2259
|
for (let i = 0; i < argc; i++) {
|
@@ -2273,8 +2279,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2273
2279
|
// no type return
|
2274
2280
|
checkFlag(0b10, [
|
2275
2281
|
// no type return & constr
|
2276
|
-
...
|
2277
|
-
...
|
2282
|
+
...newTargetWasm,
|
2283
|
+
...thisWasm,
|
2278
2284
|
...argsOut,
|
2279
2285
|
[ Opcodes.local_get, funcLocal ],
|
2280
2286
|
[ Opcodes.call_indirect, argc + 2, 0, 'no_type_return' ],
|
@@ -2288,8 +2294,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2288
2294
|
// type return
|
2289
2295
|
checkFlag(0b10, [
|
2290
2296
|
// type return & constr
|
2291
|
-
...
|
2292
|
-
...
|
2297
|
+
...newTargetWasm,
|
2298
|
+
...thisWasm,
|
2293
2299
|
...argsOut,
|
2294
2300
|
[ Opcodes.local_get, funcLocal ],
|
2295
2301
|
[ Opcodes.call_indirect, argc + 2, 0 ],
|
@@ -2371,8 +2377,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2371
2377
|
}
|
2372
2378
|
|
2373
2379
|
if (func && func.constr) {
|
2374
|
-
out.push(...createNewTarget(scope, decl, idx - importedFuncs.length));
|
2375
|
-
out.push(...createThisArg(scope, decl
|
2380
|
+
out.push(...(decl._newTargetWasm ?? createNewTarget(scope, decl, idx - importedFuncs.length)));
|
2381
|
+
out.push(...(decl._thisWasm ?? createThisArg(scope, decl)));
|
2376
2382
|
paramOffset += 4;
|
2377
2383
|
}
|
2378
2384
|
|
@@ -3956,7 +3962,7 @@ const generateForIn = (scope, decl) => {
|
|
3956
3962
|
depth.push('if');
|
3957
3963
|
depth.push('forin');
|
3958
3964
|
depth.push('block');
|
3959
|
-
depth.push('
|
3965
|
+
depth.push('if');
|
3960
3966
|
|
3961
3967
|
// setup local for left
|
3962
3968
|
generate(scope, decl.left);
|
@@ -3978,6 +3984,7 @@ const generateForIn = (scope, decl) => {
|
|
3978
3984
|
[TYPES.object]: [
|
3979
3985
|
[ Opcodes.loop, Blocktype.void ],
|
3980
3986
|
|
3987
|
+
// read key
|
3981
3988
|
[ Opcodes.local_get, pointer ],
|
3982
3989
|
[ Opcodes.i32_load, 0, 5 ],
|
3983
3990
|
[ Opcodes.local_tee, localTmp(scope, '#forin_tmp', Valtype.i32) ],
|
@@ -4003,11 +4010,18 @@ const generateForIn = (scope, decl) => {
|
|
4003
4010
|
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
4004
4011
|
|
4005
4012
|
[ Opcodes.block, Blocktype.void ],
|
4006
|
-
|
4013
|
+
|
4014
|
+
// todo/perf: do not read key for non-enumerables
|
4015
|
+
// only run body if entry is enumerable
|
4016
|
+
[ Opcodes.local_get, pointer ],
|
4017
|
+
[ Opcodes.i32_load8_u, 0, 17 ],
|
4018
|
+
[ Opcodes.i32_const, 0b0100 ],
|
4019
|
+
[ Opcodes.i32_and ],
|
4020
|
+
[ Opcodes.if, Blocktype.void ],
|
4007
4021
|
...generate(scope, decl.body),
|
4008
4022
|
[ Opcodes.end ],
|
4009
4023
|
|
4010
|
-
// increment
|
4024
|
+
// increment pointer by 14
|
4011
4025
|
[ Opcodes.local_get, pointer ],
|
4012
4026
|
...number(14, Valtype.i32),
|
4013
4027
|
[ Opcodes.i32_add ],
|
@@ -4116,7 +4130,7 @@ const generateBreak = (scope, decl) => {
|
|
4116
4130
|
while: 2, // loop > if (wanted branch) (we are here)
|
4117
4131
|
dowhile: 2, // loop > block (wanted branch) > block (we are here)
|
4118
4132
|
forof: 2, // loop > block (wanted branch) > block (we are here)
|
4119
|
-
forin: 2, // loop > block (wanted branch) >
|
4133
|
+
forin: 2, // loop > block (wanted branch) > if (we are here)
|
4120
4134
|
if: 1, // break inside if, branch 0 to skip the rest of the if
|
4121
4135
|
switch: 1
|
4122
4136
|
})[type];
|
@@ -4139,7 +4153,7 @@ const generateContinue = (scope, decl) => {
|
|
4139
4153
|
while: 1, // loop (wanted branch) > if (we are here)
|
4140
4154
|
dowhile: 3, // loop > block > block (wanted branch) (we are here)
|
4141
4155
|
forof: 3, // loop > block > block (wanted branch) (we are here)
|
4142
|
-
forin: 3 // loop > block >
|
4156
|
+
forin: 3 // loop > block > if (wanted branch) (we are here)
|
4143
4157
|
})[type];
|
4144
4158
|
|
4145
4159
|
return [
|
package/compiler/precompile.js
CHANGED
@@ -204,9 +204,10 @@ ${funcs.map(x => {
|
|
204
204
|
.replace(/\["global",(.*?),"(.*?)",(.*?)\]/g, (_, opcode, name, valtype) => `...glbl(${opcode}, '${name}', ${valtype})`)
|
205
205
|
.replace(/\"local","(.*?)",(.*?)\]/g, (_, name, valtype) => `loc('${name}', ${valtype})]`)
|
206
206
|
.replace(/\[16,"(.*?)"]/g, (_, name) => `[16, ...builtin('${name}')]`)
|
207
|
-
.replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(scope, '${constructor}', \`${message}\`)`)
|
207
|
+
.replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(scope, '${constructor}', \`${message}\`)`)
|
208
|
+
.replace(/\["get object","(.*?)"\]/g, (_, objName) => `...generateIdent(scope, { name: '${objName}' })`);
|
208
209
|
|
209
|
-
return `(scope, {${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}`.slice(0, -1)}}) => ` + str;
|
210
|
+
return `(scope, {${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}${str.includes('generateIdent(') ? 'generateIdent,' : ''}`.slice(0, -1)}}) => ` + str;
|
210
211
|
};
|
211
212
|
|
212
213
|
const locals = Object.entries(x.locals).sort((a,b) => a[1].idx - b[1].idx)
|
package/compiler/wrap.js
CHANGED
@@ -69,7 +69,10 @@ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
|
|
69
69
|
|
70
70
|
const vValue = read(Float64Array, memory, value + offset + 4, 1)[0];
|
71
71
|
const vType = tail >>> 8;
|
72
|
-
|
72
|
+
|
73
|
+
// do not recursive call forever for direct circular
|
74
|
+
const v = vValue === value && vType === type ? out :
|
75
|
+
porfToJSValue({ memory, funcs, pages }, vValue, vType);
|
73
76
|
|
74
77
|
const flags = tail & 0xff;
|
75
78
|
|
package/package.json
CHANGED
package/runner/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
import fs from 'node:fs';
|
3
|
-
globalThis.version = '0.25.
|
3
|
+
globalThis.version = '0.25.2+bd0735a02';
|
4
4
|
|
5
5
|
// deno compat
|
6
6
|
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
@@ -26,18 +26,20 @@ if (process.argv.includes('--help')) {
|
|
26
26
|
console.log(`\x1B[1m\x1B[35mPorffor\x1B[0m is a JavaScript engine/runtime/compiler. \x1B[90m(${globalThis.version})\x1B[0m`);
|
27
27
|
|
28
28
|
// basic usage
|
29
|
-
console.log(`Usage: \x1B[1mporf [command] path/to/script.js [...
|
29
|
+
console.log(`Usage: \x1B[1mporf [command] [...prefs] path/to/script.js [...args]\x1B[0m`);
|
30
30
|
|
31
31
|
// commands
|
32
32
|
console.log(`\n\x1B[1mCommands:\x1B[0m`);
|
33
33
|
for (const [ cmd, [ color, desc ] ] of Object.entries({
|
34
34
|
run: [ 34, 'Run a JS file' ],
|
35
35
|
wasm: [ 34, 'Compile a JS file to a Wasm binary\n' ],
|
36
|
+
|
36
37
|
c: [ 31, 'Compile a JS file to C source code' ],
|
37
38
|
native: [ 31, 'Compile a JS file to a native binary\n' ],
|
39
|
+
|
38
40
|
profile: [ 33, 'Profile a JS file' ],
|
39
41
|
debug: [ 33, 'Debug a JS file' ],
|
40
|
-
'debug-wasm': [ 33, 'Debug the compiled Wasm of a JS file' ]
|
42
|
+
'debug-wasm': [ 33, 'Debug the compiled Wasm of a JS file' ],
|
41
43
|
})) {
|
42
44
|
console.log(` \x1B[1m\x1B[${color}m${cmd}\x1B[0m${' '.repeat(20 - cmd.length - (desc.startsWith('🧪') ? 3 : 0))}${desc}`);
|
43
45
|
}
|
package/todo.txt
DELETED