Ok so, basically when it comes to fields and methods I need to figure out and build structures for objects to consist of. Basically I am going to define a bunch of structures that each class uses to refer to fields. Then for static fields I will need pretty much a static area that is stuck into a single section since that is all that is really needed.
One good thing about this static compiler and how I am writing it is that I do not need to handle dynamic sizing and such at least until the linkage stage is performed.
I think my
Dynamics is a bad idea. Basically the dynamics are
part of the generated code in sections rather than being a dynamic as a whole.
I mean combining and merging dynamics will result in probably less memory
usage but with the compiler design that is not really much of an issue. So
Dynamics go away and are just basic parts of sections that do lookups
depending on the situation and have dynamic resolution things as needed when
section bytes really need to be read.
So dynamics based on my comment text would be imports from a set of exports. But those might not really be known. The imports would be the entire thing for the most part. Well basically the dynamics are for caching. Say that a class object is at a given address somewhere special. And this will vary for PIC and not PIC (fixed addresses). So really based on the config the generated instruction in the section will totally differ based on the situation.
However the non-dynamics would be like accesses, but basically they are just conditions. Essentially that say a given class is extendable or similar. I can for the most part check whether things are sane all at once at the end. So this would reduce the checks that cannot be performed at class decoding. This works because I can just do the compilation stuff at first. In most cases the conditions will all pass anyway. This also allows me to defer and simplify the compiler so I do not need to handle complex verification issues until the later stage.
So this new set of classes will be conditions. Basically the conditions will
be like: does
Bar or is
Foo castable to
doing a bunch of this verification at the end allows me to not worry about
preloading classes wasting time and memory when in most cases all classes will
Conditions will get their own package because there will be quite a few dozen of conditions declared.
I think one thing I will do for methods is have an indirect pointer based on
the class type of an object. Basically my previous plan was to have the method
pointers in the objects but that is not needed at all and complications things
a bit. So basically there will be a method table for each class unit which is
then read off as a pointer. So it is like
((uintptr_t)classp + methodoffset)
where that is a function pointer which is executed. This then allows classes
which override methods to just replace those pointer points and such. I
suppose then special
specialinvoke would just use the class table on any
object in a way violating some things but still being somewhat compatible. So
this way of doing method pointer lookups is much simpler. Of course then there
are interfaces which is another thing to figure out. However at least here the
methods for objects are handled. Objects will need a hash code field and the
class pointer field. I also then suppose the
Class instances would be mostly
static for the most part. Well
Class objects need initialization. I mean
basically I do not need to have the method tables exactly at the end of the
class, they can just be part of static class data which is then pointed to by
the class object for reading things. So this static table would have access
flags, the default constructor (if any), and a table of methods that are in
the class in extendable replacement order.
Only way for it to work better would be for the method table to be somewhere
Class instance. This at least can handle relocations and such. Static
method calls on the other hand do not require any method table usage because
they are not bound to objects.
One thing I will need to do is generate array classes and perhaps have it
where you cannot just lookup non-existing array classes if they are never
statically referenced. So if there is no usage of '[[[[I' then
Class.forName() will not find any class. This simplifies things, makes it
still work and does not need it where I need to worry about generating new
classes at run-time. Also another idea I have is have a non-zero NULL for
objects. Although this would differ from integer values it simplifies
handling of objects and determining if they are NULL or not. Basically it
can done where any method calls performed on the object with relation to
the class regardless of which class it is will result in a NPE being thrown
by any method calls without modifying anything about the stack and such. So
basically it just disregards arguments and just throws a NPE. This however
means that monitorenter and monitorexit will need to be actual methods
but I intended this anyway. Naturally the null class will never compare or
is an instance of another class anyway. Also the initial methods for all
classes inlcuding the null class can include special things such as checking
for instances. The only issue would be fields, there would need to be checks
if the object is
null before fields are attempted to be accessed. Also the
null class/object pointer would have to be known or fixed and allowed to
make things work well with them. However the alternative is to instead for
method calls have the NPE check on
this on entry of instance methods and
just treat all methods as being static for the most part. The
always passed anyway. Of course objects that are null cannot get their classes
dereferenced, so no null checks are needed except before method calls. Also
for the NULL class I would need a complete set of methods for the maximum
possible depth. So having a NULL class would complicate things and require
them to be set anyway. So bad idea!
So according to Java SE runtime tests, using
Class.newInstance() in the
- private: FAIL
- package-private: PASS
- protected: PASS
- public: PASS
Now if I put it in another package?
- private: FAIL
- package-private: FAIL
- protected: FAIL
- public: PASS
So when it comes to
newInstance it seems that
protected is the same as
So that is an interesting observation.
new works when it is in another package. And
new at the language level and not the virtual machine level.
Well today I learned, in the same package that protected classes can be
constructed but outside of the package they need to be extended. This is at
least according to the compiler. But at the VM level, you can
new and invoke
protected constructors like they were public. And the classes do not even need
to follow the same hierarchy. So this means with specially crafted classes
protected on a constructor is not enough to protect a class from being
So since you can
protected constructors. This is probably
not something that may have been intended?
Actually I have an idea about what to do with the emulator. I can have a simulated executable environment which is just the flat binary placed somewhere and run in a special enviroment. It would just be MIPS for the most part but just as a flat binary.
I now own Amiga Forever and C64 Forever, so I am going to use these eventually to port SquirrelJME to these two systems. It would be an interesting experiment.
Ok so for methods, there will basically be
UnitMethod which will be
Units. There would also need to be checking for overriding too.
I could split identifier into three, one for classes, fields, and methods. Then make them unique. The only variant would be for methods.