porffor 0.30.7 → 0.30.9
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 +15 -0
- package/compiler/builtins/_internal_object.ts +41 -13
- package/compiler/builtins/object.ts +33 -6
- package/compiler/builtins/porffor.d.ts +1 -0
- package/compiler/builtins/reflect.ts +17 -0
- package/compiler/builtins.js +60 -0
- package/compiler/builtins_precompiled.js +66 -29
- package/compiler/codegen.js +130 -14
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -1895,6 +1895,77 @@ const createNewTarget = (scope, decl, idx = 0) => {
|
|
1895
1895
|
];
|
1896
1896
|
};
|
1897
1897
|
|
1898
|
+
const makeObject = (scope, obj) => {
|
1899
|
+
const properties = [];
|
1900
|
+
for (const x in obj) {
|
1901
|
+
properties.push({
|
1902
|
+
type: 'Property',
|
1903
|
+
method: false,
|
1904
|
+
shorthand: false,
|
1905
|
+
computed: false,
|
1906
|
+
key: {
|
1907
|
+
type: 'Identifier',
|
1908
|
+
name: x
|
1909
|
+
},
|
1910
|
+
value: obj[x],
|
1911
|
+
kind: 'init'
|
1912
|
+
});
|
1913
|
+
}
|
1914
|
+
|
1915
|
+
return generateObject(scope, {
|
1916
|
+
type: 'ObjectExpression',
|
1917
|
+
properties
|
1918
|
+
});
|
1919
|
+
};
|
1920
|
+
|
1921
|
+
const getObjProp = (obj, prop) => {
|
1922
|
+
if (typeof obj === 'string') obj = {
|
1923
|
+
type: 'Identifier',
|
1924
|
+
name: obj
|
1925
|
+
};
|
1926
|
+
|
1927
|
+
if (typeof prop === 'string') prop = {
|
1928
|
+
type: 'Identifier',
|
1929
|
+
name: prop
|
1930
|
+
};
|
1931
|
+
|
1932
|
+
return objectHack({
|
1933
|
+
type: 'MemberExpression',
|
1934
|
+
object: obj,
|
1935
|
+
property: prop,
|
1936
|
+
computed: false,
|
1937
|
+
optional: false
|
1938
|
+
});
|
1939
|
+
};
|
1940
|
+
|
1941
|
+
const setObjProp = (obj, prop, value) => {
|
1942
|
+
if (typeof obj === 'string') obj = {
|
1943
|
+
type: 'Identifier',
|
1944
|
+
name: obj
|
1945
|
+
};
|
1946
|
+
|
1947
|
+
if (typeof prop === 'string') prop = {
|
1948
|
+
type: 'Identifier',
|
1949
|
+
name: prop
|
1950
|
+
};
|
1951
|
+
|
1952
|
+
return objectHack({
|
1953
|
+
type: 'ExpressionStatement',
|
1954
|
+
expression: {
|
1955
|
+
type: 'AssignmentExpression',
|
1956
|
+
operator: '=',
|
1957
|
+
left: {
|
1958
|
+
type: 'MemberExpression',
|
1959
|
+
object: obj,
|
1960
|
+
property: prop,
|
1961
|
+
computed: false,
|
1962
|
+
optional: false
|
1963
|
+
},
|
1964
|
+
right: value
|
1965
|
+
}
|
1966
|
+
});
|
1967
|
+
};
|
1968
|
+
|
1898
1969
|
const createThisArg = (scope, decl, knownThis = undefined) => {
|
1899
1970
|
if (knownThis) {
|
1900
1971
|
// todo: check compliance
|
@@ -1902,11 +1973,8 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
|
|
1902
1973
|
}
|
1903
1974
|
|
1904
1975
|
if (decl._new) {
|
1905
|
-
// todo: created object should have .prototype = func.prototype
|
1906
|
-
// todo: created object should have .constructor = func
|
1907
1976
|
return [
|
1908
|
-
|
1909
|
-
...generateObject(scope, { properties: [] }),
|
1977
|
+
...makeObject(scope, {}),
|
1910
1978
|
...number(TYPES.object, Valtype.i32)
|
1911
1979
|
];
|
1912
1980
|
} else {
|
@@ -2656,7 +2724,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2656
2724
|
if (valtypeBinary === Valtype.i32 &&
|
2657
2725
|
(func && func.params[paramOffset + i * (typedParams ? 2 : 1)] === Valtype.f64)
|
2658
2726
|
) {
|
2659
|
-
out.push(Opcodes.
|
2727
|
+
out.push([ Opcodes.f64_convert_i32_u ]);
|
2660
2728
|
}
|
2661
2729
|
|
2662
2730
|
if (typedParams) out = out.concat(arg._callType ?? getNodeType(scope, arg));
|
@@ -3011,7 +3079,7 @@ const extractTypeAnnotation = decl => {
|
|
3011
3079
|
};
|
3012
3080
|
|
3013
3081
|
const setLocalWithType = (scope, name, isGlobal, decl, tee = false, overrideType = undefined) => {
|
3014
|
-
const local = isGlobal ? globals[name] : scope.locals[name];
|
3082
|
+
const local = isGlobal ? globals[name] : (scope.locals[name] ?? { idx: name });
|
3015
3083
|
const out = Array.isArray(decl) ? decl : generate(scope, decl, isGlobal, name);
|
3016
3084
|
|
3017
3085
|
// optimize away last type usage
|
@@ -3445,6 +3513,39 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3445
3513
|
// ...setLastType(scope, getNodeType(scope, decl)),
|
3446
3514
|
],
|
3447
3515
|
|
3516
|
+
[TYPES.function]: [
|
3517
|
+
...objectWasm,
|
3518
|
+
Opcodes.i32_to_u,
|
3519
|
+
...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
|
3520
|
+
...getNodeType(scope, object),
|
3521
|
+
|
3522
|
+
...propertyWasm,
|
3523
|
+
...getNodeType(scope, property),
|
3524
|
+
...toPropertyKey(scope, op === '='),
|
3525
|
+
...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3526
|
+
...(op === '=' ? [] : [
|
3527
|
+
Opcodes.i32_to_u,
|
3528
|
+
[ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
|
3529
|
+
]),
|
3530
|
+
...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
|
3531
|
+
|
3532
|
+
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
3533
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
|
3534
|
+
...getNodeType(scope, object),
|
3535
|
+
|
3536
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
|
3537
|
+
[ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
|
3538
|
+
|
3539
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
|
3540
|
+
...setLastType(scope)
|
3541
|
+
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
3542
|
+
...getNodeType(scope, decl),
|
3543
|
+
|
3544
|
+
[ Opcodes.call, includeBuiltin(scope, '__Porffor_object_set').index ],
|
3545
|
+
[ Opcodes.drop ],
|
3546
|
+
// ...setLastType(scope, getNodeType(scope, decl)),
|
3547
|
+
],
|
3548
|
+
|
3448
3549
|
...wrapBC({
|
3449
3550
|
[TYPES.uint8array]: [
|
3450
3551
|
[ Opcodes.i32_add ],
|
@@ -3738,6 +3839,8 @@ const generateUnary = (scope, decl) => {
|
|
3738
3839
|
const object = decl.argument.object;
|
3739
3840
|
const property = getMemberProperty(decl.argument);
|
3740
3841
|
|
3842
|
+
if (property.value === 'length' || property.value === 'name') scope.noFastFuncMembers = true;
|
3843
|
+
|
3741
3844
|
return [
|
3742
3845
|
...generate(scope, object),
|
3743
3846
|
Opcodes.i32_to_u,
|
@@ -5249,7 +5352,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5249
5352
|
const name = decl.object.name;
|
5250
5353
|
|
5251
5354
|
// hack: .name
|
5252
|
-
if (decl.property.name === 'name' && hasFuncWithName(name)) {
|
5355
|
+
if (decl.property.name === 'name' && hasFuncWithName(name) && !scope.noFastFuncMembers) {
|
5253
5356
|
let nameProp = name;
|
5254
5357
|
|
5255
5358
|
// eg: __String_prototype_toLowerCase -> toLowerCase
|
@@ -5262,12 +5365,14 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5262
5365
|
if (decl.property.name === 'length') {
|
5263
5366
|
// todo: support optional
|
5264
5367
|
|
5265
|
-
|
5266
|
-
|
5368
|
+
if (!scope.noFastFuncMembers) {
|
5369
|
+
const func = funcs.find(x => x.name === name);
|
5370
|
+
if (func) return withType(scope, number(countLength(func, name)), TYPES.number);
|
5267
5371
|
|
5268
|
-
|
5269
|
-
|
5270
|
-
|
5372
|
+
if (Object.hasOwn(builtinFuncs, name)) return withType(scope, number(countLength(builtinFuncs[name], name)), TYPES.number);
|
5373
|
+
if (Object.hasOwn(importedFuncs, name)) return withType(scope, number(importedFuncs[name].params.length ?? importedFuncs[name].params), TYPES.number);
|
5374
|
+
if (Object.hasOwn(internalConstrs, name)) return withType(scope, number(internalConstrs[name].length ?? 0), TYPES.number);
|
5375
|
+
}
|
5271
5376
|
|
5272
5377
|
const out = [
|
5273
5378
|
...generate(scope, decl.object),
|
@@ -5783,9 +5888,20 @@ const generateFunc = (scope, decl) => {
|
|
5783
5888
|
// todo: wrap in try and reject thrown value once supported
|
5784
5889
|
}
|
5785
5890
|
|
5891
|
+
if (!globalThis.precompile && func.constr) {
|
5892
|
+
wasm.unshift(
|
5893
|
+
// if being constructed
|
5894
|
+
[ Opcodes.local_get, '#newtarget' ],
|
5895
|
+
Opcodes.i32_to_u,
|
5896
|
+
[ Opcodes.if, Blocktype.void ],
|
5897
|
+
// set prototype of this ;)
|
5898
|
+
...generate(func, setObjProp({ type: 'ThisExpression' }, '__proto__', getObjProp(func.name, 'prototype'))),
|
5899
|
+
[ Opcodes.end ]
|
5900
|
+
);
|
5901
|
+
}
|
5902
|
+
|
5786
5903
|
if (name === 'main') {
|
5787
5904
|
func.gotLastType = true;
|
5788
|
-
|
5789
5905
|
func.export = true;
|
5790
5906
|
func.returns = [ valtypeBinary, Valtype.i32 ];
|
5791
5907
|
|
@@ -5811,7 +5927,7 @@ const generateFunc = (scope, decl) => {
|
|
5811
5927
|
else func.returns = [];
|
5812
5928
|
}
|
5813
5929
|
|
5814
|
-
// inject promise job runner func at the end of main if used
|
5930
|
+
// inject promise job runner func at the end of main if job queue is used
|
5815
5931
|
if (Object.hasOwn(funcIndex, '__ecma262_HostEnqueuePromiseJob')) {
|
5816
5932
|
wasm.push(
|
5817
5933
|
[ Opcodes.call, includeBuiltin(scope, '__Porffor_promise_runJobs').index ],
|
package/package.json
CHANGED