CLDC 8: add ByteBuffer
This commit is contained in:
parent
5fd397563e
commit
8974ea0654
88
c/native.c
88
c/native.c
@ -23,6 +23,7 @@ struct native_method {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const static struct native_method native_method[] = {
|
const static struct native_method native_method[] = {
|
||||||
|
// Math
|
||||||
{
|
{
|
||||||
.class_name = "java/lang/Math",
|
.class_name = "java/lang/Math",
|
||||||
.method_name = "sin",
|
.method_name = "sin",
|
||||||
@ -41,54 +42,92 @@ const static struct native_method native_method[] = {
|
|||||||
.method_descriptor = "(F)F",
|
.method_descriptor = "(F)F",
|
||||||
.func = native_java_lang_math_abs_1,
|
.func = native_java_lang_math_abs_1,
|
||||||
},
|
},
|
||||||
|
// Memory
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "putU4",
|
.method_name = "putU4",
|
||||||
.method_descriptor = "(II)V",
|
.method_descriptor = "(II)V",
|
||||||
.func = native_java_misc_memory_putU4_2,
|
.func = native_jvm_internal_memory_putU4_2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "putU2",
|
.method_name = "putU2",
|
||||||
.method_descriptor = "(II)V",
|
.method_descriptor = "(IS)V",
|
||||||
.func = native_java_misc_memory_putU2_2,
|
.func = native_jvm_internal_memory_putU2_2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "putU1",
|
.method_name = "putU1",
|
||||||
.method_descriptor = "(II)V",
|
.method_descriptor = "(IB)V",
|
||||||
.func = native_java_misc_memory_putU1_2,
|
.func = native_jvm_internal_memory_putU1_2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "getU4",
|
.method_name = "getU4",
|
||||||
.method_descriptor = "(I)I",
|
.method_descriptor = "(I)I",
|
||||||
.func = native_java_misc_memory_getU4_1,
|
.func = native_jvm_internal_memory_getU4_1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "getU2",
|
.method_name = "getU2",
|
||||||
.method_descriptor = "(I)I",
|
.method_descriptor = "(I)S",
|
||||||
.func = native_java_misc_memory_getU2_1,
|
.func = native_jvm_internal_memory_getU2_1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "getU1",
|
.method_name = "getU1",
|
||||||
.method_descriptor = "(I)I",
|
.method_descriptor = "(I)B",
|
||||||
.func = native_java_misc_memory_getU1_1,
|
.func = native_jvm_internal_memory_getU1_1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "putSQ1",
|
.method_name = "putU4",
|
||||||
.method_descriptor = "(Ljava/lang/Object;I)V",
|
.method_descriptor = "(IIZ)V",
|
||||||
.func = native_java_misc_memory_putSQ1_2,
|
.func = native_jvm_internal_memory_putUnalignedU4_3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.class_name = "java/misc/Memory",
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "putU2",
|
||||||
|
.method_descriptor = "(ISZ)V",
|
||||||
|
.func = native_jvm_internal_memory_putUnalignedU2_3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "putF4",
|
||||||
|
.method_descriptor = "(IFZ)V",
|
||||||
|
.func = native_jvm_internal_memory_putUnalignedU4_3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "getU4",
|
||||||
|
.method_descriptor = "(IZ)I",
|
||||||
|
.func = native_jvm_internal_memory_getUnalignedU4_2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "getU2",
|
||||||
|
.method_descriptor = "(IZ)S",
|
||||||
|
.func = native_jvm_internal_memory_getUnalignedU2_2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "getF4",
|
||||||
|
.method_descriptor = "(IZ)F",
|
||||||
|
.func = native_jvm_internal_memory_getUnalignedU4_2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
.method_name = "isBigEndian",
|
.method_name = "isBigEndian",
|
||||||
.method_descriptor = "()Z",
|
.method_descriptor = "()Z",
|
||||||
.func = native_java_misc_memory_isbigendian_0,
|
.func = native_jvm_internal_memory_isbigendian_0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.class_name = "jvm/internal/Memory",
|
||||||
|
.method_name = "allocate",
|
||||||
|
.method_descriptor = "(I)I",
|
||||||
|
.func = native_jvm_internal_memory_allocate_1,
|
||||||
|
},
|
||||||
|
// PrintStream
|
||||||
{
|
{
|
||||||
.class_name = "java/io/PrintStream",
|
.class_name = "java/io/PrintStream",
|
||||||
.method_name = "_write",
|
.method_name = "_write",
|
||||||
@ -107,6 +146,7 @@ const static struct native_method native_method[] = {
|
|||||||
.method_descriptor = "(Ljava/lang/String;)V",
|
.method_descriptor = "(Ljava/lang/String;)V",
|
||||||
.func = native_java_io_printstream_write_s_1,
|
.func = native_java_io_printstream_write_s_1,
|
||||||
},
|
},
|
||||||
|
// Loader
|
||||||
{
|
{
|
||||||
.class_name = "jvm/internal/Loader",
|
.class_name = "jvm/internal/Loader",
|
||||||
.method_name = "load",
|
.method_name = "load",
|
||||||
@ -119,6 +159,7 @@ const static struct native_method native_method[] = {
|
|||||||
.method_descriptor = "()I",
|
.method_descriptor = "()I",
|
||||||
.func = native_jvm_internal_loader_getbuffer_0,
|
.func = native_jvm_internal_loader_getbuffer_0,
|
||||||
},
|
},
|
||||||
|
// Class
|
||||||
{
|
{
|
||||||
.class_name = "java/lang/Class",
|
.class_name = "java/lang/Class",
|
||||||
.method_name = "_getName",
|
.method_name = "_getName",
|
||||||
@ -131,12 +172,14 @@ const static struct native_method native_method[] = {
|
|||||||
.method_descriptor = "(Ljava/lang/Object;)Ljava/lang/String;",
|
.method_descriptor = "(Ljava/lang/Object;)Ljava/lang/String;",
|
||||||
.func = native_java_lang_class_getsuperclass_1,
|
.func = native_java_lang_class_getsuperclass_1,
|
||||||
},
|
},
|
||||||
|
// Object
|
||||||
{
|
{
|
||||||
.class_name = "java/lang/Object",
|
.class_name = "java/lang/Object",
|
||||||
.method_name = "_getClass",
|
.method_name = "_getClass",
|
||||||
.method_descriptor = "(Ljava/lang/Object;)Ljava/lang/Class;",
|
.method_descriptor = "(Ljava/lang/Object;)Ljava/lang/Class;",
|
||||||
.func = native_java_lang_object_getclass_1,
|
.func = native_java_lang_object_getclass_1,
|
||||||
},
|
},
|
||||||
|
// Runtime
|
||||||
{
|
{
|
||||||
.class_name = "java/lang/Runtime",
|
.class_name = "java/lang/Runtime",
|
||||||
.method_name = "_freeMemory",
|
.method_name = "_freeMemory",
|
||||||
@ -155,6 +198,7 @@ const static struct native_method native_method[] = {
|
|||||||
.method_descriptor = "()I",
|
.method_descriptor = "()I",
|
||||||
.func = native_java_lang_runtime_totalmemory_0,
|
.func = native_java_lang_runtime_totalmemory_0,
|
||||||
},
|
},
|
||||||
|
// System
|
||||||
{
|
{
|
||||||
.class_name = "java/lang/System",
|
.class_name = "java/lang/System",
|
||||||
.method_name = "_hashCode",
|
.method_name = "_hashCode",
|
||||||
|
@ -1,75 +1,213 @@
|
|||||||
#include "native_types.h"
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "memory_allocator.h"
|
||||||
|
|
||||||
void native_java_misc_memory_putU4_2(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_putU4_2(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint32_t * address = (uint32_t *)args[0];
|
uint32_t * address = (uint32_t *)args[0];
|
||||||
uint32_t value = args[1];
|
uint32_t value = args[1];
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_putU2_2(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_putU2_2(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint16_t * address = (uint16_t *)args[0];
|
uint16_t * address = (uint16_t *)args[0];
|
||||||
uint16_t value = args[1];
|
uint16_t value = args[1];
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_putU1_2(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_putU1_2(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint8_t * address = (uint8_t *)args[0];
|
uint8_t * address = (uint8_t *)args[0];
|
||||||
uint8_t value = args[1];
|
uint8_t value = args[1];
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_getU4_1(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_getU4_1(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint32_t * address = (uint32_t *)args[0];
|
uint32_t * address = (uint32_t *)args[0];
|
||||||
uint32_t value = *address;
|
uint32_t value = *address;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_getU2_1(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_getU2_1(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint16_t * address = (uint16_t *)args[0];
|
uint16_t * address = (uint16_t *)args[0];
|
||||||
uint16_t value = *address;
|
uint16_t value = *address;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_getU1_1(struct vm * vm, uint32_t * args)
|
void native_jvm_internal_memory_getU1_1(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint8_t * address = (uint8_t *)args[0];
|
uint8_t * address = (uint8_t *)args[0];
|
||||||
uint8_t value = *address;
|
uint8_t value = *address;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint32_t store_queue[0x4000000] __asm("store_queue");
|
static inline void unaligned_store_u4(uint32_t address, uint32_t value, bool big_endian)
|
||||||
|
|
||||||
void native_java_misc_memory_putSQ1_2(struct vm * vm, uint32_t * args)
|
|
||||||
{
|
{
|
||||||
#if defined(__dreamcast__)
|
if ((address & 3) == 0) {
|
||||||
struct objectref * objectref = (struct objectref *)args[0];
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
uint32_t address = (uint32_t)args[1];
|
if (big_endian)
|
||||||
store_queue[0] = objectref->u32[0];
|
*((uint32_t *)address) = value;
|
||||||
store_queue[1] = objectref->u32[1];
|
else
|
||||||
store_queue[2] = objectref->u32[2];
|
*((uint32_t *)address) = __builtin_bswap32(value);
|
||||||
store_queue[3] = objectref->u32[3];
|
#else // LITTLE_ENDIAN
|
||||||
store_queue[4] = objectref->u32[4];
|
if (!big_endian)
|
||||||
store_queue[5] = objectref->u32[5];
|
*((uint32_t *)address) = value;
|
||||||
store_queue[6] = objectref->u32[6];
|
else
|
||||||
store_queue[7] = objectref->u32[7];
|
*((uint32_t *)address) = __builtin_bswap32(value);
|
||||||
|
#endif
|
||||||
*((uint32_t*)0xff000038) = ((address >> 26) & 0b111) << 2;
|
} else {
|
||||||
|
if (big_endian) {
|
||||||
__asm__ volatile ("pref @%0"
|
((uint8_t *)address)[0] = (uint8_t)(value >> 24);
|
||||||
: // output
|
((uint8_t *)address)[1] = (uint8_t)(value >> 16);
|
||||||
: "r" (&store_queue[0]) // input
|
((uint8_t *)address)[2] = (uint8_t)(value >> 8);
|
||||||
: "memory");
|
((uint8_t *)address)[3] = (uint8_t)(value >> 0);
|
||||||
#endif
|
} else {
|
||||||
|
((uint8_t *)address)[0] = (uint8_t)(value >> 0);
|
||||||
|
((uint8_t *)address)[1] = (uint8_t)(value >> 8);
|
||||||
|
((uint8_t *)address)[2] = (uint8_t)(value >> 16);
|
||||||
|
((uint8_t *)address)[3] = (uint8_t)(value >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_java_misc_memory_isbigendian_0(struct vm * vm, uint32_t * args)
|
static inline void unaligned_store_u2(uint32_t address, uint32_t value, bool big_endian)
|
||||||
|
{
|
||||||
|
if ((address & 1) == 0) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
if (big_endian)
|
||||||
|
*((uint16_t *)address) = value;
|
||||||
|
else
|
||||||
|
*((uint16_t *)address) = __builtin_bswap16(value);
|
||||||
|
#else // LITTLE_ENDIAN
|
||||||
|
if (!big_endian)
|
||||||
|
*((uint16_t *)address) = value;
|
||||||
|
else
|
||||||
|
*((uint16_t *)address) = __builtin_bswap16(value);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if (big_endian) {
|
||||||
|
((uint8_t *)address)[0] = (uint8_t)(value >> 8);
|
||||||
|
((uint8_t *)address)[1] = (uint8_t)(value >> 0);
|
||||||
|
} else {
|
||||||
|
((uint8_t *)address)[0] = (uint8_t)(value >> 0);
|
||||||
|
((uint8_t *)address)[1] = (uint8_t)(value >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_putUnalignedU4_3(struct vm * vm, uint32_t * args)
|
||||||
|
{
|
||||||
|
uint32_t address = (uint32_t)args[0];
|
||||||
|
uint32_t value = args[1];
|
||||||
|
bool big_endian = args[2];
|
||||||
|
|
||||||
|
unaligned_store_u4(address, value, big_endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_putUnalignedU2_3(struct vm * vm, uint32_t * args)
|
||||||
|
{
|
||||||
|
uint32_t address = (uint32_t)args[0];
|
||||||
|
uint32_t value = args[1];
|
||||||
|
bool big_endian = args[2];
|
||||||
|
|
||||||
|
unaligned_store_u2(address, value, big_endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t unaligned_load_u4(uint32_t address, bool big_endian)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
if ((address & 3) == 0) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
if (big_endian)
|
||||||
|
value = *((uint32_t *)address);
|
||||||
|
else
|
||||||
|
value = __builtin_bswap32(*((uint32_t *)address));
|
||||||
|
#else // LITTLE_ENDIAN
|
||||||
|
if (!big_endian)
|
||||||
|
value = *((uint32_t *)address);
|
||||||
|
else
|
||||||
|
value = __builtin_bswap32(*((uint32_t *)address));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if (big_endian) {
|
||||||
|
value =
|
||||||
|
((((uint8_t *)address)[0] << 24) |
|
||||||
|
(((uint8_t *)address)[1] << 16) |
|
||||||
|
(((uint8_t *)address)[2] << 8 ) |
|
||||||
|
(((uint8_t *)address)[3] << 0 ));
|
||||||
|
} else {
|
||||||
|
value =
|
||||||
|
((((uint8_t *)address)[0] << 0 ) |
|
||||||
|
(((uint8_t *)address)[1] << 8 ) |
|
||||||
|
(((uint8_t *)address)[2] << 16) |
|
||||||
|
(((uint8_t *)address)[3] << 24));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t unaligned_load_u2(uint32_t address, bool big_endian)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
if ((address & 1) == 0) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
if (big_endian)
|
||||||
|
value = *((uint32_t *)address);
|
||||||
|
else
|
||||||
|
value = __builtin_bswap32(*((uint32_t *)address));
|
||||||
|
#else // LITTLE_ENDIAN
|
||||||
|
if (!big_endian)
|
||||||
|
value = *((uint32_t *)address);
|
||||||
|
else
|
||||||
|
value = __builtin_bswap32(*((uint32_t *)address));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if (big_endian) {
|
||||||
|
value =
|
||||||
|
((((uint8_t *)address)[0] << 8 ) |
|
||||||
|
(((uint8_t *)address)[1] << 0 ));
|
||||||
|
} else {
|
||||||
|
value =
|
||||||
|
((((uint8_t *)address)[0] << 0 ) |
|
||||||
|
(((uint8_t *)address)[1] << 8 ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_getUnalignedU4_2(struct vm * vm, uint32_t * args)
|
||||||
|
{
|
||||||
|
uint32_t address = (uint32_t)args[0];
|
||||||
|
bool big_endian = args[1];
|
||||||
|
|
||||||
|
uint32_t value = unaligned_load_u4(address, big_endian);
|
||||||
|
|
||||||
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_getUnalignedU2_2(struct vm * vm, uint32_t * args)
|
||||||
|
{
|
||||||
|
uint32_t address = (uint32_t)args[0];
|
||||||
|
bool big_endian = args[1];
|
||||||
|
|
||||||
|
uint32_t value = unaligned_load_u2(address, big_endian);
|
||||||
|
|
||||||
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_isbigendian_0(struct vm * vm, uint32_t * args)
|
||||||
{
|
{
|
||||||
uint32_t value = (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__);
|
uint32_t value = (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__);
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_allocate_1(struct vm * vm, uint32_t * args)
|
||||||
|
{
|
||||||
|
uint32_t capacity = (uint32_t)args[0];
|
||||||
|
|
||||||
|
void * address = memory_allocate(capacity);
|
||||||
|
|
||||||
|
operand_stack_push_u32(vm->current_frame, (uint32_t)address);
|
||||||
|
}
|
||||||
|
@ -4,11 +4,18 @@
|
|||||||
|
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
void native_java_misc_memory_putU4_2(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_putU4_2(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_putU2_2(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_putU2_2(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_putU1_2(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_putU1_2(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_getU4_1(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_getU4_1(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_getU2_1(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_getU2_1(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_getU1_1(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_getU1_1(struct vm * vm, uint32_t * args);
|
||||||
void native_java_misc_memory_putSQ1_2(struct vm * vm, uint32_t * args);
|
|
||||||
void native_java_misc_memory_isbigendian_0(struct vm * vm, uint32_t * args);
|
void native_jvm_internal_memory_putUnalignedU4_3(struct vm * vm, uint32_t * args);
|
||||||
|
void native_jvm_internal_memory_putUnalignedU2_3(struct vm * vm, uint32_t * args);
|
||||||
|
void native_jvm_internal_memory_getUnalignedU4_2(struct vm * vm, uint32_t * args);
|
||||||
|
void native_jvm_internal_memory_getUnalignedU2_2(struct vm * vm, uint32_t * args);
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_isbigendian_0(struct vm * vm, uint32_t * args);
|
||||||
|
|
||||||
|
void native_jvm_internal_memory_allocate_1(struct vm * vm, uint32_t * args);
|
||||||
|
@ -1,38 +1,69 @@
|
|||||||
package java.nio;
|
package java.nio;
|
||||||
|
|
||||||
class Buffer {
|
public abstract class Buffer {
|
||||||
protected int mark = -1;
|
private final int address;
|
||||||
protected int position = 0;
|
private int position;
|
||||||
protected int limit;
|
private int limit;
|
||||||
protected final int capacity;
|
private final int capacity;
|
||||||
|
|
||||||
Buffer(int mark, int position, int limit, int capacity) {
|
protected Buffer(int address, int position, int limit, int capacity) {
|
||||||
this.mark = mark;
|
this.address = address;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int position() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int limit() {
|
|
||||||
return limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int capacity() {
|
public final int capacity() {
|
||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Buffer limit(int limit) {
|
public final Buffer clear() {
|
||||||
this.limit = limit;
|
position = 0;
|
||||||
if (position > limit) position = limit;
|
limit = capacity;
|
||||||
if (mark > limit) mark = -1;
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Buffer flip() {
|
||||||
|
limit = position;
|
||||||
|
position = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasRemaining() {
|
public final boolean hasRemaining() {
|
||||||
return position < limit;
|
return position < limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final int limit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Buffer limit(int newLimit) {
|
||||||
|
if (newLimit < 0 || newLimit > capacity)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
this.limit = newLimit;
|
||||||
|
if (position > newLimit) position = newLimit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int position() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Buffer position(int newPosition) {
|
||||||
|
if (newPosition < 0 || newPosition > limit)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
position = newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int remaining() {
|
||||||
|
int elements = limit - position;
|
||||||
|
if (elements < 0)
|
||||||
|
elements = 0;
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Buffer rewind() {
|
||||||
|
position = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,162 @@
|
|||||||
package java.nio;
|
package java.nio;
|
||||||
|
|
||||||
public class ByteBuffer extends Buffer {
|
import jvm.internal.Memory;
|
||||||
private int offset;
|
|
||||||
|
public class ByteBuffer
|
||||||
|
extends Buffer
|
||||||
|
implements Comparable<ByteBuffer> {
|
||||||
|
|
||||||
private boolean bigEndian;
|
private boolean bigEndian;
|
||||||
//private boolean sameEndian;
|
|
||||||
|
|
||||||
private byte[] array;
|
private ByteBuffer(int address, int position, int limit, int capacity, int bigEndian) {
|
||||||
|
super(address, position, limit, capacity);
|
||||||
private ByteBuffer(byte[] array, int offset, int length) {
|
bigEndian = bigEndian;
|
||||||
super(-1, 0, length, length);
|
|
||||||
this.array = array;
|
|
||||||
this.order(ByteOrder.BIG_ENDIAN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer wrap(byte[] array) {
|
public static ByteBuffer allocateDirect(int capacity) {
|
||||||
return new ByteBuffer(array, 0, array.length);
|
int address = Memory.allocate(capacity);
|
||||||
|
return new ByteBuffer(address, 0, capacity, capacity, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer wrap(byte[] array, int offset, int length) {
|
public final byte[] array() {
|
||||||
return new ByteBuffer(array, offset, length);
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int arrayOffset() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int mismatch(ByteBuffer a,
|
||||||
|
ByteBuffer b)
|
||||||
|
{
|
||||||
|
int remA = a.limit - a.position;
|
||||||
|
int remB = b.limit - b.position;
|
||||||
|
int length = remA > remB ? remB : remA;
|
||||||
|
int offA = a.position;
|
||||||
|
int offB = b.position;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (a.get(offA + i) != b.get(offB + i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
if (remA != remB)
|
||||||
|
return length;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ByteBuffer that) {
|
||||||
|
int pos = mismatch(this, that);
|
||||||
|
if (pos >= 0) {
|
||||||
|
return this.get(this.position + pos) - that.get(that.position + pos);
|
||||||
|
} else {
|
||||||
|
int thisRem = this.limit - this.position;
|
||||||
|
int thatRem = that.limit - that.position;
|
||||||
|
return thisRem - thatRem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object ob) {
|
||||||
|
if (this == ob)
|
||||||
|
return true;
|
||||||
|
if (!(ob instanceof ByteBuffer))
|
||||||
|
return false;
|
||||||
|
ByteBuffer other = (ByteBuffer)ob;
|
||||||
|
int pos = ByteBuffer.mismatch(this, other);
|
||||||
|
return pos == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get() {
|
||||||
|
if (position >= limit)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
byte b = Memory.getU1(address + position);
|
||||||
|
position += 1;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer get(byte[] dst) {
|
||||||
|
return get(dst, 0, dst.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer get(byte[] dst,
|
||||||
|
int offset,
|
||||||
|
int length) {
|
||||||
|
int rem = limit - position;
|
||||||
|
if (rem < length) {
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
}
|
||||||
|
if (offset < 0 || offset > dst.length || length < 0 || length > (dst.length - offset)) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
for (int i = offset; i < offset + length; i++)
|
||||||
|
dst[i] = get();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get(int index) {
|
||||||
|
if (index < 0 || index > limit)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
return Memory.getU1(address + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat() {
|
||||||
|
if (limit - position < 4)
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
float f = Memory.getUnalignedF4(address + position, bigEndian);
|
||||||
|
position += 4;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat(int index) {
|
||||||
|
if (index < 0 || index >= (limit - 3))
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
float f = Memory.getUnalignedF4(address + index, bigEndian);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt() {
|
||||||
|
if (limit - position < 4)
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
int i = Memory.getUnalignedU4(address + position, bigEndian);
|
||||||
|
position += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(int index) {
|
||||||
|
if (index < 0 || index >= (limit - 3))
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
in i = Memory.getUnalignedU4(address + index, bigEndian);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getShort() {
|
||||||
|
if (limit - position < 2)
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
short i = Memory.getUnalignedU2(address + position, bigEndian);
|
||||||
|
position += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getShort(short index) {
|
||||||
|
if (index < 0 || index >= (limit - 1))
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
in i = Memory.getUnalignedU2(address + index, bigEndian);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean hasArray() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int h = 1;
|
||||||
|
int limit = this.limit;
|
||||||
|
for (int i = position; i < limit; i++) {
|
||||||
|
h = 31 * h + (int)get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDirect() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteOrder order() {
|
public ByteOrder order() {
|
||||||
@ -27,103 +165,128 @@ public class ByteBuffer extends Buffer {
|
|||||||
|
|
||||||
public ByteBuffer order(ByteOrder bo) {
|
public ByteBuffer order(ByteOrder bo) {
|
||||||
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
|
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
|
||||||
//sameEndian = (bo == ByteOrder.nativeOrder());
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteBuffer offset(int off) {
|
public ByteBuffer put(byte b) {
|
||||||
offset = off;
|
if (position >= limit)
|
||||||
return this;
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
Memory.putU1(address + position);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
private int ix(int pos) {
|
|
||||||
return offset + pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte get() {
|
|
||||||
byte i0 = array[ix(position)];
|
|
||||||
position += 1;
|
position += 1;
|
||||||
return i0;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte get(int pos) {
|
public final ByteBuffer put(byte[] src) {
|
||||||
byte i0 = array[ix(pos)];
|
return put(src, 0, src.length);
|
||||||
return i0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getShort() {
|
public ByteBuffer put(byte[] src,
|
||||||
int i0 = array[ix(position) + 0];
|
int offset,
|
||||||
int i1 = array[ix(position) + 1];
|
int length) {
|
||||||
|
int rem = limit - position;
|
||||||
|
if (rem < length) {
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
}
|
||||||
|
if (offset < 0 || offset > src.length || length < 0 || length > (src.length - offset)) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
for (int i = offset; i < offset + length; i++)
|
||||||
|
put(src[i]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
position += 2;
|
public ByteBuffer put(ByteBuffer src) {
|
||||||
|
int rem = limit - position;
|
||||||
if (bigEndian) {
|
if (rem < src.length) {
|
||||||
return (short)shortBE(i0, i1);
|
throw new BufferUnderflowException();
|
||||||
} else {
|
}
|
||||||
return (short)shortLE(i0, i1);
|
if (src == this) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
for (int i = src.position; i < src.limit; i++) {
|
||||||
|
put(src.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getShort(int pos) {
|
public ByteBuffer put(int index,
|
||||||
int i0 = array[ix(pos) + 0];
|
byte b) {
|
||||||
int i1 = array[ix(pos) + 1];
|
if (index < 0 || index > limit)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
if (bigEndian) {
|
Memory.putU1(address + index, b);
|
||||||
return (short)shortBE(i0, i1);
|
return this;
|
||||||
} else {
|
|
||||||
return (short)shortLE(i0, i1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt() {
|
public ByteBuffer putFloat(float value) {
|
||||||
int i0 = array[ix(position) + 0];
|
if (limit - position < 4)
|
||||||
int i1 = array[ix(position) + 1];
|
throw new BufferUnderflowException();
|
||||||
int i2 = array[ix(position) + 2];
|
Memory.putUnalignedF4(address + position, value, bigEndian);
|
||||||
int i3 = array[ix(position) + 3];
|
|
||||||
|
|
||||||
position += 4;
|
position += 4;
|
||||||
|
return this;
|
||||||
if (bigEndian) {
|
|
||||||
return intBE(i0, i1, i2, i3);
|
|
||||||
} else {
|
|
||||||
return intLE(i0, i1, i2, i3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt(int pos) {
|
public ByteBuffer putFloat(int index,
|
||||||
int i0 = array[ix(pos) + 0];
|
float value) {
|
||||||
int i1 = array[ix(pos) + 1];
|
if (index < 0 || index >= (limit - 3))
|
||||||
int i2 = array[ix(pos) + 2];
|
throw new IndexOutOfBoundsException();
|
||||||
int i3 = array[ix(pos) + 3];
|
Memory.putUnalignedF4(address + index, value, bigEndian);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
if (bigEndian) {
|
public ByteBuffer putInt(int value) {
|
||||||
return intBE(i0, i1, i2, i3);
|
if (limit - position < 4)
|
||||||
} else {
|
throw new BufferUnderflowException();
|
||||||
return intLE(i0, i1, i2, i3);
|
Memory.putUnalignedU4(address + position, value, bigEndian);
|
||||||
}
|
position += 4;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putInt(int index,
|
||||||
|
int value) {
|
||||||
|
if (index < 0 || index >= (limit - 3))
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
Memory.putUnalignedU4(address + index, value, bigEndian);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putShort(short value) {
|
||||||
|
if (limit - position < 4)
|
||||||
|
throw new BufferUnderflowException();
|
||||||
|
Memory.putUnalignedU2(address + position, value, bigEndian);
|
||||||
|
position += 4;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putShort(int index,
|
||||||
|
short value) {
|
||||||
|
if (index < 0 || index >= (limit - 1))
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
Memory.putUnalignedU2(address + index, value, bigEndian);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer slice() {
|
||||||
|
return new ByteBuffer(address,
|
||||||
|
position,
|
||||||
|
limit,
|
||||||
|
capacity,
|
||||||
|
bigEndian);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName()
|
||||||
|
+ "[pos=" + position
|
||||||
|
+ " lim=" + limit
|
||||||
|
+ " cap=" + capacity
|
||||||
|
+ "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ByteBuffer wrap(byte[] array) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ByteBuffer wrap(byte[] array,
|
||||||
|
int offset,
|
||||||
|
int length) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,12 @@ public class ByteOrder {
|
|||||||
public static ByteOrder nativeOrder() {
|
public static ByteOrder nativeOrder() {
|
||||||
return NATIVE_ORDER;
|
return NATIVE_ORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (this == BIG_ENDIAN) {
|
||||||
|
return "BIG_ENDIAN";
|
||||||
|
} else {
|
||||||
|
return "LITTLE_ENDIAN";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,24 @@ package jvm.internal;
|
|||||||
|
|
||||||
public class Memory {
|
public class Memory {
|
||||||
public static native void putU4(int address, int value);
|
public static native void putU4(int address, int value);
|
||||||
public static native void putU2(int address, int value);
|
public static native void putU2(int address, short value);
|
||||||
public static native void putU1(int address, int value);
|
public static native void putU1(int address, byte value);
|
||||||
|
|
||||||
public static native int getU4(int address);
|
public static native int getU4(int address);
|
||||||
public static native int getU2(int address);
|
public static native short getU2(int address);
|
||||||
public static native int getU1(int address);
|
public static native byte getU1(int address);
|
||||||
|
|
||||||
|
public static native void putUnalignedU4(int address, int value, boolean bigEndian);
|
||||||
|
public static native void putUnalignedU2(int address, short value, boolean bigEndian);
|
||||||
|
public static native void putUnalignedF4(int address, float value, boolean bigEndian);
|
||||||
|
|
||||||
|
public static native int getUnalignedU4(int address, boolean bigEndian);
|
||||||
|
public static native short getUnalignedU2(int address, boolean bigEndian);
|
||||||
|
public static native float getUnalignedF4(int address, boolean bigEndian);
|
||||||
|
|
||||||
public static native void putSQ1(Object object, int address);
|
public static native void putSQ1(Object object, int address);
|
||||||
|
|
||||||
public static native boolean isBigEndian();
|
public static native boolean isBigEndian();
|
||||||
|
|
||||||
|
public static native int allocate(int size);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user