I need to fix the simulator so that instead it is a service based interface which provides operating system support based on architectures and such instead of not as concrete sets of data. Get rid of all the providers and just have a SimulationProvider which can create simulations as such.


Today is just rain.


The simulation such as architecture variants can be linked to the JIT for simplicity.


When it comes to simulating a root filesystem, the basic filesystem layout could be described in resources associated with JAR resources. This way when it comes to the binary, no other details have to actually exist. There could be a special filesystem specifier of sorts which describes the files which are available on the root. It would not be a simulation of a whole system, however it should be good enough to allow a basic system to operate properly. So essentially stuff such as /bin/sh for Linux at least would appear a resource which could use an internal special commands to execute a command which should be provided by the system (in the event of system() being called). This would also allow specific programs to be ran on the host without worrying about the host operating system at all. Certain details of the filesystem, such as block devices and character devices, can be implemented by classes. The current user directory could be mounted as a certain directory in the simulated system when applicable. Then this way, I do not have to worry about forwarding calls to the host system (if in the event the code is running on Linux). However, this would essentially permit a specific set of programs to run from any operating system.


Simulation starting details would best be placed into a single object, this way I can add more potentially in the future without requiring massive simulator changes.


I likely do not need EmulatedCPU at all, it could really just fit within SimulationThread which is initialized and emulates a given CPU such as for PowerPC.


However, I really need a single emulation core, otherwise I will end up writing many PowerPC CPU implementations. One thing I could use however is a generic CPU emulation framework. Not part of the simulator but completely different. The simualtor itself could use this emulation layer however. I could also have native emulators available so I can run other operating systems within them, for example Linux. I could use the emulators in a way where I could support specific systems in them. I could also just have a much stronger simulation core also.


However, the emulation sub-system could be used potentially with the actual run-time running as a kind of co-process potentially. Although, I could just have a much simpler simulation system which is not complex at all. I could sacrifice some things such as multiple processes in a way (although I should not do that, since some processes may rely on it).


A problem is that with the CPU manager, I will need to wrap the TLBs and MMUs for some CPUs. This depends on the number of TLBs which are available to a CPU, although ones such as x86 use an address in memory to contain page information. So I suppose what I can do instead is have a high level emulator that can emulate hardware. I will write an actual emulator which could run operating systems and uses BIOSes. When it comes to the simulator, they will just be based on the emulator except that it would provide some high level wrapping.


Actually being a bit higher than userspace would be handy. So I suppose I should go for a high level system emulator. This way I can run Linux itself while I can drop down to lower levels and run Linux programs itself. So I suppose my initial goal should be running a Linux kernel or perhaps even the Mac OS X kernel.


With unsafe there is a way where I can get away with not having any binary stubs and assembly bits.


Well, when it comes to the binary format, the loading of classes, with linking when it comes to fields and methods is system dependent. For example when it comes to ELFs the classes and such can be linked in the binary. Alternatively I can just have a bootstrap which sets up an executable region and then jumps into it. Some systems, say a hypothetical POSIX shell target will not use a binary representation of classes at all. Each class would essentially just be a field and allocated objects would be files on the disk for the most part.


Ok, so having the JIT output to an output stream with some kind of binary writer does not make sense at all for certain targets. These targets would be an interpreter which runs on an existing JVM, and perhaps esoteric targets which do not target binary formats but some other strange format. So basically the output to the JIT would be similar to before except that when it comes to output it might output to a binary format, or it might not. I really should support a kind of JITted interpreter, so that way I can test the JIT and then the class library with minimal effort. Basically the JIT would output a CompatibleExecutable as a kind of interface. However there may be a case where the JIT would want to store the result to the disk (say with AOT) while in other cases it would want it directly in memory ready to be used. So what I propose when it comes to a JIT that it can output a ready to execute format or it can use an OutputStream to a cached form of the data. These forms would be very system specific.


So, I would say it would be best kept to an interface. The interface can then declare if it wants to output a cached form directly, or also a CompatibleExecutable. Basically the handles for all methods would need to handle output to be cached or a compatible executable for direct execution.


This means that the JIT output again becomes non-abstract.


So actually, I suppose that this instead removes JITFactory which then turns into a JITOutputFactory which creates JITOutputs which are associated with a JIT. The output factory is then given an architecture and a variant. When it comes to JIT generation fully handled triplet would be used in the factory. Then the JITOutput created will handle stuff such as writing to binary formats and such. So the factory creation method would then handle cases where output is to a cached form or directly executable form. Then when it comes to actual assembly code generation, there will just be a basic output for an architecture which uses a compatible interface.


Then when it comes to the output factory, the variant could be supported or it might not be. The system specific output handler can see if a given variant and endianess is supported.


When it comes to the word size of the CPU, perhaps instead of powerpc32 it is instead part of the variant, say powerpc-32+g4,big. Then stuff such as x86 would be x86-16+286,little. This way I do not have to have quite a number of variants which target similar things.


Probably something to simplify output would be a state that can be changed accordingly. It can be made immutable when work needs to be performed. So it would essentially be a configuration of sorts.


I would suppose when it comes to an interpreter JVM, that instead of creating a JVM it would just setup a JIT and start executing the JVM as it would in the instance. Any special calls would then just modify the state. This would provide a close execution environment. It would also allow me to design the JVM so that it is closer to how real environments would run.