Ok, so going to take a break from the UI and launcher code and instead perform
a refactor and moving around of all the stuff under
For the basic interpreter in the tests during the cleanup, I can have it base
off the kernel so that way I can develop a native interface which normal
programs would use and such. So calling
interpreter-tests would create a
kernel process to launch applications with for example. This way I can still
work on the kernel and the native interfaces without worrying about the UI
layer. Once I get execution of code in place, I can use that to determine how
code should be started and such (the classpath loading and such). So calling
something such as
interpreter-tests would just bypass the launcher
completely and not require it at all. Something I also need is a rename where
I can use regular expressions, so instead of renaming all the classes one by
one manually, I can use sed to do it.
The interpreter will come in a core portion which just has simple logic. Then
there would be extensions and implementations of the core which have the
actual interpreter loops. This way the same code can be shared and plugged in.
Also the verification of classes and such will be given to the
package. Verification only makes sense when entire classes have been loaded
for the most part.
The user of the pure interpreter would be the test kernel, so similar to what I have before except it has no launcher interface.
Going to remove the base NARF exception stuff soon.
Right now a bunch of code has been commented out and such and prefixed with
a TODO. The test kernel would initialize a kernel, and an interpreter while
parsing the command line to determine what to do. Then once the kernel and
interpreter it initialized, it will setup a
ClassPath and then give that to
the kernel to be executed and such. The kernel implementation would then take
it and create a stand-alone interpreter instance which is linked to the kernel.
I could also remove the old console and the IPC UI since due to the changes in the UI code and my future potential changes, they no longer compile properly or even fit with the current code base.
Also going to remove the issue codes from the exceptions which came from the NARF code.
Now that the code compilation and the TODOs are in place, I just have to go back and reimplement those bits using the newly planned route. The test kernel creates a new kernel and setups up the pure interpreter factory and then initializes the interpreter using said factory.
Also the path separator could support multiple characters, just use
for strings for splitting.
The question is, how permissive are the magical kernel calls to be? I could
check the permissions and such in the kernel. However there may be some cases
where inline assembly must be generated and such for something to be performed.
So that the native compiler does not help generate code which contains native
code which could be used for exploitation. Actually, a way to prevent this is
that before assembly is executed, there is a check to see if code is running
in kernel mode (or as the kernel process). So basically before the raw
assembly, there will be a condition and a branch. One thing to consider however
is that assembly code might be needed in cases where the kernel has to do
something. The main library for stuff such as using system calls or getting the
class type of a class would potentially require assembly code. So ideally I can
perform the same thing. If raw assembly is used and a point is a jump target
then the check would be performed again. However, specific access to objects
could be handled by the kernel as a system call anyway. So say for example if
java.lang.Object wants the identity hash code for an object, the assembly
can just create a system call to obtain it. That system call jumps to the
kernel which is permitted to use assembly code. While in the interpreter, there
would be no native assembly so the magical stuff is handled by the interpreter
engine. There would also have to be a means of having a standard raw access
mechanism that can be used by drivers to access block devices for example. I
could also have a mapped region which is simulated as a
byte array for
example. So that would mean for any kind of arrays, there is the reference
which specifies the class type and the array length. However, the actual array
data is elsewhere in memory as another block and the array just points to that
data. So if that data is raw memory, this would provide a safe means for
native processes to access areas of memory. This would also enable the drivers
and such to operate without resorting to
ByteBuffer magic (even though that
has no mapping mechanism anyway).
I also should move the magical code down to a much lower package where it is easier to find, but still reserved in a way.
I actually need to make the JAR class unit public.