porffor 0.30.0 → 0.30.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.
@@ -665,4 +665,21 @@ export const __Object_prototype_toLocaleString = (_this: any) => __Object_protot
665
665
  export const __Object_prototype_valueOf = (_this: any) => {
666
666
  // todo: ToObject
667
667
  return _this;
668
+ };
669
+
670
+
671
+ export const __Porffor_object_spread = (dst: object, src: any): object => {
672
+ if (src == null) return;
673
+
674
+ // todo/perf: optimize this (and assign) for object instead of reading over object 2x
675
+ const keys: any[] = __Object_keys(src);
676
+ const vals: any[] = __Object_values(src);
677
+
678
+ const len: i32 = keys.length;
679
+ for (let i: i32 = 0; i < len; i++) {
680
+ // target[keys[i]] = vals[i];
681
+ Porffor.object.expr.init(dst, keys[i], vals[i]);
682
+ }
683
+
684
+ return dst;
668
685
  };
@@ -1914,6 +1914,12 @@ export const BuiltinFuncs = function() {
1914
1914
  returns: [124,127], typedReturns: 1,
1915
1915
  locals: [], localNames: ["_this","_this#type"],
1916
1916
  };
1917
+ this.__Porffor_object_spread = {
1918
+ wasm: (scope, {builtin}) => [[32,2],[33,4],[32,3],[33,5],[2,127],[32,5],[65,0],[70],[4,64,"TYPESWITCH|empty"],[65,1],[12,1],[11],[32,5],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,4],[68,0,0,0,0,0,0,0,0],[97],[12,1],[11],[32,5],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],[65,1],[12,1],[11],[65,0],[11,"TYPESWITCH_end"],[4,64],[68,0,0,0,0,0,0,0,0],[65,128,1],[15],[11],[32,2],[32,3],[16, builtin('__Object_keys')],[26],[33,6],[32,2],[32,3],[16, builtin('__Object_values')],[26],[33,8],[32,6],[252,3],[40,1,0],[184],[33,9],[68,0,0,0,0,0,0,0,0],[33,10],[3,64],[32,10],[32,9],[99],[4,64],[32,0],[252,2],[65,7],[32,6],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[33,7],[252,2],[32,7],[32,8],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[34,7],[16, builtin('__Porffor_object_expr_init')],[33,7],[183],[26],[32,10],[68,0,0,0,0,0,0,240,63],[160],[33,10],[12,1],[11],[11],[32,0],[65,7],[15]],
1919
+ params: [124,127,124,127], typedParams: 1,
1920
+ returns: [124,127], typedReturns: 1,
1921
+ locals: [124,127,124,127,124,124,124,124,124,127,127,127], localNames: ["dst","dst#type","src","src#type","#logicinner_tmp","#typeswitch_tmp1","keys","#last_type","vals","len","i","#member_obj","#member_prop","#loadArray_offset","#member_allocd","#swap"],
1922
+ };
1917
1923
  this.__ecma262_NewPromiseReactionJob = {
1918
1924
  wasm: (scope, {builtin}) => [[65,22],[16, builtin('__Porffor_allocateBytes')],[183],[34,4],[33,7],[68,0,0,0,0,0,0,0,0],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,0],[34,5],[57,0,4],[32,6],[65,208,0],[58,0,12],[32,4],[33,7],[68,0,0,0,0,0,0,240,63],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,2],[34,5],[57,0,4],[32,6],[32,3],[58,0,12],[32,4],[65,208,0],[15]],
1919
1925
  params: [124,127,124,127], typedParams: 1,
