add partial java.nio.ByteBuffer implementation

This commit is contained in:
Zack Buhman 2024-12-31 08:31:05 -06:00
parent 2fe03bf38f
commit ee27558408
13 changed files with 250 additions and 1 deletions

View File

@ -271,7 +271,7 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str
}
}
if (method_name_constant->utf8.length == 6) {
if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"putSQ", 4)) {
if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"putSQ", 5)) {
assert(nargs == 2);
assert(return_type == 'V');
switch (method_name_constant->utf8.bytes[5]) {
@ -282,6 +282,15 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str
return;
}
}
if (method_name_constant->utf8.length == 11) {
if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"isBigEndian", 11)) {
assert(nargs == 0);
assert(return_type == 'Z');
uint32_t value = native_java_misc_memory_isbigendian();
operand_stack_push_u32(vm->current_frame, value);
return;
}
}
}
int java_misc_resource_length = 18;

View File

@ -1,3 +1,5 @@
#include <stdbit.h>
#include "native.h"
#include "printf.h"
@ -123,3 +125,8 @@ uint32_t java_misc_resource_getresource_1(uint32_t * args)
return 0;
#endif
}
uint32_t native_java_misc_memory_isbigendian()
{
return (__STDC_ENDIAN_BIG__ == __STDC_ENDIAN_NATIVE__);
}

View File

@ -15,3 +15,4 @@ void native_java_misc_memory_putSQ1_2(uint32_t * args);
uint32_t native_java_lang_math_sin_1(uint32_t * args);
uint32_t native_java_lang_math_cos_1(uint32_t * args);
uint32_t java_misc_resource_getresource_1(uint32_t * args);
uint32_t native_java_misc_memory_isbigendian();

4
java/lang/Boolean.java Normal file
View File

@ -0,0 +1,4 @@
package java.lang;
class Boolean {
}

4
java/lang/Byte.java Normal file
View File

@ -0,0 +1,4 @@
package java.lang;
class Byte {
}

4
java/lang/Character.java Normal file
View File

@ -0,0 +1,4 @@
package java.lang;
class Character {
}

4
java/lang/Short.java Normal file
View File

@ -0,0 +1,4 @@
package java.lang;
class Short {
}

View File

@ -10,4 +10,9 @@ public class Memory {
public static native int getU1(int address);
public static native void putSQ1(Object object, int address);
public static native boolean isBigEndian();
// .length of the returned byte array must not be accessed
public static native byte[] wrapAddress(int address);
}

38
java/nio/Buffer.java Normal file
View File

@ -0,0 +1,38 @@
package java.nio;
class Buffer {
protected int mark = -1;
protected int position = 0;
protected int limit;
protected final int capacity;
Buffer(int mark, int position, int limit, int capacity) {
this.mark = mark;
this.position = position;
this.limit = limit;
this.capacity = capacity;
}
public final int position() {
return position;
}
public final int limit() {
return limit;
}
public final int capacity() {
return capacity;
}
public Buffer limit(int limit) {
this.limit = limit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
public final boolean hasRemaining() {
return position < limit;
}
}

120
java/nio/ByteBuffer.java Normal file
View File

@ -0,0 +1,120 @@
package java.nio;
public class ByteBuffer extends Buffer {
private int offset;
private boolean bigEndian;
//private boolean sameEndian;
private byte[] array;
private ByteBuffer(byte[] array, int offset, int length) {
super(-1, 0, length, length);
this.array = array;
this.order(ByteOrder.BIG_ENDIAN);
}
public static ByteBuffer wrap(byte[] array) {
return new ByteBuffer(array, 0, array.length);
}
public static ByteBuffer wrap(byte[] array, int offset, int length) {
return new ByteBuffer(array, offset, length);
}
public ByteOrder order() {
return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}
public ByteBuffer order(ByteOrder bo) {
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
//sameEndian = (bo == ByteOrder.nativeOrder());
return this;
}
private static int intBE(int i0, int i1, int i2, int i3) {
return ((i0 << 24)
| (i1 << 16)
| (i2 << 8)
| (i3 << 0));
}
private static int intLE(int i0, int i1, int i2, int i3) {
return ((i0 << 0)
| (i1 << 8)
| (i2 << 16)
| (i3 << 24));
}
private static int shortBE(int i0, int i1) {
return ((i0 << 8)
| (i1 << 0));
}
private static int shortLE(int i0, int i1) {
return ((i0 << 0)
| (i1 << 8));
}
public byte get() {
byte i0 = array[position];
position += 1;
return i0;
}
public byte get(int pos) {
byte i0 = array[pos];
return i0;
}
public short getShort() {
int i0 = array[position + 0];
int i1 = array[position + 1];
position += 2;
if (bigEndian) {
return (short)shortBE(i0, i1);
} else {
return (short)shortLE(i0, i1);
}
}
public short getShort(int pos) {
int i0 = array[pos + 0];
int i1 = array[pos + 1];
if (bigEndian) {
return (short)shortBE(i0, i1);
} else {
return (short)shortLE(i0, i1);
}
}
public int getInt() {
int i0 = array[position + 0];
int i1 = array[position + 1];
int i2 = array[position + 2];
int i3 = array[position + 3];
position += 4;
if (bigEndian) {
return intBE(i0, i1, i2, i3);
} else {
return intLE(i0, i1, i2, i3);
}
}
public int getInt(int pos) {
int i0 = array[pos + 0];
int i1 = array[pos + 1];
int i2 = array[pos + 2];
int i3 = array[pos + 3];
if (bigEndian) {
return intBE(i0, i1, i2, i3);
} else {
return intLE(i0, i1, i2, i3);
}
}
}

15
java/nio/ByteOrder.java Normal file
View File

@ -0,0 +1,15 @@
package java.nio;
import java.misc.Memory;
public class ByteOrder {
public static final ByteOrder BIG_ENDIAN = new ByteOrder();
public static final ByteOrder LITTLE_ENDIAN = new ByteOrder();
private static final ByteOrder NATIVE_ORDER =
Memory.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
public static ByteOrder nativeOrder() {
return NATIVE_ORDER;
}
}

26
p/TestByteBuffer.java Normal file
View File

@ -0,0 +1,26 @@
package p;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
class TestByteBuffer {
public static int test() {
byte[] a = new byte[10];
a[0] = 42;
a[1] = 0x12;
a[2] = 0x34;
a[3] = 0x56;
a[4] = 0x78;
ByteBuffer buf = ByteBuffer.wrap(a).order(ByteOrder.LITTLE_ENDIAN);
buf.get();
int b = buf.getInt();
return b;
}
public static void main() {
test();
}
}

12
p/TestByteOrder.java Normal file
View File

@ -0,0 +1,12 @@
package p;
import java.nio.ByteOrder;
class TestByteOrder {
public static boolean test() {
return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
}
public static void main() {
test();
}
}