07:44
I believe for the short register selection that when it comes to char
I will
treat it as int
, this way I can sign extend negative shorter values in
conversion. Otherwise I would need additional flagging to determine if a value
is currently unsigned. However, char
although being unsigned can be cast to
int
simply.
07:51
I will actually need to test boolean
otherwise I will have to grow it to
int
. Right now its only values are 0 and 1. One thing to consider though are
methods that return shorter types, however they will always have to be
integer sized.
07:55
baload
sign extends the boolean to the integer value, so does this mean
that false
is 0
and true
is -1
?
08:04
Using some hex editing, and looking at the javap
output, it just is 1.
08:08
Since JamVM differs, going with zero.
Zero gives me:
--> true
--> -889275714
cafebabe
If I then rewrite this integer call to the boolean
call, I get:
--> true
--> true
00000000
If I change 0xCAFEBABE to 0xCAFEBABF, I get:
--> true
--> true
00000001
So this means that on return in a boolean method, the value either becomes zero
or one, but it only considers the first bit. However the input arguments are
modified. What I should do then is modify it so that boolean
's boxing is with
Integer
instead of Boolean
.
08:19
So this is my program:
public class Foo
{
public static boolean foo(boolean __a)
{
System.err.printf("--> %b%n", __a);
return __a;
}
public static int foo(int __a)
{
System.err.printf("--> %d%n", __a);
return __a;
}
public static char foo(char __a)
{
System.err.printf("--> %d%n", (int)__a);
return __a;
}
public static void main(String... __args)
{
foo(true);
foo('a');
foo(0x12345678);
System.err.printf("%08x%n", foo(0xCAFEBABE));
}
}
I hexedit boolean's foo to print %d instead. So I get initially:
--> 1
--> 97
--> 305419896
--> -889275714
cafebabe
Changing to boolean gives me:
--> 1
--> 97
--> 305419896
--> -889275714
00000000
Changing to char gives me
--> 1
--> 97
--> 305419896
--> -889275714
0000babe
Changing to int gives me
--> 1
--> 97
--> 305419896
--> -889275714
cafebabe
So this means that input values are passed as-is, while return values are
masked to their lower bits. This means that the handling should be on the
caller's side since the callee returns large values. Then since all arguments
are passed unchanged, I really cannot pass anything lower than int
even
though it would save space. The only exception would be if I could detect small
values, but that would add to the complexity.
08:29
The callee could handle that though.
10:13
Going to setup jasmin and store these hacks in the repository. At least this way I can store my findings and not have to painfully hexedit classes.
10:40
Actually, compared to Zero, JamVM is quite incorrect.
10:43
This is the results of my short program on Zero:
boolean 0xCAFEBABE
0
boolean 0xCAFEBABF
1
byte 0xCAFEBABE
-66
byte 0xCAFEBABF
-65
short 0xCAFEBABE
-17730
short 0xCAFEBABF
-17729
char 0xCAFEBABE
47806
char 0xCAFEBABF
47807
int 0xCAFEBABE
-889275714
int 0xCAFEBABF
-889275713
And this is JamVM
boolean 0xCAFEBABE
-889275714
boolean 0xCAFEBABF
-889275713
byte 0xCAFEBABE
-889275714
byte 0xCAFEBABF
-889275713
short 0xCAFEBABE
-889275714
short 0xCAFEBABF
-889275713
char 0xCAFEBABE
-889275714
char 0xCAFEBABF
-889275713
int 0xCAFEBABE
-889275714
int 0xCAFEBABF
-889275713
So as you can see, Zero does return value conversion.
10:46
I actually need to add another value, which is not negative, but ones where the lower bits would indicate a negative. This means 0x7FFFFFFFF.
10:54
So my revised code gives
boo 0xCAFEBABE: 0
boo 0xCAFEBABF: 1
boo 0x7FFFFFFF: 1
boo 0x7FFFFFFE: 0
boo 0x7FFFFF7F: 1
byt 0xCAFEBABE: -66
byt 0xCAFEBABF: -65
byt 0x7FFFFFFF: -1
byt 0x7FFFFFFE: -2
byt 0x7FFFFF7F: 127
sho 0xCAFEBABE: -17730
sho 0xCAFEBABF: -17729
sho 0x7FFFFFFF: -1
sho 0x7FFFFFFE: -2
sho 0x7FFFFF7F: -129
cha 0xCAFEBABE: 47806
cha 0xCAFEBABF: 47807
cha 0x7FFFFFFF: 65535
cha 0x7FFFFFFE: 65534
cha 0x7FFFFF7F: 65407
int 0xCAFEBABE: -889275714
int 0xCAFEBABF: -889275713
int 0x7FFFFFFF: 2147483647
int 0x7FFFFFFE: 2147483646
int 0x7FFFFF7F: 2147483519
Which means return values before they are placed into the return registers or otherwise, are masked and then sign extended if applicable.
21:15
So this just means that return values do not have to use a full integer register which is OK-ish on lower bit systems.
21:22
Invoke can use a marker indicating the new stack base, that is to help the JITs determine which registers do not have to be saved to the stack for a call. Another thing to consider is that the native allocation might need a stack flag if not already done.
21:35
Before a method is invoked, if stack values being popped are cached off each other then they should have their original values copied before the invoke is generated. This way, it is handled by the JIT and values do not point to illegal values.
23:55
I believe for graphics, the simplest choice I could choose is JSR 239 which implements OpenGL ES 1.1. Although very out of date, I am just a single person. Luckily the older SDKs contain the given JAR for it, which means it is testable. The 3.4 SDK only contains 1.0 of the specification, however that should be good enough.