markw65 / prettier-extension-monkeyc

A VSCode extension for Garmin MonkeyC
MIT License
11 stars 1 forks source link

Bug with excludedAnnotations #3

Closed La-S closed 2 years ago

La-S commented 2 years ago

Hi @markw65 ! Thank you for all your help in building this optimizer!

I've been trying to find additional ways to save memory, and stumbled across excludedAnnotations.

I added some excludedAnnotations to my code and then ran your optimizer. The optimized build seems to have completely removed the excluded function, but the call to the function hasn't been removed. eg:

SOURCE CODE

function onKey(evt) {
  parseUpDownKeys(evt); 
}

(:buttonsonly) 
function parseUpDownKeys(evt) {
     blahblahblah
}

OPTIMIZED CODE

function onKey(evt) {
  parseUpDownKeys(evt); 
}

ERROR WITH OPTIMIZED

Undefined symbol "parseUpDownKeys" detected.

markw65 commented 2 years ago

Isn't that the expected behavior? Don't you get the same error with or without the optimizer (I do in my tests) [edit: My mistake, you only get the error if you have type checking enabled, which I always do. The rest of the answer stands]. And even if you don't get an error in the unoptimized case, you'll get a runtime error when onKey tries to call parseUpDownKeys.

If you know that onKey will never be called (or you don't care what happens when it does), exclude that too. If it will be called but may not call parseUpDownKeys (ie if the code you posted is simplified, and the real code will only call parseUpDownKeys for devices that don't have buttonsonly set), then you can avoid the compile time error by adding --Eno-invalid-symbol to your compiler options (vscode setting monkeyC.compilerOptions).

Alternatively you can use a pair of excludeAnnotations to define a constant:

(:buttonsonly)
const BUTTONS_ONLY = false;
(:buttonsandkeys)
const BUTTONS_ONLY = true;

function onKey(evt) {
  if (!BUTTONS_ONLY) {
    parseUpDownKeys(evt);
  }
}

(:buttonsonly) 
function parseUpDownKeys(evt) {
     blahblahblah
}

Without the optimizer, this will work, but has a code size and runtime cost. With the optimizer, the BUTTONS_ONLY constant will be removed, as will the entire if (and when BUTTONS_ONLY is true, the body of the if will also be removed).

markw65 commented 2 years ago

One other solution, is the prettierMonkeyC.ignoredExcludeAnnotations option. By default the optimizer produces one set of optimized code for each combination of excludeAnnotations that it finds (across all the devices you support). You can tell it to ignore particular exclude annotations via this option. So setting it to buttonsonly, would result in it not excluding that code, and just leaving it to the monkeyc compiler to deal with the annotations (setting it to * makes it ignore all excludeAnnotations).

For your particular example, it probably doesn't make any difference. For the code I posted above, you'll obviously get better code by not using ignoredExcludeAnnotations.

La-S commented 2 years ago

Hi @markw65, thank you for responding. That is a very thorough and helpful answer.