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 class_entry * origin_class_entry)
|
||||||
{
|
{
|
||||||
struct constant * interfacemethodref_constant = &origin_class_entry->class_file->constant_pool[interfacemethodref_index - 1];
|
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];
|
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);
|
assert(nameandtype_constant->tag == CONSTANT_NameAndType);
|
||||||
struct constant * method_name_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.name_index - 1];
|
struct constant * method_name_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.name_index - 1];
|
||||||
|
28
c/execute.c
28
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);
|
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)
|
void op_invokevirtual(struct vm * vm, uint32_t index)
|
||||||
{
|
{
|
||||||
struct method_entry * method_entry =
|
struct class_entry * origin_class_entry = vm->current_frame->class_entry;
|
||||||
class_resolver_lookup_method_from_methodref_index(vm->class_hash_table.length,
|
|
||||||
|
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,
|
vm->class_hash_table.entry,
|
||||||
index,
|
index,
|
||||||
|
class_entry,
|
||||||
vm->current_frame->class_entry);
|
vm->current_frame->class_entry);
|
||||||
|
|
||||||
vm_special_method_call(vm, method_entry->class_entry, method_entry->method_info);
|
vm_special_method_call(vm, method_entry.class_entry, method_entry.method_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_ior(struct vm * vm)
|
void op_ior(struct vm * vm)
|
||||||
|
@ -48,7 +48,7 @@ int find_constantvalue_name_index(struct class_file * class_file)
|
|||||||
return 0;
|
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->tag == CONSTANT_Utf8);
|
||||||
assert(descriptor_constant->utf8.length >= 2);
|
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,
|
struct hash_table_entry * class_hash_table,
|
||||||
const uint8_t * main_class,
|
const uint8_t * main_class,
|
||||||
int main_class_length);
|
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;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String valueOf(Object obj) {
|
public String toString() {
|
||||||
return (obj == null) ? "null" : obj.toString();
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String valueOf(boolean b) {
|
public static String valueOf(boolean b) {
|
||||||
@ -42,4 +42,8 @@ public class String {
|
|||||||
public static String valueOf(double d) {
|
public static String valueOf(double d) {
|
||||||
return Double.toString(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