diff --git a/Makefile b/Makefile index e5f3bf1..5704539 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protec CFLAGS += -I$(MAKEFILE_PATH)/ CFLAGS += -I$(MAKEFILE_PATH)/c CFLAGS += -DDEBUG -#CFLAGS += -DDEBUG_PRINT +CFLAGS += -DDEBUG_PRINT LDFLAGS = -lm OPT ?= -O0 DEPFLAGS = -MMD -MP diff --git a/Makefile.dreamcast.mk b/Makefile.dreamcast.mk index 20fdea2..ada47d1 100644 --- a/Makefile.dreamcast.mk +++ b/Makefile.dreamcast.mk @@ -82,57 +82,62 @@ jvm.iso: boot.bin main.bin zero.bin /=$(LIB)/COPYRIGH.TXT \ /=$(LIB)/ABSTRACT.TXT \ /=$(LIB)/BIBLIOGR.TXT \ - example/GdromDirectoryRecordHandler.class \ - example/GdromClassLoader.class \ - filesystem/iso9660/ByteParser.class \ - filesystem/iso9660/DirectoryRecord.class \ - filesystem/iso9660/ExtentReader.class \ - filesystem/iso9660/PrimaryVolumeDescriptor.class \ - filesystem/iso9660/VolumeParser.class \ - java/io/PrintStream.class \ - java/lang/DecimalDigits.class \ - java/lang/Integer.class \ - java/lang/Object.class \ - java/lang/String.class \ - java/lang/System.class \ - java/misc/Memory.class \ - jvm/internal/Loader.class \ - sega/dreamcast/gdrom/G1IF.class \ - sega/dreamcast/gdrom/GdromIF.class \ - sega/dreamcast/gdrom/GdromBits.class \ - sega/dreamcast/gdrom/Gdrom.class \ - sega/dreamcast/gdrom/GdromExtentReader.class \ - sega/dreamcast/gdrom/GdromCommandPacketFormat_cd_read.class \ - sega/dreamcast/gdrom/GdromCommandPacketFormat.class \ - sega/dreamcast/gdrom/GdromCommandPacketFormat_get_toc.class \ - sega/dreamcast/gdrom/GdromCommandPacketInterface.class \ - sega/dreamcast/gdrom/GdromProtocol.class \ - Main.class \ - example/JavaCube.class \ - example/JavaCubeDirectoryRecordHandler.class \ - model/FacePTN.class \ - model/ModelObject.class \ - model/CubeModel.class \ - model/Vec2.class \ - model/Vec3.class \ - sega/dreamcast/holly/Background.class \ - sega/dreamcast/holly/CoreBits.class \ - sega/dreamcast/holly/Core.class \ - sega/dreamcast/holly/VideoOutput.class \ - sega/dreamcast/holly/VideoOutputMode.class \ - sega/dreamcast/holly/ISPTSP.class \ - sega/dreamcast/holly/RegionArray.class \ - sega/dreamcast/holly/RegionArray_OPBSize.class \ - sega/dreamcast/holly/TABits.class \ - sega/dreamcast/holly/TAFIFOPolygonConverter.class \ - sega/dreamcast/holly/TAGlobalParameter.class \ - sega/dreamcast/holly/TAGlobalParameter_end_of_list.class \ - sega/dreamcast/holly/TAGlobalParameter_polygon_type_0.class \ - sega/dreamcast/holly/TAVertexParameter.class \ - sega/dreamcast/holly/TAVertexParameter_polygon_type_3.class \ - sega/dreamcast/holly/TextureMemoryAllocation.class \ - java/lang/Math.class \ - java/misc/Resource.class \ + classes/example/GdromDirectoryRecordHandler.class \ + classes/example/GdromClassLoader.class \ + classes/filesystem/iso9660/ByteParser.class \ + classes/filesystem/iso9660/DirectoryRecord.class \ + classes/filesystem/iso9660/ExtentReader.class \ + classes/filesystem/iso9660/PrimaryVolumeDescriptor.class \ + classes/filesystem/iso9660/VolumeParser.class \ + classes/java/io/PrintStream.class \ + classes/java/lang/DecimalDigits.class \ + classes/java/lang/Integer.class \ + classes/java/lang/Float.class \ + classes/java/lang/Number.class \ + classes/java/lang/Object.class \ + classes/java/lang/String.class \ + classes/java/lang/System.class \ + classes/java/lang/Exception.class \ + classes/java/lang/Throwable.class \ + classes/java/lang/Backtrace.class \ + classes/java/misc/Memory.class \ + classes/jvm/internal/Loader.class \ + classes/sega/dreamcast/gdrom/G1IF.class \ + classes/sega/dreamcast/gdrom/GdromIF.class \ + classes/sega/dreamcast/gdrom/GdromBits.class \ + classes/sega/dreamcast/gdrom/Gdrom.class \ + classes/sega/dreamcast/gdrom/GdromExtentReader.class \ + classes/sega/dreamcast/gdrom/GdromCommandPacketFormat_cd_read.class \ + classes/sega/dreamcast/gdrom/GdromCommandPacketFormat.class \ + classes/sega/dreamcast/gdrom/GdromCommandPacketFormat_get_toc.class \ + classes/sega/dreamcast/gdrom/GdromCommandPacketInterface.class \ + classes/sega/dreamcast/gdrom/GdromProtocol.class \ + classes/Main.class \ + classes/example/JavaCube.class \ + classes/example/JavaCubeDirectoryRecordHandler.class \ + classes/model/FacePTN.class \ + classes/model/ModelObject.class \ + classes/model/CubeModel.class \ + classes/model/Vec2.class \ + classes/model/Vec3.class \ + classes/sega/dreamcast/holly/Background.class \ + classes/sega/dreamcast/holly/CoreBits.class \ + classes/sega/dreamcast/holly/Core.class \ + classes/sega/dreamcast/holly/VideoOutput.class \ + classes/sega/dreamcast/holly/VideoOutputMode.class \ + classes/sega/dreamcast/holly/ISPTSP.class \ + classes/sega/dreamcast/holly/RegionArray.class \ + classes/sega/dreamcast/holly/RegionArray_OPBSize.class \ + classes/sega/dreamcast/holly/TABits.class \ + classes/sega/dreamcast/holly/TAFIFOPolygonConverter.class \ + classes/sega/dreamcast/holly/TAGlobalParameter.class \ + classes/sega/dreamcast/holly/TAGlobalParameter_end_of_list.class \ + classes/sega/dreamcast/holly/TAGlobalParameter_polygon_type_0.class \ + classes/sega/dreamcast/holly/TAVertexParameter.class \ + classes/sega/dreamcast/holly/TAVertexParameter_polygon_type_3.class \ + classes/sega/dreamcast/holly/TextureMemoryAllocation.class \ + classes/java/lang/Math.class \ + classes/java/misc/Resource.class \ images/java_text.data \ images/java_cup.data diff --git a/c/class_resolver.c b/c/class_resolver.c index 75ac6e4..50f4046 100644 --- a/c/class_resolver.c +++ b/c/class_resolver.c @@ -283,6 +283,7 @@ struct class_entry * class_resolver_lookup_class(int class_hash_table_length, debugf("class_resolver_lookup_class: "); for (int i = 0; i < class_name_length; i++) { debugc(class_name[i]); } debugc('\n'); + debugf("length: %d\n", class_hash_table_length); struct hash_table_entry * e = hash_table_find(class_hash_table_length, class_hash_table, diff --git a/c/classpath.h b/c/classpath.h index e7f56f5..6948870 100644 --- a/c/classpath.h +++ b/c/classpath.h @@ -8,9 +8,14 @@ #include "classes/java/io/PrintStream.class.h" #include "classes/java/lang/DecimalDigits.class.h" #include "classes/java/lang/Integer.class.h" +#include "classes/java/lang/Float.class.h" +#include "classes/java/lang/Number.class.h" #include "classes/java/lang/Object.class.h" #include "classes/java/lang/String.class.h" #include "classes/java/lang/System.class.h" +#include "classes/java/lang/Exception.class.h" +#include "classes/java/lang/Throwable.class.h" +#include "classes/java/lang/Backtrace.class.h" #include "classes/java/misc/Memory.class.h" #include "classes/sega/dreamcast/gdrom/G1IF.class.h" #include "classes/sega/dreamcast/gdrom/GdromIF.class.h" diff --git a/c/classpath.inc.c b/c/classpath.inc.c index 09bff97..a8c4114 100644 --- a/c/classpath.inc.c +++ b/c/classpath.inc.c @@ -8,9 +8,14 @@ (const uint8_t *)&_binary_classes_java_io_PrintStream_class_start, (const uint8_t *)&_binary_classes_java_lang_DecimalDigits_class_start, (const uint8_t *)&_binary_classes_java_lang_Integer_class_start, +(const uint8_t *)&_binary_classes_java_lang_Float_class_start, +(const uint8_t *)&_binary_classes_java_lang_Number_class_start, (const uint8_t *)&_binary_classes_java_lang_Object_class_start, (const uint8_t *)&_binary_classes_java_lang_String_class_start, (const uint8_t *)&_binary_classes_java_lang_System_class_start, +(const uint8_t *)&_binary_classes_java_lang_Exception_class_start, +(const uint8_t *)&_binary_classes_java_lang_Throwable_class_start, +(const uint8_t *)&_binary_classes_java_lang_Backtrace_class_start, (const uint8_t *)&_binary_classes_java_misc_Memory_class_start, (const uint8_t *)&_binary_classes_sega_dreamcast_gdrom_G1IF_class_start, (const uint8_t *)&_binary_classes_sega_dreamcast_gdrom_GdromIF_class_start, diff --git a/c/execute.c b/c/execute.c index ef05551..cfcd658 100644 --- a/c/execute.c +++ b/c/execute.c @@ -73,26 +73,50 @@ void op_aload_3(struct vm * vm) operand_stack_push_u32(vm->current_frame, objectref); } +static struct arrayref * _multiarray(struct vm * vm, int32_t * dims, int num_dimensions, int level, uint8_t * type, uint8_t * type_end); + void op_anewarray(struct vm * vm, uint32_t index) { - struct class_entry * class_entry = - class_resolver_lookup_class_from_class_index(vm->class_hash_table.length, - vm->class_hash_table.entry, - vm->current_frame->class_entry, - index); + // The run-time constant pool item at that index must be a symbolic reference to a class, array, or interface type + + struct constant * class_constant = &vm->current_frame->class_entry->class_file->constant_pool[index - 1]; + assert(class_constant->tag == CONSTANT_Class); + struct constant * type_constant = &vm->current_frame->class_entry->class_file->constant_pool[class_constant->class.name_index - 1]; + assert(type_constant->tag == CONSTANT_Utf8); + + debugs("type_constant: "); + debug_print__constant__utf8_string(type_constant); + debugc('\n'); + + uint8_t * type = type_constant->utf8.bytes; + uint8_t * type_end = type + type_constant->utf8.length; int32_t count = operand_stack_pop_u32(vm->current_frame); if (count < 0) return vm_exception(vm, vm_instance_create(vm, "java/lang/NegativeArraySizeException")); - struct arrayref * arrayref = ref_array_allocate(vm, count); - assert(arrayref != nullptr); - arrayref->class_entry = class_entry; - - /* All components of the new array are initialized to null, the default value - for reference types */ - for (int i = 0; i < count; i++) { - arrayref->oref[i] = nullptr; + struct arrayref * arrayref; + if (*type == '[') { + const int dimensions = 1; + int32_t dims[dimensions]; + dims[0] = count; + arrayref = _multiarray(vm, dims, dimensions, 0, type, type_end); + assert(arrayref != nullptr); + } else { + assert(!(*type == 'L' && *(type_end - 1) == ';')); + struct class_entry * class_entry = + class_resolver_lookup_class_from_class_index(vm->class_hash_table.length, + vm->class_hash_table.entry, + vm->current_frame->class_entry, + index); + arrayref = ref_array_allocate(vm, count); + assert(arrayref != nullptr); + arrayref->class_entry = class_entry; + /* All components of the new array are initialized to null, the default value + for reference types */ + for (int i = 0; i < count; i++) { + arrayref->oref[i] = nullptr; + } } operand_stack_push_ref(vm->current_frame, arrayref); @@ -1755,6 +1779,7 @@ static struct arrayref * _multiarray(struct vm * vm, int32_t * dims, int num_dim int type_length = type_end - type; + //printf("_multiarray parse type\n"); struct parse_type_ret parse_type_ret = parse_type(type, type_length); @@ -1777,10 +1802,10 @@ static struct arrayref * _multiarray(struct vm * vm, int32_t * dims, int num_dim debugf("u32_count: %d\n", u32_count); for (int i = 0; i < u32_count; i++) { if (level == num_dimensions - 1) { - assert(*type != '['); + //assert(*type != '['); arrayref->u32[1] = 0; } else { - assert(*type == '['); + //assert(*type == '['); arrayref->aref[i] = _multiarray(vm, dims, num_dimensions, level + 1, type + 1, type_end); } } diff --git a/c/file.c b/c/file.c index 04661aa..898c604 100644 --- a/c/file.c +++ b/c/file.c @@ -9,8 +9,10 @@ uint8_t * file_read(const char * path, size_t * file_size) { int ret; - debugf("file_read: ", path); + //debugf("file_read: %s\n", path); FILE * f = fopen(path, "rb"); + if (f == nullptr) + printf("file_read: %s\n", path); assert(f != nullptr); ret = fseek(f, 0L, SEEK_END); assert(ret != -1); diff --git a/c/hash_table.c b/c/hash_table.c index 0e81c43..14d24c3 100644 --- a/c/hash_table.c +++ b/c/hash_table.c @@ -267,7 +267,6 @@ struct hash_table_entry * hash_table_find3(int hash_table_length, hash = fnv_1(hash, key2, key2_length); hash = fnv_1(hash, key3, key3_length); hash &= (hash_table_length - 1); - struct hash_table_entry * e = &entry[hash]; while (e != nullptr && e->key != nullptr) { diff --git a/c/native.c b/c/native.c index 7ac847a..60df6cf 100644 --- a/c/native.c +++ b/c/native.c @@ -35,7 +35,7 @@ const static struct native_method native_method[] = { .func = native_java_lang_math_cos_1, }, { - .class_name = "javva/lang/Math", + .class_name = "java/lang/Math", .method_name = "abs", .method_descriptor = "(F)F", .func = native_java_lang_math_abs_1, @@ -212,6 +212,14 @@ void native_method_call(struct vm * vm, method_descriptor_constant->utf8.bytes, method_descriptor_constant->utf8.length ); + if (e == nullptr) { + print_bytes(class_name_constant->utf8.bytes, class_name_constant->utf8.length); + printc(' '); + print_bytes(method_name_constant->utf8.bytes, method_name_constant->utf8.length); + printc(' '); + print_bytes(method_descriptor_constant->utf8.bytes, method_descriptor_constant->utf8.length); + printc('\n'); + } assert(e != nullptr); assert(e->value != nullptr); diff --git a/c/native/loader.c b/c/native/loader.c index 7df0350..7d30eba 100644 --- a/c/native/loader.c +++ b/c/native/loader.c @@ -3,6 +3,7 @@ #include "string.h" #include "malloc.h" #include "loader.h" +#include "native.h" static uint8_t loader_buffer[0x100000] __attribute__ ((aligned (32))); @@ -12,13 +13,12 @@ void native_jvm_internal_loader_getbuffer_0(struct vm * vm, uint32_t * args) operand_stack_push_u32(vm->current_frame, value); } -extern struct vm vm; - void native_jvm_internal_loader_load_2(struct vm * vm, uint32_t * args) { struct arrayref * arrayref = (struct arrayref *)args[0]; const uint8_t ** buffers = (const uint8_t **)&arrayref->u32[0]; int32_t num_buffers = (int32_t)args[1]; + printf("native_jvm_internal_loader_load_2\n"); debugf("num_buffers: %d\n", num_buffers); debugf("loader_buffer[0]: %p ; buffers[0]: %p\n", &loader_buffer[0], (uint32_t)buffers[0]); @@ -33,10 +33,13 @@ void native_jvm_internal_loader_load_2(struct vm * vm, uint32_t * args) num_buffers, &class_hash_table_length); + int native_hash_table_length; + struct hash_table_entry * native_hash_table = native_init_hash_table(&native_hash_table_length); + vm_start(class_hash_table_length, class_hash_table, - vm->native_hash_table.length, - vm->native_hash_table.entry, + native_hash_table_length, + native_hash_table, main_class, main_class_length); } diff --git a/c/native/math.c b/c/native/math.c index e427a24..b1a98b0 100644 --- a/c/native/math.c +++ b/c/native/math.c @@ -5,7 +5,7 @@ native_java_lang_math_sin_1(struct vm * vm, uint32_t * args) { float arg = ((float *)args)[0]; float value = __builtin_sinf(arg); - operand_stack_push_u32(vm->current_frame, value); + operand_stack_push_f32(vm->current_frame, value); } void __attribute__ ((noinline)) __attribute__ ((optimize(0))) @@ -13,12 +13,12 @@ native_java_lang_math_cos_1(struct vm * vm, uint32_t * args) { float arg = ((float *)args)[0]; float value = __builtin_cosf(arg); - operand_stack_push_u32(vm->current_frame, value); + operand_stack_push_f32(vm->current_frame, value); } void native_java_lang_math_abs_1(struct vm * vm, uint32_t * args) { float arg = ((float *)args)[0]; float value = __builtin_fabsf(arg); - operand_stack_push_u32(vm->current_frame, value); + operand_stack_push_f32(vm->current_frame, value); } diff --git a/classes/example/JavaCube.java b/classes/example/JavaCube.java index 6fb01ec..cfc195f 100644 --- a/classes/example/JavaCube.java +++ b/classes/example/JavaCube.java @@ -21,7 +21,6 @@ import model.Vec2; import model.FacePTN; import model.ModelObject; import java.misc.Memory; -import java.misc.Resource; import filesystem.iso9660.VolumeParser; import filesystem.iso9660.DirectoryRecordHandler; import filesystem.iso9660.DirectoryRecord; @@ -342,13 +341,15 @@ public class JavaCube { int texture = TextureMemoryAllocation.texture_regions[1][0] + 512 + (512 * 512 * 2 * 2); // java_powered - int[] java_powered = Resource.getResource("images/java_powered"); - int java_powered_length = (java_powered == null) ? 0 : java_powered.length; + //int[] java_powered = Resource.getResource("images/java_powered"); + //int java_powered_length = (java_powered == null) ? 0 : java_powered.length; //System.out.print("images/java_powered length: "); //System.out.println(java_powered_length); - for (int i = 0; i < java_powered_length; i++) { - Memory.putU4(MemoryMap.texture_memory64 + texture, java_powered[i]); + //for (int i = 0; i < java_powered_length; i++) { + for (int i = 0; i < 128 * 128; i++) { + //Memory.putU4(MemoryMap.texture_memory64 + texture, java_powered[i]); + Memory.putU4(MemoryMap.texture_memory64 + texture, 0); texture += 4; } } diff --git a/classpath.mk b/classpath.mk index 5bfb2a4..1deffd7 100644 --- a/classpath.mk +++ b/classpath.mk @@ -9,9 +9,14 @@ CLASS_PATH = \ classes/java/io/PrintStream.class.o \ classes/java/lang/DecimalDigits.class.o \ classes/java/lang/Integer.class.o \ + classes/java/lang/Float.class.o \ + classes/java/lang/Number.class.o \ classes/java/lang/Object.class.o \ classes/java/lang/String.class.o \ classes/java/lang/System.class.o \ + classes/java/lang/Exception.class.o \ + classes/java/lang/Throwable.class.o \ + classes/java/lang/Backtrace.class.o \ classes/java/misc/Memory.class.o \ classes/sega/dreamcast/gdrom/G1IF.class.o \ classes/sega/dreamcast/gdrom/GdromIF.class.o \ diff --git a/generate_classpath.sh b/generate_classpath.sh index 2c008e3..ec18b1b 100644 --- a/generate_classpath.sh +++ b/generate_classpath.sh @@ -52,7 +52,7 @@ function make_header () { echo '#include ' >> "${filename}" echo '' >> "${filename}" echo '#ifdef __cplusplus' >> "${filename}" - echo 'extern C {' >> "${filename}" + echo 'extern "C" {' >> "${filename}" echo '#endif' >> "${filename}" echo '' >> "${filename}" echo "extern uint32_t _binary_${name}_start __asm(\"_binary_${name}_start\");" >> "${filename}" @@ -83,9 +83,14 @@ declare -a boot_classes=( java/io/PrintStream.class java/lang/DecimalDigits.class java/lang/Integer.class + java/lang/Float.class + java/lang/Number.class java/lang/Object.class java/lang/String.class java/lang/System.class + java/lang/Exception.class + java/lang/Throwable.class + java/lang/Backtrace.class java/misc/Memory.class sega/dreamcast/gdrom/G1IF.class sega/dreamcast/gdrom/GdromIF.class diff --git a/images/java_powered.data.h b/images/java_powered.data.h index 9b0dffc..2556f31 100644 --- a/images/java_powered.data.h +++ b/images/java_powered.data.h @@ -3,7 +3,7 @@ #include #ifdef __cplusplus -extern C { +extern "C" { #endif extern uint32_t _binary_images_java_powered_data_start __asm("_binary_images_java_powered_data_start");