porffor 0.60.22 → 0.60.23

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.
@@ -1198,6 +1198,22 @@ const nullish = (scope, wasm, type, nonbinary = true, intIn = false) => {
1198
1198
  ];
1199
1199
  };
1200
1200
 
1201
+ const eitherStringType = (leftType, rightType) => [
1202
+ ...leftType,
1203
+ number(TYPE_FLAGS.parity, Valtype.i32),
1204
+ [ Opcodes.i32_or ],
1205
+ number(TYPES.bytestring, Valtype.i32),
1206
+ [ Opcodes.i32_eq ],
1207
+
1208
+ ...rightType,
1209
+ number(TYPE_FLAGS.parity, Valtype.i32),
1210
+ [ Opcodes.i32_or ],
1211
+ number(TYPES.bytestring, Valtype.i32),
1212
+ [ Opcodes.i32_eq ],
1213
+
1214
+ [ Opcodes.i32_or ]
1215
+ ];
1216
+
1201
1217
  const performOp = (scope, op, left, right, leftType, rightType) => {
1202
1218
  if (op === '||' || op === '&&' || op === '??') {
1203
1219
  return performLogicOp(scope, op, left, right, leftType, rightType);
@@ -1294,19 +1310,7 @@ const performOp = (scope, op, left, right, leftType, rightType) => {
1294
1310
 
1295
1311
  ops.unshift(
1296
1312
  // if left or right are string or bytestring
1297
- ...leftType,
1298
- number(TYPE_FLAGS.parity, Valtype.i32),
1299
- [ Opcodes.i32_or ],
1300
- number(TYPES.bytestring, Valtype.i32),
1301
- [ Opcodes.i32_eq ],
1302
-
1303
- ...rightType,
1304
- number(TYPE_FLAGS.parity, Valtype.i32),
1305
- [ Opcodes.i32_or ],
1306
- number(TYPES.bytestring, Valtype.i32),
1307
- [ Opcodes.i32_eq ],
1308
-
1309
- [ Opcodes.i32_or ],
1313
+ ...eitherStringType(leftType, rightType),
1310
1314
  [ Opcodes.if, Blocktype.void ],
1311
1315
  ...concatStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ], leftType, rightType),
1312
1316
  [ Opcodes.br, 1 ],
@@ -1326,19 +1330,7 @@ const performOp = (scope, op, left, right, leftType, rightType) => {
1326
1330
 
1327
1331
  ops.unshift(
1328
1332
  // if left or right are string or bytestring
1329
- ...leftType,
1330
- number(TYPE_FLAGS.parity, Valtype.i32),
1331
- [ Opcodes.i32_or ],
1332
- number(TYPES.bytestring, Valtype.i32),
1333
- [ Opcodes.i32_eq ],
1334
-
1335
- ...rightType,
1336
- number(TYPE_FLAGS.parity, Valtype.i32),
1337
- [ Opcodes.i32_or ],
1338
- number(TYPES.bytestring, Valtype.i32),
1339
- [ Opcodes.i32_eq ],
1340
-
1341
- [ Opcodes.i32_or ],
1333
+ ...eitherStringType(leftType, rightType),
1342
1334
  [ Opcodes.if, Blocktype.void ],
1343
1335
  ...compareStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ], leftType, rightType),
1344
1336
  ...(op === '!==' || op === '!=' ? [ [ Opcodes.i32_eqz ] ] : []),
@@ -1599,11 +1591,11 @@ const generateLogicExp = (scope, decl) =>
1599
1591
  const getInferred = (scope, name, global = false) => {
1600
1592
  const isConst = getVarMetadata(scope, name, global)?.kind === 'const';
1601
1593
  if (global) {
1602
- if (globalInfer.has(name) && (isConst || inferLoopPrev.length === 0)) return globalInfer.get(name);
1594
+ if (name in globalInfer && (isConst || inferLoopPrev.length === 0)) return globalInfer[name];
1603
1595
  } else if (scope.inferTree) {
1604
1596
  for (let i = scope.inferTree.length - 1; i >= 0; i--) {
1605
1597
  const x = scope.inferTree[i];
1606
- if (x._infer?.has(name)) return x._infer.get(name);
1598
+ if (name in x) return x[name];
1607
1599
  }
1608
1600
  }
1609
1601
 
@@ -1612,21 +1604,20 @@ const getInferred = (scope, name, global = false) => {
1612
1604
 
1613
1605
  const setInferred = (scope, name, type, global = false) => {
1614
1606
  const isConst = getVarMetadata(scope, name, global)?.kind === 'const';
1615
- scope.inferTree ??= [];
1607
+ scope.inferTree ??= [ Object.create(null) ];
1616
1608
 
1617
1609
  if (global) {
1618
1610
  // set inferred type in global if not already and not in a loop, else make it null
1619
- globalInfer.set(name, globalInfer.has(name) || (!isConst && inferLoopPrev.length > 0) ? null : type);
1611
+ globalInfer[name] = name in globalInfer || (!isConst && inferLoopPrev.length > 0) ? null : type;
1620
1612
  } else {
1621
1613
  // set inferred type in top
1622
1614
  const top = scope.inferTree.at(-1);
1623
- top._infer ??= new Map();
1624
- top._infer.set(name, type);
1615
+ top[name] = type;
1625
1616
 
1626
1617
  // invalidate inferred type above if mismatched
1627
1618
  for (let i = scope.inferTree.length - 2; i >= 0; i--) {
1628
1619
  const x = scope.inferTree[i];
1629
- if (x._infer && x._infer.get(name) !== type) x._infer.set(name, null);
1620
+ if (name in x && x[name] !== type) x[name] = null;
1630
1621
  }
1631
1622
  }
1632
1623
  };
@@ -2051,31 +2042,6 @@ const generateChain = (scope, decl) => {
2051
2042
  return out;
2052
2043
  };
2053
2044
 
2054
- const ArrayUtil = {
2055
- getLengthI32: pointer => [
2056
- ...pointer,
2057
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ]
2058
- ],
2059
-
2060
- getLength: pointer => [
2061
- ...pointer,
2062
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
2063
- Opcodes.i32_from_u
2064
- ],
2065
-
2066
- setLengthI32: (pointer, value) => [
2067
- ...pointer,
2068
- ...value,
2069
- [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
2070
- ],
2071
-
2072
- setLength: (pointer, value) => [
2073
- ...pointer,
2074
- ...value,
2075
- Opcodes.i32_to_u,
2076
- [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
2077
- ]
2078
- };
2079
2045
 
2080
2046
  const createNewTarget = (scope, decl, idx = 0, force = false) => {
2081
2047
  if (decl._new || force) {
@@ -2824,16 +2790,6 @@ const DEFAULT_VALUE = () => ({
2824
2790
  name: 'undefined'
2825
2791
  });
2826
2792
 
2827
- const codeToSanitizedStr = code => {
2828
- let out = '';
2829
- while (code > 0) {
2830
- out += String.fromCharCode(97 + code % 26);
2831
- code -= 26;
2832
- }
2833
- return out;
2834
- };
2835
- const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
2836
-
2837
2793
  const unhackName = name => {
2838
2794
  if (!name) return name;
2839
2795
 
@@ -3299,8 +3255,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3299
3255
  try {
3300
3256
  let usedNames = [];
3301
3257
  for (const x of pattern.properties) {
3302
- const name = x.key.name;
3303
- usedNames.push(name);
3258
+ usedNames.push(x.key.name);
3304
3259
  }
3305
3260
 
3306
3261
  let path = init.arguments[0].value;
@@ -3327,7 +3282,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3327
3282
 
3328
3283
  // mock ffi function
3329
3284
  asmFunc(name, {
3330
- wasm: [],
3285
+ wasm: () => [],
3331
3286
  params: parameters.map(x => Valtype.i32),
3332
3287
  returns: result ? [ Valtype.i32 ] : [],
3333
3288
  returnType: TYPES.number
@@ -4523,27 +4478,26 @@ const generateUpdate = (scope, decl, _global, _name, valueUnused = false) => {
4523
4478
  ];
4524
4479
  };
4525
4480
 
4526
- const inferBranchStart = (scope, decl) => {
4527
- scope.inferTree ??= [];
4528
- scope.inferTree.push(decl);
4481
+ const inferBranchStart = scope => {
4482
+ scope.inferTree ??= [ Object.create(null) ];
4483
+ scope.inferTree.push(Object.create(null));
4529
4484
  };
4530
4485
 
4531
4486
  const inferBranchEnd = scope => {
4532
4487
  scope.inferTree.pop();
4533
4488
  };
4534
4489
 
4535
- const inferBranchElse = (scope, decl) => {
4490
+ const inferBranchElse = scope => {
4491
+ // todo/opt: at end of else, find inferences in common and keep them?
4536
4492
  inferBranchEnd(scope);
4537
- inferBranchStart(scope, decl);
4493
+ inferBranchStart(scope);
4538
4494
  };
4539
4495
 
4540
4496
  const inferLoopPrev = [];
4541
- const inferLoopStart = (scope, decl) => {
4542
- scope.inferTree ??= [];
4543
-
4497
+ const inferLoopStart = scope => {
4544
4498
  // todo/opt: do not just wipe the infer tree for loops
4545
- inferLoopPrev.push(scope.inferTree);
4546
- scope.inferTree = [ decl ];
4499
+ inferLoopPrev.push(scope.inferTree ?? [ Object.create(null) ]);
4500
+ scope.inferTree = [ Object.create(null) ];
4547
4501
  };
4548
4502
 
4549
4503
  const inferLoopEnd = scope => {
@@ -4562,23 +4516,23 @@ const generateIf = (scope, decl) => {
4562
4516
  const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test));
4563
4517
  out.push([ Opcodes.if, Blocktype.void ]);
4564
4518
  depth.push('if');
4565
- inferBranchStart(scope, decl.consequent);
4519
+ inferBranchStart(scope);
4566
4520
 
4567
4521
  out.push(
4568
4522
  ...generate(scope, decl.consequent),
4569
4523
  [ Opcodes.drop ]
4570
4524
  );
4571
4525
 
4572
- inferBranchEnd(scope);
4526
+
4573
4527
  if (decl.alternate) {
4574
- inferBranchStart(scope, decl.alternate);
4528
+ inferBranchElse(scope);
4575
4529
  out.push(
4576
4530
  [ Opcodes.else ],
4577
4531
  ...generate(scope, decl.alternate),
4578
4532
  [ Opcodes.drop ]
4579
4533
  );
4580
4534
  inferBranchEnd(scope);
4581
- }
4535
+ } else inferBranchEnd(scope);
4582
4536
 
4583
4537
  out.push(
4584
4538
  [ Opcodes.end ],
@@ -4594,7 +4548,7 @@ const generateConditional = (scope, decl) => {
4594
4548
 
4595
4549
  out.push([ Opcodes.if, valtypeBinary ]);
4596
4550
  depth.push('if');
4597
- inferBranchStart(scope, decl.consequent);
4551
+ inferBranchStart(scope);
4598
4552
 
4599
4553
  out.push(
4600
4554
  ...generate(scope, decl.consequent),
@@ -4602,7 +4556,7 @@ const generateConditional = (scope, decl) => {
4602
4556
  );
4603
4557
 
4604
4558
  out.push([ Opcodes.else ]);
4605
- inferBranchElse(scope, decl.alternate);
4559
+ inferBranchElse(scope);
4606
4560
 
4607
4561
  out.push(
4608
4562
  ...generate(scope, decl.alternate),
@@ -4624,7 +4578,7 @@ const generateFor = (scope, decl) => {
4624
4578
  [ Opcodes.drop ]
4625
4579
  );
4626
4580
 
4627
- inferLoopStart(scope, decl);
4581
+ inferLoopStart(scope);
4628
4582
  out.push([ Opcodes.loop, Blocktype.void ]);
4629
4583
  depth.push('for');
4630
4584
 
@@ -4663,7 +4617,7 @@ const generateFor = (scope, decl) => {
4663
4617
 
4664
4618
  const generateWhile = (scope, decl) => {
4665
4619
  const out = [];
4666
- inferLoopStart(scope, decl);
4620
+ inferLoopStart(scope);
4667
4621
 
4668
4622
  out.push([ Opcodes.loop, Blocktype.void ]);
4669
4623
  depth.push('while');
@@ -4691,7 +4645,7 @@ const generateWhile = (scope, decl) => {
4691
4645
 
4692
4646
  const generateDoWhile = (scope, decl) => {
4693
4647
  const out = [];
4694
- inferLoopStart(scope, decl);
4648
+ inferLoopStart(scope);
4695
4649
 
4696
4650
  out.push([ Opcodes.loop, Blocktype.void ]);
4697
4651
 
@@ -4764,7 +4718,7 @@ const generateForOf = (scope, decl) => {
4764
4718
  [ Opcodes.local_set, length ]
4765
4719
  );
4766
4720
 
4767
- inferLoopStart(scope, decl);
4721
+ inferLoopStart(scope);
4768
4722
  depth.push('forof');
4769
4723
  depth.push('block');
4770
4724
 
@@ -5104,7 +5058,7 @@ const generateForIn = (scope, decl) => {
5104
5058
  [ Opcodes.if, Blocktype.void ]
5105
5059
  );
5106
5060
 
5107
- inferLoopStart(scope, decl);
5061
+ inferLoopStart(scope);
5108
5062
  depth.push('if');
5109
5063
  depth.push('forin');
5110
5064
  depth.push('block');
@@ -6829,7 +6783,6 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6829
6783
  async: decl.async,
6830
6784
  subclass: decl._subclass, _onlyConstr: decl._onlyConstr, _onlyThisMethod: decl._onlyThisMethod,
6831
6785
  strict: scope.strict || decl.strict,
6832
- inferTree: [ decl ],
6833
6786
 
6834
6787
  generate() {
6835
6788
  if (func.wasm) return func.wasm;
@@ -7185,8 +7138,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
7185
7138
  const generateBlock = (scope, decl) => {
7186
7139
  let out = [];
7187
7140
 
7188
- scope.inferTree ??= [];
7189
- scope.inferTree.push(decl);
7141
+ inferBranchStart(scope);
7190
7142
 
7191
7143
  let len = decl.body.length, j = 0;
7192
7144
  for (let i = 0; i < len; i++) {
@@ -7197,7 +7149,7 @@ const generateBlock = (scope, decl) => {
7197
7149
  out = out.concat(generate(scope, x));
7198
7150
  }
7199
7151
 
7200
- scope.inferTree.pop();
7152
+ inferBranchEnd(scope);
7201
7153
 
7202
7154
  if (out.length === 0) out.push(number(UNDEFINED));
7203
7155
  return out;
@@ -7403,7 +7355,7 @@ export default program => {
7403
7355
  typeswitchDepth = 0;
7404
7356
  usedTypes = new Set([ TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ]);
7405
7357
  coctc = new Map();
7406
- globalInfer = new Map();
7358
+ globalInfer = Object.create(null);
7407
7359
 
7408
7360
  // set generic opcodes for current valtype
7409
7361
  Opcodes.const = valtypeBinary === Valtype.i32 ? Opcodes.i32_const : Opcodes.f64_const;
@@ -7429,7 +7381,7 @@ export default program => {
7429
7381
  objectHackers = ['assert', 'compareArray', 'Test262Error', ...new Set(Object.keys(builtinFuncs).map(getObjectName).concat(Object.keys(builtinVars).map(getObjectName)).filter(x => x))];
7430
7382
  }
7431
7383
 
7432
- const [ main ] = generateFunc({}, {
7384
+ generateFunc({}, {
7433
7385
  type: 'Program',
7434
7386
  id: { name: '#main' },
7435
7387
  body: {
@@ -7438,9 +7390,6 @@ export default program => {
7438
7390
  }
7439
7391
  });
7440
7392
 
7441
- // if wanted and blank main func and other exports, remove it
7442
- if (Prefs.rmBlankMain && main.wasm.length === 0 && funcs.some(x => x.export)) funcs.splice(main.index - importedFuncs.length, 1);
7443
-
7444
7393
  for (let i = 0; i < funcs.length; i++) {
7445
7394
  const f = funcs[i];
7446
7395
 
package/compiler/parse.js CHANGED
@@ -17,7 +17,7 @@ globalThis.parser = '';
17
17
  let parse;
18
18
  const loadParser = async (fallbackParser = 'acorn', forceParser) => {
19
19
  parser = forceParser ?? Prefs.parser ?? fallbackParser;
20
- const mod = (await import((globalThis.document || globalThis.Deno ? 'https://esm.sh/' : '') + parser));
20
+ const mod = (await import((globalThis.document ? 'https://esm.sh/' : '') + parser));
21
21
  if (mod.parseSync) parse = mod.parseSync;
22
22
  else parse = mod.parse;
23
23
  };
package/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honk/porffor",
3
- "version": "0.60.22",
3
+ "version": "0.60.23",
4
4
  "exports": "./compiler/wrap.js",
5
5
  "publish": {
6
6
  "exclude": [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.60.22",
4
+ "version": "0.60.23",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.60.22';
3
+ globalThis.version = '0.60.23';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
package/foo.js DELETED
@@ -1 +0,0 @@
1
- (typeof console === 'undefined' ? print : console.log)('lol');