2016/09/17

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.