5 So later today will probably be generation of machine code, which means the
6 `FragmentBuilder` and the associated classes for output of machine code. At
7 least with the split off expanded handler I can implement that rather simply
8 then later on when I want something optimized I can generate machine code.
9 I can also handle stuff such as software floating point and other
10 virtualized operations if a given CPU does not support certain things. The
11 only thing is then is when it comes to register sizes and such. Some target
12 architectures I plan on supporting, such as the Z80, only have mostly
13 8-bit registers and a small number of them. I could actually cheat though.
14 The naive translator could always not support anything below 32-bit and
15 have it require registers with a size of at least 32-bits. For 8-bit systems
16 since virtually every operation would be 32-bits in size, there would need
17 to be some kind of optimization to prevent blatant waste of resources. But
18 actually, there could be an 8-bit and 16-bit filter that is used after the
19 given output. I think that would be the best route to be honest. Maybe for
20 the 8-bit/16-bit, instead of it being an expanded thing I can instead just
21 have it be a `MachineCodeOutput` that can be layered. Basically when the
22 `MachineCodeOutput` is to be initialized from a config, if the target is a
23 8-bit or 16-bit system then the native output would be wrapped. Then it
24 would handle virtualizing registers and expanding any needed mathematical
25 operations as required. It would be a bit of a kludge but it could work. At
26 least the 8-bit/16-bit handler would be standalone. Then the native output
27 would not need to handle `int`/`long` operations (which would result in
32 The translators would always pretty much write to `MachineCodeOutput`
33 anyway, at least mine would. The translators just take the expanded byte code
34 and make operations from them.
38 However, the low bits filter could be used for every CPU that is below 64-bits
39 since Java does have `long`. It would pretty much be write once in a way.
43 I can probably handle default values a bit better if I had a linear process of
44 handling them. Basically if I did not make the `JITConfig` a `Map`, I could
45 instead have it where a get of any value will return something specific
46 depending on the internal value or derived values.
50 And `JITConfig` is not a `Map` so that is good.
54 I am thinking that perhaps I should target x86 first. That is where most of
55 the user base today is on and having extra users could be useful to be honest.
56 Other architectures could follow after that. At least with more users it would
57 be much easier to find issues because there would be a larger pool of users.
61 I could make SquirrelJME output an object that is linked but that would be a
62 bit messy. One thing about writing a compiler is the various ABIs for variants
63 of systems. For example, I should link with the C library dynamically although
64 I could use a static library. I should probably keep my library footprint to
65 a minimum. One big thing though with native calls is how methods are treated
66 and such. I suppose what I would need is special JIT library glue which
67 matches a target API and provides an interface for execution. Basically
68 something which wraps C level API and is in a way auto-generated so to speak.
69 I would say that this stuff goes into unsafe and is kept hidden. When the
70 wrapper `SquirrelJME` wishes to do things, it forwards to that. But thinking
71 about it, having everything in a single class is a bit ugly, I can split it
72 up. Basically, I can have the unsafe package have quite a number of classes
73 where internal stuff is specially crafted.
77 Basically, I have a bunch of outer exposed classes. These then forward their
78 calls to internal classes. So `SquirrelJME` calls into `__SquirrelJME__` after
79 doing some basic checks. However any call to `__SquirrelJME__` would then
80 instead call elsewhere, so it would just be rewritten to another class that
81 handles the things. Then that class would instead call other architecture
82 specific code. I could probably have a special naming setup for the class
83 rewriting. Perhaps just `__Ext_Foo__` where `Foo` is a class which can be
88 So anything that is operating specific that cannot internally be handled by
89 SquirrelJME in `SquirrelJME` is to be removed. This would be like standard
90 output and stuff like getting the current time or killing the VM.
94 I wonder if I should nuke mailboxes. They do work but I wonder if I should
95 keep them or move them around in a way where they work via the `__Ext_` system
96 and where the build system can use the same exact code.
100 The mailboxes are used by IMC though, so I need those. I will just commonize
101 their code between the build system and SquirrelJME. At least with this, I can
102 make it so that I only need to implement the `__Ext_` classes in the build
103 system while they can still be rewritten as such.
107 Going to use a new checked exception for mailbox failures. This would make
108 things much easier personally.
112 Ok so now I have common code between the build system and SquirrelJME, which
113 is good, because the nastily duplicated interfaces were a bit ugly.
117 So now system services can be looked up via properties so they can be
122 I believe `systemService` should not belong in `SystemVM`? Because that is
123 very much an OS related thing. Maybe instead add an `SystemEnvironment` which
124 handles that. The VM I want to be very OS independent as it can just be
125 machine code for a target.