porffor 0.30.0 → 0.30.1
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/object.ts +17 -0
- package/compiler/builtins_precompiled.js +6 -0
- package/compiler/codegen.js +85 -24
- package/package.json +1 -1
- package/runner/index.js +1 -1
@@ -665,4 +665,21 @@ export const __Object_prototype_toLocaleString = (_this: any) => __Object_protot
|
|
665
665
|
export const __Object_prototype_valueOf = (_this: any) => {
|
666
666
|
// todo: ToObject
|
667
667
|
return _this;
|
668
|
+
};
|
669
|
+
|
670
|
+
|
671
|
+
export const __Porffor_object_spread = (dst: object, src: any): object => {
|
672
|
+
if (src == null) return;
|
673
|
+
|
674
|
+
// todo/perf: optimize this (and assign) for object instead of reading over object 2x
|
675
|
+
const keys: any[] = __Object_keys(src);
|
676
|
+
const vals: any[] = __Object_values(src);
|
677
|
+
|
678
|
+
const len: i32 = keys.length;
|
679
|
+
for (let i: i32 = 0; i < len; i++) {
|
680
|
+
// target[keys[i]] = vals[i];
|
681
|
+
Porffor.object.expr.init(dst, keys[i], vals[i]);
|
682
|
+
}
|
683
|
+
|
684
|
+
return dst;
|
668
685
|
};
|
@@ -1914,6 +1914,12 @@ export const BuiltinFuncs = function() {
|
|
1914
1914
|
returns: [124,127], typedReturns: 1,
|
1915
1915
|
locals: [], localNames: ["_this","_this#type"],
|
1916
1916
|
};
|
1917
|
+
this.__Porffor_object_spread = {
|
1918
|
+
wasm: (scope, {builtin}) => [[32,2],[33,4],[32,3],[33,5],[2,127],[32,5],[65,0],[70],[4,64,"TYPESWITCH|empty"],[65,1],[12,1],[11],[32,5],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,4],[68,0,0,0,0,0,0,0,0],[97],[12,1],[11],[32,5],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],[65,1],[12,1],[11],[65,0],[11,"TYPESWITCH_end"],[4,64],[68,0,0,0,0,0,0,0,0],[65,128,1],[15],[11],[32,2],[32,3],[16, builtin('__Object_keys')],[26],[33,6],[32,2],[32,3],[16, builtin('__Object_values')],[26],[33,8],[32,6],[252,3],[40,1,0],[184],[33,9],[68,0,0,0,0,0,0,0,0],[33,10],[3,64],[32,10],[32,9],[99],[4,64],[32,0],[252,2],[65,7],[32,6],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[33,7],[252,2],[32,7],[32,8],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[34,7],[16, builtin('__Porffor_object_expr_init')],[33,7],[183],[26],[32,10],[68,0,0,0,0,0,0,240,63],[160],[33,10],[12,1],[11],[11],[32,0],[65,7],[15]],
|
1919
|
+
params: [124,127,124,127], typedParams: 1,
|
1920
|
+
returns: [124,127], typedReturns: 1,
|
1921
|
+
locals: [124,127,124,127,124,124,124,124,124,127,127,127], localNames: ["dst","dst#type","src","src#type","#logicinner_tmp","#typeswitch_tmp1","keys","#last_type","vals","len","i","#member_obj","#member_prop","#loadArray_offset","#member_allocd","#swap"],
|
1922
|
+
};
|
1917
1923
|
this.__ecma262_NewPromiseReactionJob = {
|
1918
1924
|
wasm: (scope, {builtin}) => [[65,22],[16, builtin('__Porffor_allocateBytes')],[183],[34,4],[33,7],[68,0,0,0,0,0,0,0,0],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,0],[34,5],[57,0,4],[32,6],[65,208,0],[58,0,12],[32,4],[33,7],[68,0,0,0,0,0,0,240,63],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,2],[34,5],[57,0,4],[32,6],[32,3],[58,0,12],[32,4],[65,208,0],[15]],
|
1919
1925
|
params: [124,127,124,127], typedParams: 1,
|
package/compiler/codegen.js
CHANGED
@@ -1438,11 +1438,25 @@ const getType = (scope, _name) => {
|
|
1438
1438
|
|
1439
1439
|
if (Object.hasOwn(builtinVars, name)) return number(builtinVars[name].type ?? TYPES.number, Valtype.i32);
|
1440
1440
|
|
1441
|
-
if (
|
1442
|
-
|
1441
|
+
if (Object.hasOwn(scope.locals, name)) {
|
1442
|
+
if (scope.locals[name]?.metadata?.type != null) return number(scope.locals[name].metadata.type, Valtype.i32);
|
1443
1443
|
|
1444
|
-
|
1445
|
-
|
1444
|
+
const typeLocal = scope.locals[name + '#type'];
|
1445
|
+
if (typeLocal) return [ [ Opcodes.local_get, typeLocal.idx ] ];
|
1446
|
+
|
1447
|
+
// todo: warn here?
|
1448
|
+
return number(TYPES.undefined, Valtype.i32);
|
1449
|
+
}
|
1450
|
+
|
1451
|
+
if (Object.hasOwn(globals, name)) {
|
1452
|
+
if (globals[name]?.metadata?.type != null) return number(globals[name].metadata.type, Valtype.i32);
|
1453
|
+
|
1454
|
+
const typeLocal = globals[name + '#type'];
|
1455
|
+
if (typeLocal) return [ [ Opcodes.global_get, typeLocal.idx ] ];
|
1456
|
+
|
1457
|
+
// todo: warn here?
|
1458
|
+
return number(TYPES.undefined, Valtype.i32);
|
1459
|
+
}
|
1446
1460
|
|
1447
1461
|
if (Object.hasOwn(builtinFuncs, name) || Object.hasOwn(importedFuncs, name) ||
|
1448
1462
|
Object.hasOwn(funcIndex, name) || Object.hasOwn(internalConstrs, name))
|
@@ -1458,17 +1472,31 @@ const setType = (scope, _name, type) => {
|
|
1458
1472
|
|
1459
1473
|
const out = typeof type === 'number' ? number(type, Valtype.i32) : type;
|
1460
1474
|
|
1461
|
-
if (
|
1462
|
-
|
1463
|
-
...out,
|
1464
|
-
[ Opcodes.local_set, scope.locals[name + '#type'].idx ]
|
1465
|
-
];
|
1475
|
+
if (Object.hasOwn(scope.locals, name)) {
|
1476
|
+
if (scope.locals[name]?.metadata?.type != null) return [];
|
1466
1477
|
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1478
|
+
const typeLocal = scope.locals[name + '#type'];
|
1479
|
+
if (typeLocal) return [
|
1480
|
+
...out,
|
1481
|
+
[ Opcodes.local_set, typeLocal.idx ]
|
1482
|
+
];
|
1483
|
+
|
1484
|
+
// todo: warn here?
|
1485
|
+
return [];
|
1486
|
+
}
|
1487
|
+
|
1488
|
+
if (Object.hasOwn(globals, name)) {
|
1489
|
+
if (globals[name]?.metadata?.type != null) return [];
|
1490
|
+
|
1491
|
+
const typeLocal = globals[name + '#type'];
|
1492
|
+
if (typeLocal) return [
|
1493
|
+
...out,
|
1494
|
+
[ Opcodes.global_set, typeLocal.idx ]
|
1495
|
+
];
|
1496
|
+
|
1497
|
+
// todo: warn here?
|
1498
|
+
return [];
|
1499
|
+
}
|
1472
1500
|
|
1473
1501
|
// throw new Error('could not find var');
|
1474
1502
|
return [];
|
@@ -3096,7 +3124,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3096
3124
|
elements.push(...e.argument.elements);
|
3097
3125
|
} else {
|
3098
3126
|
decls.push(
|
3099
|
-
...generateVarDstr(scope, kind, e.argument
|
3127
|
+
...generateVarDstr(scope, kind, e.argument, {
|
3100
3128
|
type: 'CallExpression',
|
3101
3129
|
callee: {
|
3102
3130
|
type: 'Identifier',
|
@@ -3202,8 +3230,22 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3202
3230
|
}, undefined, global)
|
3203
3231
|
);
|
3204
3232
|
}
|
3205
|
-
} else { // let { ...foo } = {}
|
3206
|
-
|
3233
|
+
} else if (prop.type === 'RestElement') { // let { ...foo } = {}
|
3234
|
+
decls.push(
|
3235
|
+
...generateVarDstr(scope, kind, prop.argument, {
|
3236
|
+
type: 'CallExpression',
|
3237
|
+
callee: {
|
3238
|
+
type: 'Identifier',
|
3239
|
+
name: '__Porffor_object_spread'
|
3240
|
+
},
|
3241
|
+
arguments: [
|
3242
|
+
{ type: 'ObjectExpression', properties: [] },
|
3243
|
+
{ type: 'Identifier', name: tmpName }
|
3244
|
+
]
|
3245
|
+
}, undefined, global)
|
3246
|
+
);
|
3247
|
+
} else {
|
3248
|
+
return todo(scope, `${prop.type} is not supported in object patterns`);
|
3207
3249
|
}
|
3208
3250
|
}
|
3209
3251
|
|
@@ -3979,10 +4021,9 @@ const generateForOf = (scope, decl) => {
|
|
3979
4021
|
|
3980
4022
|
// setup local for left
|
3981
4023
|
let setVar;
|
3982
|
-
|
3983
4024
|
if (decl.left.type === 'Identifier') {
|
3984
4025
|
// todo: should be sloppy mode only
|
3985
|
-
setVar = generateVarDstr(scope, 'var', decl.left
|
4026
|
+
setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
|
3986
4027
|
} else {
|
3987
4028
|
// todo: verify this is correct
|
3988
4029
|
const global = scope.name === 'main' && decl.left.kind === 'var';
|
@@ -4347,14 +4388,13 @@ const generateForIn = (scope, decl) => {
|
|
4347
4388
|
localTmp(scope, tmpName + '#type', Valtype.i32);
|
4348
4389
|
|
4349
4390
|
let setVar;
|
4350
|
-
|
4351
4391
|
if (decl.left.type === 'Identifier') {
|
4352
4392
|
// todo: should be sloppy mode only
|
4353
|
-
setVar = generateVarDstr(scope, 'var', decl.left
|
4393
|
+
setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
|
4354
4394
|
} else {
|
4355
4395
|
// todo: verify this is correct
|
4356
4396
|
const global = scope.name === 'main' && decl.left.kind === 'var';
|
4357
|
-
setVar = generateVarDstr(scope, 'var', decl.left
|
4397
|
+
setVar = generateVarDstr(scope, 'var', decl.left?.declarations?.[0]?.id ?? decl.left, { type: 'Identifier', name: tmpName }, undefined, global);
|
4358
4398
|
}
|
4359
4399
|
|
4360
4400
|
// set type for local
|
@@ -5090,12 +5130,33 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
|
|
5090
5130
|
];
|
5091
5131
|
|
5092
5132
|
if (decl.properties.length > 0) {
|
5093
|
-
const
|
5133
|
+
const tmpName = `#objectexpr${uniqId()}`;
|
5134
|
+
const tmp = localTmp(scope, tmpName, Valtype.i32);
|
5135
|
+
addVarMetadata(scope, tmpName, false, { type: TYPES.object });
|
5136
|
+
|
5094
5137
|
out.push([ Opcodes.local_tee, tmp ]);
|
5095
5138
|
|
5096
5139
|
for (const x of decl.properties) {
|
5097
5140
|
// method, shorthand are made into useful values by parser for us :)
|
5098
|
-
const { computed, kind, key, value } = x;
|
5141
|
+
const { type, argument, computed, kind, key, value } = x;
|
5142
|
+
|
5143
|
+
if (type === 'SpreadElement') {
|
5144
|
+
out.push(
|
5145
|
+
...generateCall(scope, {
|
5146
|
+
type: 'CallExpression',
|
5147
|
+
callee: {
|
5148
|
+
type: 'Identifier',
|
5149
|
+
name: '__Porffor_object_spread'
|
5150
|
+
},
|
5151
|
+
arguments: [
|
5152
|
+
{ type: 'Identifier', name: tmpName },
|
5153
|
+
argument
|
5154
|
+
]
|
5155
|
+
}),
|
5156
|
+
[ Opcodes.drop ]
|
5157
|
+
);
|
5158
|
+
continue;
|
5159
|
+
}
|
5099
5160
|
|
5100
5161
|
let k = key;
|
5101
5162
|
if (!computed && key.type !== 'Literal') k = {
|
package/package.json
CHANGED