So later today will probably be generation of machine code, which means the FragmentBuilder and the associated classes for output of machine code. At least with the split off expanded handler I can implement that rather simply then later on when I want something optimized I can generate machine code. I can also handle stuff such as software floating point and other virtualized operations if a given CPU does not support certain things. The only thing is then is when it comes to register sizes and such. Some target architectures I plan on supporting, such as the Z80, only have mostly 8-bit registers and a small number of them. I could actually cheat though. The naive translator could always not support anything below 32-bit and have it require registers with a size of at least 32-bits. For 8-bit systems since virtually every operation would be 32-bits in size, there would need to be some kind of optimization to prevent blatant waste of resources. But actually, there could be an 8-bit and 16-bit filter that is used after the given output. I think that would be the best route to be honest. Maybe for the 8-bit/16-bit, instead of it being an expanded thing I can instead just have it be a MachineCodeOutput that can be layered. Basically when the MachineCodeOutput is to be initialized from a config, if the target is a 8-bit or 16-bit system then the native output would be wrapped. Then it would handle virtualizing registers and expanding any needed mathematical operations as required. It would be a bit of a kludge but it could work. At least the 8-bit/16-bit handler would be standalone. Then the native output would not need to handle int/long operations (which would result in failure anyway).


The translators would always pretty much write to MachineCodeOutput anyway, at least mine would. The translators just take the expanded byte code and make operations from them.


However, the low bits filter could be used for every CPU that is below 64-bits since Java does have long. It would pretty much be write once in a way.


I can probably handle default values a bit better if I had a linear process of handling them. Basically if I did not make the JITConfig a Map, I could instead have it where a get of any value will return something specific depending on the internal value or derived values.


And JITConfig is not a Map so that is good.


I am thinking that perhaps I should target x86 first. That is where most of the user base today is on and having extra users could be useful to be honest. Other architectures could follow after that. At least with more users it would be much easier to find issues because there would be a larger pool of users.


I could make SquirrelJME output an object that is linked but that would be a bit messy. One thing about writing a compiler is the various ABIs for variants of systems. For example, I should link with the C library dynamically although I could use a static library. I should probably keep my library footprint to a minimum. One big thing though with native calls is how methods are treated and such. I suppose what I would need is special JIT library glue which matches a target API and provides an interface for execution. Basically something which wraps C level API and is in a way auto-generated so to speak. I would say that this stuff goes into unsafe and is kept hidden. When the wrapper SquirrelJME wishes to do things, it forwards to that. But thinking about it, having everything in a single class is a bit ugly, I can split it up. Basically, I can have the unsafe package have quite a number of classes where internal stuff is specially crafted.


Basically, I have a bunch of outer exposed classes. These then forward their calls to internal classes. So SquirrelJME calls into __SquirrelJME__ after doing some basic checks. However any call to __SquirrelJME__ would then instead call elsewhere, so it would just be rewritten to another class that handles the things. Then that class would instead call other architecture specific code. I could probably have a special naming setup for the class rewriting. Perhaps just __Ext_Foo__ where Foo is a class which can be rewritten.


So anything that is operating specific that cannot internally be handled by SquirrelJME in SquirrelJME is to be removed. This would be like standard output and stuff like getting the current time or killing the VM.


I wonder if I should nuke mailboxes. They do work but I wonder if I should keep them or move them around in a way where they work via the __Ext_ system and where the build system can use the same exact code.


The mailboxes are used by IMC though, so I need those. I will just commonize their code between the build system and SquirrelJME. At least with this, I can make it so that I only need to implement the __Ext_ classes in the build system while they can still be rewritten as such.


Going to use a new checked exception for mailbox failures. This would make things much easier personally.


Ok so now I have common code between the build system and SquirrelJME, which is good, because the nastily duplicated interfaces were a bit ugly.


So now system services can be looked up via properties so they can be overidden if needed.


I believe systemService should not belong in SystemVM? Because that is very much an OS related thing. Maybe instead add an SystemEnvironment which handles that. The VM I want to be very OS independent as it can just be machine code for a target.