implement java.lang.Class.getName
This commit is contained in:
parent
aaa55a4f9d
commit
008690543d
@ -441,14 +441,22 @@ struct method_entry class_resolver_lookup_method_from_interfacemethodref_index(i
|
||||
struct attribute_info * attribute = find_attribute(code_index,
|
||||
method_info->attributes_count,
|
||||
method_info->attributes);
|
||||
assert(attribute != nullptr);
|
||||
|
||||
if ((method_info->access_flags & METHOD_ACC_NATIVE) != 0) {
|
||||
return (struct method_entry){
|
||||
.class_entry = class_entry,
|
||||
.method_info = method_info,
|
||||
.code_attribute = nullptr,
|
||||
};
|
||||
} else {
|
||||
assert(attribute != nullptr);
|
||||
return (struct method_entry){
|
||||
.class_entry = class_entry,
|
||||
.method_info = method_info,
|
||||
.code_attribute = attribute->code,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (class_entry->class_file->super_class == 0)
|
||||
break;
|
||||
@ -606,24 +614,12 @@ struct objectref * class_resolver_lookup_string(struct vm * vm,
|
||||
struct constant * utf8_constant = &class_entry->class_file->constant_pool[string_constant->string.string_index - 1];
|
||||
assert(utf8_constant->tag == CONSTANT_Utf8);
|
||||
|
||||
int32_t count = utf8_constant->utf8.length;
|
||||
struct arrayref * arrayref = prim_array_allocate(vm, 1, count);
|
||||
assert(arrayref != nullptr);
|
||||
arrayref->class_entry = nullptr; // byte[]
|
||||
arrayref->length = utf8_constant->utf8.length;
|
||||
for (int i = 0; i < utf8_constant->utf8.length; i++) {
|
||||
arrayref->u8[i] = utf8_constant->utf8.bytes[i];
|
||||
}
|
||||
|
||||
struct objectref * objectref = vm_instance_create(vm, "java/lang/String");
|
||||
assert(objectref != nullptr);
|
||||
assert(objectref->class_entry->instance_fields_count >= 1);
|
||||
objectref->aref[0] = arrayref;
|
||||
struct objectref * string_objectref = vm_instance_string_from_constant(vm, utf8_constant);
|
||||
|
||||
// cache the result
|
||||
class_entry->attribute_entry[string_index - 1].string_objectref = objectref;
|
||||
class_entry->attribute_entry[string_index - 1].string_objectref = string_objectref;
|
||||
|
||||
return objectref;
|
||||
return string_objectref;
|
||||
}
|
||||
|
||||
bool class_resolver_instanceof(int class_hash_table_length,
|
||||
|
22
c/native.c
22
c/native.c
@ -3,10 +3,12 @@
|
||||
#include "string.h"
|
||||
#include "printf.h"
|
||||
#include "native.h"
|
||||
#include "native/class.h"
|
||||
#include "native/loader.h"
|
||||
#include "native/math.h"
|
||||
#include "native/memory.h"
|
||||
#include "native/object.h"
|
||||
#include "native/printstream.h"
|
||||
#include "native/loader.h"
|
||||
|
||||
typedef void (* native_func_t)(struct vm * vm, uint32_t * args);
|
||||
|
||||
@ -102,6 +104,24 @@ const static struct native_method native_method[] = {
|
||||
.method_descriptor = "()I",
|
||||
.func = native_jvm_internal_loader_getbuffer_0,
|
||||
},
|
||||
{
|
||||
.class_name = "java/lang/Class",
|
||||
.method_name = "getClassName",
|
||||
.method_descriptor = "()Ljava/lang/String;",
|
||||
.func = native_java_lang_class_getclassname_1,
|
||||
},
|
||||
{
|
||||
.class_name = "java/lang/Object",
|
||||
.method_name = "getClass",
|
||||
.method_descriptor = "()Ljava/lang/Class;",
|
||||
.func = native_java_lang_object_getclass_1,
|
||||
},
|
||||
{
|
||||
.class_name = "java/lang/Object",
|
||||
.method_name = "hashCode",
|
||||
.method_descriptor = "()I",
|
||||
.func = native_java_lang_object_hashcode_1,
|
||||
},
|
||||
};
|
||||
|
||||
struct hash_table_entry * native_init_hash_table(int * hash_table_length)
|
||||
|
23
c/native/class.c
Normal file
23
c/native/class.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "class.h"
|
||||
#include "printf.h"
|
||||
#include "vm_instance.h"
|
||||
|
||||
void native_java_lang_class_getclassname_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];
|
||||
assert(class_constant->tag == CONSTANT_Class);
|
||||
|
||||
struct constant * class_name_constant = &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);
|
||||
}
|
7
c/native/class.h
Normal file
7
c/native/class.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
void native_java_lang_class_getclassname_1(struct vm * vm, uint32_t * args);
|
23
c/native/object.c
Normal file
23
c/native/object.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "object.h"
|
||||
#include "printf.h"
|
||||
#include "vm_instance.h"
|
||||
|
||||
void native_java_lang_object_getclass_1(struct vm * vm, uint32_t * args)
|
||||
{
|
||||
struct objectref * objectref = (struct objectref *)args[0];
|
||||
assert(objectref != nullptr);
|
||||
|
||||
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] = objectref;
|
||||
|
||||
operand_stack_push_ref(vm->current_frame, class_objectref);
|
||||
}
|
||||
|
||||
void native_java_lang_object_hashcode_1(struct vm * vm, uint32_t * args)
|
||||
{
|
||||
struct objectref * objectref = (struct objectref *)args[0];
|
||||
operand_stack_push_u32(vm->current_frame, (uint32_t)objectref); // objectref as integer
|
||||
}
|
9
c/native/object.h
Normal file
9
c/native/object.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
void native_java_lang_object_getclass_1(struct vm * vm, uint32_t * args);
|
||||
|
||||
void native_java_lang_object_hashcode_1(struct vm * vm, uint32_t * args);
|
@ -21,3 +21,22 @@ struct objectref * vm_instance_create(struct vm * vm, const char * class_name)
|
||||
|
||||
return objectref;
|
||||
}
|
||||
|
||||
struct objectref * vm_instance_string_from_constant(struct vm * vm, struct constant * constant)
|
||||
{
|
||||
int32_t count = constant->utf8.length;
|
||||
struct arrayref * arrayref = prim_array_allocate(vm, 1, count);
|
||||
assert(arrayref != nullptr);
|
||||
arrayref->class_entry = nullptr; // byte[]
|
||||
arrayref->length = constant->utf8.length;
|
||||
for (int i = 0; i < constant->utf8.length; i++) {
|
||||
arrayref->u8[i] = constant->utf8.bytes[i];
|
||||
}
|
||||
|
||||
struct objectref * objectref = vm_instance_create(vm, "java/lang/String");
|
||||
assert(objectref != nullptr);
|
||||
assert(objectref->class_entry->instance_fields_count >= 1);
|
||||
objectref->aref[0] = arrayref;
|
||||
|
||||
return objectref;
|
||||
}
|
||||
|
@ -3,3 +3,4 @@
|
||||
#include "frame.h"
|
||||
|
||||
struct objectref * vm_instance_create(struct vm * vm, const char * class_name);
|
||||
struct objectref * vm_instance_string_from_constant(struct vm * vm, struct constant * constant);
|
||||
|
8
classes/test/TestClass.java
Normal file
8
classes/test/TestClass.java
Normal file
@ -0,0 +1,8 @@
|
||||
package test;
|
||||
|
||||
class TestClass {
|
||||
public static void main() {
|
||||
TestClass obj = new TestClass();
|
||||
System.out.println(obj.getClass().getName());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user