porffor 0.31.0 → 0.33.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.
@@ -548,7 +548,8 @@ export const __Porffor_object_isObjectOrSymbol = (arg: any): boolean => {
|
|
548
548
|
|
549
549
|
|
550
550
|
// used for { foo: 5 }
|
551
|
-
export const __Porffor_object_expr_init = (obj:
|
551
|
+
export const __Porffor_object_expr_init = (obj: any, key: any, value: any): void => {
|
552
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
|
552
553
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
553
554
|
if (entryPtr == -1) {
|
554
555
|
// add new entry
|
@@ -573,7 +574,8 @@ export const __Porffor_object_expr_init = (obj: object, key: any, value: any): v
|
|
573
574
|
};
|
574
575
|
|
575
576
|
// used for { get foo() {} }
|
576
|
-
export const __Porffor_object_expr_get = (obj:
|
577
|
+
export const __Porffor_object_expr_get = (obj: any, key: any, get: any): void => {
|
578
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
|
577
579
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
578
580
|
let set: any = undefined;
|
579
581
|
if (entryPtr == -1) {
|
@@ -602,7 +604,8 @@ export const __Porffor_object_expr_get = (obj: object, key: any, get: any): void
|
|
602
604
|
};
|
603
605
|
|
604
606
|
// used for { set foo(v) {} }
|
605
|
-
export const __Porffor_object_expr_set = (obj:
|
607
|
+
export const __Porffor_object_expr_set = (obj: any, key: any, set: any): void => {
|
608
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
|
606
609
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
607
610
|
let get: any = undefined;
|
608
611
|
if (entryPtr == -1) {
|
@@ -96,19 +96,19 @@ params:[127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
|
96
96
|
locals:[127],localNames:["arg","arg#type","t"],
|
97
97
|
};
|
98
98
|
this.__Porffor_object_expr_init = {
|
99
|
-
wasm:(_,{builtin})=>[[32,
|
99
|
+
wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('__Porffor_object_getObject')],[33,6],[252,2],[34,0],[32,6],[33,1],[26],[11],[32,0],[32,1],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[34,7],[65,127],[70],[4,64],[32,0],[40,0,0],[33,8],[32,0],[32,8],[65,1],[106],[54,0,0],[32,0],[65,5],[106],[32,8],[65,14],[108],[106],[34,7],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,6],[26],[11],[32,7],[32,4],[57,0,4],[32,7],[65,14],[32,5],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
|
100
100
|
params:[127,127,127,127,124,127],typedParams:1,returns:[127,127],typedReturns:1,
|
101
|
-
locals:[127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","
|
101
|
+
locals:[127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","#last_type","entryPtr","size"],
|
102
102
|
};
|
103
103
|
this.__Porffor_object_expr_get = {
|
104
|
-
wasm:(_,{builtin})=>[[32,
|
104
|
+
wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('__Porffor_object_getObject')],[33,6],[252,2],[34,0],[32,6],[33,1],[26],[11],[32,0],[32,1],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[33,7],[65,0],[33,8],[65,128,1],[33,9],[32,7],[65,127],[70],[4,64],[32,0],[40,0,0],[33,10],[32,0],[32,10],[65,1],[106],[54,0,0],[32,0],[65,5],[106],[32,10],[65,14],[108],[106],[34,7],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,6],[26],[5],[32,7],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,9],[33,8],[11],[32,7],[32,4],[32,5],[32,8],[32,9],[16,builtin('__Porffor_object_packAccessor')],[33,6],[57,0,4],[32,7],[65,15],[65,1],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
|
105
105
|
params:[127,127,127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
106
|
-
locals:[127,127,127,127,127],localNames:["obj","obj#type","key","key#type","get","get#type","
|
106
|
+
locals:[127,127,127,127,127],localNames:["obj","obj#type","key","key#type","get","get#type","#last_type","entryPtr","set","set#type","size"],
|
107
107
|
};
|
108
108
|
this.__Porffor_object_expr_set = {
|
109
|
-
wasm:(_,{builtin})=>[[32,
|
109
|
+
wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('__Porffor_object_getObject')],[33,6],[252,2],[34,0],[32,6],[33,1],[26],[11],[32,0],[32,1],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[33,7],[65,0],[33,8],[65,128,1],[33,9],[32,7],[65,127],[70],[4,64],[32,0],[40,0,0],[33,10],[32,0],[32,10],[65,1],[106],[54,0,0],[32,0],[65,5],[106],[32,10],[65,14],[108],[106],[34,7],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,6],[26],[5],[32,7],[65,1],[16,builtin('__Porffor_object_accessorGet')],[33,9],[33,8],[11],[32,7],[32,8],[32,9],[32,4],[32,5],[16,builtin('__Porffor_object_packAccessor')],[33,6],[57,0,4],[32,7],[65,15],[65,1],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
|
110
110
|
params:[127,127,127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
111
|
-
locals:[127,127,127,127,127],localNames:["obj","obj#type","key","key#type","set","set#type","
|
111
|
+
locals:[127,127,127,127,127],localNames:["obj","obj#type","key","key#type","set","set#type","#last_type","entryPtr","get","get#type","size"],
|
112
112
|
};
|
113
113
|
this.__String_prototype_big = {
|
114
114
|
wasm:(_,{allocPage})=>[...number(allocPage(_,'string: __String_prototype_big/out','i16')*pageSize,127),[34,2],[65,10],[106],[33,3],[32,0],[33,4],[32,0],[40,1,0],[33,5],[32,4],[32,5],[65,2],[108],[106],[33,6],[3,64],[32,4],[32,6],[72],[4,64],[32,4],[47,0,4],[33,7],[32,3],[32,7],[59,0,4],[32,4],[65,2],[106],[33,4],[32,3],[65,2],[106],[33,3],[12,1],[11],[11],[32,3],[65,60],[59,0,4],[32,3],[65,47],[59,0,6],[32,3],[65,226,0],[59,0,8],[32,3],[65,233,0],[59,0,10],[32,3],[65,231,0],[59,0,12],[32,3],[65,62],[59,0,14],[32,2],[34,9],[32,5],[65,11],[106],[34,8],[54,1,0],[32,2],[65,195,0],[15]],
|
package/compiler/codegen.js
CHANGED
@@ -37,7 +37,8 @@ const todo = (scope, msg, expectsValue = undefined) => {
|
|
37
37
|
};
|
38
38
|
|
39
39
|
const isFuncType = type =>
|
40
|
-
type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression'
|
40
|
+
type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression' ||
|
41
|
+
type === 'ClassDeclaration' || type === 'ClassExpression';
|
41
42
|
const hasFuncWithName = name =>
|
42
43
|
Object.hasOwn(funcIndex, name) || Object.hasOwn(builtinFuncs, name) || Object.hasOwn(importedFuncs, name) || Object.hasOwn(internalConstrs, name);
|
43
44
|
|
@@ -71,13 +72,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
71
72
|
case 'ArrowFunctionExpression':
|
72
73
|
case 'FunctionDeclaration':
|
73
74
|
case 'FunctionExpression':
|
74
|
-
|
75
|
-
|
76
|
-
if (decl.type.endsWith('Expression')) {
|
77
|
-
return cacheAst(decl, funcRef(func.index, func.name));
|
78
|
-
}
|
79
|
-
|
80
|
-
return cacheAst(decl, []);
|
75
|
+
return cacheAst(decl, generateFunc(scope, decl)[1]);
|
81
76
|
|
82
77
|
case 'BlockStatement':
|
83
78
|
return cacheAst(decl, generateCode(scope, decl));
|
@@ -175,6 +170,10 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
175
170
|
case 'MemberExpression':
|
176
171
|
return cacheAst(decl, generateMember(scope, decl, global, name));
|
177
172
|
|
173
|
+
case 'ClassExpression':
|
174
|
+
case 'ClassDeclaration':
|
175
|
+
return cacheAst(decl, generateClass(scope, decl));
|
176
|
+
|
178
177
|
case 'ExportNamedDeclaration':
|
179
178
|
if (!decl.declaration) return todo(scope, 'unsupported export declaration');
|
180
179
|
|
@@ -1696,12 +1695,12 @@ const getNodeType = (scope, node) => {
|
|
1696
1695
|
}
|
1697
1696
|
}
|
1698
1697
|
|
1699
|
-
if (node.type
|
1698
|
+
if (node.type === 'ThisExpression') {
|
1700
1699
|
if (!scope.constr) return getType(scope, 'globalThis');
|
1701
1700
|
return [ [ Opcodes.local_get, '#this#type' ] ];
|
1702
1701
|
}
|
1703
1702
|
|
1704
|
-
if (node.type
|
1703
|
+
if (node.type === 'MetaProperty') {
|
1705
1704
|
switch (`${node.meta.name}.${node.property.name}`) {
|
1706
1705
|
case 'new.target': {
|
1707
1706
|
return [ [ Opcodes.local_get, '#newtarget#type' ] ];
|
@@ -2002,9 +2001,12 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
|
|
2002
2001
|
};
|
2003
2002
|
|
2004
2003
|
const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
2004
|
+
let out = [];
|
2005
2005
|
let name = mapName(decl.callee.name);
|
2006
|
-
|
2007
|
-
|
2006
|
+
|
2007
|
+
// opt: virtualize iifes
|
2008
|
+
if (isFuncType(decl.callee.type)) {
|
2009
|
+
const [ func ] = generateFunc(scope, decl.callee);
|
2008
2010
|
name = func.name;
|
2009
2011
|
}
|
2010
2012
|
|
@@ -2102,7 +2104,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2102
2104
|
target = decl.callee.object;
|
2103
2105
|
}
|
2104
2106
|
|
2105
|
-
let out = [];
|
2106
2107
|
if (protoName) {
|
2107
2108
|
if (protoName === 'call') {
|
2108
2109
|
const valTmp = localTmp(scope, '#call_val');
|
@@ -5765,6 +5766,87 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5765
5766
|
return out;
|
5766
5767
|
};
|
5767
5768
|
|
5769
|
+
const generateClass = (scope, decl) => {
|
5770
|
+
const expr = decl.type === 'ClassExpression';
|
5771
|
+
if (decl.superClass) return todo(scope, 'class extends is not supported yet', expr);
|
5772
|
+
|
5773
|
+
const name = decl.id ? decl.id.name : `#anonymous${uniqId()}`;
|
5774
|
+
if (name == null) return todo(scope, 'unknown name for class', expr);
|
5775
|
+
|
5776
|
+
const body = decl.body.body;
|
5777
|
+
const root = {
|
5778
|
+
type: 'Identifier',
|
5779
|
+
name
|
5780
|
+
};
|
5781
|
+
|
5782
|
+
const constr = body.find(x => x.kind === 'constructor')?.value ?? {
|
5783
|
+
type: 'FunctionExpression',
|
5784
|
+
id: root,
|
5785
|
+
params: [],
|
5786
|
+
body: {
|
5787
|
+
type: 'BlockStatement',
|
5788
|
+
body: []
|
5789
|
+
}
|
5790
|
+
};
|
5791
|
+
|
5792
|
+
const [ func, out ] = generateFunc(scope, {
|
5793
|
+
...constr,
|
5794
|
+
_onlyConstr: `Class constructor ${name} requires 'new'`,
|
5795
|
+
type: expr ? 'FunctionExpression' : 'FunctionDeclaration'
|
5796
|
+
});
|
5797
|
+
|
5798
|
+
for (const x of body) {
|
5799
|
+
let { type, key, value, kind, static: _static, computed } = x;
|
5800
|
+
if (type !== 'MethodDefinition' && type !== 'PropertyDefinition') return todo(scope, `class body type ${type} is not supported yet`, expr);
|
5801
|
+
|
5802
|
+
if (kind === 'constructor') continue;
|
5803
|
+
|
5804
|
+
const object = _static ? root : {
|
5805
|
+
type: 'MemberExpression',
|
5806
|
+
object: root,
|
5807
|
+
property: {
|
5808
|
+
type: 'Identifier',
|
5809
|
+
name: 'prototype'
|
5810
|
+
},
|
5811
|
+
computed: false,
|
5812
|
+
optional: false
|
5813
|
+
};
|
5814
|
+
|
5815
|
+
let k = key;
|
5816
|
+
if (!computed && key.type !== 'Literal') k = {
|
5817
|
+
type: 'Literal',
|
5818
|
+
value: key.name
|
5819
|
+
};
|
5820
|
+
|
5821
|
+
let initKind = 'init';
|
5822
|
+
if (kind === 'get' || kind === 'set') initKind = kind;
|
5823
|
+
|
5824
|
+
// default value to undefined
|
5825
|
+
value ??= DEFAULT_VALUE();
|
5826
|
+
|
5827
|
+
out.push(
|
5828
|
+
...generate(scope, object),
|
5829
|
+
Opcodes.i32_to_u,
|
5830
|
+
...getNodeType(scope, object),
|
5831
|
+
|
5832
|
+
...generate(scope, k),
|
5833
|
+
...getNodeType(scope, k),
|
5834
|
+
...toPropertyKey(scope, true),
|
5835
|
+
|
5836
|
+
...generate(scope, value),
|
5837
|
+
...(initKind !== 'init' ? [ Opcodes.i32_to_u ] : []),
|
5838
|
+
...getNodeType(scope, value),
|
5839
|
+
|
5840
|
+
[ Opcodes.call, includeBuiltin(scope, `__Porffor_object_expr_${initKind}`).index ],
|
5841
|
+
|
5842
|
+
[ Opcodes.drop ],
|
5843
|
+
[ Opcodes.drop ]
|
5844
|
+
);
|
5845
|
+
}
|
5846
|
+
|
5847
|
+
return out;
|
5848
|
+
};
|
5849
|
+
|
5768
5850
|
globalThis._uniqId = 0;
|
5769
5851
|
const uniqId = () => '_' + globalThis._uniqId++;
|
5770
5852
|
|
@@ -5816,6 +5898,16 @@ const objectHack = node => {
|
|
5816
5898
|
|
5817
5899
|
const generateFunc = (scope, decl) => {
|
5818
5900
|
const name = decl.id ? decl.id.name : `#anonymous${uniqId()}`;
|
5901
|
+
if (decl.type.startsWith('Class')) {
|
5902
|
+
const out = generateClass(scope, {
|
5903
|
+
...decl,
|
5904
|
+
id: { name }
|
5905
|
+
});
|
5906
|
+
|
5907
|
+
const func = funcs.find(x => x.name === name);
|
5908
|
+
return [ func, out ];
|
5909
|
+
}
|
5910
|
+
|
5819
5911
|
const params = decl.params ?? [];
|
5820
5912
|
|
5821
5913
|
// TODO: share scope/locals between !!!
|
@@ -5837,6 +5929,8 @@ const generateFunc = (scope, decl) => {
|
|
5837
5929
|
funcIndex[name] = func.index;
|
5838
5930
|
funcs.push(func);
|
5839
5931
|
|
5932
|
+
const out = decl.type.endsWith('Expression') ? funcRef(func.index, func.name) : [];
|
5933
|
+
|
5840
5934
|
let errorWasm = null;
|
5841
5935
|
if (decl.generator) errorWasm = todo(scope, 'generator functions are not supported');
|
5842
5936
|
|
@@ -5847,7 +5941,7 @@ const generateFunc = (scope, decl) => {
|
|
5847
5941
|
]);
|
5848
5942
|
func.params = [];
|
5849
5943
|
func.constr = false;
|
5850
|
-
return func;
|
5944
|
+
return [ func, out ];
|
5851
5945
|
}
|
5852
5946
|
|
5853
5947
|
if (typedInput && decl.returnType) {
|
@@ -5977,17 +6071,39 @@ const generateFunc = (scope, decl) => {
|
|
5977
6071
|
);
|
5978
6072
|
}
|
5979
6073
|
|
6074
|
+
if (decl._onlyConstr) {
|
6075
|
+
wasm.unshift(
|
6076
|
+
// error if not being constructed
|
6077
|
+
[ Opcodes.local_get, '#newtarget' ],
|
6078
|
+
Opcodes.i32_to_u,
|
6079
|
+
[ Opcodes.i32_eqz ],
|
6080
|
+
[ Opcodes.if, Blocktype.void ],
|
6081
|
+
...internalThrow(func, 'TypeError', decl._onlyConstr),
|
6082
|
+
[ Opcodes.end ]
|
6083
|
+
);
|
6084
|
+
}
|
6085
|
+
|
5980
6086
|
if (name === 'main') {
|
5981
6087
|
func.gotLastType = true;
|
5982
6088
|
func.export = true;
|
5983
6089
|
func.returns = [ valtypeBinary, Valtype.i32 ];
|
5984
6090
|
|
6091
|
+
let finalStatement = decl.body.body[decl.body.body.length - 1];
|
6092
|
+
if (finalStatement?.type === 'EmptyStatement') finalStatement = decl.body.body[decl.body.body.length - 2];
|
6093
|
+
|
5985
6094
|
const lastInst = func.wasm[func.wasm.length - 1] ?? [ Opcodes.end ];
|
5986
6095
|
if (lastInst[0] === Opcodes.drop) {
|
5987
|
-
|
5988
|
-
|
5989
|
-
|
5990
|
-
|
6096
|
+
if (finalStatement.type.endsWith('Declaration')) {
|
6097
|
+
// final statement is decl, force undefined
|
6098
|
+
disposeLeftover(wasm);
|
6099
|
+
func.wasm.push(
|
6100
|
+
...number(UNDEFINED),
|
6101
|
+
...number(TYPES.undefined, Valtype.i32)
|
6102
|
+
);
|
6103
|
+
} else {
|
6104
|
+
func.wasm.splice(func.wasm.length - 1, 1);
|
6105
|
+
func.wasm.push(...getNodeType(func, finalStatement));
|
6106
|
+
}
|
5991
6107
|
}
|
5992
6108
|
|
5993
6109
|
if (lastInst[0] === Opcodes.end || lastInst[0] === Opcodes.local_set || lastInst[0] === Opcodes.global_set) {
|
@@ -6050,7 +6166,7 @@ const generateFunc = (scope, decl) => {
|
|
6050
6166
|
}
|
6051
6167
|
}
|
6052
6168
|
|
6053
|
-
return func;
|
6169
|
+
return [ func, out ];
|
6054
6170
|
};
|
6055
6171
|
|
6056
6172
|
const generateCode = (scope, decl) => {
|
@@ -6266,7 +6382,7 @@ export default program => {
|
|
6266
6382
|
|
6267
6383
|
if (Prefs.astLog) console.log(JSON.stringify(program.body.body, null, 2));
|
6268
6384
|
|
6269
|
-
const main = generateFunc(scope, program);
|
6385
|
+
const [ main ] = generateFunc(scope, program);
|
6270
6386
|
|
6271
6387
|
delete globals['#ind'];
|
6272
6388
|
|
package/package.json
CHANGED