@markw65/monkeyc-optimizer 1.1.60 → 1.1.62

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to the "monkeyc-optimizer" package will be documented in this file.
4
4
 
5
+ ### 1.1.62
6
+
7
+ - Update to [@markw65/prettier-plugin-monkeyc@1.0.58](https://github.com/markw65/prettier-plugin-monkeyc/blob/main/CHANGELOG.md#1058)
8
+ - Fix an indentation issue with interfaces
9
+ - Track uninitialized fields in class initializers (Part of fix for #35)
10
+ - Fix lookups for MemberExpressions with literal objects (Rest of fix for #35)
11
+ - Don't report parameters as missing symbols in interface functions (Fixes #36)
12
+
13
+ ### 1.1.61
14
+
15
+ - Disable more post-build optimizations to allow apps to verify.
16
+ - Add an `allowForbiddenOpts` option to re-enable the optimizations in simulator or device build mode.
17
+
5
18
  ### 1.1.60
6
19
 
7
20
  - Disable the "remove argc" optimization, as it's going to start breaking verification in the app store.
package/build/api.cjs CHANGED
@@ -18,47 +18,47 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var api_exports = {};
20
20
  __export(api_exports, {
21
- checkCompilerVersion: () => import_chunk_X2C4HXXZ.checkCompilerVersion,
22
- collectNamespaces: () => import_chunk_X2C4HXXZ.collectNamespaces,
23
- createDocumentationMap: () => import_chunk_X2C4HXXZ.createDocumentationMap,
24
- diagnostic: () => import_chunk_X2C4HXXZ.diagnostic,
25
- diagnosticHelper: () => import_chunk_X2C4HXXZ.diagnosticHelper,
26
- findNamesInScope: () => import_chunk_X2C4HXXZ.findNamesInScope,
27
- findUsingForNode: () => import_chunk_X2C4HXXZ.findUsingForNode,
28
- formatAst: () => import_chunk_X2C4HXXZ.formatAst,
29
- formatAstLongLines: () => import_chunk_X2C4HXXZ.formatAstLongLines,
30
- formatScopedName: () => import_chunk_X2C4HXXZ.formatScopedName,
31
- getApiFunctionInfo: () => import_chunk_X2C4HXXZ.getApiFunctionInfo,
32
- getApiMapping: () => import_chunk_X2C4HXXZ.getApiMapping,
33
- getSuperClasses: () => import_chunk_X2C4HXXZ.getSuperClasses,
21
+ checkCompilerVersion: () => import_chunk_WVEFLPTH.checkCompilerVersion,
22
+ collectNamespaces: () => import_chunk_WVEFLPTH.collectNamespaces,
23
+ createDocumentationMap: () => import_chunk_WVEFLPTH.createDocumentationMap,
24
+ diagnostic: () => import_chunk_WVEFLPTH.diagnostic,
25
+ diagnosticHelper: () => import_chunk_WVEFLPTH.diagnosticHelper,
26
+ findNamesInScope: () => import_chunk_WVEFLPTH.findNamesInScope,
27
+ findUsingForNode: () => import_chunk_WVEFLPTH.findUsingForNode,
28
+ formatAst: () => import_chunk_WVEFLPTH.formatAst,
29
+ formatAstLongLines: () => import_chunk_WVEFLPTH.formatAstLongLines,
30
+ formatScopedName: () => import_chunk_WVEFLPTH.formatScopedName,
31
+ getApiFunctionInfo: () => import_chunk_WVEFLPTH.getApiFunctionInfo,
32
+ getApiMapping: () => import_chunk_WVEFLPTH.getApiMapping,
33
+ getSuperClasses: () => import_chunk_WVEFLPTH.getSuperClasses,
34
34
  hasProperty: () => import_chunk_MBTLUWXR.hasProperty,
35
- isClassVariable: () => import_chunk_X2C4HXXZ.isClassVariable,
36
- isLocal: () => import_chunk_X2C4HXXZ.isLocal,
37
- isLookupCandidate: () => import_chunk_X2C4HXXZ.isLookupCandidate,
38
- isStateNode: () => import_chunk_X2C4HXXZ.isStateNode,
39
- lookupByFullName: () => import_chunk_X2C4HXXZ.lookupByFullName,
40
- lookupNext: () => import_chunk_X2C4HXXZ.lookupNext,
41
- lookupResultContains: () => import_chunk_X2C4HXXZ.lookupResultContains,
42
- lookupWithType: () => import_chunk_X2C4HXXZ.lookupWithType,
43
- makeToyboxLink: () => import_chunk_X2C4HXXZ.makeToyboxLink,
44
- mapVarDeclsByType: () => import_chunk_X2C4HXXZ.mapVarDeclsByType,
45
- markInvokeClassMethod: () => import_chunk_X2C4HXXZ.markInvokeClassMethod,
46
- parseSdkVersion: () => import_chunk_X2C4HXXZ.parseSdkVersion,
47
- resolveDiagnostics: () => import_chunk_X2C4HXXZ.resolveDiagnostics,
48
- resolveDiagnosticsMap: () => import_chunk_X2C4HXXZ.resolveDiagnosticsMap,
49
- sameLookupResult: () => import_chunk_X2C4HXXZ.sameLookupResult,
35
+ isClassVariable: () => import_chunk_WVEFLPTH.isClassVariable,
36
+ isLocal: () => import_chunk_WVEFLPTH.isLocal,
37
+ isLookupCandidate: () => import_chunk_WVEFLPTH.isLookupCandidate,
38
+ isStateNode: () => import_chunk_WVEFLPTH.isStateNode,
39
+ lookupByFullName: () => import_chunk_WVEFLPTH.lookupByFullName,
40
+ lookupNext: () => import_chunk_WVEFLPTH.lookupNext,
41
+ lookupResultContains: () => import_chunk_WVEFLPTH.lookupResultContains,
42
+ lookupWithType: () => import_chunk_WVEFLPTH.lookupWithType,
43
+ makeToyboxLink: () => import_chunk_WVEFLPTH.makeToyboxLink,
44
+ mapVarDeclsByType: () => import_chunk_WVEFLPTH.mapVarDeclsByType,
45
+ markInvokeClassMethod: () => import_chunk_WVEFLPTH.markInvokeClassMethod,
46
+ parseSdkVersion: () => import_chunk_WVEFLPTH.parseSdkVersion,
47
+ resolveDiagnostics: () => import_chunk_WVEFLPTH.resolveDiagnostics,
48
+ resolveDiagnosticsMap: () => import_chunk_WVEFLPTH.resolveDiagnosticsMap,
49
+ sameLookupResult: () => import_chunk_WVEFLPTH.sameLookupResult,
50
50
  traverseAst: () => import_chunk_MBTLUWXR.traverseAst,
51
- variableDeclarationName: () => import_chunk_X2C4HXXZ.variableDeclarationName,
52
- visitReferences: () => import_chunk_X2C4HXXZ.visitReferences,
53
- visit_resources: () => import_chunk_X2C4HXXZ.visit_resources,
54
- visitorNode: () => import_chunk_X2C4HXXZ.visitorNode
51
+ variableDeclarationName: () => import_chunk_WVEFLPTH.variableDeclarationName,
52
+ visitReferences: () => import_chunk_WVEFLPTH.visitReferences,
53
+ visit_resources: () => import_chunk_WVEFLPTH.visit_resources,
54
+ visitorNode: () => import_chunk_WVEFLPTH.visitorNode
55
55
  });
56
56
  module.exports = __toCommonJS(api_exports);
57
- var import_chunk_X2C4HXXZ = require("./chunk-X2C4HXXZ.cjs");
57
+ var import_chunk_WVEFLPTH = require("./chunk-WVEFLPTH.cjs");
58
58
  var import_chunk_SG7ODKRM = require("./chunk-SG7ODKRM.cjs");
59
59
  var import_chunk_MBTLUWXR = require("./chunk-MBTLUWXR.cjs");
60
60
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
61
- (0, import_chunk_X2C4HXXZ.init_api)();
61
+ (0, import_chunk_WVEFLPTH.init_api)();
62
62
  // Annotate the CommonJS export names for ESM import in node:
63
63
  0 && (module.exports = {
64
64
  checkCompilerVersion,
@@ -26,8 +26,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var chunk_X2C4HXXZ_exports = {};
30
- __export(chunk_X2C4HXXZ_exports, {
29
+ var chunk_WVEFLPTH_exports = {};
30
+ __export(chunk_WVEFLPTH_exports, {
31
31
  EnumTagsConst: () => EnumTagsConst,
32
32
  LastTypeTag: () => LastTypeTag,
33
33
  ObjectLikeTagsConst: () => ObjectLikeTagsConst,
@@ -133,7 +133,7 @@ __export(chunk_X2C4HXXZ_exports, {
133
133
  visitorNode: () => visitorNode,
134
134
  xml_util_exports: () => xml_util_exports
135
135
  });
136
- module.exports = __toCommonJS(chunk_X2C4HXXZ_exports);
136
+ module.exports = __toCommonJS(chunk_WVEFLPTH_exports);
137
137
  var import_chunk_SG7ODKRM = require("./chunk-SG7ODKRM.cjs");
138
138
  var import_chunk_MBTLUWXR = require("./chunk-MBTLUWXR.cjs");
139
139
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
@@ -12477,8 +12477,14 @@ function clearAssocPaths(blockState, decl, v) {
12477
12477
  }
12478
12478
  }
12479
12479
  function cloneTypeState(blockState) {
12480
- const { map: map2, trackedMemberDecls, liveCopyPropEvents, ...rest } = blockState;
12481
- const clone = { map: new Map(map2), ...rest };
12480
+ const { map: map2, inited, trackedMemberDecls, liveCopyPropEvents, ...rest } = blockState;
12481
+ const clone = {
12482
+ map: new Map(map2),
12483
+ ...rest
12484
+ };
12485
+ if (inited) {
12486
+ clone.inited = new Set(inited);
12487
+ }
12482
12488
  clone.map.forEach((value2, key) => {
12483
12489
  if (value2.equivSet) {
12484
12490
  if (key === Array.from(value2.equivSet)[0]) {
@@ -12675,6 +12681,7 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
12675
12681
  tov.curType = result;
12676
12682
  changes = true;
12677
12683
  });
12684
+ to.inited?.forEach((k) => from.inited.has(k) || to.inited?.delete(k));
12678
12685
  return changes;
12679
12686
  }
12680
12687
  function typeStateEntry(value2, key) {
@@ -12788,13 +12795,16 @@ function updateAffected(blockState, objectType, baseDecl, assignedPath, affected
12788
12795
  function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStores, logThisRun) {
12789
12796
  const order = getPostOrder(graph).reverse();
12790
12797
  const queue = new DataflowQueue();
12791
- let selfClassDecl = null;
12792
12798
  const isStatic = !!(func.attributes & 8);
12793
12799
  const klass = func.stack?.[func.stack?.length - 1].sn;
12794
- if (klass && klass.type === "ClassDeclaration") {
12795
- selfClassDecl = klass;
12796
- }
12797
- const isInitialize = selfClassDecl && func.name === "initialize";
12800
+ const selfClassDecl = klass && klass.type === "ClassDeclaration" ? klass : null;
12801
+ const uninitClassDecls = selfClassDecl && func.name === "initialize" && selfClassDecl.decls ? new Set(
12802
+ Object.values(selfClassDecl.decls).filter(
12803
+ (decls) => decls.some(
12804
+ (decl) => decl.type === "VariableDeclarator" && decl.node.kind === "var" && !decl.node.init
12805
+ )
12806
+ ).flat()
12807
+ ) : null;
12798
12808
  order.forEach((block, i) => {
12799
12809
  block.order = i;
12800
12810
  });
@@ -13040,7 +13050,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13040
13050
  }
13041
13051
  return [cur, updateAny];
13042
13052
  }
13043
- function typeConstraint(decls) {
13053
+ function typeConstraint(decls, blockState) {
13044
13054
  return (0, import_chunk_SG7ODKRM.reduce)(
13045
13055
  decls,
13046
13056
  (cur, decl) => {
@@ -13055,7 +13065,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13055
13065
  cur,
13056
13066
  decl.type === "Literal" ? typeFromLiteral(decl) : typeFromTypeStateNode(state, decl, true)
13057
13067
  );
13058
- if (isInitialize && decl.type === "VariableDeclarator" && !decl.node.init && decl.node.kind === "var" && decl.stack[decl.stack.length - 1].sn === selfClassDecl) {
13068
+ if (blockState.inited && !blockState.inited.has(decl) && decl.type === "VariableDeclarator" && !decl.node.init && decl.node.kind === "var" && decl.stack[decl.stack.length - 1].sn === selfClassDecl) {
13059
13069
  cur.type |= 1;
13060
13070
  }
13061
13071
  return cur;
@@ -13112,7 +13122,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13112
13122
  if (Array.isArray(decl) || decl.type !== "MemberDecl" && decl.type !== "Unknown") {
13113
13123
  let tsVal = blockState.map.get(decl);
13114
13124
  if (!tsVal) {
13115
- tsVal = { curType: typeConstraint(decl) };
13125
+ tsVal = { curType: typeConstraint(decl, blockState) };
13116
13126
  blockState.map.set(decl, tsVal);
13117
13127
  }
13118
13128
  return tsVal;
@@ -13592,7 +13602,9 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13592
13602
  }
13593
13603
  (0, import_node_assert3.default)(!tsv.copyPropItem);
13594
13604
  clearRelatedCopyPropEvents(curState, decl, nodeCopyProp);
13595
- curState.map.set(decl, { curType: typeConstraint(decl) });
13605
+ curState.map.set(decl, {
13606
+ curType: typeConstraint(decl, curState)
13607
+ });
13596
13608
  } else if (type.type & (32768 | 512 | 1024) && (calleeEffects == null ? calleeEffects = !callees || !(0, import_chunk_SG7ODKRM.every)(callees, (callee) => callee.info === false) : calleeEffects)) {
13597
13609
  if (type.value != null && type.type & 32768) {
13598
13610
  const odata = getObjectValue(tsv.curType);
@@ -13615,6 +13627,12 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13615
13627
  break;
13616
13628
  }
13617
13629
  case "def": {
13630
+ if (uninitClassDecls?.size) {
13631
+ (0, import_chunk_SG7ODKRM.forEach)(
13632
+ event.decl,
13633
+ (decl) => uninitClassDecls.has(decl) && curState.inited?.add(decl)
13634
+ );
13635
+ }
13618
13636
  const lval = event.node.type === "UpdateExpression" ? event.node.argument : event.node.type === "AssignmentExpression" ? event.node.left : null;
13619
13637
  if (lval) {
13620
13638
  if (nodeCopyProp.size && lval.type === "MemberExpression") {
@@ -13701,7 +13719,9 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13701
13719
  clearAssocPaths(curState, decls, value2);
13702
13720
  }
13703
13721
  (0, import_node_assert3.default)(!value2.copyPropItem);
13704
- curState.map.set(decls, { curType: typeConstraint(decls) });
13722
+ curState.map.set(decls, {
13723
+ curType: typeConstraint(decls, curState)
13724
+ });
13705
13725
  clearRelatedCopyPropEvents(curState, decls, nodeCopyProp);
13706
13726
  }
13707
13727
  });
@@ -13818,6 +13838,8 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
13818
13838
  };
13819
13839
  blockStates[0] = { map: /* @__PURE__ */ new Map(), visits: 0 };
13820
13840
  const head = blockStates[0];
13841
+ if (uninitClassDecls?.size)
13842
+ head.inited = /* @__PURE__ */ new Set();
13821
13843
  func.node.params.forEach((param) => {
13822
13844
  setStateEvent(
13823
13845
  head,
@@ -18063,6 +18085,8 @@ function visitReferences(state, ast, name, defn, callback, includeDefs = false,
18063
18085
  );
18064
18086
  }
18065
18087
  }
18088
+ } else if (state.inType && node.operator === "as") {
18089
+ return ["right"];
18066
18090
  }
18067
18091
  break;
18068
18092
  case "CallExpression":
@@ -18560,6 +18584,20 @@ function lookup(state, decls, node, name, maybeStack, nonlocal, ignoreImports) {
18560
18584
  }
18561
18585
  return [null, null];
18562
18586
  }
18587
+ case "Literal": {
18588
+ const [, type] = (0, import_chunk_MBTLUWXR.getNodeValue)(node);
18589
+ if (type === "Null")
18590
+ break;
18591
+ return [
18592
+ name ?? `${node.value}`,
18593
+ [
18594
+ {
18595
+ parent: null,
18596
+ results: lookupByFullName(state, `Toybox.Lang.${type}`)
18597
+ }
18598
+ ]
18599
+ ];
18600
+ }
18563
18601
  }
18564
18602
  return [false, false];
18565
18603
  }
@@ -19414,6 +19452,7 @@ function getSuperClasses(klass) {
19414
19452
  var init_api = (0, import_chunk_ABYVSU2C.__esm)({
19415
19453
  "src/api.ts"() {
19416
19454
  (0, import_chunk_MBTLUWXR.init_ast)();
19455
+ init_data_flow();
19417
19456
  init_mc_rewrite();
19418
19457
  init_negative_fixups();
19419
19458
  init_optimizer_types();
@@ -19422,8 +19461,6 @@ var init_api = (0, import_chunk_ABYVSU2C.__esm)({
19422
19461
  init_type_flow_util();
19423
19462
  init_types();
19424
19463
  (0, import_chunk_SG7ODKRM.init_util)();
19425
- (0, import_chunk_MBTLUWXR.init_ast)();
19426
- init_data_flow();
19427
19464
  init_visitor();
19428
19465
  }
19429
19466
  });
@@ -22067,7 +22104,7 @@ function localDCE(func, context) {
22067
22104
  switch (bytecode.op) {
22068
22105
  case 19: {
22069
22106
  const liveLocal = dceInfo.locals.has(bytecode.arg);
22070
- if (!liveLocal) {
22107
+ if (!liveLocal && (bytecode.arg || context.config.allowForbiddenOpts)) {
22071
22108
  (0, import_chunk_SG7ODKRM.logger)(
22072
22109
  "dce",
22073
22110
  2,
@@ -22344,17 +22381,22 @@ function minimizeLocals2(func, equivSets, context) {
22344
22381
  locals.forEach((local, key) => {
22345
22382
  if (key.op !== 19)
22346
22383
  return;
22347
- let inUse = 0n;
22348
- local.conflicts.forEach((conflict) => {
22349
- const color = colors.get(conflict);
22350
- if (color != null) {
22351
- inUse |= 1n << BigInt(color);
22384
+ let lowest = context.config.allowForbiddenOpts ? 0 : 1;
22385
+ if (key.arg === 0 && !context.config.allowForbiddenOpts) {
22386
+ lowest = 0;
22387
+ } else {
22388
+ let inUse = 0n;
22389
+ local.conflicts.forEach((conflict) => {
22390
+ const color = colors.get(conflict);
22391
+ if (color != null) {
22392
+ inUse |= 1n << BigInt(color);
22393
+ }
22394
+ });
22395
+ inUse >>= BigInt(lowest);
22396
+ while (inUse & 1n) {
22397
+ lowest++;
22398
+ inUse >>= 1n;
22352
22399
  }
22353
- });
22354
- let lowest = 0;
22355
- while (inUse & 1n) {
22356
- lowest++;
22357
- inUse >>= 1n;
22358
22400
  }
22359
22401
  colors.set(key, lowest);
22360
22402
  if (!merge[lowest]) {
@@ -22403,7 +22445,7 @@ function minimizeLocals2(func, equivSets, context) {
22403
22445
  (0, import_node_assert9.default)(color != null);
22404
22446
  let name = null;
22405
22447
  Array.from(value2.live).some((bc) => {
22406
- if ((bc.op === 18 || bc.op === 19) && bc.range) {
22448
+ if ("range" in bc && bc.range) {
22407
22449
  if (!name) {
22408
22450
  name = bc.range.name;
22409
22451
  } else if (name !== bc.range.name) {
@@ -22420,11 +22462,18 @@ function minimizeLocals2(func, equivSets, context) {
22420
22462
  name = Array.from(name).join("_");
22421
22463
  }
22422
22464
  range = { name, id: context.nextLocalId++ };
22423
- if (key.op === 18) {
22465
+ if (key.op !== 19) {
22424
22466
  range.isParam = true;
22425
22467
  }
22426
22468
  }
22427
- value2.live.forEach((bc) => fixupMap.set(bc, { color, range }));
22469
+ value2.live.forEach((bc) => {
22470
+ if (bc.op === 19 ? bc.arg === 0 : opReadsLocal(bc) === 0) {
22471
+ if (color !== 0) {
22472
+ console.log("oops");
22473
+ }
22474
+ }
22475
+ fixupMap.set(bc, { color, range });
22476
+ });
22428
22477
  });
22429
22478
  func.blocks.forEach((block) => {
22430
22479
  let filter = false;
@@ -22622,7 +22671,12 @@ function mergeSplitRanges(splitRanges) {
22622
22671
  (count, set) => count + (set.has(key) ? 1 : 0),
22623
22672
  0
22624
22673
  );
22625
- (0, import_node_assert9.default)(num === 1);
22674
+ if (num === 0) {
22675
+ (0, import_node_assert9.default)(x.live.size === 0);
22676
+ putvSets.add(/* @__PURE__ */ new Set([key]));
22677
+ } else {
22678
+ (0, import_node_assert9.default)(num === 1);
22679
+ }
22626
22680
  });
22627
22681
  const newRange = /* @__PURE__ */ new Map();
22628
22682
  putvSets.forEach((pvSet) => {
@@ -23123,7 +23177,8 @@ function optimizeFunc(func, context) {
23123
23177
  if (sizeBasedPRE2(func, context))
23124
23178
  continue;
23125
23179
  }
23126
- if (!minimizeLocals2(func, equivSets, context) && !changes) {
23180
+ changes = minimizeLocals2(func, equivSets, context) || changes;
23181
+ if (!changes) {
23127
23182
  return;
23128
23183
  }
23129
23184
  }
@@ -23157,18 +23212,27 @@ function doArrayInits(func, liveInState, context) {
23157
23212
  );
23158
23213
  return changes;
23159
23214
  }
23160
- function simpleOpts(func, _context) {
23215
+ function simpleOpts(func, context) {
23161
23216
  const equalsSym = 8388787;
23162
23217
  const logging3 = (0, import_chunk_SG7ODKRM.wouldLog)("optimize", 5);
23163
23218
  return Array.from(func.blocks.values()).reduce((changes, block) => {
23164
23219
  for (let i = block.bytecodes.length; i--; ) {
23165
23220
  const cur = block.bytecodes[i];
23166
- if (cur.op === 0 || cur.op === 1 && cur.arg === 0) {
23221
+ if (cur.op === 0 || cur.op === 1 && cur.arg === 0 || cur.op === 53 && context.config.removeArgc && context.config.allowForbiddenOpts) {
23167
23222
  block.bytecodes.splice(i, 1);
23168
23223
  changes = true;
23169
23224
  if (logging3) {
23170
23225
  (0, import_chunk_SG7ODKRM.log)(`${func.name}: deleting ${bytecodeToString(cur, null)}`);
23171
23226
  }
23227
+ } else if (cur.op === 74 && context.config.removeArgc && context.config.allowForbiddenOpts) {
23228
+ const arg = cur.arg.incsp;
23229
+ const incsp = cur;
23230
+ incsp.op = 1;
23231
+ incsp.arg = arg;
23232
+ changes = true;
23233
+ if (logging3) {
23234
+ (0, import_chunk_SG7ODKRM.log)(`${func.name}: argcincsp => incsp`);
23235
+ }
23172
23236
  } else if (i && cur.op === 39 && cur.arg === equalsSym) {
23173
23237
  changes = equalSymbolToEq(block, i) || changes;
23174
23238
  } else if (i && cur.op === 10) {
@@ -23714,14 +23778,17 @@ function getLocalsInfo(func) {
23714
23778
  (block) => new Map(liveOutLocals.get(block.offset)),
23715
23779
  (block, bc, locals) => {
23716
23780
  switch (bc.op) {
23781
+ case 70:
23717
23782
  case 18: {
23718
23783
  const range = bc.range;
23719
23784
  if (range) {
23720
- locals.set(bc.arg, {
23785
+ const localNum = opReadsLocal(bc);
23786
+ (0, import_node_assert13.default)(localNum != null);
23787
+ locals.set(localNum, {
23721
23788
  name: range.name,
23722
23789
  id: range.id,
23723
23790
  isParam: range.isParam === true,
23724
- slot: bc.arg
23791
+ slot: localNum
23725
23792
  });
23726
23793
  }
23727
23794
  break;
@@ -24056,8 +24123,9 @@ function markLocals(context) {
24056
24123
  e.push(localInfo.sid);
24057
24124
  }
24058
24125
  });
24059
- if (bc.op === 18 || bc.op === 19) {
24060
- const local = live.get(bc.arg);
24126
+ if (bc.op === 19 || bc.op === 18 || bc.op === 70) {
24127
+ const localNum = bc.op === 70 ? bc.arg.local : bc.arg;
24128
+ const local = live.get(localNum);
24061
24129
  if (local) {
24062
24130
  const range2 = { name: local.name, id: local.range };
24063
24131
  if (local.arg) {
@@ -24311,7 +24379,7 @@ function bytecodeToString(bytecode, symbolTable) {
24311
24379
  arg = offsetToString(bytecode.arg);
24312
24380
  break;
24313
24381
  case 70:
24314
- arg = `${bytecode.range ? `${bytecode.range.name} ${bytecode.arg}${bytecode.range.isParam ? " (param)" : ""}` : bytecode.arg.local} ${symbol(bytecode.arg.var)}`;
24382
+ arg = `${bytecode.range ? `${bytecode.range.name} ${bytecode.arg.local}${bytecode.range.isParam ? " (param)" : ""}` : bytecode.arg.local} ${symbol(bytecode.arg.var)}`;
24315
24383
  break;
24316
24384
  case 69:
24317
24385
  arg = `${symbol(bytecode.arg.module)} ${symbol(bytecode.arg.var)}`;
@@ -24439,8 +24507,12 @@ function findFunctions({
24439
24507
  continue;
24440
24508
  }
24441
24509
  func.set(next2, block);
24442
- if (func.size === 1 && block.bytecodes.length && block.bytecodes[0].op === 53) {
24443
- argc = block.bytecodes[0].arg;
24510
+ if (func.size === 1 && block.bytecodes.length) {
24511
+ if (block.bytecodes[0].op === 53) {
24512
+ argc = block.bytecodes[0].arg;
24513
+ } else if (block.bytecodes[0].op === 74) {
24514
+ argc = block.bytecodes[0].arg.argc;
24515
+ }
24444
24516
  }
24445
24517
  blocks.delete(next2);
24446
24518
  if (block.exsucc != null) {
@@ -29146,7 +29218,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
29146
29218
  const opt_time = await (0, import_chunk_SG7ODKRM.first_modified)(
29147
29219
  Object.values(fnMap).map((v) => v.output)
29148
29220
  );
29149
- if (source_time < opt_time && 1715292882674 < opt_time) {
29221
+ if (source_time < opt_time && 1716742569780 < opt_time) {
29150
29222
  return {
29151
29223
  hasTests,
29152
29224
  diagnostics: prevDiagnostics,
@@ -29185,7 +29257,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
29185
29257
  hasTests: hasTests2,
29186
29258
  diagnostics,
29187
29259
  sdkVersion,
29188
- optimizerVersion: "1.1.60",
29260
+ optimizerVersion: "1.1.62",
29189
29261
  ...Object.fromEntries(
29190
29262
  configOptionsToCheck.map((option) => [option, config[option]])
29191
29263
  )
@@ -29701,6 +29773,9 @@ function optimizePackage(filepath, devKey, output, config) {
29701
29773
  if (!devKey) {
29702
29774
  throw new Error(`Can't sign ${filepath} without a developer key`);
29703
29775
  }
29776
+ if (config?.allowForbiddenOpts) {
29777
+ config = { ...config, allowForbiddenOpts: false };
29778
+ }
29704
29779
  const inBase = path5.basename(filepath, ".iq");
29705
29780
  if (!output) {
29706
29781
  output = path5.join(path5.dirname(filepath), inBase) + ".opt.iq";
@@ -18,28 +18,28 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var optimizer_exports = {};
20
20
  __export(optimizer_exports, {
21
- StateNodeAttributes: () => import_chunk_X2C4HXXZ.StateNodeAttributes,
22
- buildOptimizedProject: () => import_chunk_X2C4HXXZ.buildOptimizedProject,
21
+ StateNodeAttributes: () => import_chunk_WVEFLPTH.StateNodeAttributes,
22
+ buildOptimizedProject: () => import_chunk_WVEFLPTH.buildOptimizedProject,
23
23
  copyRecursiveAsNeeded: () => import_chunk_SG7ODKRM.copyRecursiveAsNeeded,
24
- defaultConfig: () => import_chunk_X2C4HXXZ.defaultConfig,
25
- display: () => import_chunk_X2C4HXXZ.display,
26
- generateOneConfig: () => import_chunk_X2C4HXXZ.generateOneConfig,
27
- generateOptimizedProject: () => import_chunk_X2C4HXXZ.generateOptimizedProject,
28
- getConfig: () => import_chunk_X2C4HXXZ.getConfig,
29
- getProjectAnalysis: () => import_chunk_X2C4HXXZ.getProjectAnalysis,
30
- get_jungle: () => import_chunk_X2C4HXXZ.get_jungle,
31
- isErrorWithLocation: () => import_chunk_X2C4HXXZ.isErrorWithLocation,
32
- launchSimulator: () => import_chunk_X2C4HXXZ.launchSimulator,
33
- manifestProducts: () => import_chunk_X2C4HXXZ.manifestProducts,
34
- mctree: () => import_chunk_X2C4HXXZ.mctree,
35
- simulateProgram: () => import_chunk_X2C4HXXZ.simulateProgram
24
+ defaultConfig: () => import_chunk_WVEFLPTH.defaultConfig,
25
+ display: () => import_chunk_WVEFLPTH.display,
26
+ generateOneConfig: () => import_chunk_WVEFLPTH.generateOneConfig,
27
+ generateOptimizedProject: () => import_chunk_WVEFLPTH.generateOptimizedProject,
28
+ getConfig: () => import_chunk_WVEFLPTH.getConfig,
29
+ getProjectAnalysis: () => import_chunk_WVEFLPTH.getProjectAnalysis,
30
+ get_jungle: () => import_chunk_WVEFLPTH.get_jungle,
31
+ isErrorWithLocation: () => import_chunk_WVEFLPTH.isErrorWithLocation,
32
+ launchSimulator: () => import_chunk_WVEFLPTH.launchSimulator,
33
+ manifestProducts: () => import_chunk_WVEFLPTH.manifestProducts,
34
+ mctree: () => import_chunk_WVEFLPTH.mctree,
35
+ simulateProgram: () => import_chunk_WVEFLPTH.simulateProgram
36
36
  });
37
37
  module.exports = __toCommonJS(optimizer_exports);
38
- var import_chunk_X2C4HXXZ = require("./chunk-X2C4HXXZ.cjs");
38
+ var import_chunk_WVEFLPTH = require("./chunk-WVEFLPTH.cjs");
39
39
  var import_chunk_SG7ODKRM = require("./chunk-SG7ODKRM.cjs");
40
40
  var import_chunk_MBTLUWXR = require("./chunk-MBTLUWXR.cjs");
41
41
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
42
- (0, import_chunk_X2C4HXXZ.init_optimizer)();
42
+ (0, import_chunk_WVEFLPTH.init_optimizer)();
43
43
  // Annotate the CommonJS export names for ESM import in node:
44
44
  0 && (module.exports = {
45
45
  StateNodeAttributes,
@@ -18,25 +18,25 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var sdk_util_exports = {};
20
20
  __export(sdk_util_exports, {
21
- SectionKinds: () => import_chunk_X2C4HXXZ.SectionKinds,
22
- appSupport: () => import_chunk_X2C4HXXZ.appSupport,
23
- connectiq: () => import_chunk_X2C4HXXZ.connectiq,
24
- getDeviceInfo: () => import_chunk_X2C4HXXZ.getDeviceInfo,
25
- getFunctionDocumentation: () => import_chunk_X2C4HXXZ.getFunctionDocumentation,
26
- getLanguages: () => import_chunk_X2C4HXXZ.getLanguages,
27
- getSdkPath: () => import_chunk_X2C4HXXZ.getSdkPath,
28
- isWin: () => import_chunk_X2C4HXXZ.isWin,
29
- optimizeProgram: () => import_chunk_X2C4HXXZ.optimizeProgram,
30
- readPrg: () => import_chunk_X2C4HXXZ.readPrg,
31
- readPrgWithOffsets: () => import_chunk_X2C4HXXZ.readPrgWithOffsets,
32
- xmlUtil: () => import_chunk_X2C4HXXZ.xml_util_exports
21
+ SectionKinds: () => import_chunk_WVEFLPTH.SectionKinds,
22
+ appSupport: () => import_chunk_WVEFLPTH.appSupport,
23
+ connectiq: () => import_chunk_WVEFLPTH.connectiq,
24
+ getDeviceInfo: () => import_chunk_WVEFLPTH.getDeviceInfo,
25
+ getFunctionDocumentation: () => import_chunk_WVEFLPTH.getFunctionDocumentation,
26
+ getLanguages: () => import_chunk_WVEFLPTH.getLanguages,
27
+ getSdkPath: () => import_chunk_WVEFLPTH.getSdkPath,
28
+ isWin: () => import_chunk_WVEFLPTH.isWin,
29
+ optimizeProgram: () => import_chunk_WVEFLPTH.optimizeProgram,
30
+ readPrg: () => import_chunk_WVEFLPTH.readPrg,
31
+ readPrgWithOffsets: () => import_chunk_WVEFLPTH.readPrgWithOffsets,
32
+ xmlUtil: () => import_chunk_WVEFLPTH.xml_util_exports
33
33
  });
34
34
  module.exports = __toCommonJS(sdk_util_exports);
35
- var import_chunk_X2C4HXXZ = require("./chunk-X2C4HXXZ.cjs");
35
+ var import_chunk_WVEFLPTH = require("./chunk-WVEFLPTH.cjs");
36
36
  var import_chunk_SG7ODKRM = require("./chunk-SG7ODKRM.cjs");
37
37
  var import_chunk_MBTLUWXR = require("./chunk-MBTLUWXR.cjs");
38
38
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
39
- (0, import_chunk_X2C4HXXZ.init_sdk_util)();
39
+ (0, import_chunk_WVEFLPTH.init_sdk_util)();
40
40
  // Annotate the CommonJS export names for ESM import in node:
41
41
  0 && (module.exports = {
42
42
  SectionKinds,
@@ -47,6 +47,7 @@ export type BuildConfig = {
47
47
  checkTypes?: DiagnosticType | "OFF";
48
48
  removeArgc?: boolean;
49
49
  postBuildPRE?: boolean;
50
+ allowForbiddenOpts?: boolean;
50
51
  };
51
52
  export type StateNodeDecl = StateNode | mctree.EnumStringMember | mctree.TypedIdentifier;
52
53
  export type StateNodeDecls = {
@@ -21,17 +21,17 @@ __export(worker_thread_exports, {
21
21
  default: () => worker_thread_default
22
22
  });
23
23
  module.exports = __toCommonJS(worker_thread_exports);
24
- var import_chunk_X2C4HXXZ = require("./chunk-X2C4HXXZ.cjs");
24
+ var import_chunk_WVEFLPTH = require("./chunk-WVEFLPTH.cjs");
25
25
  var import_chunk_SG7ODKRM = require("./chunk-SG7ODKRM.cjs");
26
26
  var import_chunk_MBTLUWXR = require("./chunk-MBTLUWXR.cjs");
27
27
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
28
28
  var import_node_worker_threads = require("node:worker_threads");
29
29
  var require_worker_thread = (0, import_chunk_ABYVSU2C.__commonJS)({
30
30
  "src/worker-thread.ts"() {
31
- (0, import_chunk_X2C4HXXZ.init_worker_task)();
31
+ (0, import_chunk_WVEFLPTH.init_worker_task)();
32
32
  if (import_node_worker_threads.parentPort) {
33
33
  import_node_worker_threads.parentPort.on("message", async (task) => {
34
- return import_node_worker_threads.parentPort.postMessage(await (0, import_chunk_X2C4HXXZ.performTask)(task));
34
+ return import_node_worker_threads.parentPort.postMessage(await (0, import_chunk_WVEFLPTH.performTask)(task));
35
35
  });
36
36
  }
37
37
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "commonjs",
4
- "version": "1.1.60",
4
+ "version": "1.1.62",
5
5
  "description": "Source to source optimizer for Garmin Monkey C code",
6
6
  "main": "build/optimizer.cjs",
7
7
  "types": "build/src/optimizer.d.ts",
@@ -25,8 +25,12 @@
25
25
  "test": "npm run test-mocha && npm run test-analysis && npm run test-optimized && npm run test-unopt && npm run test-post-only && npm run test-tiny && npm run test-remote && npm run test-remote-tests && npm run test-personality",
26
26
  "test-mocha": "npx mocha --timeout 999999 build/mocha.cjs",
27
27
  "test-remote": "node ./test/test.js --showInfo --postOptimize --product=pick-one --github",
28
- "test-remote-tests": "node ./test/test.js --showInfo --postOptimize --product=pick-one --run-tests --github",
29
- "test-optimized": "node test/test.js --showInfo --postOptimize --typeCheckLevel Strict --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
28
+ "test-remote-tests-default": "node ./test/test.js --showInfo --postOptimize --product=pick-one --run-tests --github",
29
+ "test-remote-tests-with-forbidden": "npm run test-remote-tests-default -- --allowForbiddenOpts",
30
+ "test-remote-tests": "npm run test-remote-tests-default && npm run test-remote-tests-with-forbidden",
31
+ "test-optimized-default": "node test/test.js --showInfo --postOptimize --typeCheckLevel Strict --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
32
+ "test-optimized-with-forbidden": "npm run test-optimized-default -- --allowForbiddenOpts",
33
+ "test-optimized": "npm run test-optimized-default && npm run test-optimized-with-forbidden",
30
34
  "test-unopt": "node test/test.js --typeCheckLevel Strict --skipOptimization --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
31
35
  "test-post-only": "node test/test.js --showInfo --typeCheckLevel Strict --skipOptimization --postOptimize --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
32
36
  "test-garmin-opt": "node test/test.js --typeCheckLevel Strict --skipOptimization --garminOptLevel=2 --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
@@ -52,7 +56,7 @@
52
56
  "author": "markw65",
53
57
  "license": "MIT",
54
58
  "dependencies": {
55
- "@markw65/prettier-plugin-monkeyc": "^1.0.57"
59
+ "@markw65/prettier-plugin-monkeyc": "^1.0.58"
56
60
  },
57
61
  "devDependencies": {
58
62
  "@markw65/peggy-optimizer": "^1.0.1",