09:07
For the buffer, I should also have a base and an offset variant also.
10:52
If I follow the model of storing locals as they are set, then I do not need a
boundary for exception handlers, however something that I will need is which
exception block is currently being used. So that if an exception handler is
called then the exception can be handled properly. As planned before the
first instruction on entry of a method will be one which checks whether an
exception was thrown, and if it was then checks are made to see which handler
to use or if the exception should propogate upwards. Doing it this way would
make it mappable to C's setjmp/longjmp. Say C source code is desired to be
generated, then the start of the method would be a setjmp which is given a
value or where an exception is stored elsewhere. That return value would be the
exception block number that was last executed. There would be a global
variable for a given thread which indicates the exception currently being
thrown. If the exception block index is non-zero then the exception is read
along with its class type. Execution is made at the start against comparisons
which check if it matches the given block or if there is no handler for the
given exception. Note that in C, using setjmp/longjmp would be slightly more
complicated since local items would have to be copied to the stack before a
method call or exception throwing. C code would be structured so that basic
blocks are in their own scope. There would be labels at the start of each
basic block. For exception handlers, the initial stack item is initialized an
then the exception is clearaed in the handler and a goto
is performed. When
the set of exception handlers changes, then the exception handler ID will be
updated accordingly. This permits the machine code instead of multiple
comparisons the exception handler ID is just a table which contains an address
relative to some base to jump to. The class type instance comparisons would be
made in those however, and those would require comparisons. However, to
simplify checking of classes, since most code would be static anyway and all
ran programs are JITed or AOTed, then... I was going to say that I could just
check against an index but due to inheritence this cannot be done. So for each
exception an instanceof check has to be performed. So instead for speed the
exception handler table can instead be another table (the ID table would
point to this). That second table would have the expected class type and the
jump target to the handler (since a single instruction can have many handlers),
a simple and cheap "system call" would be made (that does not require stack
manipulation or variable saving) on the class of the exception to potentially
be handled if a given class type is an instance of it. Each class that extends
Throwable would have a special table in it which contains the class IDs of all
the other Throwable
class types which are compatible with the given
exception.
11:14
Note that exception handlers for a given block MUST match the order that
they appear in the Code
attribute in. So basically in pseudo code of sorts
the exception handler at the start of the method looks like this:
global thrownException
non-thrashed-local exceptionBlock
if (exceptionBlock != 0)
{
table exceptions;
switch (exceptionBlock)
{
case 1: exceptions = table1; break;
case 2: exceptions = table2; break;
case 3: exceptions = table3; break;
default: goto propogateException;
}
for (entry e : exceptions)
if (thrownException.isInstance(e.type))
goto e.handler;
label propogateException:
...
}
label normalEntryPoint:
...
label exceptionHandlerA:
...
label exceptionHandlerB:
...
11:27
So the part of any NRProgram
will be the exception double table. This also
means that I will need a volatile variable per thread or a reserved one for
the current exception block and the exception which was thrown. Also, there
will be a need for storing the exception block. So before a method or exception
is thrown by a program, the exception block ID is stored into some value. If
an exception handler throws an exception out of the method by returning then
the exception block ID will have to be stored and then restored.
if (thrownException != null && exceptionBlock == 0)
exceptionBlock = savedExceptionBlock;
if (exceptionBlock != 0)
{
However, in the case of propogation down, this means that after every method call (if I want to keep it simple) would have to check if an exception was thrown (the thrownException global/register is not null) and if it is, jump to the start of the method which contains the exception jumping code. An alternative to this would be if instead there were an exceptional return address used. So say if the exception handler propgates upwards, instead of returning the address of the previous instruction, it is instead returned to the exception handler. However, this can complicate restoring saved local variables and stack entries which are stored on the stack. Doing it that way would also require some variables to be "locked" into position so that a generic restoration of values can be performed. So due to that complexity and the double return address and the need of an extra register (when they might be few), means that after each method invocation, there must be a check for a thrown exception. This check however would be performed after all of the local values are restored however.
11:35
This would be the simplest to implement as a slight cost of code bloat and speed. Note that value restoration is only concerned with registers, so if a local value is stored on the stack and this is a CISC where stack access really does not matter when it comes to using values, then restoration is not really needed as much anyway. So the start of the method will be very important. This then would mean that the exceptionBlock is restored also and the check if an exception was thrown and the block is zero does not have to be done at all, which will save an extra check for those conditions at the start. So there is some tradeoff. So, check for exceptions after going away and performing a method call would be the way to go.
12:44
So the code attribute should have the exception table also. The exceptions should be cached and immutable.
18:54
This revision 1710f107b5bccc6a50ccccdac446995d7f9c6fe8 has quite a number of
c
in it, but I stopped programming in C really.
19:01
I wonder if I can base64 a favicon, appears that I can.
19:11
I figured out what my downscaler would be called, it would be called a weighted color downscale. Basically "heavier" colors will appear more than lower colors. If downscaling for example by 16 times, the color which has the most weight attached to the downscale area would be shown instead.
19:27
I suppose for image reading, thinking about by pixel or by whatever, but likely I would just load plain RGB data.
19:43
I thought Java ME 8 lacked Reader and InputStream reader, but it does have it so handling the XPM image would be easier.
19:46
I suppose for correct XPM read support, I need to implement some part of a C preprocessor.
21:04
XPM parsing likely does not require a very complex C preprocessor to be used.
23:02
For complete speed and potentially reduced memory usage, the code parser might
just complicate things a bit. I would want a mutable NRProgram
but that might
just not be that required. An alternative to this would just to have
NRProgram
which would perform the work of the code parser and such. At least
in the constructor of sorts it can build the required operation tables and
such.