correct invokevirtual method resolution order
This commit is contained in:
parent
5c88c8f7c1
commit
9677332560
@ -389,7 +389,7 @@ struct method_entry class_resolver_lookup_method_from_interfacemethodref_index(i
|
||||
struct class_entry * origin_class_entry)
|
||||
{
|
||||
struct constant * interfacemethodref_constant = &origin_class_entry->class_file->constant_pool[interfacemethodref_index - 1];
|
||||
assert(interfacemethodref_constant->tag == CONSTANT_InterfaceMethodref);
|
||||
assert(interfacemethodref_constant->tag == CONSTANT_InterfaceMethodref || interfacemethodref_constant->tag == CONSTANT_Methodref);
|
||||
struct constant * nameandtype_constant = &origin_class_entry->class_file->constant_pool[interfacemethodref_constant->interfacemethodref.name_and_type_index - 1];
|
||||
assert(nameandtype_constant->tag == CONSTANT_NameAndType);
|
||||
struct constant * method_name_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.name_index - 1];
|
||||
|
34
c/execute.c
34
c/execute.c
@ -1157,15 +1157,37 @@ void op_invokestatic(struct vm * vm, uint32_t index)
|
||||
vm_static_method_call(vm, method_entry->class_entry, method_entry->method_info);
|
||||
}
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
void op_invokevirtual(struct vm * vm, uint32_t index)
|
||||
{
|
||||
struct method_entry * method_entry =
|
||||
class_resolver_lookup_method_from_methodref_index(vm->class_hash_table.length,
|
||||
vm->class_hash_table.entry,
|
||||
index,
|
||||
vm->current_frame->class_entry);
|
||||
struct class_entry * origin_class_entry = vm->current_frame->class_entry;
|
||||
|
||||
vm_special_method_call(vm, method_entry->class_entry, method_entry->method_info);
|
||||
struct constant * interfacemethodref_constant = &origin_class_entry->class_file->constant_pool[index - 1];
|
||||
assert(interfacemethodref_constant->tag == CONSTANT_Methodref);
|
||||
struct constant * nameandtype_constant = &origin_class_entry->class_file->constant_pool[interfacemethodref_constant->interfacemethodref.name_and_type_index - 1];
|
||||
assert(nameandtype_constant->tag == CONSTANT_NameAndType);
|
||||
struct constant * method_name_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.name_index - 1];
|
||||
assert(method_name_constant->tag == CONSTANT_Utf8);
|
||||
struct constant * method_descriptor_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.descriptor_index - 1];
|
||||
assert(method_descriptor_constant->tag == CONSTANT_Utf8);
|
||||
|
||||
uint8_t return_type;
|
||||
int nargs = descriptor_nargs(method_descriptor_constant, &return_type);
|
||||
(void)return_type;
|
||||
|
||||
int32_t * objectref = (int32_t *)operand_stack_peek_u32(vm->current_frame, nargs + 1);
|
||||
assert(objectref != nullptr);
|
||||
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
||||
|
||||
struct method_entry method_entry =
|
||||
class_resolver_lookup_method_from_interfacemethodref_index(vm->class_hash_table.length,
|
||||
vm->class_hash_table.entry,
|
||||
index,
|
||||
class_entry,
|
||||
vm->current_frame->class_entry);
|
||||
|
||||
vm_special_method_call(vm, method_entry.class_entry, method_entry.method_info);
|
||||
}
|
||||
|
||||
void op_ior(struct vm * vm)
|
||||
|
@ -48,7 +48,7 @@ int find_constantvalue_name_index(struct class_file * class_file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int descriptor_nargs(struct constant * descriptor_constant, uint8_t * return_type)
|
||||
int descriptor_nargs(struct constant * descriptor_constant, uint8_t * return_type)
|
||||
{
|
||||
assert(descriptor_constant->tag == CONSTANT_Utf8);
|
||||
assert(descriptor_constant->utf8.length >= 2);
|
||||
|
@ -164,3 +164,4 @@ void vm_start(int class_hash_table_length,
|
||||
struct hash_table_entry * class_hash_table,
|
||||
const uint8_t * main_class,
|
||||
int main_class_length);
|
||||
int descriptor_nargs(struct constant * descriptor_constant, uint8_t * return_type);
|
||||
|
@ -19,8 +19,8 @@ public class String {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static String valueOf(Object obj) {
|
||||
return (obj == null) ? "null" : obj.toString();
|
||||
public String toString() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public static String valueOf(boolean b) {
|
||||
@ -42,4 +42,8 @@ public class String {
|
||||
public static String valueOf(double d) {
|
||||
return Double.toString(d);
|
||||
}
|
||||
|
||||
public static String valueOf(Object obj) {
|
||||
return (obj == null) ? "null" : obj.toString();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user