porffor 0.57.24 → 0.57.26
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 +301 -39
- package/compiler/builtins_precompiled.js +570 -552
- package/compiler/codegen.js +74 -34
- package/compiler/precompile.js +5 -0
- package/compiler/prefs.js +2 -7
- package/package.json +1 -1
- package/runtime/index.js +1 -1
- package/foo.js +0 -1
- package/foo.ts +0 -12
package/compiler/codegen.js
CHANGED
@@ -3583,19 +3583,43 @@ const memberTmpNames = scope => {
|
|
3583
3583
|
};
|
3584
3584
|
};
|
3585
3585
|
|
3586
|
-
|
3587
|
-
|
3588
|
-
|
3586
|
+
const ctHash = prop => {
|
3587
|
+
if (!Prefs.ctHash || !prop ||
|
3588
|
+
prop.computed || prop.optional ||
|
3589
|
+
prop.property.type === 'PrivateIdentifier'
|
3590
|
+
) return null;
|
3591
|
+
|
3592
|
+
prop = prop.property.name;
|
3593
|
+
if (!prop || prop === '__proto__' || !byteStringable(prop)) return null;
|
3594
|
+
|
3595
|
+
let i = 0;
|
3596
|
+
const len = prop.length;
|
3597
|
+
let hash = 374761393 + len;
|
3589
3598
|
|
3590
|
-
|
3591
|
-
|
3592
|
-
prop.computed || prop.optional ||
|
3593
|
-
['prototype', 'size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'length', '__proto__'].includes(prop.property.name)
|
3594
|
-
) return 0;
|
3599
|
+
const rotl = (n, k) => (n << k) | (n >>> (32 - k));
|
3600
|
+
const read = () => (prop.charCodeAt(i + 3) << 24 | prop.charCodeAt(i + 2) << 16 | prop.charCodeAt(i + 1) << 8 | prop.charCodeAt(i));
|
3595
3601
|
|
3596
|
-
|
3602
|
+
// hash in chunks of i32 (4 bytes)
|
3603
|
+
for (; i <= len; i += 4) {
|
3604
|
+
hash = Math.imul(rotl(hash + Math.imul(read(), 3266489917), 17), 668265263);
|
3597
3605
|
}
|
3598
3606
|
|
3607
|
+
// final avalanche
|
3608
|
+
hash = Math.imul(hash ^ (hash >>> 15), 2246822519);
|
3609
|
+
hash = Math.imul(hash ^ (hash >>> 13), 3266489917);
|
3610
|
+
return (hash ^ (hash >>> 16));
|
3611
|
+
};
|
3612
|
+
|
3613
|
+
// COCTC: cross-object compile-time (inline) cache
|
3614
|
+
const coctcOffset = prop => {
|
3615
|
+
if (!Prefs.coctc || !prop ||
|
3616
|
+
prop.computed || prop.optional ||
|
3617
|
+
prop.property.type === 'PrivateIdentifier'
|
3618
|
+
) return 0;
|
3619
|
+
|
3620
|
+
prop = prop.property.name;
|
3621
|
+
if (!prop || ['prototype', 'size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'length', '__proto__'].includes(prop)) return 0;
|
3622
|
+
|
3599
3623
|
let offset = coctc.get(prop);
|
3600
3624
|
if (offset == null) {
|
3601
3625
|
offset = (coctc.lastOffset ?? Prefs.coctcOffset ?? (globalThis.pageSize - 128)) - 9;
|
@@ -3726,8 +3750,9 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3726
3750
|
// todo/perf: use i32 object (and prop?) locals
|
3727
3751
|
const { objectTmp, propertyTmp, objectGet, propertyGet } = memberTmpNames(scope);
|
3728
3752
|
|
3729
|
-
const
|
3730
|
-
|
3753
|
+
const hash = ctHash(decl.left);
|
3754
|
+
const coctc = coctcOffset(decl.left);
|
3755
|
+
if (coctc > 0) valueUnused = false;
|
3731
3756
|
|
3732
3757
|
// opt: do not mark prototype funcs as referenced to optimize this in them
|
3733
3758
|
if (object?.property?.name === 'prototype' && isFuncType(decl.right.type)) decl.right._doNotMarkFuncRef = true;
|
@@ -4004,12 +4029,24 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
4004
4029
|
[ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
|
4005
4030
|
[ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
|
4006
4031
|
|
4007
|
-
|
4032
|
+
...(hash != null ? [
|
4033
|
+
number(hash, Valtype.i32),
|
4034
|
+
number(TYPES.number, Valtype.i32),
|
4035
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get_withHash').index ]
|
4036
|
+
] : [
|
4037
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ]
|
4038
|
+
]),
|
4008
4039
|
...setLastType(scope)
|
4009
4040
|
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right))),
|
4010
4041
|
...getNodeType(scope, decl),
|
4011
4042
|
|
4012
|
-
|
4043
|
+
...(hash != null ? [
|
4044
|
+
number(hash, Valtype.i32),
|
4045
|
+
number(TYPES.number, Valtype.i32),
|
4046
|
+
[ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict_withHash' : '__Porffor_object_set_withHash').index ],
|
4047
|
+
] : [
|
4048
|
+
[ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
|
4049
|
+
]),
|
4013
4050
|
[ Opcodes.drop ],
|
4014
4051
|
...(valueUnused ? [ [ Opcodes.drop ] ] : [])
|
4015
4052
|
// ...setLastType(scope, getNodeType(scope, decl)),
|
@@ -4018,9 +4055,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
4018
4055
|
...optional(number(UNDEFINED), valueUnused)
|
4019
4056
|
];
|
4020
4057
|
|
4021
|
-
if (
|
4058
|
+
if (coctc > 0) {
|
4022
4059
|
// set COCTC
|
4023
|
-
const offset = coctcOffset(decl.left.property.name);
|
4024
4060
|
const valueTmp = localTmp(scope, '#coctc_value');
|
4025
4061
|
const objectTmp = localTmp(scope, '#coctc_object', Valtype.i32);
|
4026
4062
|
|
@@ -4030,11 +4066,11 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
4030
4066
|
|
4031
4067
|
[ Opcodes.local_get, objectTmp ],
|
4032
4068
|
[ Opcodes.local_get, valueTmp ],
|
4033
|
-
[ Opcodes.f64_store, 0, ...unsignedLEB128(
|
4069
|
+
[ Opcodes.f64_store, 0, ...unsignedLEB128(coctc) ],
|
4034
4070
|
|
4035
4071
|
[ Opcodes.local_get, objectTmp ],
|
4036
4072
|
...getNodeType(scope, decl),
|
4037
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(
|
4073
|
+
[ Opcodes.i32_store8, 0, ...unsignedLEB128(coctc + 8) ]
|
4038
4074
|
);
|
4039
4075
|
}
|
4040
4076
|
|
@@ -4222,8 +4258,8 @@ const generateUnary = (scope, decl) => {
|
|
4222
4258
|
const property = getProperty(decl.argument);
|
4223
4259
|
if (property.value === 'length' || property.value === 'name') scope.noFastFuncMembers = true;
|
4224
4260
|
|
4225
|
-
const
|
4226
|
-
const objectTmp =
|
4261
|
+
const coctc = coctcOffset(decl.argument);
|
4262
|
+
const objectTmp = coctc > 0 && localTmp(scope, '#coctc_object', Valtype.i32);
|
4227
4263
|
|
4228
4264
|
const out = [
|
4229
4265
|
...generate(scope, object),
|
@@ -4237,20 +4273,18 @@ const generateUnary = (scope, decl) => {
|
|
4237
4273
|
Opcodes.i32_from_u
|
4238
4274
|
];
|
4239
4275
|
|
4240
|
-
if (
|
4276
|
+
if (coctc > 0) {
|
4241
4277
|
// set COCTC
|
4242
|
-
const offset = coctcOffset(decl.argument.property.name);
|
4243
|
-
|
4244
4278
|
out.push(
|
4245
4279
|
...coctcSetup(scope, object, objectTmp, null, [ [ Opcodes.local_get, objectTmp ] ], false),
|
4246
4280
|
|
4247
4281
|
[ Opcodes.local_get, objectTmp ],
|
4248
4282
|
number(0),
|
4249
|
-
[ Opcodes.f64_store, 0, ...unsignedLEB128(
|
4283
|
+
[ Opcodes.f64_store, 0, ...unsignedLEB128(coctc) ],
|
4250
4284
|
|
4251
4285
|
[ Opcodes.local_get, objectTmp ],
|
4252
4286
|
number(0, Valtype.i32),
|
4253
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(
|
4287
|
+
[ Opcodes.i32_store8, 0, ...unsignedLEB128(coctc + 8) ]
|
4254
4288
|
);
|
4255
4289
|
}
|
4256
4290
|
|
@@ -5860,8 +5894,9 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
5860
5894
|
if (known == null) extraBC = bc;
|
5861
5895
|
}
|
5862
5896
|
|
5863
|
-
const
|
5864
|
-
const
|
5897
|
+
const hash = ctHash(decl);
|
5898
|
+
const coctc = coctcOffset(decl);
|
5899
|
+
const coctcObjTmp = coctc > 0 && localTmp(scope, '#coctc_obj' + uniqId(), Valtype.i32);
|
5865
5900
|
|
5866
5901
|
const out = typeSwitch(scope, type, {
|
5867
5902
|
...(decl.computed ? {
|
@@ -6057,7 +6092,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
6057
6092
|
[TYPES.undefined]: internalThrow(scope, 'TypeError', `Cannot read property of undefined`, true),
|
6058
6093
|
|
6059
6094
|
default: () => [
|
6060
|
-
...(
|
6095
|
+
...(coctc > 0 && known === TYPES.object ? [
|
6061
6096
|
[ Opcodes.local_get, coctcObjTmp ],
|
6062
6097
|
number(TYPES.object, Valtype.i32)
|
6063
6098
|
] : [
|
@@ -6068,7 +6103,14 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
6068
6103
|
|
6069
6104
|
...toPropertyKey(scope, [ propertyGet ], getNodeType(scope, property), decl.computed, true),
|
6070
6105
|
|
6071
|
-
|
6106
|
+
...(hash != null ? [
|
6107
|
+
number(hash, Valtype.i32),
|
6108
|
+
number(TYPES.number, Valtype.i32),
|
6109
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get_withHash').index ]
|
6110
|
+
] : [
|
6111
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ]
|
6112
|
+
]),
|
6113
|
+
|
6072
6114
|
...setLastType(scope)
|
6073
6115
|
],
|
6074
6116
|
|
@@ -6096,21 +6138,19 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
6096
6138
|
[ Opcodes.end ]
|
6097
6139
|
);
|
6098
6140
|
} else {
|
6099
|
-
if (
|
6141
|
+
if (coctc > 0) {
|
6100
6142
|
// fast path: COCTC
|
6101
|
-
const offset = coctcOffset(decl.property.name);
|
6102
|
-
|
6103
6143
|
out.unshift(
|
6104
6144
|
...generate(scope, decl.object),
|
6105
6145
|
[ Opcodes.local_set, objectTmp ],
|
6106
6146
|
...coctcSetup(scope, decl.object, coctcObjTmp, 'get', [ [ Opcodes.local_get, objectTmp ] ]),
|
6107
6147
|
|
6108
6148
|
[ Opcodes.local_get, coctcObjTmp ],
|
6109
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(
|
6149
|
+
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(coctc + 8) ],
|
6110
6150
|
[ Opcodes.local_tee, localTmp(scope, '#coctc_tmp', Valtype.i32) ],
|
6111
6151
|
[ Opcodes.if, Valtype.f64 ],
|
6112
6152
|
[ Opcodes.local_get, coctcObjTmp ],
|
6113
|
-
[ Opcodes.f64_load, 0, ...unsignedLEB128(
|
6153
|
+
[ Opcodes.f64_load, 0, ...unsignedLEB128(coctc) ],
|
6114
6154
|
|
6115
6155
|
...setLastType(scope, [
|
6116
6156
|
[ Opcodes.local_get, localTmp(scope, '#coctc_tmp', Valtype.i32) ],
|
@@ -6493,7 +6533,7 @@ const objectHack = node => {
|
|
6493
6533
|
if (node.type === 'MemberExpression') {
|
6494
6534
|
const out = (() => {
|
6495
6535
|
const abortOut = { ...node, object: objectHack(node.object) };
|
6496
|
-
if (node.computed || node.optional) return;
|
6536
|
+
if (node.computed || node.optional || node.property.type === 'PrivateIdentifier') return;
|
6497
6537
|
|
6498
6538
|
// hack: block these properties as they can be accessed on functions
|
6499
6539
|
if (node.object.name !== 'Porffor' && (node.property.name === 'length' || node.property.name === 'name' || node.property.name === 'call')) return abortOut;
|
package/compiler/precompile.js
CHANGED
@@ -23,14 +23,19 @@ globalThis.precompile = true;
|
|
23
23
|
globalThis.valtypeOverrides = {
|
24
24
|
returns: {
|
25
25
|
__Porffor_object_get: [ Valtype.f64, Valtype.i32 ],
|
26
|
+
__Porffor_object_get_withHash: [ Valtype.f64, Valtype.i32 ],
|
26
27
|
__Porffor_object_readValue: [ Valtype.f64, Valtype.i32 ],
|
27
28
|
__Porffor_object_set: [ Valtype.f64, Valtype.i32 ],
|
29
|
+
__Porffor_object_set_withHash: [ Valtype.f64, Valtype.i32 ],
|
28
30
|
__Porffor_object_setStrict: [ Valtype.f64, Valtype.i32 ],
|
31
|
+
__Porffor_object_setStrict_withHash: [ Valtype.f64, Valtype.i32 ],
|
29
32
|
__Porffor_object_packAccessor: [ Valtype.f64 ]
|
30
33
|
},
|
31
34
|
params: {
|
32
35
|
__Porffor_object_set: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
36
|
+
__Porffor_object_set_withHash: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
33
37
|
__Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
38
|
+
__Porffor_object_setStrict_withHash: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
34
39
|
__Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
35
40
|
__Porffor_object_fastAdd: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
36
41
|
__Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
package/compiler/prefs.js
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
const onByDefault = [ 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused', 'data', 'passiveData', 'rmUnusedTypes', 'optTypes', 'coctc' ];
|
1
|
+
const onByDefault = [ 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused', 'data', 'passiveData', 'rmUnusedTypes', 'optTypes', 'coctc', 'ctHash' ];
|
2
2
|
|
3
3
|
const nameToKey = x => x.replace(/[a-z]\-[a-z]/g, y => `${y[0]}${y[2].toUpperCase()}`);
|
4
4
|
|
5
|
-
let prefs = {};
|
6
5
|
const getPrefs = () => {
|
7
|
-
prefs = {};
|
6
|
+
const prefs = globalThis.Prefs = {};
|
8
7
|
for (const x of onByDefault) prefs[x] = true;
|
9
8
|
|
10
9
|
for (const x of process.argv) {
|
@@ -18,12 +17,8 @@ const getPrefs = () => {
|
|
18
17
|
prefs[nameToKey(name)] = value ?? true;
|
19
18
|
}
|
20
19
|
}
|
21
|
-
|
22
|
-
globalThis.Prefs = prefs;
|
23
20
|
};
|
24
21
|
getPrefs();
|
25
22
|
|
26
|
-
// export default prefs;
|
27
|
-
|
28
23
|
export const uncache = () => getPrefs();
|
29
24
|
globalThis.argvChanged = uncache;
|
package/package.json
CHANGED
package/runtime/index.js
CHANGED
package/foo.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
console.log(await Promise.resolve(5));
|
package/foo.ts
DELETED