From 89cac52b14143a428f27fc7a5e2fc32bd4c04c43 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Thu, 26 Dec 2024 06:10:52 -0600 Subject: [PATCH] add memory manipulation native functions --- Makefile | 2 +- c/debug_class_file.c | 2 +- c/frame.c | 36 ++++++++++++++++++++++++++++++++++++ c/native.c | 42 ++++++++++++++++++++++++++++++++++++++++++ c/native.h | 6 ++++++ java/misc/Memory.java | 11 +++++++++++ p/Native.java | 6 +++++- 7 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 java/misc/Memory.java diff --git a/Makefile b/Makefile index 9aaf4b8..fb8cc25 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ CC ?= gcc ARCH = -m32 CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g CFLAGS += -DDEBUG -#CFLAGS += -DDEBUG_PRINT +CFLAGS += -DDEBUG_PRINT OPT ?= -O0 DEPFLAGS = -MMD -MP diff --git a/c/debug_class_file.c b/c/debug_class_file.c index 470f329..847583c 100644 --- a/c/debug_class_file.c +++ b/c/debug_class_file.c @@ -220,7 +220,7 @@ void print_class_file(struct class_file * class_file) debugf("constants:\n"); for (int i = 0; i < class_file->constant_pool_count - 1; i++) { if (class_file->constant_pool[i].tag != 0) { - debugf("% 3d: ", i + 1); + debugf("%4d: ", i + 1); print_constant(&class_file->constant_pool[i]); } } diff --git a/c/frame.c b/c/frame.c index 468ec69..f84dc7e 100644 --- a/c/frame.c +++ b/c/frame.c @@ -225,14 +225,50 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"write", method_name_constant->utf8.length); if (write) { if (nargs == 1) { + assert(return_type == 'V'); native_java_io_printstream_write_1(args); return; } else if (nargs == 2) { + assert(return_type == 'V'); native_java_io_printstream_write_2(args); return; } } } + + int java_misc_memory_length = 16; + bool java_misc_memory = + class_name_constant->utf8.length == java_misc_memory_length && + hash_table_key_equal(class_name_constant->utf8.bytes, (const uint8_t *)"java/misc/Memory", class_name_constant->utf8.length); + if (java_misc_memory) { + if (method_name_constant->utf8.length == 5) { + if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"putU", 4)) { + assert(nargs == 2); + assert(return_type == 'V'); + switch (method_name_constant->utf8.bytes[4]) { + case '4': native_java_misc_memory_putU4_2(args); break; + case '2': native_java_misc_memory_putU2_2(args); break; + case '1': native_java_misc_memory_putU1_2(args); break; + default: assert(false); + } + return; + } + if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"getU", 4)) { + assert(nargs == 1); + assert(return_type == 'I'); + uint32_t value; + switch (method_name_constant->utf8.bytes[4]) { + case '4': value = native_java_misc_memory_getU4_1(args); break; + case '2': value = native_java_misc_memory_getU2_1(args); break; + case '1': value = native_java_misc_memory_getU1_1(args); break; + default: assert(false); + } + operand_stack_push_u32(vm->current_frame, value); + return; + } + } + } + assert(false); } diff --git a/c/native.c b/c/native.c index 4bed98b..d73cb2a 100644 --- a/c/native.c +++ b/c/native.c @@ -20,3 +20,45 @@ void native_java_io_printstream_write_2(uint32_t * args) uint32_t * arrayref = (uint32_t *)args[1]; native_java_io_printstream_write(arrayref); } + +void native_java_misc_memory_putU4_2(uint32_t * args) +{ + uint32_t * address = (uint32_t *)args[0]; + uint32_t value = args[1]; + *address = value; +} + +void native_java_misc_memory_putU2_2(uint32_t * args) +{ + uint16_t * address = (uint16_t *)args[0]; + uint16_t value = args[1]; + *address = value; +} + +void native_java_misc_memory_putU1_2(uint32_t * args) +{ + uint8_t * address = (uint8_t *)args[0]; + uint8_t value = args[1]; + *address = value; +} + +uint32_t native_java_misc_memory_getU4_1(uint32_t * args) +{ + uint32_t * address = (uint32_t *)args[0]; + uint32_t value = *address; + return value; +} + +uint32_t native_java_misc_memory_getU2_1(uint32_t * args) +{ + uint16_t * address = (uint16_t *)args[0]; + uint16_t value = *address; + return value; +} + +uint32_t native_java_misc_memory_getU1_1(uint32_t * args) +{ + uint8_t * address = (uint8_t *)args[0]; + uint8_t value = *address; + return value; +} diff --git a/c/native.h b/c/native.h index 1744ae5..485f668 100644 --- a/c/native.h +++ b/c/native.h @@ -5,3 +5,9 @@ void native_java_io_printstream_write(uint32_t * arrayref); void native_java_io_printstream_write_1(uint32_t * args); void native_java_io_printstream_write_2(uint32_t * args); +void native_java_misc_memory_putU4_2(uint32_t * args); +void native_java_misc_memory_putU2_2(uint32_t * args); +void native_java_misc_memory_putU1_2(uint32_t * args); +uint32_t native_java_misc_memory_getU4_1(uint32_t * args); +uint32_t native_java_misc_memory_getU2_1(uint32_t * args); +uint32_t native_java_misc_memory_getU1_1(uint32_t * args); diff --git a/java/misc/Memory.java b/java/misc/Memory.java new file mode 100644 index 0000000..faad20b --- /dev/null +++ b/java/misc/Memory.java @@ -0,0 +1,11 @@ +package java.misc; + +public class Memory { + public static native void putU4(int address, int value); + public static native void putU2(int address, int value); + public static native void putU1(int address, int value); + + public static native int getU4(int address); + public static native int getU2(int address); + public static native int getU1(int address); +} diff --git a/p/Native.java b/p/Native.java index a35c7e2..a6e7bda 100644 --- a/p/Native.java +++ b/p/Native.java @@ -1,10 +1,14 @@ package p; -import java.io.IOException; +import java.misc.Memory; class Native { public static void main() { String foo = "hello Dreamcast"; System.out.println(foo); + + int address = 0x1234; + int value = 0x5678; + Memory.putU4(address, value); } }