porffor 0.42.6 → 0.42.7
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/math.ts +1 -1
- package/compiler/builtins_precompiled.js +2 -2
- package/compiler/codegen.js +52 -56
- package/package.json +1 -1
- package/r.js +4 -0
- package/runner/index.js +1 -1
- package/runner/repl.js +8 -1
@@ -1780,9 +1780,9 @@ params:[124,127],typedParams:1,returns:[124,127],typedReturns:1,
|
|
1780
1780
|
locals:[124,124],localNames:["y","y#type","x","prev"],
|
1781
1781
|
}
|
1782
1782
|
this.__Math_cbrt = {
|
1783
|
-
wasm:(_,{builtin})=>[[32,0],[68,0],[97],[4,64],[68,0],[65,1],[15],[11],[32,0],[16,builtin('__Number_isFinite')],[68,0],[97],[4,64],[32,0],[65,1],[15],[11],[32,0],[16,builtin('__Math_abs')],[33,2],[
|
1783
|
+
wasm:(_,{builtin})=>[[32,0],[68,0],[97],[4,64],[68,0],[65,1],[15],[11],[32,0],[16,builtin('__Number_isFinite')],[68,0],[97],[4,64],[32,0],[65,1],[15],[11],[32,0],[16,builtin('__Math_abs')],[33,2],[3,64],[2,64],[32,2],[33,3],[68,2],[32,2],[162],[32,0],[32,2],[32,2],[162],[163],[160],[68,3],[163],[33,2],[32,3],[32,2],[161],[16,builtin('__Math_abs')],[68,1e-15],[100],[13,1],[11],[11],[32,0],[68,0],[99],[4,124],[32,2],[154],[65,1],[33,4],[5],[32,2],[65,1],[33,4],[11],[32,4],[15]],
|
1784
1784
|
params:[124,127],typedParams:1,returns:[124,127],typedReturns:1,
|
1785
|
-
locals:[124,
|
1785
|
+
locals:[124,124,127],localNames:["y","y#type","x","prev","#last_type"],
|
1786
1786
|
}
|
1787
1787
|
this.__Math_hypot = {
|
1788
1788
|
wasm:(_,{builtin})=>[[32,0],[32,0],[162],[32,2],[32,2],[162],[160],[65,1],[16,builtin('__Math_sqrt')],[34,4],[15]],
|
package/compiler/codegen.js
CHANGED
@@ -1340,8 +1340,12 @@ const setType = (scope, name, type) => {
|
|
1340
1340
|
};
|
1341
1341
|
|
1342
1342
|
const getLastType = scope => {
|
1343
|
+
if (!scope.locals['#last_type']) return number(TYPES.number, Valtype.i32);
|
1344
|
+
|
1343
1345
|
scope.gotLastType = true;
|
1344
|
-
return [
|
1346
|
+
return [
|
1347
|
+
[ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ]
|
1348
|
+
];
|
1345
1349
|
};
|
1346
1350
|
|
1347
1351
|
const setLastType = (scope, type = []) => {
|
@@ -1388,11 +1392,7 @@ const getNodeType = (scope, node) => {
|
|
1388
1392
|
|
1389
1393
|
if (name == null) {
|
1390
1394
|
// iife
|
1391
|
-
|
1392
|
-
|
1393
|
-
// presume
|
1394
|
-
if (Prefs.warnAssumedType) console.warn(`Indirect call assumed to be number`);
|
1395
|
-
return TYPES.number;
|
1395
|
+
return getLastType(scope);
|
1396
1396
|
}
|
1397
1397
|
|
1398
1398
|
const func = funcByName(name);
|
@@ -1426,38 +1426,7 @@ const getNodeType = (scope, node) => {
|
|
1426
1426
|
return TYPES.number;
|
1427
1427
|
}
|
1428
1428
|
|
1429
|
-
|
1430
|
-
|
1431
|
-
// presume
|
1432
|
-
if (Prefs.warnAssumedType) console.warn(`Call to ${name} assumed to be number`);
|
1433
|
-
return TYPES.number;
|
1434
|
-
|
1435
|
-
// let protoFunc;
|
1436
|
-
// // ident.func()
|
1437
|
-
// if (name && name.startsWith('__')) {
|
1438
|
-
// const spl = name.slice(2).split('_');
|
1439
|
-
|
1440
|
-
// const baseName = spl.slice(0, -1).join('_');
|
1441
|
-
// const baseType = getType(scope, baseName);
|
1442
|
-
|
1443
|
-
// const func = spl[spl.length - 1];
|
1444
|
-
// protoFunc = prototypeFuncs[baseType]?.[func];
|
1445
|
-
// }
|
1446
|
-
|
1447
|
-
// // literal.func()
|
1448
|
-
// if (!name && node.callee.type === 'MemberExpression') {
|
1449
|
-
// if (node.callee.object.regex) {
|
1450
|
-
// const funcName = node.callee.property.name;
|
1451
|
-
// return Rhemyn[funcName] ? TYPES.boolean : TYPES.undefined;
|
1452
|
-
// }
|
1453
|
-
|
1454
|
-
// const baseType = getNodeType(scope, node.callee.object);
|
1455
|
-
|
1456
|
-
// const func = node.callee.property.name;
|
1457
|
-
// protoFunc = prototypeFuncs[baseType]?.[func];
|
1458
|
-
// }
|
1459
|
-
|
1460
|
-
// if (protoFunc) return protoFunc.returnType;
|
1429
|
+
return getLastType(scope);
|
1461
1430
|
}
|
1462
1431
|
|
1463
1432
|
if (node.type === 'ExpressionStatement') {
|
@@ -1505,10 +1474,7 @@ const getNodeType = (scope, node) => {
|
|
1505
1474
|
if (knownLeft === TYPES.bytestring || knownRight === TYPES.bytestring)
|
1506
1475
|
guess = TYPES.bytestring;
|
1507
1476
|
|
1508
|
-
|
1509
|
-
|
1510
|
-
// presume
|
1511
|
-
return TYPES.number;
|
1477
|
+
return getLastType(scope);
|
1512
1478
|
}
|
1513
1479
|
|
1514
1480
|
if (node.type === 'UnaryExpression') {
|
@@ -1542,11 +1508,7 @@ const getNodeType = (scope, node) => {
|
|
1542
1508
|
}
|
1543
1509
|
}
|
1544
1510
|
|
1545
|
-
|
1546
|
-
|
1547
|
-
// presume
|
1548
|
-
if (Prefs.warnAssumedType) console.warn(`Member access to field .${name} assumed to be number`);
|
1549
|
-
return TYPES.number;
|
1511
|
+
return getLastType(scope);
|
1550
1512
|
}
|
1551
1513
|
|
1552
1514
|
if (node.type === 'TemplateLiteral') {
|
@@ -1579,11 +1541,7 @@ const getNodeType = (scope, node) => {
|
|
1579
1541
|
}
|
1580
1542
|
}
|
1581
1543
|
|
1582
|
-
|
1583
|
-
|
1584
|
-
// presume
|
1585
|
-
if (Prefs.warnAssumedType) console.warn(`AST node ${node.type} assumed to be number`);
|
1586
|
-
return TYPES.number;
|
1544
|
+
return getLastType(scope);
|
1587
1545
|
})();
|
1588
1546
|
|
1589
1547
|
const out = typeof ret === 'number' ? number(ret, Valtype.i32) : ret;
|
@@ -2447,6 +2405,31 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2447
2405
|
paramOffset += 4;
|
2448
2406
|
}
|
2449
2407
|
|
2408
|
+
if (args.at(-1)?.type === 'SpreadElement') {
|
2409
|
+
// hack: support spread element if last by doing essentially:
|
2410
|
+
// const foo = (a, b, c, d) => ...
|
2411
|
+
// foo(a, b, ...c) -> _ = c; foo(a, b, _[0], _[1])
|
2412
|
+
const arg = args.at(-1).argument;
|
2413
|
+
out.push(
|
2414
|
+
...generate(scope, arg),
|
2415
|
+
[ Opcodes.local_set, localTmp(scope, '#spread') ],
|
2416
|
+
...getNodeType(scope, arg),
|
2417
|
+
[ Opcodes.local_set, localTmp(scope, '#spread#type', Valtype.i32) ]
|
2418
|
+
);
|
2419
|
+
|
2420
|
+
args.pop();
|
2421
|
+
const leftover = paramCount - args.length;
|
2422
|
+
for (let i = 0; i < leftover; i++) {
|
2423
|
+
args.push({
|
2424
|
+
type: 'MemberExpression',
|
2425
|
+
object: { type: 'Identifier', name: '#spread' },
|
2426
|
+
property: { type: 'Literal', value: i },
|
2427
|
+
computed: true,
|
2428
|
+
optional: false
|
2429
|
+
});
|
2430
|
+
}
|
2431
|
+
}
|
2432
|
+
|
2450
2433
|
if (func && args.length < paramCount) {
|
2451
2434
|
// too little args, push undefineds
|
2452
2435
|
args = args.concat(new Array(paramCount - (func.hasRestArgument ? 1 : 0) - args.length).fill(DEFAULT_VALUE()));
|
@@ -3689,7 +3672,10 @@ const ifIdentifierErrors = (scope, decl) => {
|
|
3689
3672
|
const generateUnary = (scope, decl) => {
|
3690
3673
|
switch (decl.operator) {
|
3691
3674
|
case '+':
|
3692
|
-
//
|
3675
|
+
// opt: skip ToNumber if already known as number type
|
3676
|
+
generate(scope, decl.argument); // hack: fix last type not being defined for getNodeType before generation
|
3677
|
+
const known = knownType(scope, getNodeType(scope, decl.argument));
|
3678
|
+
if (known === TYPES.number) return generate(scope, decl.argument);
|
3693
3679
|
|
3694
3680
|
// 13.5.4 Unary + Operator, 13.5.4.1 Runtime Semantics: Evaluation
|
3695
3681
|
// https://tc39.es/ecma262/#sec-unary-plus-operator-runtime-semantics-evaluation
|
@@ -3707,7 +3693,7 @@ const generateUnary = (scope, decl) => {
|
|
3707
3693
|
});
|
3708
3694
|
|
3709
3695
|
case '-':
|
3710
|
-
// * -1
|
3696
|
+
// +x * -1
|
3711
3697
|
|
3712
3698
|
if (decl.prefix && decl.argument.type === 'Literal' && typeof decl.argument.value === 'number') {
|
3713
3699
|
// if -n, just return that as a const
|
@@ -3715,7 +3701,12 @@ const generateUnary = (scope, decl) => {
|
|
3715
3701
|
}
|
3716
3702
|
|
3717
3703
|
return [
|
3718
|
-
...generate(scope,
|
3704
|
+
...generate(scope, {
|
3705
|
+
type: 'UnaryExpression',
|
3706
|
+
operator: '+',
|
3707
|
+
prefix: true,
|
3708
|
+
argument: decl.argument
|
3709
|
+
}),
|
3719
3710
|
...(valtype === 'f64' ? [ [ Opcodes.f64_neg ] ] : [ ...number(-1), [ Opcodes.mul ] ])
|
3720
3711
|
];
|
3721
3712
|
|
@@ -3731,7 +3722,12 @@ const generateUnary = (scope, decl) => {
|
|
3731
3722
|
|
3732
3723
|
case '~':
|
3733
3724
|
return [
|
3734
|
-
...generate(scope,
|
3725
|
+
...generate(scope, {
|
3726
|
+
type: 'UnaryExpression',
|
3727
|
+
operator: '+',
|
3728
|
+
prefix: true,
|
3729
|
+
argument: decl.argument
|
3730
|
+
}),
|
3735
3731
|
Opcodes.i32_to,
|
3736
3732
|
[ Opcodes.i32_const, ...signedLEB128(-1) ],
|
3737
3733
|
[ Opcodes.i32_xor ],
|
package/package.json
CHANGED
package/r.js
ADDED
package/runner/index.js
CHANGED
package/runner/repl.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { TYPE_NAMES } from '../compiler/types.js';
|
2
2
|
import compile from '../compiler/wrap.js';
|
3
|
+
import parse from '../compiler/parse.js';
|
3
4
|
|
4
5
|
import util from 'node:util';
|
5
6
|
|
@@ -83,7 +84,13 @@ const run = (source, _context, _filename, callback, run = true) => {
|
|
83
84
|
// hack: print "secret" before latest code ran to only enable printing for new code
|
84
85
|
|
85
86
|
source = source.trim();
|
86
|
-
if (source.startsWith('{') && source.endsWith('}'))
|
87
|
+
if (source.startsWith('{') && source.endsWith('}')) {
|
88
|
+
const wrapped = '(' + source + ')';
|
89
|
+
try {
|
90
|
+
parse(wrapped);
|
91
|
+
source = wrapped;
|
92
|
+
} catch {}
|
93
|
+
}
|
87
94
|
|
88
95
|
let toRun = (prev ? (prev + `;\nprint(-0x1337);\n`) : '') + source;
|
89
96
|
|