2016/06/22

08:39

The operations will need a list of externals that it accesses.

08:41

What could help is a raw operation map which just has the operation code and the input values passed to it.

08:45

Then I can use interpretations of the raw argument data with a kind of data interpreter.

11:36

I can switch the explicit verification states to use an array where the states are binary searched instead of using a map.

13:56

Perhaps what I can use in the byte code is some kind of pseudo operation definition of sorts. What really is needed though for the operations is just the logic that states how it modifies the stack, if it accesses any local variables, and other things.

13:59

So it would basically be a micro operation that defines what a byte code instruction does. The compiler could actually in a way optimize a program based on the micro operations rather than the whole operations.

14:02

Then stack verification would use the microoperations to determine the input and output state. An interpreter could also be purely based on the more simpler micro operations also.

17:22

I suppose for micro operations, object would be used instead of integer values since that would be a bit more expressive.

17:25

Alternatively instead of micro operations, there are instead micro-executions. If a concrete representitive form is needed then that can always be created from the executions.

18:52

One thing to consider however are conditional operations. I suppose I should have explicit jumps at the end of every operation that points to the instruction that should be jumped to unconditionally. So after the bulk of instructions, there will just be an unconditional jump to the next instruction. This could then be used to build a tree or some other structure used by the compiler to determine how the program flows for potential optimization. Also the micro-executions should make native code generation simpler.

20:20

Something which I can use are co-dependencies in a way. Have it so I can have the binary sort code in another package along with the SquirrelJME JVM specific classes. This way javame-cldc-compact can be kept clear of SquirrelJME specific classes.

20:27

Actually before I do that, I should have a new build system of sorts which uses code that exists in the project directory as a kind of bootstrap of sorts. When it comes to the compiler, I can use -implicit:none so that classes which are co-dependencies do not get class files generated in the output. Then this way I can have source code depend on each other as such yet not require a special algorithm be used to filter out co-dependencies.

20:35

I can also then have a generic build interface that can be given an interface which can be used with a compiler or run-time system. In the event such a system would run on SquirrelJME itself the interface will instead map to a Java compiler which I have written along with an interpreter. Then this way, a build system can be shared inside and outside of SquirrelJME.

20:37

Also, I likely do not need to prefix my packages with squirreljme since this is SquirrelJME.

21:02

Doing a refactor of the source code layout and packages that code exists in. One thing I can do is remove all of the extra before the io and util packages.

22:31

Also, the javame prefix could be removed also.

22:48

I should and must have a base class for SquirrelJME itself, then the PVM JVM can be based on that class. Initialization code and other things could be shared and as such it would be similar to the kernel for the most part.

22:53

Then instead the PVM JVM could use a jit which just uses Java code as its output instead. So I could effectively work on the JIT at the same time as the PVM JVM. The JIT would potentially need the facilities to handle Java byte code translation.

22:56

I would suppose that I will use something similar to GCC's triplets. Except that it would be quadruplets. arch-vendor-os-variant. So some examples:

Although alternatively it could be hardware instead of vendor.

Then there could be a sub-variant of sorts using '_'. This could simplify things a bit.

23:03

However, the architecture would either be generic or support either one or both 32-bit or 64-bit (or any other mode). I could also have a unique name for each individual CPU. Support for specific operating systems, output JITs, variants, and otherwise should be pluggable. So one could say attempt to mix and match impossible scenarios such as:

The operating system is an important level along with the architecture. The architecture could have ABI information but that could be changed by the operating system. So I suppose when it comes to the ABI selection used by the JIT, it can have prepackaged supported ABIs. Then the OS just says that it uses one of the ABIs that are available. This way the architecture and OS interfaces generally would not touch. The architecture API would just handle register access, saving states, resuming states, and some other details such as memory maps potentially. However, some systems may need a slightly different way to manage memory.

23:11

I would also want variants. Say on Linux there could be a X based interface while another could use GTK directly. These would have to be split into multiple projects. However, a basic OS interface could implement the required details. So essentially they will need to be overridden. So I suppose there would need to be a dispatching interface of sorts. There would be the base interace operating systems and variants would use. Then the dispatcher just chooses one with the most score. Since some systems might get complex, the variant support should be split across multiple interfaces. This way filesystem access can be plugged in on top of an existing variant or similar. A variant could also optionally call the variant with the next lower priority. So this way if I just need to change the graphical system I can just switch the class to be used while keeping stuff such as the filesystem.