porffor 0.48.6 → 0.48.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/codegen.js +83 -71
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -164,7 +164,8 @@ const funcRef = func => {
|
|
164
164
|
[ Opcodes.local_get, 0 ], // new.target value
|
165
165
|
Opcodes.i32_to_u,
|
166
166
|
[ Opcodes.if, Blocktype.void ], // if value is non-zero
|
167
|
-
...internalThrow(wrapperFunc, 'TypeError', `${unhackName(func.name)} is not a constructor`), // throw type error
|
167
|
+
// ...internalThrow(wrapperFunc, 'TypeError', `${unhackName(func.name)} is not a constructor`), // throw type error
|
168
|
+
...internalThrow(wrapperFunc, 'TypeError', `Function is not a constructor`), // throw type error
|
168
169
|
[ Opcodes.end ]
|
169
170
|
);
|
170
171
|
}
|
@@ -1730,7 +1731,11 @@ const generateSequence = (scope, decl) => {
|
|
1730
1731
|
};
|
1731
1732
|
|
1732
1733
|
const generateChain = (scope, decl) => {
|
1733
|
-
|
1734
|
+
scope.chainMembers = 0;
|
1735
|
+
const out = generate(scope, decl.expression);
|
1736
|
+
scope.chainMembers = null;
|
1737
|
+
|
1738
|
+
return out;
|
1734
1739
|
};
|
1735
1740
|
|
1736
1741
|
const ArrayUtil = {
|
@@ -1859,6 +1864,21 @@ const aliasPrimObjsBC = bc => {
|
|
1859
1864
|
add(TYPES.string, TYPES.stringobject);
|
1860
1865
|
};
|
1861
1866
|
|
1867
|
+
const typeIsIterable = wasm => [
|
1868
|
+
// array, set, string, bytestring, generator
|
1869
|
+
...typeIsOneOf(wasm, [ TYPES.array, TYPES.set, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
|
1870
|
+
// typed array
|
1871
|
+
...wasm,
|
1872
|
+
...number(TYPES.uint8array, Valtype.i32),
|
1873
|
+
[ Opcodes.i32_ge_s ],
|
1874
|
+
...wasm,
|
1875
|
+
...number(TYPES.float64array, Valtype.i32),
|
1876
|
+
[ Opcodes.i32_le_s ],
|
1877
|
+
[ Opcodes.i32_and ],
|
1878
|
+
[ Opcodes.i32_or ],
|
1879
|
+
[ Opcodes.i32_eqz ],
|
1880
|
+
];
|
1881
|
+
|
1862
1882
|
const createThisArg = (scope, decl) => {
|
1863
1883
|
const name = decl.callee?.name;
|
1864
1884
|
if (decl._new) {
|
@@ -2273,6 +2293,36 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2273
2293
|
}
|
2274
2294
|
}
|
2275
2295
|
|
2296
|
+
let args = decl.arguments.slice();
|
2297
|
+
if (args.at(-1)?.type === 'SpreadElement') {
|
2298
|
+
// hack: support spread element if last by doing essentially:
|
2299
|
+
// const foo = () => ...;
|
2300
|
+
// foo(a, b, ...c) -> _ = c; foo(a, b, _[0], _[1], ...)
|
2301
|
+
const arg = args.at(-1).argument;
|
2302
|
+
out.push(
|
2303
|
+
...generate(scope, arg),
|
2304
|
+
[ Opcodes.local_set, localTmp(scope, '#spread') ],
|
2305
|
+
...getNodeType(scope, arg),
|
2306
|
+
[ Opcodes.local_set, localTmp(scope, '#spread#type', Valtype.i32) ],
|
2307
|
+
|
2308
|
+
...typeIsIterable([ [ Opcodes.local_get, localTmp(scope, '#spread#type', Valtype.i32) ] ]),
|
2309
|
+
[ Opcodes.if, Blocktype.void ],
|
2310
|
+
...internalThrow(scope, 'TypeError', 'Cannot spread a non-iterable'),
|
2311
|
+
[ Opcodes.end ]
|
2312
|
+
);
|
2313
|
+
|
2314
|
+
args.pop();
|
2315
|
+
for (let i = 0; i < 8; i++) {
|
2316
|
+
args.push({
|
2317
|
+
type: 'MemberExpression',
|
2318
|
+
object: { type: 'Identifier', name: '#spread' },
|
2319
|
+
property: { type: 'Literal', value: i },
|
2320
|
+
computed: true,
|
2321
|
+
optional: false
|
2322
|
+
});
|
2323
|
+
}
|
2324
|
+
}
|
2325
|
+
|
2276
2326
|
let idx;
|
2277
2327
|
if (Object.hasOwn(funcIndex, name)) {
|
2278
2328
|
idx = funcIndex[name];
|
@@ -2350,11 +2400,9 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2350
2400
|
funcs.table = true;
|
2351
2401
|
scope.table = true;
|
2352
2402
|
|
2353
|
-
let args = decl.arguments;
|
2354
2403
|
const wrapperArgc = Prefs.indirectWrapperArgc ?? 8;
|
2355
|
-
|
2356
|
-
|
2357
|
-
}
|
2404
|
+
const underflow = wrapperArgc - args.length;
|
2405
|
+
for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
|
2358
2406
|
|
2359
2407
|
for (let i = 0; i < args.length; i++) {
|
2360
2408
|
const arg = args[i];
|
@@ -2442,7 +2490,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2442
2490
|
return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a constructor`, true);
|
2443
2491
|
}
|
2444
2492
|
|
2445
|
-
let args = [...decl.arguments];
|
2446
2493
|
const internalProtoFunc = func && func.internal && func.name.includes('_prototype_');
|
2447
2494
|
if (!globalThis.precompile && internalProtoFunc && !decl._protoInternalCall) {
|
2448
2495
|
// just function called, not as prototype, add this to start
|
@@ -2455,34 +2502,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2455
2502
|
paramOffset += 4;
|
2456
2503
|
}
|
2457
2504
|
|
2458
|
-
if (args.at(-1)?.type === 'SpreadElement') {
|
2459
|
-
// hack: support spread element if last by doing essentially:
|
2460
|
-
// const foo = (a, b, c, d) => ...
|
2461
|
-
// foo(a, b, ...c) -> _ = c; foo(a, b, _[0], _[1])
|
2462
|
-
const arg = args.at(-1).argument;
|
2463
|
-
out.push(
|
2464
|
-
...generate(scope, arg),
|
2465
|
-
[ Opcodes.local_set, localTmp(scope, '#spread') ],
|
2466
|
-
...getNodeType(scope, arg),
|
2467
|
-
[ Opcodes.local_set, localTmp(scope, '#spread#type', Valtype.i32) ]
|
2468
|
-
);
|
2469
|
-
|
2470
|
-
args.pop();
|
2471
|
-
const leftover = paramCount - args.length;
|
2472
|
-
for (let i = 0; i < leftover; i++) {
|
2473
|
-
args.push({
|
2474
|
-
type: 'MemberExpression',
|
2475
|
-
object: { type: 'Identifier', name: '#spread' },
|
2476
|
-
property: { type: 'Literal', value: i },
|
2477
|
-
computed: true,
|
2478
|
-
optional: false
|
2479
|
-
});
|
2480
|
-
}
|
2481
|
-
}
|
2482
|
-
|
2483
2505
|
if (func && args.length < paramCount) {
|
2484
2506
|
// too little args, push undefineds
|
2485
|
-
|
2507
|
+
const underflow = paramCount - (func.hasRestArgument ? 1 : 0) - args.length;
|
2508
|
+
for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
|
2486
2509
|
}
|
2487
2510
|
|
2488
2511
|
if (func && func.hasRestArgument) {
|
@@ -3126,7 +3149,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3126
3149
|
let out = generateVarDstr(scope, 'const', tmpName, init, defaultValue, false);
|
3127
3150
|
|
3128
3151
|
let i = 0;
|
3129
|
-
const elements =
|
3152
|
+
const elements = pattern.elements.slice();
|
3130
3153
|
for (const e of elements) {
|
3131
3154
|
switch (e?.type) {
|
3132
3155
|
case 'RestElement': { // let [ ...foo ] = []
|
@@ -3187,24 +3210,11 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3187
3210
|
|
3188
3211
|
out = out.concat([
|
3189
3212
|
// check tmp is iterable
|
3190
|
-
|
3191
|
-
...typeIsOneOf(getType(scope, tmpName), [ TYPES.array, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
|
3192
|
-
// typed array
|
3193
|
-
...getType(scope, tmpName),
|
3194
|
-
...number(TYPES.uint8array, Valtype.i32),
|
3195
|
-
[ Opcodes.i32_ge_s ],
|
3196
|
-
...getType(scope, tmpName),
|
3197
|
-
...number(TYPES.float64array, Valtype.i32),
|
3198
|
-
[ Opcodes.i32_le_s ],
|
3199
|
-
[ Opcodes.i32_and ],
|
3200
|
-
[ Opcodes.i32_or ],
|
3201
|
-
[ Opcodes.i32_eqz ],
|
3213
|
+
...typeIsIterable(getType(scope, tmpName)),
|
3202
3214
|
[ Opcodes.if, Blocktype.void ],
|
3203
3215
|
...internalThrow(scope, 'TypeError', 'Cannot array destructure a non-iterable'),
|
3204
3216
|
[ Opcodes.end ],
|
3205
|
-
|
3206
|
-
...decls
|
3207
|
-
]);
|
3217
|
+
], decls);
|
3208
3218
|
|
3209
3219
|
return out;
|
3210
3220
|
}
|
@@ -3214,7 +3224,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3214
3224
|
const tmpName = '#destructure' + uniqId();
|
3215
3225
|
let out = generateVarDstr(scope, 'const', tmpName, init, defaultValue, false);
|
3216
3226
|
|
3217
|
-
const properties =
|
3227
|
+
const properties = pattern.properties.slice();
|
3218
3228
|
const usedProps = [];
|
3219
3229
|
for (const prop of properties) {
|
3220
3230
|
if (prop.type == 'Property') { // let { foo } = {}
|
@@ -3277,10 +3287,8 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3277
3287
|
[ Opcodes.i32_or ],
|
3278
3288
|
[ Opcodes.if, Blocktype.void ],
|
3279
3289
|
...internalThrow(scope, 'TypeError', 'Cannot object destructure undefined or null'),
|
3280
|
-
[ Opcodes.end ]
|
3281
|
-
|
3282
|
-
...decls
|
3283
|
-
]);
|
3290
|
+
[ Opcodes.end ]
|
3291
|
+
], decls);
|
3284
3292
|
|
3285
3293
|
return out;
|
3286
3294
|
}
|
@@ -4125,18 +4133,7 @@ const generateForOf = (scope, decl) => {
|
|
4125
4133
|
[ Opcodes.local_set, counter ],
|
4126
4134
|
|
4127
4135
|
// check tmp is iterable
|
4128
|
-
|
4129
|
-
...typeIsOneOf(iterType, [ TYPES.array, TYPES.set, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
|
4130
|
-
// typed array
|
4131
|
-
...iterType,
|
4132
|
-
...number(TYPES.uint8array, Valtype.i32),
|
4133
|
-
[ Opcodes.i32_ge_s ],
|
4134
|
-
...iterType,
|
4135
|
-
...number(TYPES.float64array, Valtype.i32),
|
4136
|
-
[ Opcodes.i32_le_s ],
|
4137
|
-
[ Opcodes.i32_and ],
|
4138
|
-
[ Opcodes.i32_or ],
|
4139
|
-
[ Opcodes.i32_eqz ],
|
4136
|
+
...typeIsIterable(iterType),
|
4140
4137
|
[ Opcodes.if, Blocktype.void ],
|
4141
4138
|
...internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`),
|
4142
4139
|
[ Opcodes.end ],
|
@@ -5284,7 +5281,7 @@ const countLength = (func, name = undefined) => {
|
|
5284
5281
|
return count;
|
5285
5282
|
};
|
5286
5283
|
|
5287
|
-
const generateMember = (scope, decl, _global, _name
|
5284
|
+
const generateMember = (scope, decl, _global, _name) => {
|
5288
5285
|
let final = [], finalEnd, extraBC = {};
|
5289
5286
|
let name = decl.object.name;
|
5290
5287
|
|
@@ -5302,6 +5299,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5302
5299
|
const object = decl.object;
|
5303
5300
|
const property = getProperty(decl);
|
5304
5301
|
|
5302
|
+
let chainCount = scope.chainMembers != null ? ++scope.chainMembers : 0;
|
5303
|
+
|
5305
5304
|
// generate now so type is gotten correctly later (it gets cached)
|
5306
5305
|
generate(scope, object);
|
5307
5306
|
|
@@ -5640,7 +5639,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5640
5639
|
if (decl.optional) {
|
5641
5640
|
out.unshift(
|
5642
5641
|
[ Opcodes.block, valtypeBinary ],
|
5643
|
-
...
|
5642
|
+
...generate(scope, object),
|
5644
5643
|
[ Opcodes.local_tee, localTmp(scope, '#member_obj') ],
|
5645
5644
|
...(scope.locals['#member_obj#type'] ? [
|
5646
5645
|
...getNodeType(scope, object),
|
@@ -5651,7 +5650,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5651
5650
|
[ Opcodes.if, Blocktype.void ],
|
5652
5651
|
...setLastType(scope, TYPES.undefined),
|
5653
5652
|
...number(0),
|
5654
|
-
[ Opcodes.br,
|
5653
|
+
[ Opcodes.br, chainCount ],
|
5655
5654
|
[ Opcodes.end ],
|
5656
5655
|
|
5657
5656
|
...generate(scope, property, false, '#member_prop'),
|
@@ -5663,7 +5662,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5663
5662
|
);
|
5664
5663
|
} else {
|
5665
5664
|
out.unshift(
|
5666
|
-
...
|
5665
|
+
...generate(scope, object),
|
5667
5666
|
[ Opcodes.local_set, localTmp(scope, '#member_obj') ],
|
5668
5667
|
...(scope.locals['#member_obj#type'] ? [
|
5669
5668
|
...getNodeType(scope, object),
|
@@ -5673,6 +5672,17 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5673
5672
|
...generate(scope, property, false, '#member_prop'),
|
5674
5673
|
[ Opcodes.local_set, localTmp(scope, '#member_prop') ]
|
5675
5674
|
);
|
5675
|
+
|
5676
|
+
// todo: maybe this just needs 1 block?
|
5677
|
+
if (chainCount > 0) {
|
5678
|
+
out.unshift(
|
5679
|
+
[ Opcodes.block, valtypeBinary ]
|
5680
|
+
);
|
5681
|
+
|
5682
|
+
out.push(
|
5683
|
+
[ Opcodes.end ]
|
5684
|
+
);
|
5685
|
+
}
|
5676
5686
|
}
|
5677
5687
|
|
5678
5688
|
if (final.length > 0) {
|
@@ -6153,7 +6163,9 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
|
|
6153
6163
|
typeUsed(func, TYPES.promise);
|
6154
6164
|
}
|
6155
6165
|
|
6156
|
-
|
6166
|
+
const preface = wasm;
|
6167
|
+
wasm = generate(func, body);
|
6168
|
+
wasm.unshift(...preface);
|
6157
6169
|
|
6158
6170
|
if (func.generator) {
|
6159
6171
|
// make generator at the start
|
package/package.json
CHANGED