porffor 0.36.5 → 0.36.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/__internal_object.ts +56 -18
- package/compiler/builtins/_internal_object.ts +148 -14
- package/compiler/builtins/console.ts +7 -3
- package/compiler/builtins/object.ts +65 -32
- package/compiler/builtins/reflect.ts +18 -10
- package/compiler/builtins_precompiled.js +98 -72
- package/compiler/codegen.js +128 -144
- package/compiler/precompile.js +2 -0
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -104,6 +104,9 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
104
104
|
case 'ThisExpression':
|
105
105
|
return cacheAst(decl, generateThis(scope, decl));
|
106
106
|
|
107
|
+
case 'Super':
|
108
|
+
return cacheAst(decl, generateSuper(scope, decl));
|
109
|
+
|
107
110
|
case 'Literal':
|
108
111
|
return cacheAst(decl, generateLiteral(scope, decl, global, name));
|
109
112
|
|
@@ -311,7 +314,8 @@ const lookupName = (scope, _name) => {
|
|
311
314
|
};
|
312
315
|
|
313
316
|
const internalThrow = (scope, constructor, message, expectsValue = Prefs.alwaysValueInternalThrows) => [
|
314
|
-
...
|
317
|
+
...generate(scope, {
|
318
|
+
type: 'ThrowStatement',
|
315
319
|
argument: {
|
316
320
|
type: 'NewExpression',
|
317
321
|
callee: {
|
@@ -1601,8 +1605,8 @@ const RTArrayUtil = {
|
|
1601
1605
|
]
|
1602
1606
|
};
|
1603
1607
|
|
1604
|
-
const createNewTarget = (scope, decl, idx = 0) => {
|
1605
|
-
if (decl._new) {
|
1608
|
+
const createNewTarget = (scope, decl, idx = 0, force = false) => {
|
1609
|
+
if (decl._new || force) {
|
1606
1610
|
return [
|
1607
1611
|
...(typeof idx === 'number' ? number(idx) : idx),
|
1608
1612
|
...number(TYPES.function, Valtype.i32)
|
@@ -1632,7 +1636,7 @@ const makeObject = (scope, obj) => {
|
|
1632
1636
|
});
|
1633
1637
|
}
|
1634
1638
|
|
1635
|
-
return
|
1639
|
+
return generate(scope, {
|
1636
1640
|
type: 'ObjectExpression',
|
1637
1641
|
properties
|
1638
1642
|
});
|
@@ -1692,13 +1696,48 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
|
|
1692
1696
|
return knownThis;
|
1693
1697
|
}
|
1694
1698
|
|
1699
|
+
const name = mapName(decl.callee?.name);
|
1695
1700
|
if (decl._new) {
|
1701
|
+
// if precompiling or builtin func, just make empty object
|
1702
|
+
if (globalThis.precompile || Object.hasOwn(builtinFuncs, name)) return [
|
1703
|
+
...makeObject(scope, {}),
|
1704
|
+
...number(TYPES.object, Valtype.i32)
|
1705
|
+
];
|
1706
|
+
|
1707
|
+
// create new object with __proto__ set to callee prototype
|
1708
|
+
const tmp = localTmp(scope, '#this_create_tmp');
|
1709
|
+
const proto = getObjProp(decl.callee, 'prototype');
|
1710
|
+
localTmp(scope, '#member_prop_assign');
|
1711
|
+
|
1696
1712
|
return [
|
1697
1713
|
...makeObject(scope, {}),
|
1714
|
+
[ Opcodes.local_tee, tmp ],
|
1715
|
+
Opcodes.i32_to_u,
|
1716
|
+
|
1717
|
+
...number(TYPES.object, Valtype.i32),
|
1718
|
+
|
1719
|
+
...generate(scope, {
|
1720
|
+
type: 'Literal',
|
1721
|
+
value: '__proto__'
|
1722
|
+
}, false, '#member_prop_assign'),
|
1723
|
+
Opcodes.i32_to_u,
|
1724
|
+
...number(TYPES.bytestring, Valtype.i32),
|
1725
|
+
|
1726
|
+
...generate(scope, proto),
|
1727
|
+
...getNodeType(scope, proto),
|
1728
|
+
|
1729
|
+
// flags: writable
|
1730
|
+
...number(0b1000, Valtype.i32),
|
1731
|
+
...number(TYPES.number, Valtype.i32),
|
1732
|
+
|
1733
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_expr_initWithFlags').index ],
|
1734
|
+
[ Opcodes.drop ],
|
1735
|
+
[ Opcodes.drop ],
|
1736
|
+
|
1737
|
+
[ Opcodes.local_get, tmp ],
|
1698
1738
|
...number(TYPES.object, Valtype.i32)
|
1699
1739
|
];
|
1700
1740
|
} else {
|
1701
|
-
const name = mapName(decl.callee?.name);
|
1702
1741
|
if (name && name.startsWith('__') && name.includes('_prototype_')) {
|
1703
1742
|
// todo: this should just be same as decl._new
|
1704
1743
|
// but we do not support prototype, constructor, etc yet
|
@@ -1714,7 +1753,7 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
|
|
1714
1753
|
};
|
1715
1754
|
|
1716
1755
|
return [
|
1717
|
-
...
|
1756
|
+
...generate(scope, node),
|
1718
1757
|
...getNodeType(scope, node)
|
1719
1758
|
];
|
1720
1759
|
}
|
@@ -1733,7 +1772,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1733
1772
|
|
1734
1773
|
// opt: virtualize iifes
|
1735
1774
|
if (isFuncType(decl.callee.type)) {
|
1736
|
-
const [ func ] = generateFunc(scope, decl.callee
|
1775
|
+
const [ func ] = generateFunc(scope, decl.callee);
|
1737
1776
|
name = func.name;
|
1738
1777
|
}
|
1739
1778
|
|
@@ -1836,7 +1875,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1836
1875
|
const valTmp = localTmp(scope, '#call_val');
|
1837
1876
|
const typeTmp = localTmp(scope, '#call_type', Valtype.i32);
|
1838
1877
|
|
1839
|
-
return
|
1878
|
+
return generate(scope, {
|
1840
1879
|
type: 'CallExpression',
|
1841
1880
|
callee: target,
|
1842
1881
|
arguments: decl.arguments.slice(1),
|
@@ -1939,7 +1978,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1939
1978
|
const type = TYPES[x.split('_prototype_')[0].slice(2).toLowerCase()];
|
1940
1979
|
if (type == null) continue;
|
1941
1980
|
|
1942
|
-
protoBC[type] =
|
1981
|
+
protoBC[type] = generate(scope, {
|
1982
|
+
type: 'CallExpression',
|
1943
1983
|
callee: {
|
1944
1984
|
type: 'Identifier',
|
1945
1985
|
name: x
|
@@ -2233,11 +2273,22 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2233
2273
|
];
|
2234
2274
|
}
|
2235
2275
|
|
2276
|
+
let callee = decl.callee, callAsNew = decl._new, overrideThisWasm = decl._thisWasm;
|
2277
|
+
if (callee.type === 'Super') {
|
2278
|
+
// call super constructor with direct super() call
|
2279
|
+
callee = getObjProp(callee, 'constructor');
|
2280
|
+
callAsNew = true;
|
2281
|
+
overrideThisWasm = [
|
2282
|
+
...generate(scope, { type: 'ThisExpression' }),
|
2283
|
+
...getNodeType(scope, { type: 'ThisExpression' })
|
2284
|
+
];
|
2285
|
+
}
|
2286
|
+
|
2236
2287
|
const newTargetWasm = decl._newTargetWasm ?? createNewTarget(scope, decl, [
|
2237
2288
|
[ Opcodes.local_get, funcLocal ],
|
2238
2289
|
Opcodes.i32_from_u
|
2239
|
-
]);
|
2240
|
-
const thisWasm =
|
2290
|
+
], callAsNew);
|
2291
|
+
const thisWasm = overrideThisWasm ?? createThisArg(scope, decl, knownThis);
|
2241
2292
|
|
2242
2293
|
const gen = argc => {
|
2243
2294
|
const argsOut = [];
|
@@ -2305,11 +2356,11 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2305
2356
|
return [
|
2306
2357
|
...(getCalleeObj ? [
|
2307
2358
|
...initCalleeObj,
|
2308
|
-
...
|
2309
|
-
]: generate(scope,
|
2359
|
+
...generate(scope, callee, false, undefined, getCalleeObj)
|
2360
|
+
]: generate(scope, callee)),
|
2310
2361
|
[ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
|
2311
2362
|
|
2312
|
-
...typeSwitch(scope, getNodeType(scope,
|
2363
|
+
...typeSwitch(scope, getNodeType(scope, callee), {
|
2313
2364
|
[TYPES.function]: [
|
2314
2365
|
...out,
|
2315
2366
|
|
@@ -2327,7 +2378,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2327
2378
|
[ Opcodes.local_set, flags ],
|
2328
2379
|
|
2329
2380
|
// check if non-constructor was called with new, if so throw
|
2330
|
-
...(
|
2381
|
+
...(callAsNew ? [
|
2331
2382
|
[ Opcodes.local_get, flags ],
|
2332
2383
|
...number(0b10, Valtype.i32),
|
2333
2384
|
[ Opcodes.i32_and ],
|
@@ -2535,6 +2586,9 @@ const generateThis = (scope, decl) => {
|
|
2535
2586
|
];
|
2536
2587
|
};
|
2537
2588
|
|
2589
|
+
const generateSuper = (scope, decl) => generate(scope,
|
2590
|
+
getObjProp(getObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__'), '__proto__'));
|
2591
|
+
|
2538
2592
|
// bad hack for undefined and null working without additional logic
|
2539
2593
|
const DEFAULT_VALUE = () => ({
|
2540
2594
|
type: 'Identifier',
|
@@ -2676,7 +2730,7 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, allowFallThrough =
|
|
2676
2730
|
}
|
2677
2731
|
|
2678
2732
|
if (Prefs.typeswitchBrtable) {
|
2679
|
-
if (allowFallThrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`)
|
2733
|
+
if (allowFallThrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`);
|
2680
2734
|
return brTable(type, bc, returns);
|
2681
2735
|
}
|
2682
2736
|
|
@@ -2892,7 +2946,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
2892
2946
|
// hack for let a = function () { ... }
|
2893
2947
|
if (!init.id) {
|
2894
2948
|
init.id = { name };
|
2895
|
-
generateFunc(scope, init
|
2949
|
+
generateFunc(scope, init);
|
2896
2950
|
return out;
|
2897
2951
|
}
|
2898
2952
|
}
|
@@ -3288,68 +3342,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3288
3342
|
[ Opcodes.local_get, newValueTmp ]
|
3289
3343
|
],
|
3290
3344
|
|
3291
|
-
[TYPES.object]: [
|
3292
|
-
...objectWasm,
|
3293
|
-
Opcodes.i32_to_u,
|
3294
|
-
...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
|
3295
|
-
...getNodeType(scope, object),
|
3296
|
-
|
3297
|
-
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
|
3298
|
-
...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3299
|
-
...(op === '=' ? [] : [
|
3300
|
-
Opcodes.i32_to_u,
|
3301
|
-
[ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
|
3302
|
-
]),
|
3303
|
-
...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3304
|
-
|
3305
|
-
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
3306
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
|
3307
|
-
...getNodeType(scope, object),
|
3308
|
-
|
3309
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
|
3310
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
|
3311
|
-
|
3312
|
-
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
3313
|
-
...setLastType(scope)
|
3314
|
-
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
3315
|
-
...getNodeType(scope, decl),
|
3316
|
-
|
3317
|
-
[ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
|
3318
|
-
[ Opcodes.drop ],
|
3319
|
-
// ...setLastType(scope, getNodeType(scope, decl)),
|
3320
|
-
],
|
3321
|
-
|
3322
|
-
[TYPES.function]: [
|
3323
|
-
...objectWasm,
|
3324
|
-
Opcodes.i32_to_u,
|
3325
|
-
...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
|
3326
|
-
...getNodeType(scope, object),
|
3327
|
-
|
3328
|
-
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
|
3329
|
-
...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3330
|
-
...(op === '=' ? [] : [
|
3331
|
-
Opcodes.i32_to_u,
|
3332
|
-
[ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
|
3333
|
-
]),
|
3334
|
-
...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3335
|
-
|
3336
|
-
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
3337
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
|
3338
|
-
...getNodeType(scope, object),
|
3339
|
-
|
3340
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
|
3341
|
-
[ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
|
3342
|
-
|
3343
|
-
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
3344
|
-
...setLastType(scope)
|
3345
|
-
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
3346
|
-
...getNodeType(scope, decl),
|
3347
|
-
|
3348
|
-
[ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
|
3349
|
-
[ Opcodes.drop ],
|
3350
|
-
// ...setLastType(scope, getNodeType(scope, decl)),
|
3351
|
-
],
|
3352
|
-
|
3353
3345
|
...wrapBC({
|
3354
3346
|
[TYPES.uint8array]: [
|
3355
3347
|
[ Opcodes.i32_add ],
|
@@ -3511,12 +3503,33 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3511
3503
|
// default: internalThrow(scope, 'TypeError', `Cannot assign member with this type`)
|
3512
3504
|
default: [
|
3513
3505
|
...objectWasm,
|
3514
|
-
|
3506
|
+
Opcodes.i32_to_u,
|
3507
|
+
...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
|
3508
|
+
...getNodeType(scope, object),
|
3515
3509
|
|
3516
|
-
...propertyWasm,
|
3517
|
-
[ Opcodes.
|
3510
|
+
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
|
3511
|
+
...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3512
|
+
...(op === '=' ? [] : [
|
3513
|
+
Opcodes.i32_to_u,
|
3514
|
+
[ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
|
3515
|
+
]),
|
3516
|
+
...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3517
|
+
|
3518
|
+
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
3519
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
|
3520
|
+
...getNodeType(scope, object),
|
3518
3521
|
|
3519
|
-
|
3522
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
|
3523
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
|
3524
|
+
|
3525
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
3526
|
+
...setLastType(scope)
|
3527
|
+
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
3528
|
+
...getNodeType(scope, decl),
|
3529
|
+
|
3530
|
+
[ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
|
3531
|
+
[ Opcodes.drop ],
|
3532
|
+
// ...setLastType(scope, getNodeType(scope, decl)),
|
3520
3533
|
]
|
3521
3534
|
}, valtypeBinary)
|
3522
3535
|
];
|
@@ -3584,7 +3597,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3584
3597
|
|
3585
3598
|
const ifIdentifierErrors = (scope, decl) => {
|
3586
3599
|
if (decl.type === 'Identifier') {
|
3587
|
-
const out =
|
3600
|
+
const out = generate(scope, decl);
|
3588
3601
|
if (out[1]) return true;
|
3589
3602
|
}
|
3590
3603
|
|
@@ -3661,7 +3674,7 @@ const generateUnary = (scope, decl) => {
|
|
3661
3674
|
let toReturn = true, toGenerate = true;
|
3662
3675
|
|
3663
3676
|
if (decl.argument.type === 'Identifier') {
|
3664
|
-
const out =
|
3677
|
+
const out = generate(scope, decl.argument);
|
3665
3678
|
|
3666
3679
|
// if ReferenceError (undeclared var), ignore and return true. otherwise false
|
3667
3680
|
if (!out[1]) {
|
@@ -4438,7 +4451,7 @@ const generateSwitch = (scope, decl) => {
|
|
4438
4451
|
const ret = typeSwitch(scope, getNodeType(scope, decl.discriminant.arguments[0]), () => {
|
4439
4452
|
const ret = [];
|
4440
4453
|
for (const [type, consequent] of cases) {
|
4441
|
-
const o =
|
4454
|
+
const o = generate(scope, { type: 'BlockStatement', body: consequent });
|
4442
4455
|
ret.push([type, o]);
|
4443
4456
|
}
|
4444
4457
|
return ret;
|
@@ -4481,7 +4494,7 @@ const generateSwitch = (scope, decl) => {
|
|
4481
4494
|
depth.pop();
|
4482
4495
|
out.push(
|
4483
4496
|
[ Opcodes.end ],
|
4484
|
-
...
|
4497
|
+
...generate(scope, { type: 'BlockStatement', body: cases[i].consequent })
|
4485
4498
|
);
|
4486
4499
|
}
|
4487
4500
|
|
@@ -5083,7 +5096,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
|
|
5083
5096
|
|
5084
5097
|
if (type === 'SpreadElement') {
|
5085
5098
|
out.push(
|
5086
|
-
...
|
5099
|
+
...generate(scope, {
|
5087
5100
|
type: 'CallExpression',
|
5088
5101
|
callee: {
|
5089
5102
|
type: 'Identifier',
|
@@ -5278,7 +5291,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5278
5291
|
const type = TYPES[x.split('_prototype_')[0].slice(2).toLowerCase()];
|
5279
5292
|
if (type == null) continue;
|
5280
5293
|
|
5281
|
-
if (type === known) return
|
5294
|
+
if (type === known) return generate(scope, {
|
5295
|
+
type: 'CallExpression',
|
5282
5296
|
callee: {
|
5283
5297
|
type: 'Identifier',
|
5284
5298
|
name: x
|
@@ -5287,7 +5301,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5287
5301
|
_protoInternalCall: true
|
5288
5302
|
});
|
5289
5303
|
|
5290
|
-
bc[type] =
|
5304
|
+
bc[type] = generate(scope, {
|
5305
|
+
type: 'CallExpression',
|
5291
5306
|
callee: {
|
5292
5307
|
type: 'Identifier',
|
5293
5308
|
name: x
|
@@ -5322,7 +5337,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5322
5337
|
};
|
5323
5338
|
|
5324
5339
|
bc[type] = [
|
5325
|
-
...
|
5340
|
+
...generate(scope, ident),
|
5326
5341
|
...setLastType(scope, getNodeType(scope, ident))
|
5327
5342
|
];
|
5328
5343
|
if (type === known) return bc[type];
|
@@ -5406,28 +5421,6 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5406
5421
|
...setLastType(scope, TYPES.bytestring)
|
5407
5422
|
],
|
5408
5423
|
|
5409
|
-
[TYPES.object]: [
|
5410
|
-
...objectWasm,
|
5411
|
-
Opcodes.i32_to_u,
|
5412
|
-
...getNodeType(scope, object),
|
5413
|
-
|
5414
|
-
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
|
5415
|
-
|
5416
|
-
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
5417
|
-
...setLastType(scope)
|
5418
|
-
],
|
5419
|
-
|
5420
|
-
[TYPES.function]: [
|
5421
|
-
...objectWasm,
|
5422
|
-
Opcodes.i32_to_u,
|
5423
|
-
...getNodeType(scope, object),
|
5424
|
-
|
5425
|
-
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
|
5426
|
-
|
5427
|
-
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
5428
|
-
...setLastType(scope)
|
5429
|
-
],
|
5430
|
-
|
5431
5424
|
...wrapBC({
|
5432
5425
|
[TYPES.uint8array]: [
|
5433
5426
|
[ Opcodes.i32_add ],
|
@@ -5510,8 +5503,14 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5510
5503
|
|
5511
5504
|
// default: internalThrow(scope, 'TypeError', 'Unsupported member expression object', true)
|
5512
5505
|
default: [
|
5513
|
-
...
|
5514
|
-
|
5506
|
+
...objectWasm,
|
5507
|
+
Opcodes.i32_to_u,
|
5508
|
+
...getNodeType(scope, object),
|
5509
|
+
|
5510
|
+
...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
|
5511
|
+
|
5512
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
5513
|
+
...setLastType(scope)
|
5515
5514
|
],
|
5516
5515
|
|
5517
5516
|
...extraBC
|
@@ -5569,7 +5568,7 @@ const generateAwait = (scope, decl) => {
|
|
5569
5568
|
|
5570
5569
|
// todo: warn here if -d?
|
5571
5570
|
|
5572
|
-
return
|
5571
|
+
return generate(scope, {
|
5573
5572
|
type: 'CallExpression',
|
5574
5573
|
callee: {
|
5575
5574
|
type: 'Identifier',
|
@@ -5603,7 +5602,7 @@ const generateClass = (scope, decl) => {
|
|
5603
5602
|
optional: false
|
5604
5603
|
};
|
5605
5604
|
|
5606
|
-
const
|
5605
|
+
const [ func, out ] = generateFunc(scope, {
|
5607
5606
|
...(body.find(x => x.kind === 'constructor')?.value ?? {
|
5608
5607
|
type: 'FunctionExpression',
|
5609
5608
|
params: [],
|
@@ -5612,12 +5611,9 @@ const generateClass = (scope, decl) => {
|
|
5612
5611
|
body: []
|
5613
5612
|
}
|
5614
5613
|
}),
|
5615
|
-
id: root
|
5616
|
-
};
|
5617
|
-
|
5618
|
-
const [ func, out ] = generateFunc(scope, {
|
5619
|
-
...constr,
|
5614
|
+
id: root,
|
5620
5615
|
_onlyConstr: true,
|
5616
|
+
strict: true,
|
5621
5617
|
type: expr ? 'FunctionExpression' : 'FunctionDeclaration'
|
5622
5618
|
});
|
5623
5619
|
|
@@ -5645,7 +5641,7 @@ const generateClass = (scope, decl) => {
|
|
5645
5641
|
|
5646
5642
|
const k = getProperty(x, true);
|
5647
5643
|
|
5648
|
-
let initKind = '
|
5644
|
+
let initKind = type === 'MethodDefinition' ? 'method' : 'value';
|
5649
5645
|
if (kind === 'get' || kind === 'set') initKind = kind;
|
5650
5646
|
|
5651
5647
|
// default value to undefined
|
@@ -5663,7 +5659,7 @@ const generateClass = (scope, decl) => {
|
|
5663
5659
|
outScope = func;
|
5664
5660
|
}
|
5665
5661
|
|
5666
|
-
if (isFuncType(value.type)
|
5662
|
+
if (isFuncType(value.type)) {
|
5667
5663
|
let id = value.id;
|
5668
5664
|
|
5669
5665
|
// todo: support computed names properly
|
@@ -5675,6 +5671,7 @@ const generateClass = (scope, decl) => {
|
|
5675
5671
|
value = {
|
5676
5672
|
...value,
|
5677
5673
|
id,
|
5674
|
+
strict: true,
|
5678
5675
|
_onlyThisMethod: true
|
5679
5676
|
};
|
5680
5677
|
}
|
@@ -5687,10 +5684,10 @@ const generateClass = (scope, decl) => {
|
|
5687
5684
|
...toPropertyKey(outScope, generate(outScope, k), getNodeType(outScope, k), computed, true),
|
5688
5685
|
|
5689
5686
|
...generate(outScope, value),
|
5690
|
-
...(initKind !== '
|
5687
|
+
...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
|
5691
5688
|
...getNodeType(outScope, value),
|
5692
5689
|
|
5693
|
-
[ Opcodes.call, includeBuiltin(outScope, `
|
5690
|
+
[ Opcodes.call, includeBuiltin(outScope, `__Porffor_object_class_${initKind}`).index ],
|
5694
5691
|
|
5695
5692
|
[ Opcodes.drop ],
|
5696
5693
|
[ Opcodes.drop ]
|
@@ -5807,7 +5804,7 @@ const funcByIndex = idx => {
|
|
5807
5804
|
};
|
5808
5805
|
const funcByName = name => funcByIndex(funcIndex[name]);
|
5809
5806
|
|
5810
|
-
const generateFunc = (scope, decl
|
5807
|
+
const generateFunc = (scope, decl) => {
|
5811
5808
|
const name = decl.id ? decl.id.name : `#anonymous${uniqId()}`;
|
5812
5809
|
if (decl.type.startsWith('Class')) {
|
5813
5810
|
const out = generateClass(scope, {
|
@@ -5816,6 +5813,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
|
|
5816
5813
|
});
|
5817
5814
|
|
5818
5815
|
const func = funcByName(name);
|
5816
|
+
astCache.set(decl, out);
|
5819
5817
|
return [ func, out ];
|
5820
5818
|
}
|
5821
5819
|
|
@@ -5837,7 +5835,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
|
|
5837
5835
|
// not async or generator
|
5838
5836
|
!decl.async && !decl.generator,
|
5839
5837
|
_onlyConstr: decl._onlyConstr, _onlyThisMethod: decl._onlyThisMethod,
|
5840
|
-
strict: scope.strict,
|
5838
|
+
strict: scope.strict || decl.strict,
|
5841
5839
|
|
5842
5840
|
generate() {
|
5843
5841
|
if (func.wasm) return func.wasm;
|
@@ -5893,21 +5891,6 @@ const generateFunc = (scope, decl, outUnused = false) => {
|
|
5893
5891
|
// todo: wrap in try and reject thrown value once supported
|
5894
5892
|
}
|
5895
5893
|
|
5896
|
-
if (!globalThis.precompile && func.constr && !func._onlyThisMethod) {
|
5897
|
-
wasm.unshift(
|
5898
|
-
// opt: do not check for pure constructors
|
5899
|
-
...(func._onlyConstr ? [] : [
|
5900
|
-
// if being constructed
|
5901
|
-
[ Opcodes.local_get, func.locals['#newtarget'].idx ],
|
5902
|
-
Opcodes.i32_to_u,
|
5903
|
-
[ Opcodes.if, Blocktype.void ],
|
5904
|
-
]),
|
5905
|
-
// set prototype of this ;)
|
5906
|
-
...generate(func, setObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__', getObjProp(func.name, 'prototype'))),
|
5907
|
-
...(func._onlyConstr ? [] : [ [ Opcodes.end ] ])
|
5908
|
-
);
|
5909
|
-
}
|
5910
|
-
|
5911
5894
|
if (name === 'main') {
|
5912
5895
|
func.gotLastType = true;
|
5913
5896
|
func.export = true;
|
@@ -6063,7 +6046,8 @@ const generateFunc = (scope, decl, outUnused = false) => {
|
|
6063
6046
|
// force generate all for precompile
|
6064
6047
|
if (globalThis.precompile) func.generate();
|
6065
6048
|
|
6066
|
-
const out = decl.type.endsWith('Expression')
|
6049
|
+
const out = decl.type.endsWith('Expression') ? funcRef(func) : [];
|
6050
|
+
astCache.set(decl, out);
|
6067
6051
|
return [ func, out ];
|
6068
6052
|
};
|
6069
6053
|
|
package/compiler/precompile.js
CHANGED
@@ -62,6 +62,8 @@ const compile = async (file, _funcs) => {
|
|
62
62
|
__Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
63
63
|
__Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
64
64
|
__Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
65
|
+
__Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
66
|
+
__Porffor_object_class_method: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
65
67
|
__Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
66
68
|
};
|
67
69
|
|
package/package.json
CHANGED