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: object, key: any, value: any): void => {
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: object, key: any, get: any): void => {
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: object, key: any, set: any): void => {
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,0],[65,7],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[34,6],[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,6],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,7],[26],[11],[32,6],[32,4],[57,0,4],[32,6],[65,14],[32,5],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
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","entryPtr","#last_type","size"],
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,0],[65,7],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[33,6],[65,0],[33,8],[65,128,1],[33,9],[32,6],[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,6],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,7],[26],[5],[32,6],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,9],[33,8],[11],[32,6],[32,4],[32,5],[32,8],[32,9],[16,builtin('__Porffor_object_packAccessor')],[33,7],[57,0,4],[32,6],[65,15],[65,1],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
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","entryPtr","#last_type","set","set#type","size"],
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,0],[65,7],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[33,6],[65,0],[33,8],[65,128,1],[33,9],[32,6],[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,6],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,7],[26],[5],[32,6],[65,1],[16,builtin('__Porffor_object_accessorGet')],[33,9],[33,8],[11],[32,6],[32,8],[32,9],[32,4],[32,5],[16,builtin('__Porffor_object_packAccessor')],[33,7],[57,0,4],[32,6],[65,15],[65,1],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
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","entryPtr","#last_type","get","get#type","size"],
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]],
@@ -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
- const func = generateFunc(scope, decl);
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 == 'ThisExpression') {
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 == 'MetaProperty') {
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
- if (isFuncType(decl.callee.type)) { // iife
2007
- const func = generateFunc(scope, decl.callee);
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
- func.wasm.splice(func.wasm.length - 1, 1);
5988
-
5989
- const finalStatement = decl.body.body[decl.body.body.length - 1];
5990
- func.wasm.push(...getNodeType(func, finalStatement));
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.31.0+c8cd1d6c9",
4
+ "version": "0.33.1+77ec3428e",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.31.0+c8cd1d6c9';
3
+ globalThis.version = '0.33.1+77ec3428e';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {