porffor 0.36.5 → 0.36.7

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.
@@ -104,6 +104,9 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
104
104
  case 'ThisExpression':
105
105
  return cacheAst(decl, generateThis(scope, decl));
106
106
 
107
+ case 'Super':
108
+ return cacheAst(decl, generateSuper(scope, decl));
109
+
107
110
  case 'Literal':
108
111
  return cacheAst(decl, generateLiteral(scope, decl, global, name));
109
112
 
@@ -311,7 +314,8 @@ const lookupName = (scope, _name) => {
311
314
  };
312
315
 
313
316
  const internalThrow = (scope, constructor, message, expectsValue = Prefs.alwaysValueInternalThrows) => [
314
- ...generateThrow(scope, {
317
+ ...generate(scope, {
318
+ type: 'ThrowStatement',
315
319
  argument: {
316
320
  type: 'NewExpression',
317
321
  callee: {
@@ -1601,8 +1605,8 @@ const RTArrayUtil = {
1601
1605
  ]
1602
1606
  };
1603
1607
 
1604
- const createNewTarget = (scope, decl, idx = 0) => {
1605
- if (decl._new) {
1608
+ const createNewTarget = (scope, decl, idx = 0, force = false) => {
1609
+ if (decl._new || force) {
1606
1610
  return [
1607
1611
  ...(typeof idx === 'number' ? number(idx) : idx),
1608
1612
  ...number(TYPES.function, Valtype.i32)
@@ -1632,7 +1636,7 @@ const makeObject = (scope, obj) => {
1632
1636
  });
1633
1637
  }
1634
1638
 
1635
- return generateObject(scope, {
1639
+ return generate(scope, {
1636
1640
  type: 'ObjectExpression',
1637
1641
  properties
1638
1642
  });
@@ -1692,13 +1696,48 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
1692
1696
  return knownThis;
1693
1697
  }
1694
1698
 
1699
+ const name = mapName(decl.callee?.name);
1695
1700
  if (decl._new) {
1701
+ // if precompiling or builtin func, just make empty object
1702
+ if (globalThis.precompile || Object.hasOwn(builtinFuncs, name)) return [
1703
+ ...makeObject(scope, {}),
1704
+ ...number(TYPES.object, Valtype.i32)
1705
+ ];
1706
+
1707
+ // create new object with __proto__ set to callee prototype
1708
+ const tmp = localTmp(scope, '#this_create_tmp');
1709
+ const proto = getObjProp(decl.callee, 'prototype');
1710
+ localTmp(scope, '#member_prop_assign');
1711
+
1696
1712
  return [
1697
1713
  ...makeObject(scope, {}),
1714
+ [ Opcodes.local_tee, tmp ],
1715
+ Opcodes.i32_to_u,
1716
+
1717
+ ...number(TYPES.object, Valtype.i32),
1718
+
1719
+ ...generate(scope, {
1720
+ type: 'Literal',
1721
+ value: '__proto__'
1722
+ }, false, '#member_prop_assign'),
1723
+ Opcodes.i32_to_u,
1724
+ ...number(TYPES.bytestring, Valtype.i32),
1725
+
1726
+ ...generate(scope, proto),
1727
+ ...getNodeType(scope, proto),
1728
+
1729
+ // flags: writable
1730
+ ...number(0b1000, Valtype.i32),
1731
+ ...number(TYPES.number, Valtype.i32),
1732
+
1733
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_expr_initWithFlags').index ],
1734
+ [ Opcodes.drop ],
1735
+ [ Opcodes.drop ],
1736
+
1737
+ [ Opcodes.local_get, tmp ],
1698
1738
  ...number(TYPES.object, Valtype.i32)
1699
1739
  ];
1700
1740
  } else {
1701
- const name = mapName(decl.callee?.name);
1702
1741
  if (name && name.startsWith('__') && name.includes('_prototype_')) {
1703
1742
  // todo: this should just be same as decl._new
1704
1743
  // but we do not support prototype, constructor, etc yet
@@ -1714,7 +1753,7 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
1714
1753
  };
1715
1754
 
1716
1755
  return [
1717
- ...generateCall(scope, node),
1756
+ ...generate(scope, node),
1718
1757
  ...getNodeType(scope, node)
1719
1758
  ];
1720
1759
  }
@@ -1733,7 +1772,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1733
1772
 
1734
1773
  // opt: virtualize iifes
1735
1774
  if (isFuncType(decl.callee.type)) {
1736
- const [ func ] = generateFunc(scope, decl.callee, true);
1775
+ const [ func ] = generateFunc(scope, decl.callee);
1737
1776
  name = func.name;
1738
1777
  }
1739
1778
 
@@ -1836,7 +1875,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1836
1875
  const valTmp = localTmp(scope, '#call_val');
1837
1876
  const typeTmp = localTmp(scope, '#call_type', Valtype.i32);
1838
1877
 
1839
- return generateCall(scope, {
1878
+ return generate(scope, {
1840
1879
  type: 'CallExpression',
1841
1880
  callee: target,
1842
1881
  arguments: decl.arguments.slice(1),
@@ -1939,7 +1978,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1939
1978
  const type = TYPES[x.split('_prototype_')[0].slice(2).toLowerCase()];
1940
1979
  if (type == null) continue;
1941
1980
 
1942
- protoBC[type] = generateCall(scope, {
1981
+ protoBC[type] = generate(scope, {
1982
+ type: 'CallExpression',
1943
1983
  callee: {
1944
1984
  type: 'Identifier',
1945
1985
  name: x
@@ -2233,11 +2273,22 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2233
2273
  ];
2234
2274
  }
2235
2275
 
2276
+ let callee = decl.callee, callAsNew = decl._new, overrideThisWasm = decl._thisWasm;
2277
+ if (callee.type === 'Super') {
2278
+ // call super constructor with direct super() call
2279
+ callee = getObjProp(callee, 'constructor');
2280
+ callAsNew = true;
2281
+ overrideThisWasm = [
2282
+ ...generate(scope, { type: 'ThisExpression' }),
2283
+ ...getNodeType(scope, { type: 'ThisExpression' })
2284
+ ];
2285
+ }
2286
+
2236
2287
  const newTargetWasm = decl._newTargetWasm ?? createNewTarget(scope, decl, [
2237
2288
  [ Opcodes.local_get, funcLocal ],
2238
2289
  Opcodes.i32_from_u
2239
- ]);
2240
- const thisWasm = decl._thisWasm ?? createThisArg(scope, decl, knownThis);
2290
+ ], callAsNew);
2291
+ const thisWasm = overrideThisWasm ?? createThisArg(scope, decl, knownThis);
2241
2292
 
2242
2293
  const gen = argc => {
2243
2294
  const argsOut = [];
@@ -2305,11 +2356,11 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2305
2356
  return [
2306
2357
  ...(getCalleeObj ? [
2307
2358
  ...initCalleeObj,
2308
- ...generateMember(scope, decl.callee, false, undefined, getCalleeObj)
2309
- ]: generate(scope, decl.callee)),
2359
+ ...generate(scope, callee, false, undefined, getCalleeObj)
2360
+ ]: generate(scope, callee)),
2310
2361
  [ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
2311
2362
 
2312
- ...typeSwitch(scope, getNodeType(scope, decl.callee), {
2363
+ ...typeSwitch(scope, getNodeType(scope, callee), {
2313
2364
  [TYPES.function]: [
2314
2365
  ...out,
2315
2366
 
@@ -2327,7 +2378,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2327
2378
  [ Opcodes.local_set, flags ],
2328
2379
 
2329
2380
  // check if non-constructor was called with new, if so throw
2330
- ...(decl._new ? [
2381
+ ...(callAsNew ? [
2331
2382
  [ Opcodes.local_get, flags ],
2332
2383
  ...number(0b10, Valtype.i32),
2333
2384
  [ Opcodes.i32_and ],
@@ -2535,6 +2586,9 @@ const generateThis = (scope, decl) => {
2535
2586
  ];
2536
2587
  };
2537
2588
 
2589
+ const generateSuper = (scope, decl) => generate(scope,
2590
+ getObjProp(getObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__'), '__proto__'));
2591
+
2538
2592
  // bad hack for undefined and null working without additional logic
2539
2593
  const DEFAULT_VALUE = () => ({
2540
2594
  type: 'Identifier',
@@ -2676,7 +2730,7 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, allowFallThrough =
2676
2730
  }
2677
2731
 
2678
2732
  if (Prefs.typeswitchBrtable) {
2679
- if (allowFallThrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`)
2733
+ if (allowFallThrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`);
2680
2734
  return brTable(type, bc, returns);
2681
2735
  }
2682
2736
 
@@ -2892,7 +2946,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
2892
2946
  // hack for let a = function () { ... }
2893
2947
  if (!init.id) {
2894
2948
  init.id = { name };
2895
- generateFunc(scope, init, true);
2949
+ generateFunc(scope, init);
2896
2950
  return out;
2897
2951
  }
2898
2952
  }
@@ -3288,68 +3342,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3288
3342
  [ Opcodes.local_get, newValueTmp ]
3289
3343
  ],
3290
3344
 
3291
- [TYPES.object]: [
3292
- ...objectWasm,
3293
- Opcodes.i32_to_u,
3294
- ...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
3295
- ...getNodeType(scope, object),
3296
-
3297
- ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
3298
- ...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3299
- ...(op === '=' ? [] : [
3300
- Opcodes.i32_to_u,
3301
- [ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
3302
- ]),
3303
- ...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3304
-
3305
- ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
3306
- [ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
3307
- ...getNodeType(scope, object),
3308
-
3309
- [ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
3310
- [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
3311
-
3312
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
3313
- ...setLastType(scope)
3314
- ], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
3315
- ...getNodeType(scope, decl),
3316
-
3317
- [ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
3318
- [ Opcodes.drop ],
3319
- // ...setLastType(scope, getNodeType(scope, decl)),
3320
- ],
3321
-
3322
- [TYPES.function]: [
3323
- ...objectWasm,
3324
- Opcodes.i32_to_u,
3325
- ...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
3326
- ...getNodeType(scope, object),
3327
-
3328
- ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
3329
- ...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3330
- ...(op === '=' ? [] : [
3331
- Opcodes.i32_to_u,
3332
- [ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
3333
- ]),
3334
- ...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3335
-
3336
- ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
3337
- [ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
3338
- ...getNodeType(scope, object),
3339
-
3340
- [ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
3341
- [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
3342
-
3343
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
3344
- ...setLastType(scope)
3345
- ], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
3346
- ...getNodeType(scope, decl),
3347
-
3348
- [ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
3349
- [ Opcodes.drop ],
3350
- // ...setLastType(scope, getNodeType(scope, decl)),
3351
- ],
3352
-
3353
3345
  ...wrapBC({
3354
3346
  [TYPES.uint8array]: [
3355
3347
  [ Opcodes.i32_add ],
@@ -3511,12 +3503,33 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3511
3503
  // default: internalThrow(scope, 'TypeError', `Cannot assign member with this type`)
3512
3504
  default: [
3513
3505
  ...objectWasm,
3514
- [ Opcodes.drop ],
3506
+ Opcodes.i32_to_u,
3507
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
3508
+ ...getNodeType(scope, object),
3515
3509
 
3516
- ...propertyWasm,
3517
- [ Opcodes.drop ],
3510
+ ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.left.computed, op === '='),
3511
+ ...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3512
+ ...(op === '=' ? [] : [
3513
+ Opcodes.i32_to_u,
3514
+ [ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
3515
+ ]),
3516
+ ...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3517
+
3518
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
3519
+ [ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
3520
+ ...getNodeType(scope, object),
3518
3521
 
3519
- ...generate(scope, decl.right)
3522
+ [ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
3523
+ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
3524
+
3525
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
3526
+ ...setLastType(scope)
3527
+ ], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
3528
+ ...getNodeType(scope, decl),
3529
+
3530
+ [ Opcodes.call, includeBuiltin(scope, scope.strict ? '__Porffor_object_setStrict' : '__Porffor_object_set').index ],
3531
+ [ Opcodes.drop ],
3532
+ // ...setLastType(scope, getNodeType(scope, decl)),
3520
3533
  ]
3521
3534
  }, valtypeBinary)
3522
3535
  ];
@@ -3584,7 +3597,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3584
3597
 
3585
3598
  const ifIdentifierErrors = (scope, decl) => {
3586
3599
  if (decl.type === 'Identifier') {
3587
- const out = generateIdent(scope, decl);
3600
+ const out = generate(scope, decl);
3588
3601
  if (out[1]) return true;
3589
3602
  }
3590
3603
 
@@ -3661,7 +3674,7 @@ const generateUnary = (scope, decl) => {
3661
3674
  let toReturn = true, toGenerate = true;
3662
3675
 
3663
3676
  if (decl.argument.type === 'Identifier') {
3664
- const out = generateIdent(scope, decl.argument);
3677
+ const out = generate(scope, decl.argument);
3665
3678
 
3666
3679
  // if ReferenceError (undeclared var), ignore and return true. otherwise false
3667
3680
  if (!out[1]) {
@@ -4438,7 +4451,7 @@ const generateSwitch = (scope, decl) => {
4438
4451
  const ret = typeSwitch(scope, getNodeType(scope, decl.discriminant.arguments[0]), () => {
4439
4452
  const ret = [];
4440
4453
  for (const [type, consequent] of cases) {
4441
- const o = generateCode(scope, { body: consequent });
4454
+ const o = generate(scope, { type: 'BlockStatement', body: consequent });
4442
4455
  ret.push([type, o]);
4443
4456
  }
4444
4457
  return ret;
@@ -4481,7 +4494,7 @@ const generateSwitch = (scope, decl) => {
4481
4494
  depth.pop();
4482
4495
  out.push(
4483
4496
  [ Opcodes.end ],
4484
- ...generateCode(scope, { body: cases[i].consequent })
4497
+ ...generate(scope, { type: 'BlockStatement', body: cases[i].consequent })
4485
4498
  );
4486
4499
  }
4487
4500
 
@@ -5083,7 +5096,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5083
5096
 
5084
5097
  if (type === 'SpreadElement') {
5085
5098
  out.push(
5086
- ...generateCall(scope, {
5099
+ ...generate(scope, {
5087
5100
  type: 'CallExpression',
5088
5101
  callee: {
5089
5102
  type: 'Identifier',
@@ -5278,7 +5291,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5278
5291
  const type = TYPES[x.split('_prototype_')[0].slice(2).toLowerCase()];
5279
5292
  if (type == null) continue;
5280
5293
 
5281
- if (type === known) return generateCall(scope, {
5294
+ if (type === known) return generate(scope, {
5295
+ type: 'CallExpression',
5282
5296
  callee: {
5283
5297
  type: 'Identifier',
5284
5298
  name: x
@@ -5287,7 +5301,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5287
5301
  _protoInternalCall: true
5288
5302
  });
5289
5303
 
5290
- bc[type] = generateCall(scope, {
5304
+ bc[type] = generate(scope, {
5305
+ type: 'CallExpression',
5291
5306
  callee: {
5292
5307
  type: 'Identifier',
5293
5308
  name: x
@@ -5322,7 +5337,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5322
5337
  };
5323
5338
 
5324
5339
  bc[type] = [
5325
- ...generateIdent(scope, ident),
5340
+ ...generate(scope, ident),
5326
5341
  ...setLastType(scope, getNodeType(scope, ident))
5327
5342
  ];
5328
5343
  if (type === known) return bc[type];
@@ -5406,28 +5421,6 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5406
5421
  ...setLastType(scope, TYPES.bytestring)
5407
5422
  ],
5408
5423
 
5409
- [TYPES.object]: [
5410
- ...objectWasm,
5411
- Opcodes.i32_to_u,
5412
- ...getNodeType(scope, object),
5413
-
5414
- ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
5415
-
5416
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
5417
- ...setLastType(scope)
5418
- ],
5419
-
5420
- [TYPES.function]: [
5421
- ...objectWasm,
5422
- Opcodes.i32_to_u,
5423
- ...getNodeType(scope, object),
5424
-
5425
- ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
5426
-
5427
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
5428
- ...setLastType(scope)
5429
- ],
5430
-
5431
5424
  ...wrapBC({
5432
5425
  [TYPES.uint8array]: [
5433
5426
  [ Opcodes.i32_add ],
@@ -5510,8 +5503,14 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5510
5503
 
5511
5504
  // default: internalThrow(scope, 'TypeError', 'Unsupported member expression object', true)
5512
5505
  default: [
5513
- ...number(0),
5514
- ...setLastType(scope, TYPES.undefined)
5506
+ ...objectWasm,
5507
+ Opcodes.i32_to_u,
5508
+ ...getNodeType(scope, object),
5509
+
5510
+ ...toPropertyKey(scope, propertyWasm, getNodeType(scope, property), decl.computed, true),
5511
+
5512
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
5513
+ ...setLastType(scope)
5515
5514
  ],
5516
5515
 
5517
5516
  ...extraBC
@@ -5569,7 +5568,7 @@ const generateAwait = (scope, decl) => {
5569
5568
 
5570
5569
  // todo: warn here if -d?
5571
5570
 
5572
- return generateCall(scope, {
5571
+ return generate(scope, {
5573
5572
  type: 'CallExpression',
5574
5573
  callee: {
5575
5574
  type: 'Identifier',
@@ -5603,7 +5602,7 @@ const generateClass = (scope, decl) => {
5603
5602
  optional: false
5604
5603
  };
5605
5604
 
5606
- const constr = {
5605
+ const [ func, out ] = generateFunc(scope, {
5607
5606
  ...(body.find(x => x.kind === 'constructor')?.value ?? {
5608
5607
  type: 'FunctionExpression',
5609
5608
  params: [],
@@ -5612,12 +5611,9 @@ const generateClass = (scope, decl) => {
5612
5611
  body: []
5613
5612
  }
5614
5613
  }),
5615
- id: root
5616
- };
5617
-
5618
- const [ func, out ] = generateFunc(scope, {
5619
- ...constr,
5614
+ id: root,
5620
5615
  _onlyConstr: true,
5616
+ strict: true,
5621
5617
  type: expr ? 'FunctionExpression' : 'FunctionDeclaration'
5622
5618
  });
5623
5619
 
@@ -5645,7 +5641,7 @@ const generateClass = (scope, decl) => {
5645
5641
 
5646
5642
  const k = getProperty(x, true);
5647
5643
 
5648
- let initKind = 'init';
5644
+ let initKind = type === 'MethodDefinition' ? 'method' : 'value';
5649
5645
  if (kind === 'get' || kind === 'set') initKind = kind;
5650
5646
 
5651
5647
  // default value to undefined
@@ -5663,7 +5659,7 @@ const generateClass = (scope, decl) => {
5663
5659
  outScope = func;
5664
5660
  }
5665
5661
 
5666
- if (isFuncType(value.type) && type === 'MethodDefinition') {
5662
+ if (isFuncType(value.type)) {
5667
5663
  let id = value.id;
5668
5664
 
5669
5665
  // todo: support computed names properly
@@ -5675,6 +5671,7 @@ const generateClass = (scope, decl) => {
5675
5671
  value = {
5676
5672
  ...value,
5677
5673
  id,
5674
+ strict: true,
5678
5675
  _onlyThisMethod: true
5679
5676
  };
5680
5677
  }
@@ -5687,10 +5684,10 @@ const generateClass = (scope, decl) => {
5687
5684
  ...toPropertyKey(outScope, generate(outScope, k), getNodeType(outScope, k), computed, true),
5688
5685
 
5689
5686
  ...generate(outScope, value),
5690
- ...(initKind !== 'init' ? [ Opcodes.i32_to_u ] : []),
5687
+ ...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
5691
5688
  ...getNodeType(outScope, value),
5692
5689
 
5693
- [ Opcodes.call, includeBuiltin(outScope, `__Porffor_object_expr_${initKind}`).index ],
5690
+ [ Opcodes.call, includeBuiltin(outScope, `__Porffor_object_class_${initKind}`).index ],
5694
5691
 
5695
5692
  [ Opcodes.drop ],
5696
5693
  [ Opcodes.drop ]
@@ -5807,7 +5804,7 @@ const funcByIndex = idx => {
5807
5804
  };
5808
5805
  const funcByName = name => funcByIndex(funcIndex[name]);
5809
5806
 
5810
- const generateFunc = (scope, decl, outUnused = false) => {
5807
+ const generateFunc = (scope, decl) => {
5811
5808
  const name = decl.id ? decl.id.name : `#anonymous${uniqId()}`;
5812
5809
  if (decl.type.startsWith('Class')) {
5813
5810
  const out = generateClass(scope, {
@@ -5816,6 +5813,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
5816
5813
  });
5817
5814
 
5818
5815
  const func = funcByName(name);
5816
+ astCache.set(decl, out);
5819
5817
  return [ func, out ];
5820
5818
  }
5821
5819
 
@@ -5837,7 +5835,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
5837
5835
  // not async or generator
5838
5836
  !decl.async && !decl.generator,
5839
5837
  _onlyConstr: decl._onlyConstr, _onlyThisMethod: decl._onlyThisMethod,
5840
- strict: scope.strict,
5838
+ strict: scope.strict || decl.strict,
5841
5839
 
5842
5840
  generate() {
5843
5841
  if (func.wasm) return func.wasm;
@@ -5893,21 +5891,6 @@ const generateFunc = (scope, decl, outUnused = false) => {
5893
5891
  // todo: wrap in try and reject thrown value once supported
5894
5892
  }
5895
5893
 
5896
- if (!globalThis.precompile && func.constr && !func._onlyThisMethod) {
5897
- wasm.unshift(
5898
- // opt: do not check for pure constructors
5899
- ...(func._onlyConstr ? [] : [
5900
- // if being constructed
5901
- [ Opcodes.local_get, func.locals['#newtarget'].idx ],
5902
- Opcodes.i32_to_u,
5903
- [ Opcodes.if, Blocktype.void ],
5904
- ]),
5905
- // set prototype of this ;)
5906
- ...generate(func, setObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__', getObjProp(func.name, 'prototype'))),
5907
- ...(func._onlyConstr ? [] : [ [ Opcodes.end ] ])
5908
- );
5909
- }
5910
-
5911
5894
  if (name === 'main') {
5912
5895
  func.gotLastType = true;
5913
5896
  func.export = true;
@@ -6063,7 +6046,8 @@ const generateFunc = (scope, decl, outUnused = false) => {
6063
6046
  // force generate all for precompile
6064
6047
  if (globalThis.precompile) func.generate();
6065
6048
 
6066
- const out = decl.type.endsWith('Expression') && !outUnused ? funcRef(func) : [];
6049
+ const out = decl.type.endsWith('Expression') ? funcRef(func) : [];
6050
+ astCache.set(decl, out);
6067
6051
  return [ func, out ];
6068
6052
  };
6069
6053
 
@@ -62,6 +62,8 @@ const compile = async (file, _funcs) => {
62
62
  __Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
63
63
  __Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
64
64
  __Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
65
+ __Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
66
+ __Porffor_object_class_method: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
65
67
  __Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
66
68
  };
67
69
 
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.36.5+1b34b2d12",
4
+ "version": "0.36.7+e872827a7",
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.36.5+1b34b2d12';
3
+ globalThis.version = '0.36.7+e872827a7';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {