diff --git a/c/native.c b/c/native.c index 60df6cf..45aaab0 100644 --- a/c/native.c +++ b/c/native.c @@ -121,9 +121,15 @@ const static struct native_method native_method[] = { { .class_name = "java/lang/Class", .method_name = "_getName", - .method_descriptor = "()Ljava/lang/String;", + .method_descriptor = "(Ljava/lang/Object;)Ljava/lang/String;", .func = native_java_lang_class_getname_1, }, + { + .class_name = "java/lang/Class", + .method_name = "_getSuperclass", + .method_descriptor = "(Ljava/lang/Object;)Ljava/lang/String;", + .func = native_java_lang_class_getsuperclass_1, + }, { .class_name = "java/lang/Object", .method_name = "_getClass", diff --git a/c/native/class.c b/c/native/class.c index 75c7c26..58f995f 100644 --- a/c/native/class.c +++ b/c/native/class.c @@ -6,18 +6,39 @@ void native_java_lang_class_getname_1(struct vm * vm, uint32_t * args) { struct objectref * objectref = (struct objectref *)args[0]; assert(objectref != nullptr); - assert(objectref->oref[0] != nullptr); - assert(objectref->oref[0]->class_entry != nullptr); - struct class_file * class_file = objectref->oref[0]->class_entry->class_file; - struct constant * class_constant = &class_file->constant_pool[class_file->this_class - 1]; + struct class_entry * class_entry = (struct class_entry *)objectref->oref[0]; + + struct constant * class_constant = &class_entry->class_file->constant_pool[class_entry->class_file->this_class - 1]; assert(class_constant->tag == CONSTANT_Class); - struct constant * class_name_constant = &class_file->constant_pool[class_constant->class.name_index - 1]; + struct constant * class_name_constant = &class_entry->class_file->constant_pool[class_constant->class.name_index - 1]; assert(class_name_constant->tag == CONSTANT_Utf8); struct objectref * string_objectref = vm_instance_string_from_constant(vm, class_name_constant); operand_stack_push_ref(vm->current_frame, string_objectref); } + +void native_java_lang_class_getsuperclass_1(struct vm * vm, uint32_t * args) +{ + struct objectref * objectref = (struct objectref *)args[0]; + assert(objectref != nullptr); + assert(objectref->oref[0] != nullptr); + + struct class_entry * class_entry = (struct class_entry *)objectref->oref[0]; + + struct class_entry * super_class_entry = class_resolver_lookup_class_from_class_index(vm->class_hash_table.length, + vm->class_hash_table.entry, + class_entry, + class_entry->class_file->super_class); + + struct objectref * class_objectref = vm_instance_create(vm, "java/lang/Class"); + assert(class_objectref != nullptr); + assert(class_objectref->class_entry->instance_fields_count >= 1); + + class_objectref->oref[0] = (struct objectref *)super_class_entry; + + operand_stack_push_ref(vm->current_frame, class_objectref); +} diff --git a/c/native/class.h b/c/native/class.h index 0c7a33c..8f98d37 100644 --- a/c/native/class.h +++ b/c/native/class.h @@ -5,3 +5,4 @@ #include "frame.h" void native_java_lang_class_getname_1(struct vm * vm, uint32_t * args); +void native_java_lang_class_getsuperclass_1(struct vm * vm, uint32_t * args); diff --git a/c/native/object.c b/c/native/object.c index 8e7c3d6..0d34cb8 100644 --- a/c/native/object.c +++ b/c/native/object.c @@ -10,7 +10,7 @@ void native_java_lang_object_getclass_1(struct vm * vm, uint32_t * args) assert(class_objectref != nullptr); assert(class_objectref->class_entry->instance_fields_count >= 1); - class_objectref->oref[0] = objectref; + class_objectref->oref[0] = (struct objectref *)objectref->class_entry; operand_stack_push_ref(vm->current_frame, class_objectref); } diff --git a/classes/java/lang/Class.java b/classes/java/lang/Class.java index 5fd5f89..80245bc 100644 --- a/classes/java/lang/Class.java +++ b/classes/java/lang/Class.java @@ -1,18 +1,24 @@ package java.lang; public final class Class { - private Object object; + private Object klass; // struct class_entry * private String name; private Class() { } - private native String _getName(); + private static native String _getName(Object o); public String getName() { if (this.name == null) { - this.name = _getName(); + this.name = _getName(this); } return this.name; } + + private static native Class _getSuperclass(Class c); + + public Class getSuperclass() { + return (Class)(_getSuperclass(this)); + } } diff --git a/classes/java/lang/Enum.java b/classes/java/lang/Enum.java new file mode 100644 index 0000000..7cdee91 --- /dev/null +++ b/classes/java/lang/Enum.java @@ -0,0 +1,58 @@ +package java.lang; + +public abstract class Enum> + implements Comparable { + + final String name; + + final int ordinal; + + protected Enum(String name, + int ordinal) { + this.name = name; + this.ordinal = ordinal; + } + + protected final Object clone() + throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + public final int compareTo(E o) { + if (getDeclaringClass() != o.getDeclaringClass()) + throw new ClassCastException(); + return ordinal - o.ordinal; + } + + public final boolean equals(Object other) { + return this == other; + } + + public final Class getDeclaringClass() { + Class c = getClass(); + if (c.getSuperclass() != Enum.class) + c = c.getSuperclass(); + return c; + } + + public final int hashCode() { + return ordinal; + } + + public final String name() { + return name; + } + + public final int ordinal() { + return ordinal; + } + + public String toString() { + return name; + } + + public static > T valueOf(Class enumType, + String name) { + return null; + } +} diff --git a/classes/test/TestEnum.java b/classes/test/TestEnum.java new file mode 100644 index 0000000..184a2dc --- /dev/null +++ b/classes/test/TestEnum.java @@ -0,0 +1,15 @@ +package test; + +public class TestEnum { + enum Level { + LOW, + MEDIUM, + HIGH + } + + public static void main() { + System.out.println(args.length); + Level level = Level.MEDIUM; + System.out.println(level); + } +}