porffor 0.35.4 → 0.36.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/__internal_object.ts +9 -5
- package/compiler/builtins/object.ts +21 -23
- package/compiler/builtins_objects.js +17 -18
- package/compiler/builtins_precompiled.js +118 -118
- package/compiler/codegen.js +88 -72
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -3883,18 +3883,21 @@ const generateForOf = (scope, decl) => {
|
|
3883
3883
|
if (depth[i] === 'forof') count++;
|
3884
3884
|
}
|
3885
3885
|
|
3886
|
-
const iterType = getNodeType(scope, decl.right);
|
3887
|
-
|
3888
3886
|
const pointer = localTmp(scope, '#forof_base_pointer' + count, Valtype.i32);
|
3889
3887
|
const length = localTmp(scope, '#forof_length' + count, Valtype.i32);
|
3890
3888
|
const counter = localTmp(scope, '#forof_counter' + count, Valtype.i32);
|
3891
3889
|
|
3890
|
+
const iterType = [ [ Opcodes.local_get, localTmp(scope, '#forof_itertype' + count, Valtype.i32) ] ];
|
3891
|
+
|
3892
3892
|
out.push(
|
3893
3893
|
// set pointer as right
|
3894
3894
|
...generate(scope, decl.right),
|
3895
3895
|
Opcodes.i32_to_u,
|
3896
3896
|
[ Opcodes.local_set, pointer ],
|
3897
3897
|
|
3898
|
+
...getNodeType(scope, decl.right),
|
3899
|
+
[ Opcodes.local_set, localTmp(scope, '#forof_itertype' + count, Valtype.i32) ],
|
3900
|
+
|
3898
3901
|
// set counter as 0 (could be already used)
|
3899
3902
|
...number(0, Valtype.i32),
|
3900
3903
|
[ Opcodes.local_set, counter ],
|
@@ -4260,8 +4263,6 @@ const generateForIn = (scope, decl) => {
|
|
4260
4263
|
if (depth[i] === 'forin') count++;
|
4261
4264
|
}
|
4262
4265
|
|
4263
|
-
const iterType = getNodeType(scope, decl.right);
|
4264
|
-
|
4265
4266
|
const pointer = localTmp(scope, '#forin_base_pointer' + count, Valtype.i32);
|
4266
4267
|
const length = localTmp(scope, '#forin_length' + count, Valtype.i32);
|
4267
4268
|
const counter = localTmp(scope, '#forin_counter' + count, Valtype.i32);
|
@@ -4276,14 +4277,6 @@ const generateForIn = (scope, decl) => {
|
|
4276
4277
|
...number(0, Valtype.i32),
|
4277
4278
|
[ Opcodes.local_set, counter ],
|
4278
4279
|
|
4279
|
-
...iterType,
|
4280
|
-
...number(TYPES.object, Valtype.i32),
|
4281
|
-
[ Opcodes.i32_eq ],
|
4282
|
-
[ Opcodes.i32_eqz ],
|
4283
|
-
[ Opcodes.if, Blocktype.void ],
|
4284
|
-
...internalThrow(scope, 'TypeError', `Tried for..in on unsupported type`),
|
4285
|
-
[ Opcodes.end ],
|
4286
|
-
|
4287
4280
|
// get length
|
4288
4281
|
[ Opcodes.local_get, pointer ],
|
4289
4282
|
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
@@ -4313,70 +4306,64 @@ const generateForIn = (scope, decl) => {
|
|
4313
4306
|
|
4314
4307
|
// set type for local
|
4315
4308
|
// todo: optimize away counter and use end pointer
|
4316
|
-
out.push(
|
4317
|
-
[
|
4318
|
-
[ Opcodes.loop, Blocktype.void ],
|
4319
|
-
|
4320
|
-
// read key
|
4321
|
-
[ Opcodes.local_get, pointer ],
|
4322
|
-
[ Opcodes.i32_load, 0, 5 ],
|
4323
|
-
[ Opcodes.local_tee, tmp ],
|
4309
|
+
out.push(
|
4310
|
+
[ Opcodes.loop, Blocktype.void ],
|
4324
4311
|
|
4325
|
-
|
4326
|
-
|
4327
|
-
|
4328
|
-
|
4329
|
-
// unset MSB in tmp
|
4330
|
-
[ Opcodes.local_get, tmp ],
|
4331
|
-
...number(0x7fffffff, Valtype.i32),
|
4332
|
-
[ Opcodes.i32_and ],
|
4333
|
-
[ Opcodes.local_set, tmp ],
|
4312
|
+
// read key
|
4313
|
+
[ Opcodes.local_get, pointer ],
|
4314
|
+
[ Opcodes.i32_load, 0, 5 ],
|
4315
|
+
[ Opcodes.local_tee, tmp ],
|
4334
4316
|
|
4335
|
-
|
4336
|
-
|
4337
|
-
|
4338
|
-
|
4339
|
-
|
4317
|
+
...setType(scope, tmpName, [
|
4318
|
+
[ Opcodes.i32_const, 31 ],
|
4319
|
+
[ Opcodes.i32_shr_u ],
|
4320
|
+
[ Opcodes.if, Valtype.i32 ],
|
4321
|
+
// unset MSB in tmp
|
4322
|
+
[ Opcodes.local_get, tmp ],
|
4323
|
+
...number(0x7fffffff, Valtype.i32),
|
4324
|
+
[ Opcodes.i32_and ],
|
4325
|
+
[ Opcodes.local_set, tmp ],
|
4340
4326
|
|
4341
|
-
|
4327
|
+
[ Opcodes.i32_const, ...unsignedLEB128(TYPES.string) ],
|
4328
|
+
[ Opcodes.else ],
|
4329
|
+
[ Opcodes.i32_const, ...unsignedLEB128(TYPES.bytestring) ],
|
4330
|
+
[ Opcodes.end ]
|
4331
|
+
]),
|
4342
4332
|
|
4343
|
-
|
4333
|
+
...setVar,
|
4344
4334
|
|
4345
|
-
|
4346
|
-
// only run body if entry is enumerable
|
4347
|
-
[ Opcodes.local_get, pointer ],
|
4348
|
-
[ Opcodes.i32_load8_u, 0, 17 ],
|
4349
|
-
[ Opcodes.i32_const, 0b0100 ],
|
4350
|
-
[ Opcodes.i32_and ],
|
4351
|
-
[ Opcodes.if, Blocktype.void ],
|
4352
|
-
...generate(scope, decl.body),
|
4353
|
-
[ Opcodes.end ],
|
4335
|
+
[ Opcodes.block, Blocktype.void ],
|
4354
4336
|
|
4355
|
-
|
4356
|
-
|
4357
|
-
|
4358
|
-
|
4359
|
-
|
4337
|
+
// todo/perf: do not read key for non-enumerables
|
4338
|
+
// only run body if entry is enumerable
|
4339
|
+
[ Opcodes.local_get, pointer ],
|
4340
|
+
[ Opcodes.i32_load8_u, 0, 17 ],
|
4341
|
+
[ Opcodes.i32_const, 0b0100 ],
|
4342
|
+
[ Opcodes.i32_and ],
|
4343
|
+
[ Opcodes.if, Blocktype.void ],
|
4344
|
+
...generate(scope, decl.body),
|
4345
|
+
[ Opcodes.end ],
|
4360
4346
|
|
4361
|
-
|
4362
|
-
|
4363
|
-
|
4364
|
-
|
4365
|
-
|
4347
|
+
// increment pointer by 14
|
4348
|
+
[ Opcodes.local_get, pointer ],
|
4349
|
+
...number(14, Valtype.i32),
|
4350
|
+
[ Opcodes.i32_add ],
|
4351
|
+
[ Opcodes.local_set, pointer ],
|
4366
4352
|
|
4367
|
-
|
4368
|
-
|
4369
|
-
|
4370
|
-
|
4353
|
+
// increment counter by 1
|
4354
|
+
[ Opcodes.local_get, counter ],
|
4355
|
+
...number(1, Valtype.i32),
|
4356
|
+
[ Opcodes.i32_add ],
|
4357
|
+
[ Opcodes.local_tee, counter ],
|
4371
4358
|
|
4372
|
-
|
4373
|
-
|
4374
|
-
],
|
4359
|
+
// loop if counter != length
|
4360
|
+
[ Opcodes.local_get, length ],
|
4361
|
+
[ Opcodes.i32_ne ],
|
4362
|
+
[ Opcodes.br_if, 1 ],
|
4375
4363
|
|
4376
|
-
|
4377
|
-
|
4378
|
-
|
4379
|
-
}, Blocktype.void));
|
4364
|
+
[ Opcodes.end ],
|
4365
|
+
[ Opcodes.end ]
|
4366
|
+
);
|
4380
4367
|
|
4381
4368
|
out.push([ Opcodes.end ]); // end if
|
4382
4369
|
|
@@ -4384,7 +4371,33 @@ const generateForIn = (scope, decl) => {
|
|
4384
4371
|
depth.pop();
|
4385
4372
|
depth.pop();
|
4386
4373
|
|
4387
|
-
return
|
4374
|
+
return typeSwitch(scope, getNodeType(scope, decl.right), {
|
4375
|
+
// fast path for objects
|
4376
|
+
[TYPES.object]: out,
|
4377
|
+
|
4378
|
+
// wrap for of object.keys
|
4379
|
+
default: generate(scope, {
|
4380
|
+
type: 'ForOfStatement',
|
4381
|
+
left: decl.left,
|
4382
|
+
body: decl.body,
|
4383
|
+
right: {
|
4384
|
+
type: 'CallExpression',
|
4385
|
+
callee: {
|
4386
|
+
type: 'Identifier',
|
4387
|
+
name: '__Object_keys'
|
4388
|
+
},
|
4389
|
+
arguments: [ {
|
4390
|
+
type: 'LogicalExpression',
|
4391
|
+
left: decl.right,
|
4392
|
+
operator: '??',
|
4393
|
+
right: {
|
4394
|
+
type: 'Literal',
|
4395
|
+
value: 0
|
4396
|
+
}
|
4397
|
+
} ]
|
4398
|
+
}
|
4399
|
+
})
|
4400
|
+
}, Blocktype.void);
|
4388
4401
|
};
|
4389
4402
|
|
4390
4403
|
const generateSwitch = (scope, decl) => {
|
@@ -5730,24 +5743,27 @@ const objectHack = node => {
|
|
5730
5743
|
|
5731
5744
|
if (node.type === 'MemberExpression') {
|
5732
5745
|
const out = (() => {
|
5746
|
+
const abortOut = { ...node, object: objectHack(node.object) };
|
5733
5747
|
if (node.computed || node.optional) return;
|
5734
5748
|
|
5735
5749
|
// hack: block these properties as they can be accessed on functions
|
5736
|
-
if (node.property.name === 'length' || node.property.name === 'name' || node.property.name === 'call') return;
|
5750
|
+
if (node.property.name === 'length' || node.property.name === 'name' || node.property.name === 'call') return abortOut;
|
5737
5751
|
|
5738
|
-
if (node.property.name === '__proto__') return;
|
5752
|
+
if (node.property.name === '__proto__') return abortOut;
|
5739
5753
|
|
5740
5754
|
let objectName = node.object.name;
|
5741
5755
|
|
5742
5756
|
// if object is not identifier or another member exp, give up
|
5743
|
-
if (node.object.type !== 'Identifier' && node.object.type !== 'MemberExpression') return;
|
5744
|
-
if (objectName && ['undefined', 'null', 'NaN', 'Infinity'].includes(objectName)) return;
|
5757
|
+
if (node.object.type !== 'Identifier' && node.object.type !== 'MemberExpression') return abortOut;
|
5758
|
+
if (objectName && ['undefined', 'null', 'NaN', 'Infinity'].includes(objectName)) return abortOut;
|
5745
5759
|
|
5746
5760
|
if (!objectName) objectName = objectHack(node.object)?.name?.slice?.(2);
|
5747
5761
|
if (!objectName || (!objectHackers.includes(objectName) && !objectHackers.some(x => objectName.startsWith(`${x}_`)))) {
|
5748
|
-
return;
|
5762
|
+
return abortOut;
|
5749
5763
|
}
|
5750
5764
|
|
5765
|
+
if (objectName !== 'Object_prototype' && (node.property.name === 'propertyIsEnumerable' || node.property.name === 'hasOwnProperty' || node.property.name === 'isPrototypeOf')) return abortOut;
|
5766
|
+
|
5751
5767
|
const name = '__' + objectName + '_' + node.property.name;
|
5752
5768
|
if (Prefs.codeLog) log('codegen', `object hack! ${node.object.name}.${node.property.name} -> ${name}`);
|
5753
5769
|
|
package/package.json
CHANGED