@@ -1438,11 +1438,25 @@ const getType = (scope, _name) => {
1438
1438
 
1439
1439
  if (Object.hasOwn(builtinVars, name)) return number(builtinVars[name].type ?? TYPES.number, Valtype.i32);
1440
1440
 
1441
- if (typedInput && scope.locals[name]?.metadata?.type != null) return number(scope.locals[name].metadata.type, Valtype.i32);
1442
- if (Object.hasOwn(scope.locals, name)) return [ [ Opcodes.local_get, scope.locals[name + '#type'].idx ] ];
1441
+ if (Object.hasOwn(scope.locals, name)) {
1442
+ if (scope.locals[name]?.metadata?.type != null) return number(scope.locals[name].metadata.type, Valtype.i32);
1443
1443
 
1444
- if (typedInput && globals[name]?.metadata?.type != null) return number(globals[name].metadata.type, Valtype.i32);
1445
- if (Object.hasOwn(globals, name)) return [ [ Opcodes.global_get, globals[name + '#type'].idx ] ];
1444
+ const typeLocal = scope.locals[name + '#type'];
1445
+ if (typeLocal) return [ [ Opcodes.local_get, typeLocal.idx ] ];
1446
+
1447
+ // todo: warn here?
1448
+ return number(TYPES.undefined, Valtype.i32);
1449
+ }
1450
+
1451
+ if (Object.hasOwn(globals, name)) {
1452
+ if (globals[name]?.metadata?.type != null) return number(globals[name].metadata.type, Valtype.i32);
1453
+
1454
+ const typeLocal = globals[name + '#type'];
1455
+ if (typeLocal) return [ [ Opcodes.global_get, typeLocal.idx ] ];
1456
+
1457
+ // todo: warn here?
1458
+ return number(TYPES.undefined, Valtype.i32);
1459
+ }
1446
1460
 
1447
1461
  if (Object.hasOwn(builtinFuncs, name) || Object.hasOwn(importedFuncs, name) ||
1448
1462
  Object.hasOwn(funcIndex, name) || Object.hasOwn(internalConstrs, name))
@@ -1458,17 +1472,31 @@ const setType = (scope, _name, type) => {
1458
1472
 
1459
1473
  const out = typeof type === 'number' ? number(type, Valtype.i32) : type;
1460
1474
 
1461
- if (typedInput && scope.locals[name]?.metadata?.type != null) return [];
1462
- if (Object.hasOwn(scope.locals, name)) return [
1463
- ...out,
1464
- [ Opcodes.local_set, scope.locals[name + '#type'].idx ]
1465
- ];
1475
+ if (Object.hasOwn(scope.locals, name)) {
1476
+ if (scope.locals[name]?.metadata?.type != null) return [];
1466
1477
 
1467
- if (typedInput && globals[name]?.metadata?.type != null) return [];
1468
- if (Object.hasOwn(globals, name)) return [
1469
- ...out,
1470
- [ Opcodes.global_set, globals[name + '#type'].idx ]
1471
- ];
1478
+ const typeLocal = scope.locals[name + '#type'];
1479
+ if (typeLocal) return [
1480
+ ...out,
1481
+ [ Opcodes.local_set, typeLocal.idx ]
1482
+ ];
1483
+
1484
+ // todo: warn here?
1485
+ return [];
1486
+ }
1487
+
1488
+ if (Object.hasOwn(globals, name)) {
1489
+ if (globals[name]?.metadata?.type != null) return [];
1490
+
1491
+ const typeLocal = globals[name + '#type'];
1492
+ if (typeLocal) return [
1493
+ ...out,
1494
+ [ Opcodes.global_set, typeLocal.idx ]
1495
+ ];
1496
+
1497
+ // todo: warn here?
1498
+ return [];
1499
+ }
1472
1500
 
1473
1501
  // throw new Error('could not find var');
1474
1502
  return [];
@@ -3096,7 +3124,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3096
3124
  elements.push(...e.argument.elements);
3097
3125
  } else {
3098
3126
  decls.push(
3099
- ...generateVarDstr(scope, kind, e.argument.name, {
3127
+ ...generateVarDstr(scope, kind, e.argument, {
3100
3128
  type: 'CallExpression',
3101
3129
  callee: {
3102
3130
  type: 'Identifier',
@@ -3202,8 +3230,22 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3202
3230
  }, undefined, global)
3203
3231
  );
3204
3232
  }
3205
- } else { // let { ...foo } = {}
3206
- return todo(scope, 'object rest destructuring is not supported yet')
3233
+ } else if (prop.type === 'RestElement') { // let { ...foo } = {}
3234
+ decls.push(
3235
+ ...generateVarDstr(scope, kind, prop.argument, {
3236
+ type: 'CallExpression',
3237
+ callee: {
3238
+ type: 'Identifier',
3239
+ name: '__Porffor_object_spread'
3240
+ },
3241
+ arguments: [
3242
+ { type: 'ObjectExpression', properties: [] },
3243
+ { type: 'Identifier', name: tmpName }
3244
+ ]
3245
+ }, undefined, global)
3246
+ );
3247
+ } else {
3248
+ return todo(scope, `${prop.type} is not supported in object patterns`);
3207
3249
  }
3208
3250
  }
3209
3251
 
@@ -3979,10 +4021,9 @@ const generateForOf = (scope, decl) => {
3979
4021
 
3980
4022
  // setup local for left
3981
4023
  let setVar;
3982
-
3983
4024
  if (decl.left.type === 'Identifier') {
3984
4025
  // todo: should be sloppy mode only
3985
- setVar = generateVarDstr(scope, 'var', decl.left.name, { type: 'Identifier', name: tmpName }, undefined, true);
4026
+ setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
3986
4027
  } else {
3987
4028
  // todo: verify this is correct
3988
4029
  const global = scope.name === 'main' && decl.left.kind === 'var';
@@ -4347,14 +4388,13 @@ const generateForIn = (scope, decl) => {
4347
4388
  localTmp(scope, tmpName + '#type', Valtype.i32);
4348
4389
 
4349
4390
  let setVar;
4350
-
4351
4391
  if (decl.left.type === 'Identifier') {
4352
4392
  // todo: should be sloppy mode only
4353
- setVar = generateVarDstr(scope, 'var', decl.left.name, { type: 'Identifier', name: tmpName }, undefined, true);
4393
+ setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
4354
4394
  } else {
4355
4395
  // todo: verify this is correct
4356
4396
  const global = scope.name === 'main' && decl.left.kind === 'var';
4357
- setVar = generateVarDstr(scope, 'var', decl.left.declarations[0].id, { type: 'Identifier', name: tmpName }, undefined, global);
4397
+ setVar = generateVarDstr(scope, 'var', decl.left?.declarations?.[0]?.id ?? decl.left, { type: 'Identifier', name: tmpName }, undefined, global);
4358
4398
  }
4359
4399
 
4360
4400
  // set type for local
@@ -5090,12 +5130,33 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5090
5130
  ];
5091
5131
 
5092
5132
  if (decl.properties.length > 0) {
5093
- const tmp = localTmp(scope, `#objectexpr${uniqId()}`, Valtype.i32);
5133
+ const tmpName = `#objectexpr${uniqId()}`;
5134
+ const tmp = localTmp(scope, tmpName, Valtype.i32);
5135
+ addVarMetadata(scope, tmpName, false, { type: TYPES.object });
5136
+
5094
5137
  out.push([ Opcodes.local_tee, tmp ]);
5095
5138
 
5096
5139
  for (const x of decl.properties) {
5097
5140
  // method, shorthand are made into useful values by parser for us :)
5098
- const { computed, kind, key, value } = x;
5141
+ const { type, argument, computed, kind, key, value } = x;
5142
+
5143
+ if (type === 'SpreadElement') {
5144
+ out.push(
5145
+ ...generateCall(scope, {
5146
+ type: 'CallExpression',
5147
+ callee: {
5148
+ type: 'Identifier',
5149
+ name: '__Porffor_object_spread'
5150
+ },
5151
+ arguments: [
5152
+ { type: 'Identifier', name: tmpName },
5153
+ argument
5154
+ ]
5155
+ }),
5156
+ [ Opcodes.drop ]
5157
+ );
5158
+ continue;
5159
+ }
5099
5160
 
5100
5161
  let k = key;
5101
5162
  if (!computed && key.type !== 'Literal') k = {
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.30.0+b1785d63e",
4
+ "version": "0.30.1+616eeaaf5",
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.30.0+b1785d63e';
3
+ globalThis.version = '0.30.1+616eeaaf5';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {