Based on the URI specification, the scheme specific part is always the path.
Actually a class path system based on URIs could be complex although rather
java.net.URI has really non-conforming URI layouts and some
of the constructors are very simple and just paste strings together rather
than encoding them as they should.
Actually the JVM could be backed using the standard MEEP interfaces. Instead of
class-path, I just instead have an implementation of the
TaskManager. The base would act as a kind of kernel of
So there would be basically two levels. A JVM would run as the kernel which then manages sub-JVMs running at lower ends.
JVM can be
final. Then it can either be constructor or an
implementation specific factory be used. At least with an implementation
specific factory there can be fallbacks in the event new features are added
to the JVM. If something is missing then there would be a fallback.
So the first thing to do for the ability factory is provide an interface that would be used with the Suite manager to find the launcher JAR. Then once the JAR is located a task should be created and then switched to.
The JVM's suite manager should have only a single implementation managed by the JVM itself. However, due to some of the varying needs that might not exist (such as a filesystem), suites should still be installable by passing the raw JAR bytes for example (after a download or other unpack).
I will need to implement the classes used in the suite manager since they do not exist and I have no templates to base from.
I wonder why
SuiteInstaller and stuff such as
Suite are classes instead
of interfaces. I suppose the intention that despite there being many managers
that there will just be a set few when it comes to suites? Regardless, the
suite managers and such will instead be an artifact that is used in the
user space process and not the kernel. Otherwise when it comes to suite
management the kernel can get confused if it is running a virtual enviroment
on SquirrelJME or another Java ME implementation.
final that means it cannot be used at all. So
SWM is completely client side. However after manually typing out the classes
I have a feel of how it would work.
Task have package private or private constructors that
do not exist in the documentation. JavaDoc really should have included
information if a class can even be constructed at all. I am going to guess that
the constructors are private or package private. The classes that exist are
just stubs which even lack constructors.
And with that the entire MEEP SWM has been implemented. That took about 3 hours or so to complete.
So what I need to do when it comes to the
JVM since SWM is application side
(and not JVM side) is just provide access to the available suites via the
unsafe classes. So the suite code and such will just call into the system
code and such. However the
JVM itself can still use some of the MEEP flags
and states such as the enumerations. So there will essentially just be a JVM
side of the MEEP code that
unsafe bridges to.
Ok so since including all of the verification details and class transformation
would be difficult in the
JVM, perhaps the launcher can perform all the
details. When an application requests to download a JAR from the internet it
can instead forward the request through to the launcher. So basically the
installation system of a JAR is purely handled by the launcher. The JVM would
have a full permissions mode which is used by the launcher. When it comes to
the JVM's set of suites, there will just be a basic install output stream of
sorts. This would assume that the launcher verified all the details and such.
So the JVM's default suite (to replace the class path stuff) will just
contain a simple interface means of accessing built-in suites that are
pre-installed. In the event of native code, these JAR suites would be
completely built into the executable (and not be in other JARs). However in the
case of the JVM based one, it will just treat all JARs in the current
directory as preinstalled. Then with it done this way, this would mean that
native binaries just come alone with precompiled code and suite setups. The
access to preinstalled suites will just basically be
and likely another interface such as an executable class context.
One thing I can do is potential native integration of sorts. Have the SquirrelJME executable. For each installed program a new binary appears. This binary is just a wrapper which then calls SquirrelJME with the program that it represents. The program would just launch and provide an icon for the most part. So for example on Palm OS native applications can be created and placed on the list of applications to quickly switch to JARs which are available. There could still be a single SquirrelJME process running with the VM however.
Well actually the JVM has the native compiler and not the launcher, however when it comes to native execution of code the JVM could recompile any classes that need to be recompiled if they have not be cached or similar.
Due to my goal of supporting very limited systems, perhaps my handling of the
classes is completely wrong. Right now when it comes to compilation I will
basically load everything about the class into memory. Then that gets
natively compiled. If I can make it so a Java class file can be put into an
input stream which is passed to compiler. It performs some basic verifications
that it can perform at the given stage along with basic stack map details and
such. It will basically just fly through the code attribute as is and perform
compilation in a single pass, perhaps without even loading the exception table
and stack map table attribute. Then the code can pass through the micro
operations execution-like system for each operation. Then that would be
output to the JIT which produces native code for a method. Once all of the
native code has been compiled it will then package it in an executable blob
that will be loaded into memory or become part of global blob in an executable.
If the blob route is taken then executables can just be made out of a bunch
of executable blobs with some initialization code (so the
JVM can load).
Having a JIT on systems with as small as 64KiB could potentially be done using
this method. It would also be very fast. The ZIP code requires a sliding
window however, so as long as the classes remain small they should work on
a multitude of systems. So classes need to have not many methods and be within
a given size. I would suppose in the build system I can warn if a class
exceeds a given size (so I can trim it). I would suppose that the lowest of
lower limits I can go for is 4KiB. If a class exceeds that size then it is
way too large. The larger a class, the more difficult it is to handle as the
more memory it consumes.
4KiB might be a little too low, especially if there is debug information in the JARs. However, debugging information is rather useful to have at least for now. So I suppose the current limit I can impose is 12KiB. When writing the JARs for a distribution I can strip the debugging information anyway since SquirrelJME would likely not be capable of line based debugging.
So I need the JIT to be as small and as fast as possible while using the least amount of memory. This would then equal faster than interpretation on limited systems. Due to the lack of reflection and invokedynamic I do need to perform some checks. I would suppose that the code generated in a class should be together as one. At the end of a class chunk there can be symbol information which contains information on any classes which are referenced along with methods. Then with this, blobs can be independent. The only major concern are that symbol references can be quite long. So I suppose a UTF-8 form is used so that characters take up a byte instead of a char in the file. I can have special String handling for UTF-8 strings with non ASCII characters in it. However in the general case this will never be the situation because when it comes to class names and such, there will generally never be characters beyond the basic ASCII range.
Another consideration is that there can be symbolic special names which use
a preset dictionary to refer to classes. There can even be prefixed forms of
these too. So if I limit strings to be 32768 bytes then that means I can use
the upper bit for a string prefix. The
String class can handle these special
prefixed data. I would also have to memory map the class constant data area
also by using
byte which write to actual addresses. Using handles as I
plan to do means I need not worry about it. When it comes to a prefix I can
support 127 of them, then 255 bytes can be used for remaining UTF-8 data.