07:37
Need to include some more class details.
08:05
When it comes to methods and fields, I should have precomposed descriptors for them so that they do not need to be parsed at the start. However for the C code and simplicity I will do that in C code.
08:08
That is pretty much it, there are just fields and methods. The main work will be going through the byte code. However once that is done I would have to delve into the initialization and then the class library. My first goal would be to write a simple string print.
10:56
I will need to implement virtual dispatching in C. So I would suppose that
I would need a table associated with a VM for a given class. Actually thinking
about it, if I target Java instead of C I would not need to worry about using
extern or having potentially incompatible C and JVM execution. The end result
would be pretty much the same. An issue with Java however would be the lack of
pointers, although that is not really important. If I target Java ME (which I
should) I could have a virtualized environment that could be built on J2ME
devices. One thing though, is still virtual dispatch. Personally being able to
compile to Java and build a J2ME program would be more valuable to me. if I
target older virtual machines, that could form the basis for a kind of
bootstrap project. Then with a compiler, I can run and test SquirrelJME on
much older systems that do not support Java 7. With Java at least, namespaces
can be stored in packages instead of being prefixed to the name. One issue
though would be classes, although they would be static there would just be
direct class references in a global namespace class so to speak. Resources
could be included there also. Since Java ME lacks reflection (apart from
finding classes), this means that all class objects when they are used have to
be initialized (using newInstance()
). A class would have actual methods,
input arguments (as boxed classes). For a given virtual machine, the call stack
and other such things need to be kept for the GC. So I would need an efficient
means of storing this information that tries as much as possible to avoid
allocating Objects. I could have an int tread and an Object tread, when a long,
float, or double are read those can be handled using wrappers and such.
11:09
Since byte code can jump around in some places, I will need a means of jumping to other portions of the code without requiring such things.
11:11
Although in the end it might not matter as much.
14:22
Ok, so this is not going to work. There are targets which do not support the
JIT, so having the JIT code included in them would be rather pointless. Also as
a note, the linkBinary
needs to be given system properties which are final
in the linked binary (cannot be replaced) and are global. These would specify
the class which contains the JIT, the target, and a few other properties (such
as the build date). Builder
needs an option called -jit
which can specify
an alternative class to use for the JIT or specify none
for no JIT. Packages
for an operating system, cannot depend on the JIT. They just get an optional
dependency on a JIT. The jit
gets split into jit
and jit-base
(where
jit
depends on jit-base
. The base project just contains the triplet and a
few other simple things. Then CPU specific targets will be prefixed with
jit-cpu-
. os
will remain the same. Each os
package would have a new
manifest field which specifies the package which contains the JIT. Then the
architecture specific JIT package defines the classes which implement a JIT to
be used. If a JIT is not to be included, then the target binary would not
compile the JIT code.
14:28
Another issue would be native executable output, I want architecture
independent code. So basically, I create a new exe
class which can output for
a given binary type (such as ELF) then include some bootstrap code. Then to
make it where the OS code is lighter, place the bootstrap code in another
package and make it accessible via getResourceAsStream()
on a class in the
package. To reduce duplication everywhere, the ELF linker can be very generic.
Then this way, the extra files which are used in the output do not have to
needlessly be included in the namespace.
15:13
I can also just remove the C based JIT output. Instead I can have a generic JIT serialization which could be used by an interpreter.
15:28
The builder also needs a way to list all of the available systems, variants,
and other such things. Since all stuff is included optionally that can simply
be done by scanning the package list and then calling the JITs and output
supports. So on that note, os-
only contains operating system support. There
may optionally be a JIT bound to the operating system (via jit-base
). Then
for SquirrelJME specific output, there would be builder-os-arch
essentially
(which would be optional dependencies also). Then this way, there would be no
code at all that knows about linking the os-
or the CPU JITs.
15:35
Then the way to invoke the emulator can be used with the builder support also.
15:36
Also, I suppose I will remove the PowerPC and Linux related stuff, none of that code exists yet and will just get in the way for the most part.
17:15
Actually, I do not need to scan the package list because the target builders can just suggest prefixes to try.
18:46
Initially it would be best to not compile any tests so it completes as fast as possible.
18:47
I suppose following getting the projects to build would be getting the
JITOutputFactory
and such. However, at least now with the new builder setup
it can be kept out of the way. So I essentially do not even have to build and
compile the JIT itself. So this means faster generation. For sanity though,
there will have to be an encodable JIT configuration which is used in a
system property of sorts. I would like the actual JITs to have no operating
system specific parts to them (which is easier with the current way of things).
As such, an operating system builder will have to generate a JITOutputConfig
that is to be used.
18:56
This also means that the JIT does not need linkBinary
as that is an artifact
of the builder itself. So this in essence simplifies the JIT and reduces
useless code bloat because that method will only ever be called by the builder.
19:42
This new code is far better than the old code. I just need to get back into the namespace writer. Before it was just output to the cache stream, I could just do that again for the most part.
22:23
For the resource writer, I need to remove the OutputStream
and instead use
another interface which does the same thing. This way JITs can have base
classes for output, which would be reasonable.
22:56
So reaching where I previously was (in the C code) should be quite simple. Also the new classes for writing are much cleaner. At least for the interpreter I do not need to worry about potential forward declaration due to late binding poentially being used. Namespace initialization would likely be in the order of last to first. At least when it comes to the interpreter, the emulator can handle everything. Then once I have enough to print a message, I will make a video and post it.