Technical Debt

This is all the technical debt that exists within SquirrelJME along with the potential solution to solving it, which generally should be a simple process with the caveat of being a long and drawn out repetitive task.

Any repetitive technical debt could be solved with a script or IntelliJ replace intentions.

Any solved solution will remain here so that issues that come from the past are not repeated.

Error Code Migration

The error codes in the form of "NARG" and "AA01" take up memory to store strings and otherwise in classes, which just causes more static memory usage than is actually needed. NanoCoat uses simplified error codes. The reason these error codes were made is that in the early days of the virtual machine it was very difficult to debug crashes and stack traces with a library that was barely implemented. This effectively acted as a system that could be used to reverse to the exact file and line where an error happened. This though is useful to find issues, however it could be made to be simpler and more efficient in both memory and space.

Potential Ideas

Go through classes and rewrite invokestatic to a special method such as public static int __seq__() to instead be bipush/sipush and sequentially replace this within the class. Each one could be then placed in a CSV for the file and line, along with the nearest description or otherwise. The description could be in a comment or annotation. For comments, this would depend on a SquirrelJME-specific proprietary Javadoc to get comments to lines if they were to be Javadoc tags. Annotations could be associated with the __seq__() call. Naturally, instructions at a given index can get their line determined by the LineNumberTable attribute in the code.

Resultant Solution

TODO

@SquirrelJMEVendorApi and @KeepWhenCompacting Cleanup (Done)

With the ProGuard changes there are cases where @SquirrelJMEVendorApi was added to prevent it from removing a class, which no longer has an effect for private and package-private. For those cases where it is needed, then @KeepWhenCompacting should be used. Otherwise, it should be removed completely.

Additionally, @SquirrelJMEVendorApi should only be used on APIs that are intended to be used by vendors and end-users who want to use specific SquirrelJME features, and not public implementations of specific services or utilities. An example where it would not apply would be an implementation of Connection, it needs a @KeepWhenCompacting so it is not removed for ServiceLoader usage however it can be compacted to reduce space usage. This also applies for cases where there are native callbacks from the MLE layer called to a class, it is appropriate to use @KeepWhenCompacting.

Potential Ideas

Mostly just seeing what works and what does not.

Resultant Solution

The ProGuard rules were redone to effectively never shrink, ProGuard's term for removing classes, and only optimize and obfuscate. This means that there is now never a worry for a class being deleted. What followed was effectively going through ProGuard's set of optimizations, each likely one that would break code would be flipped and SpringCoat Release would be run to ensure that it still runs the launcher and reaches the main list. The mystify and hello demos were also run to ensure that this operated correctly. This took about four days on and off.

Once everything worked, removing the debug code required more optimizations to be flipped, naturally being checked to make sure everything still ran. The check for debugging was also turned into a method as some javac compilers seem to inline static fields and otherwise; or ProGuard seems to just have an easier time overall if a method is called rather than a field being accessed. This removes virtually all debugging output, which results in slightly smaller code sizes.

Note that class and member names are still always unique and that type clashing has been specifically disabled in ProGuard. Although this slightly does reduce the ability to make everything smaller, it does allow for better debugging for release builds along with more sane stack traces. I would rather have that than smaller code. It also is easier to figure out exactly which method is being called as well.

Thus from all of this, @SquirrelJMEVendorApi and @KeepWhenCompacting are no longer needed and thus have been deleted.

There is now @KeepAbsolutelyEverything to force ProGuard to keep everything for a specific class. This is only set at the top of the class level and affects all members so it only needs to be specified once.

For reference, the initial classes to be flagged are as followed for the given reason: