porffor 0.60.10 → 0.60.12
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/compiler/builtins/_internal_object.ts +6 -0
- package/compiler/builtins/function.ts +9 -0
- package/compiler/builtins/object_hiddenPrototype.js +1 -1
- package/compiler/builtins/regexp.ts +15 -15
- package/compiler/builtins_precompiled.js +1290 -1273
- package/compiler/codegen.js +24 -32
- package/compiler/precompile.js +3 -2
- package/deno.lock +18 -0
- package/foo.js +36 -30
- package/package.json +1 -1
- package/runtime/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -73,17 +73,6 @@ export const allocStr = (scope, str, bytestring) => {
|
|
73
73
|
return allocBytes(scope, str, bytes);
|
74
74
|
};
|
75
75
|
|
76
|
-
const todo = (scope, msg, expectsValue = undefined) => {
|
77
|
-
msg = `todo: ${msg}`;
|
78
|
-
|
79
|
-
switch (Prefs.todoTime ?? 'runtime') {
|
80
|
-
case 'compile':
|
81
|
-
throw new Error(msg);
|
82
|
-
|
83
|
-
case 'runtime':
|
84
|
-
return internalThrow(scope, 'Error', msg, expectsValue);
|
85
|
-
}
|
86
|
-
};
|
87
76
|
|
88
77
|
const isFuncType = type =>
|
89
78
|
type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression' ||
|
@@ -107,7 +96,7 @@ const funcRef = func => {
|
|
107
96
|
|
108
97
|
func.generate?.();
|
109
98
|
|
110
|
-
const wrapperArgc = Prefs.indirectWrapperArgc ??
|
99
|
+
const wrapperArgc = Prefs.indirectWrapperArgc ?? 16;
|
111
100
|
if (!func.wrapperFunc) {
|
112
101
|
const locals = {
|
113
102
|
['#length']: { idx: 0, type: Valtype.i32 }
|
@@ -202,11 +191,11 @@ const funcRef = func => {
|
|
202
191
|
wasm.push(
|
203
192
|
[ Opcodes.local_get, array ],
|
204
193
|
[ Opcodes.local_get, 5 + i * 2 ],
|
205
|
-
[ Opcodes.f64_store, 0, offset ],
|
194
|
+
[ Opcodes.f64_store, 0, ...unsignedLEB128(offset) ],
|
206
195
|
|
207
196
|
[ Opcodes.local_get, array ],
|
208
197
|
[ Opcodes.local_get, 6 + i * 2 ],
|
209
|
-
[ Opcodes.i32_store8, 0, offset + 8 ],
|
198
|
+
[ Opcodes.i32_store8, 0, ...unsignedLEB128(offset + 8) ],
|
210
199
|
);
|
211
200
|
offset += 9;
|
212
201
|
}
|
@@ -443,7 +432,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
443
432
|
return cacheAst(decl, generateTaggedTemplate(scope, decl, global, name, valueUnused));
|
444
433
|
|
445
434
|
case 'ExportNamedDeclaration':
|
446
|
-
if (!decl.declaration) return
|
435
|
+
if (!decl.declaration) return internalThrow(scope, 'Error', 'porffor: unsupported export declaration', true);
|
447
436
|
|
448
437
|
const funcsBefore = funcs.map(x => x.name);
|
449
438
|
generate(scope, decl.declaration);
|
@@ -469,6 +458,12 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
469
458
|
if (Prefs.d) log.warning('codegen', 'with is not supported, treating as expression');
|
470
459
|
return cacheAst(decl, generate(scope, decl.body));
|
471
460
|
|
461
|
+
case 'PrivateIdentifier':
|
462
|
+
return cacheAst(decl, generate(scope, {
|
463
|
+
type: 'Literal',
|
464
|
+
value: privateIDName(decl.name)
|
465
|
+
}));
|
466
|
+
|
472
467
|
case 'TSEnumDeclaration':
|
473
468
|
return cacheAst(decl, generateEnum(scope, decl));
|
474
469
|
|
@@ -479,7 +474,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
479
474
|
return cacheAst(decl, [ number(UNDEFINED) ]);
|
480
475
|
}
|
481
476
|
|
482
|
-
return cacheAst(decl,
|
477
|
+
return cacheAst(decl, internalThrow(scope, 'Error', `porffor: no generation for ${decl.type}`, true));
|
483
478
|
}
|
484
479
|
};
|
485
480
|
|
@@ -905,8 +900,6 @@ const performLogicOp = (scope, op, left, right, leftType, rightType) => {
|
|
905
900
|
'??': nullish
|
906
901
|
};
|
907
902
|
|
908
|
-
if (!checks[op]) return todo(scope, `logic operator ${op} not implemented yet`, true);
|
909
|
-
|
910
903
|
// generic structure for {a} OP {b}
|
911
904
|
// _ = {a}; if (OP_CHECK) {b} else _
|
912
905
|
|
@@ -1286,7 +1279,6 @@ const performOp = (scope, op, left, right, leftType, rightType) => {
|
|
1286
1279
|
|
1287
1280
|
// some complex ops are implemented in funcs
|
1288
1281
|
if (typeof ops === 'function') return finalize(asmFuncToAsm(scope, ops, { left, right }));
|
1289
|
-
if (!ops) return todo(scope, `operator ${op} not implemented yet`, true);
|
1290
1282
|
if (!Array.isArray(ops)) ops = [ ops ];
|
1291
1283
|
ops = [ ops ];
|
1292
1284
|
|
@@ -1950,6 +1942,13 @@ const getNodeType = (scope, node) => {
|
|
1950
1942
|
return getNodeType(scope, node.body);
|
1951
1943
|
}
|
1952
1944
|
|
1945
|
+
if (node.type === 'PrivateIdentifier') {
|
1946
|
+
return getNodeType(scope, {
|
1947
|
+
type: 'Literal',
|
1948
|
+
value: privateIDName(node.name)
|
1949
|
+
});
|
1950
|
+
}
|
1951
|
+
|
1953
1952
|
if (node.type.endsWith('Statement') || node.type.endsWith('Declaration')) {
|
1954
1953
|
return TYPES.undefined;
|
1955
1954
|
}
|
@@ -2021,8 +2020,6 @@ const generateLiteral = (scope, decl, global, name) => {
|
|
2021
2020
|
]
|
2022
2021
|
});
|
2023
2022
|
}
|
2024
|
-
|
2025
|
-
return todo(scope, `cannot generate literal of type ${typeof decl.value}`, true);
|
2026
2023
|
};
|
2027
2024
|
|
2028
2025
|
const generateExp = (scope, decl) => {
|
@@ -2561,7 +2558,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2561
2558
|
funcs.table = true;
|
2562
2559
|
scope.table = true;
|
2563
2560
|
|
2564
|
-
const wrapperArgc = Prefs.indirectWrapperArgc ??
|
2561
|
+
const wrapperArgc = Prefs.indirectWrapperArgc ?? 16;
|
2565
2562
|
const underflow = wrapperArgc - args.length;
|
2566
2563
|
for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
|
2567
2564
|
if (args.length > wrapperArgc) args = args.slice(0, wrapperArgc);
|
@@ -2629,14 +2626,14 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2629
2626
|
|
2630
2627
|
...typeSwitch(scope, getNodeType(scope, callee), {
|
2631
2628
|
[TYPES.function]: () => [
|
2632
|
-
number(
|
2629
|
+
number(wrapperArgc - underflow, Valtype.i32),
|
2633
2630
|
...forceDuoValtype(scope, newTargetWasm, Valtype.f64),
|
2634
2631
|
...forceDuoValtype(scope, thisWasm, Valtype.f64),
|
2635
2632
|
...out,
|
2636
2633
|
|
2637
2634
|
[ Opcodes.local_get, calleeLocal ],
|
2638
2635
|
Opcodes.i32_to_u,
|
2639
|
-
[ Opcodes.call_indirect, args.length + 2, 0
|
2636
|
+
[ Opcodes.call_indirect, args.length + 2, 0 ],
|
2640
2637
|
...setLastType(scope)
|
2641
2638
|
],
|
2642
2639
|
|
@@ -3525,8 +3522,6 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3525
3522
|
]
|
3526
3523
|
}, undefined, global)
|
3527
3524
|
);
|
3528
|
-
} else {
|
3529
|
-
return todo(scope, `${prop.type} is not supported in object patterns`);
|
3530
3525
|
}
|
3531
3526
|
}
|
3532
3527
|
|
@@ -3567,8 +3562,6 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3567
3562
|
}),
|
3568
3563
|
[ Opcodes.drop ]
|
3569
3564
|
];
|
3570
|
-
|
3571
|
-
return todo(scope, `variable declarators of type ${pattern.type} are not supported yet`);
|
3572
3565
|
}
|
3573
3566
|
|
3574
3567
|
const generateVar = (scope, decl) => {
|
@@ -3637,7 +3630,7 @@ const memberTmpNames = scope => {
|
|
3637
3630
|
};
|
3638
3631
|
|
3639
3632
|
// todo: generate this array procedurally
|
3640
|
-
const builtinPrototypeGets = ['size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'source', 'flags', 'global', 'ignoreCase', 'multiline', 'dotAll', 'unicode', 'sticky', 'hasIndices', 'unicodeSets'];
|
3633
|
+
const builtinPrototypeGets = ['size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'source', 'flags', 'global', 'ignoreCase', 'multiline', 'dotAll', 'unicode', 'sticky', 'hasIndices', 'unicodeSets', 'lastIndex'];
|
3641
3634
|
|
3642
3635
|
const ctHash = prop => {
|
3643
3636
|
if (!Prefs.ctHash || !prop ||
|
@@ -4437,8 +4430,6 @@ const generateUnary = (scope, decl) => {
|
|
4437
4430
|
return out;
|
4438
4431
|
}
|
4439
4432
|
}
|
4440
|
-
|
4441
|
-
return todo(scope, `unary operator ${decl.operator} not implemented yet`, true);
|
4442
4433
|
};
|
4443
4434
|
|
4444
4435
|
const generateUpdate = (scope, decl, _global, _name, valueUnused = false) => {
|
@@ -5564,7 +5555,8 @@ const generateMeta = (scope, decl) => {
|
|
5564
5555
|
return [ number(UNDEFINED) ];
|
5565
5556
|
}
|
5566
5557
|
|
5567
|
-
|
5558
|
+
// todo: import.meta
|
5559
|
+
return internalThrow(scope, 'Error', `porffor: meta property ${decl.meta.name}.${decl.property.name} is not supported yet`, true);
|
5568
5560
|
};
|
5569
5561
|
|
5570
5562
|
const compileBytes = (val, itemType) => {
|
package/compiler/precompile.js
CHANGED
@@ -57,7 +57,7 @@ const compile = async (file, _funcs) => {
|
|
57
57
|
first = source.slice(0, source.indexOf('\n'));
|
58
58
|
}
|
59
59
|
|
60
|
-
let args = ['--module', '--
|
60
|
+
let args = ['--module', '--truthy=no_nan_negative', '--no-rm-unused-types', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--no-treeshake-wasm-imports', '--no-coctc'];
|
61
61
|
if (first.startsWith('// @porf')) {
|
62
62
|
args = first.slice('// @porf '.length).split(' ').concat(args);
|
63
63
|
}
|
@@ -88,6 +88,7 @@ const compile = async (file, _funcs) => {
|
|
88
88
|
const body = globalThis.funcBodies[x.name];
|
89
89
|
const bodyHasTopLevelThrow = body?.body && body.body.some(x => x.type === 'ThrowStatement');
|
90
90
|
|
91
|
+
if (x.name === '_eval') x.name = 'eval';
|
91
92
|
if (x.data) {
|
92
93
|
x.data = x.data.reduce((acc, x) => { acc[data[x].page] = data[x].bytes; return acc; }, {});
|
93
94
|
}
|
@@ -278,7 +279,7 @@ ${funcs.map(x => {
|
|
278
279
|
const name = x.name.includes('#') ? `['${x.name}']` : `.${x.name}`;
|
279
280
|
|
280
281
|
const returnTypes = [...(x.returnTypes ?? [])].filter(x => ![ TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ].includes(x));
|
281
|
-
return `x${name}
|
282
|
+
return `x${name}={
|
282
283
|
wasm:${rewriteWasm(x.wasm)},
|
283
284
|
params:${JSON.stringify(x.params)},typedParams:1,returns:${JSON.stringify(x.returns)},${x.returnType != null ? `returnType:${JSON.stringify(x.returnType)},` : ''}${returnTypes.length > 0 ? `returnTypes:${JSON.stringify(returnTypes)},` : ''}jsLength:${x.jsLength},
|
284
285
|
locals:${JSON.stringify(locals.slice(x.params.length).map(x => x[1].type))},localNames:${JSON.stringify(locals.map(x => x[0]))},
|
package/deno.lock
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"version": "5",
|
3
|
+
"redirects": {
|
4
|
+
"https://esm.sh/acorn": "https://esm.sh/acorn@8.14.0"
|
5
|
+
},
|
6
|
+
"remote": {
|
7
|
+
"https://esm.sh/acorn@8.14.0": "b5a42b450cfd514709a3f855bfb1d886104d9c72a01b7d111e6e26c86e5f41e2",
|
8
|
+
"https://esm.sh/acorn@8.14.0/denonext/acorn.mjs": "669c981ded732a02351d5e6b1f6d5641d71a8d5165c0fed93be7f40c676be0b8"
|
9
|
+
},
|
10
|
+
"workspace": {
|
11
|
+
"packageJson": {
|
12
|
+
"dependencies": [
|
13
|
+
"npm:acorn@^8.15.0",
|
14
|
+
"npm:node-repl-polyfill@~0.1.2"
|
15
|
+
]
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
package/foo.js
CHANGED
@@ -1,34 +1,40 @@
|
|
1
|
-
//
|
2
|
-
|
3
|
-
|
1
|
+
// Function.prototype;
|
2
|
+
// // Object.defineProperty(Function.prototype, "prop", {
|
3
|
+
// // value: 1001,
|
4
|
+
// // writable: false,
|
5
|
+
// // enumerable: false,
|
6
|
+
// // configurable: true
|
7
|
+
// // });
|
8
|
+
// var funObj = function() {};
|
9
|
+
// // console.log(Function.prototype.hasOwnProperty);
|
10
|
+
// // console.log(Function.prototype.hasOwnProperty === Object.prototype.hasOwnProperty);
|
11
|
+
// // console.log(Object.getPrototypeOf(funObj) === Function.prototype);
|
12
|
+
// // console.log(Object.getPrototypeOf(Object.getPrototypeOf(funObj)) === Object.prototype);
|
13
|
+
// console.log(funObj.hasOwnProperty);
|
4
14
|
|
5
|
-
//
|
6
|
-
const o = Object.create(null);
|
7
|
-
o[key] = 123;
|
15
|
+
// // console.log(funObj.hasOwnProperty("prop"), false, 'funObj.hasOwnProperty("prop")');
|
8
16
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
if (key in o) {
|
13
|
-
// noop
|
14
|
-
}
|
15
|
-
}
|
16
|
-
console.log(`in: ${Date.now() - t1}ms`);
|
17
|
+
var FACTORY = function() {
|
18
|
+
this.aproperty = 1;
|
19
|
+
};
|
17
20
|
|
18
|
-
|
19
|
-
const t2 = Date.now();
|
20
|
-
for (let i = 0; i < ITER; i++) {
|
21
|
-
if (Object.hasOwn(o, key)) {
|
22
|
-
// noop
|
23
|
-
}
|
24
|
-
}
|
25
|
-
console.log(`Object.hasOwn: ${Date.now() - t2}ms`);
|
21
|
+
var instance = new FACTORY;
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
console.log(
|
23
|
+
console.log(instance.__proto__ == FACTORY.prototype);
|
24
|
+
console.log(instance.__proto__.__proto__ == Object.prototype);
|
25
|
+
console.log(instance.hasOwnProperty);
|
26
|
+
console.log(instance.__proto__.hasOwnProperty);
|
27
|
+
console.log(instance.__proto__.__proto__.hasOwnProperty);
|
28
|
+
console.log()
|
29
|
+
|
30
|
+
console.log(
|
31
|
+
typeof Object.prototype.hasOwnProperty,
|
32
|
+
"function",
|
33
|
+
'The value of `typeof Object.prototype.hasOwnProperty` is expected to be "function"'
|
34
|
+
);
|
35
|
+
|
36
|
+
console.log(
|
37
|
+
typeof instance.hasOwnProperty,
|
38
|
+
"function",
|
39
|
+
'The value of `typeof instance.hasOwnProperty` is expected to be "function"'
|
40
|
+
);
|
package/package.json
CHANGED