Compare commits
2 Commits
45501b58cb
...
9982538c89
Author | SHA1 | Date | |
---|---|---|---|
9982538c89 | |||
8f49f69e7e |
@ -2,18 +2,19 @@
|
|||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "class_file.h"
|
#include "class_file.h"
|
||||||
#include "hash_table.h"
|
|
||||||
#include "malloc.h"
|
|
||||||
#include "class_resolver.h"
|
#include "class_resolver.h"
|
||||||
#include "string.h"
|
|
||||||
#include "memory_allocator.h"
|
|
||||||
#include "printf.h"
|
|
||||||
#include "field_size.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "fatal.h"
|
#include "fatal.h"
|
||||||
#include "parse_type.h"
|
#include "field_size.h"
|
||||||
#include "find_attribute.h"
|
#include "find_attribute.h"
|
||||||
|
#include "hash_table.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "memory_allocator.h"
|
||||||
|
#include "native_method.h"
|
||||||
#include "native_types_allocate.h"
|
#include "native_types_allocate.h"
|
||||||
|
#include "parse_type.h"
|
||||||
|
#include "printf.h"
|
||||||
|
#include "string.h"
|
||||||
#include "vm_instance.h"
|
#include "vm_instance.h"
|
||||||
|
|
||||||
static int field_info_field_size(struct class_file * class_file, struct field_info * field_info)
|
static int field_info_field_size(struct class_file * class_file, struct field_info * field_info)
|
||||||
@ -441,9 +442,7 @@ struct method_info * class_resolver_lookup_method(int methods_hash_table_length,
|
|||||||
static struct Code_attribute * resolve_code_attribute(struct class_entry * class_entry,
|
static struct Code_attribute * resolve_code_attribute(struct class_entry * class_entry,
|
||||||
struct method_info * method_info)
|
struct method_info * method_info)
|
||||||
{
|
{
|
||||||
if ((method_info->access_flags & METHOD_ACC_NATIVE) != 0) {
|
assert((method_info->access_flags & METHOD_ACC_NATIVE) == 0);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int code_index = find_code_name_index(class_entry->class_file);
|
int code_index = find_code_name_index(class_entry->class_file);
|
||||||
assert(code_index != 0);
|
assert(code_index != 0);
|
||||||
@ -454,7 +453,8 @@ static struct Code_attribute * resolve_code_attribute(struct class_entry * class
|
|||||||
return attribute->code;
|
return attribute->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_method_entry(struct class_entry * class_entry,
|
static void resolve_method_entry(struct vm * vm,
|
||||||
|
struct class_entry * class_entry,
|
||||||
struct constant * method_name_constant,
|
struct constant * method_name_constant,
|
||||||
struct constant * method_descriptor_constant,
|
struct constant * method_descriptor_constant,
|
||||||
struct method_entry * method_entry)
|
struct method_entry * method_entry)
|
||||||
@ -470,7 +470,26 @@ static void resolve_method_entry(struct class_entry * class_entry,
|
|||||||
|
|
||||||
method_entry->class_entry = class_entry;
|
method_entry->class_entry = class_entry;
|
||||||
method_entry->method_info = method_info;
|
method_entry->method_info = method_info;
|
||||||
|
if ((method_info->access_flags & METHOD_ACC_NATIVE) == 0) {
|
||||||
method_entry->code_attribute = resolve_code_attribute(class_entry, method_info);
|
method_entry->code_attribute = resolve_code_attribute(class_entry, method_info);
|
||||||
|
} else {
|
||||||
|
struct class_file * class_file = 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 constant * method_name_constant = &class_file->constant_pool[method_info->name_index - 1];
|
||||||
|
assert(method_name_constant->tag == CONSTANT_Utf8);
|
||||||
|
struct constant * method_descriptor_constant = &class_file->constant_pool[method_info->descriptor_index - 1];
|
||||||
|
assert(method_descriptor_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
|
method_entry->native_func = native_method_lookup(vm->native_hash_table.length,
|
||||||
|
vm->native_hash_table.entry,
|
||||||
|
class_name_constant,
|
||||||
|
method_name_constant,
|
||||||
|
method_descriptor_constant);
|
||||||
|
}
|
||||||
|
|
||||||
debugf("method resolved:\n");
|
debugf("method resolved:\n");
|
||||||
debugf(" class: ");
|
debugf(" class: ");
|
||||||
@ -480,8 +499,7 @@ static void resolve_method_entry(struct class_entry * class_entry,
|
|||||||
debugc('\n');
|
debugc('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_method_entry_from_superclasses(int class_hash_table_length,
|
static void resolve_method_entry_from_superclasses(struct vm * vm,
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
struct class_entry * class_entry,
|
struct class_entry * class_entry,
|
||||||
struct constant * method_name_constant,
|
struct constant * method_name_constant,
|
||||||
struct constant * method_descriptor_constant,
|
struct constant * method_descriptor_constant,
|
||||||
@ -492,7 +510,8 @@ static void resolve_method_entry_from_superclasses(int class_hash_table_length,
|
|||||||
method_entry->method_info = nullptr;
|
method_entry->method_info = nullptr;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
resolve_method_entry(class_entry,
|
resolve_method_entry(vm,
|
||||||
|
class_entry,
|
||||||
method_name_constant,
|
method_name_constant,
|
||||||
method_descriptor_constant,
|
method_descriptor_constant,
|
||||||
method_entry);
|
method_entry);
|
||||||
@ -508,20 +527,20 @@ static void resolve_method_entry_from_superclasses(int class_hash_table_length,
|
|||||||
assert(class_name_constant->tag == CONSTANT_Utf8);
|
assert(class_name_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
// lookup the method from the superclass
|
// lookup the method from the superclass
|
||||||
class_entry = class_resolver_lookup_class_from_class_index(class_hash_table_length,
|
class_entry = class_resolver_lookup_class_from_class_index(vm->class_hash_table.length,
|
||||||
class_hash_table,
|
vm->class_hash_table.entry,
|
||||||
class_entry,
|
class_entry,
|
||||||
class_entry->class_file->super_class);
|
class_entry->class_file->super_class);
|
||||||
assert(class_entry != nullptr);
|
assert(class_entry != nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct method_entry class_resolver_lookup_method_from_objectref_class(int class_hash_table_length,
|
struct method_entry class_resolver_lookup_method_from_objectref_class(struct vm * vm,
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
int32_t methodref_index,
|
int32_t methodref_index,
|
||||||
struct class_entry * objectref_class_entry,
|
struct class_entry * objectref_class_entry)
|
||||||
struct class_entry * origin_class_entry)
|
|
||||||
{
|
{
|
||||||
|
struct class_entry * origin_class_entry = vm->current_frame->class_entry;
|
||||||
|
|
||||||
struct constant * methodref_constant = &origin_class_entry->class_file->constant_pool[methodref_index - 1];
|
struct constant * methodref_constant = &origin_class_entry->class_file->constant_pool[methodref_index - 1];
|
||||||
assert(methodref_constant->tag == CONSTANT_InterfaceMethodref || methodref_constant->tag == CONSTANT_Methodref);
|
assert(methodref_constant->tag == CONSTANT_InterfaceMethodref || methodref_constant->tag == CONSTANT_Methodref);
|
||||||
struct constant * nameandtype_constant = &origin_class_entry->class_file->constant_pool[methodref_constant->methodref.name_and_type_index - 1];
|
struct constant * nameandtype_constant = &origin_class_entry->class_file->constant_pool[methodref_constant->methodref.name_and_type_index - 1];
|
||||||
@ -535,8 +554,7 @@ struct method_entry class_resolver_lookup_method_from_objectref_class(int class_
|
|||||||
|
|
||||||
struct method_entry method_entry;
|
struct method_entry method_entry;
|
||||||
|
|
||||||
resolve_method_entry_from_superclasses(class_hash_table_length,
|
resolve_method_entry_from_superclasses(vm,
|
||||||
class_hash_table,
|
|
||||||
class_entry,
|
class_entry,
|
||||||
method_name_constant,
|
method_name_constant,
|
||||||
method_descriptor_constant,
|
method_descriptor_constant,
|
||||||
@ -545,11 +563,10 @@ struct method_entry class_resolver_lookup_method_from_objectref_class(int class_
|
|||||||
return method_entry;
|
return method_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct method_entry * class_resolver_lookup_method_from_origin_class(int class_hash_table_length,
|
struct method_entry * class_resolver_lookup_method_from_origin_class(struct vm * vm,
|
||||||
struct hash_table_entry * class_hash_table,
|
int32_t methodref_index)
|
||||||
int32_t methodref_index,
|
|
||||||
struct class_entry * origin_class_entry)
|
|
||||||
{
|
{
|
||||||
|
struct class_entry * origin_class_entry = vm->current_frame->class_entry;
|
||||||
if (origin_class_entry->attribute_entry[methodref_index - 1].method_entry != nullptr) {
|
if (origin_class_entry->attribute_entry[methodref_index - 1].method_entry != nullptr) {
|
||||||
debugf("class_resolver_lookup_method_from_origin_class %d: [cached]\n", methodref_index);
|
debugf("class_resolver_lookup_method_from_origin_class %d: [cached]\n", methodref_index);
|
||||||
return origin_class_entry->attribute_entry[methodref_index - 1].method_entry;
|
return origin_class_entry->attribute_entry[methodref_index - 1].method_entry;
|
||||||
@ -564,15 +581,14 @@ struct method_entry * class_resolver_lookup_method_from_origin_class(int class_h
|
|||||||
struct constant * method_descriptor_constant = &origin_class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.descriptor_index - 1];
|
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);
|
assert(method_descriptor_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
struct class_entry * class_entry = class_resolver_lookup_class_from_class_index(class_hash_table_length,
|
struct class_entry * class_entry = class_resolver_lookup_class_from_class_index(vm->class_hash_table.length,
|
||||||
class_hash_table,
|
vm->class_hash_table.entry,
|
||||||
origin_class_entry,
|
origin_class_entry,
|
||||||
methodref_constant->methodref.class_index);
|
methodref_constant->methodref.class_index);
|
||||||
|
|
||||||
struct method_entry * method_entry = malloc_class_arena((sizeof (struct method_entry)));
|
struct method_entry * method_entry = malloc_class_arena((sizeof (struct method_entry)));
|
||||||
|
|
||||||
resolve_method_entry_from_superclasses(class_hash_table_length,
|
resolve_method_entry_from_superclasses(vm,
|
||||||
class_hash_table,
|
|
||||||
class_entry,
|
class_entry,
|
||||||
method_name_constant,
|
method_name_constant,
|
||||||
method_descriptor_constant,
|
method_descriptor_constant,
|
||||||
@ -597,8 +613,8 @@ struct method_entry class_resolver_lookup_method_from_method_name_method_descrip
|
|||||||
method_name_length,
|
method_name_length,
|
||||||
method_descriptor,
|
method_descriptor,
|
||||||
method_descriptor_length);
|
method_descriptor_length);
|
||||||
|
|
||||||
if (method_info != nullptr) {
|
if (method_info != nullptr) {
|
||||||
|
assert ((method_info->access_flags & METHOD_ACC_NATIVE) == 0);
|
||||||
int code_index = find_code_name_index(class_entry->class_file);
|
int code_index = find_code_name_index(class_entry->class_file);
|
||||||
assert(code_index != 0);
|
assert(code_index != 0);
|
||||||
debugf("code_index: %d\n", code_index);
|
debugf("code_index: %d\n", code_index);
|
||||||
|
@ -19,15 +19,11 @@ struct class_entry * class_resolver_lookup_class_from_class_index(int class_hash
|
|||||||
struct class_entry * class_entry,
|
struct class_entry * class_entry,
|
||||||
int32_t class_index);
|
int32_t class_index);
|
||||||
|
|
||||||
struct method_entry class_resolver_lookup_method_from_objectref_class(int class_hash_table_length,
|
struct method_entry class_resolver_lookup_method_from_objectref_class(struct vm * vm,
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
int32_t methodref_index,
|
int32_t methodref_index,
|
||||||
struct class_entry * objectref_class_entry,
|
struct class_entry * objectref_class_entry);
|
||||||
struct class_entry * origin_class_entry);
|
struct method_entry * class_resolver_lookup_method_from_origin_class(struct vm * vm,
|
||||||
struct method_entry * class_resolver_lookup_method_from_origin_class(int class_hash_table_length,
|
int32_t methodref_index);
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
int32_t methodref_index,
|
|
||||||
struct class_entry * origin_class_entry);
|
|
||||||
|
|
||||||
struct method_entry class_resolver_lookup_method_from_method_name_method_descriptor(struct class_entry * class_entry,
|
struct method_entry class_resolver_lookup_method_from_method_name_method_descriptor(struct class_entry * class_entry,
|
||||||
const uint8_t * method_name,
|
const uint8_t * method_name,
|
||||||
|
22
c/execute.c
22
c/execute.c
@ -1210,11 +1210,9 @@ void op_invokeinterface(struct vm * vm, uint32_t index, uint32_t count)
|
|||||||
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
||||||
|
|
||||||
struct method_entry method_entry =
|
struct method_entry method_entry =
|
||||||
class_resolver_lookup_method_from_objectref_class(vm->class_hash_table.length,
|
class_resolver_lookup_method_from_objectref_class(vm,
|
||||||
vm->class_hash_table.entry,
|
|
||||||
index,
|
index,
|
||||||
objectref->class_entry,
|
objectref->class_entry);
|
||||||
vm->current_frame->class_entry);
|
|
||||||
|
|
||||||
vm_special_method_call(vm, method_entry.class_entry, &method_entry);
|
vm_special_method_call(vm, method_entry.class_entry, &method_entry);
|
||||||
}
|
}
|
||||||
@ -1239,10 +1237,7 @@ void op_invokespecial(struct vm * vm, uint32_t index)
|
|||||||
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
||||||
|
|
||||||
struct method_entry * method_entry =
|
struct method_entry * method_entry =
|
||||||
class_resolver_lookup_method_from_origin_class(vm->class_hash_table.length,
|
class_resolver_lookup_method_from_origin_class(vm, index);
|
||||||
vm->class_hash_table.entry,
|
|
||||||
index,
|
|
||||||
vm->current_frame->class_entry);
|
|
||||||
|
|
||||||
vm_special_method_call(vm, method_entry->class_entry, method_entry);
|
vm_special_method_call(vm, method_entry->class_entry, method_entry);
|
||||||
}
|
}
|
||||||
@ -1250,10 +1245,7 @@ void op_invokespecial(struct vm * vm, uint32_t index)
|
|||||||
void op_invokestatic(struct vm * vm, uint32_t index)
|
void op_invokestatic(struct vm * vm, uint32_t index)
|
||||||
{
|
{
|
||||||
struct method_entry * method_entry =
|
struct method_entry * method_entry =
|
||||||
class_resolver_lookup_method_from_origin_class(vm->class_hash_table.length,
|
class_resolver_lookup_method_from_origin_class(vm, index);
|
||||||
vm->class_hash_table.entry,
|
|
||||||
index,
|
|
||||||
vm->current_frame->class_entry);
|
|
||||||
|
|
||||||
/* On successful resolution of the method, the class or interface that
|
/* On successful resolution of the method, the class or interface that
|
||||||
declared the resolved method is initialized if that class or interface has
|
declared the resolved method is initialized if that class or interface has
|
||||||
@ -1282,11 +1274,9 @@ void op_invokevirtual(struct vm * vm, uint32_t index)
|
|||||||
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
return vm_exception(vm, vm_instance_create(vm, "java/lang/NullPointerException"));
|
||||||
|
|
||||||
struct method_entry method_entry =
|
struct method_entry method_entry =
|
||||||
class_resolver_lookup_method_from_objectref_class(vm->class_hash_table.length,
|
class_resolver_lookup_method_from_objectref_class(vm,
|
||||||
vm->class_hash_table.entry,
|
|
||||||
index,
|
index,
|
||||||
objectref->class_entry,
|
objectref->class_entry);
|
||||||
vm->current_frame->class_entry);
|
|
||||||
|
|
||||||
vm_special_method_call(vm, method_entry.class_entry, &method_entry);
|
vm_special_method_call(vm, method_entry.class_entry, &method_entry);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "vm.h"
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
enum initialization_state {
|
enum initialization_state {
|
||||||
@ -11,10 +10,17 @@ enum initialization_state {
|
|||||||
CLASS_INITIALIZED,
|
CLASS_INITIALIZED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vm;
|
||||||
|
|
||||||
|
typedef void (native_func_t)(struct vm * vm, uint32_t * args);
|
||||||
|
|
||||||
struct method_entry {
|
struct method_entry {
|
||||||
struct class_entry * class_entry;
|
struct class_entry * class_entry;
|
||||||
struct method_info * method_info;
|
struct method_info * method_info;
|
||||||
|
union {
|
||||||
struct Code_attribute * code_attribute;
|
struct Code_attribute * code_attribute;
|
||||||
|
native_func_t * native_func;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
union attribute_entry {
|
union attribute_entry {
|
||||||
@ -74,6 +80,20 @@ struct stack {
|
|||||||
int32_t capacity;
|
int32_t capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vm {
|
||||||
|
struct stack frame_stack;
|
||||||
|
struct stack data_stack;
|
||||||
|
struct frame * current_frame;
|
||||||
|
struct {
|
||||||
|
int length;
|
||||||
|
struct hash_table_entry * entry;
|
||||||
|
} class_hash_table;
|
||||||
|
struct {
|
||||||
|
int length;
|
||||||
|
struct hash_table_entry * entry;
|
||||||
|
} native_hash_table;
|
||||||
|
};
|
||||||
|
|
||||||
static inline struct frame * stack_push_frame(struct stack * stack, int num_frames)
|
static inline struct frame * stack_push_frame(struct stack * stack, int num_frames)
|
||||||
{
|
{
|
||||||
struct frame * frame = &stack->frame[stack->ix];
|
struct frame * frame = &stack->frame[stack->ix];
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "class_resolver.h"
|
#include "class_resolver.h"
|
||||||
#include "native.h"
|
#include "native_method.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
|
|
||||||
#include "classpath.h"
|
#include "classpath.h"
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "printf.h"
|
|
||||||
#include "class_resolver.h"
|
#include "class_resolver.h"
|
||||||
#include "string.h"
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "native.h"
|
|
||||||
#include "memory_allocator.h"
|
#include "memory_allocator.h"
|
||||||
|
#include "native_method.h"
|
||||||
|
#include "printf.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
void * memset(void * s, int c, size_t n);
|
void * memset(void * s, int c, size_t n);
|
||||||
|
|
||||||
|
10
c/native.h
10
c/native.h
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "vm.h"
|
|
||||||
|
|
||||||
void native_method_call(struct vm * vm,
|
|
||||||
struct constant * class_name_constant,
|
|
||||||
struct constant * method_name_constant,
|
|
||||||
struct constant * method_descriptor_constant,
|
|
||||||
uint32_t * args);
|
|
||||||
struct hash_table_entry * native_init_hash_table(int * hash_table_length);
|
|
@ -1,10 +1,10 @@
|
|||||||
|
#include "class_resolver.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "native_method.h"
|
||||||
#include "native_types.h"
|
#include "native_types.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "malloc.h"
|
|
||||||
#include "loader.h"
|
|
||||||
#include "native.h"
|
|
||||||
#include "class_resolver.h"
|
|
||||||
|
|
||||||
static uint8_t loader_buffer[0x100000] __attribute__ ((aligned (32)));
|
static uint8_t loader_buffer[0x100000] __attribute__ ((aligned (32)));
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
|
#include "frame_stack.h" // for native_func_t
|
||||||
#include "hash_table.h"
|
#include "hash_table.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "string.h"
|
|
||||||
#include "printf.h"
|
|
||||||
#include "native.h"
|
|
||||||
#include "native/class.h"
|
#include "native/class.h"
|
||||||
#include "native/libcinputstream.h"
|
#include "native/libcinputstream.h"
|
||||||
#include "native/loader.h"
|
#include "native/loader.h"
|
||||||
@ -13,14 +11,15 @@
|
|||||||
#include "native/runtime.h"
|
#include "native/runtime.h"
|
||||||
#include "native/sh4intrinsic.h"
|
#include "native/sh4intrinsic.h"
|
||||||
#include "native/system.h"
|
#include "native/system.h"
|
||||||
|
#include "native_method.h"
|
||||||
typedef void (* native_func_t)(struct vm * vm, uint32_t * args);
|
#include "printf.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
struct native_method {
|
struct native_method {
|
||||||
const char * class_name;
|
const char * class_name;
|
||||||
const char * method_name;
|
const char * method_name;
|
||||||
const char * method_descriptor;
|
const char * method_descriptor;
|
||||||
native_func_t func;
|
native_func_t * func;
|
||||||
};
|
};
|
||||||
|
|
||||||
const static struct native_method native_method[] = {
|
const static struct native_method native_method[] = {
|
||||||
@ -301,14 +300,14 @@ struct hash_table_entry * native_init_hash_table(int * hash_table_length)
|
|||||||
return native_hash_table;
|
return native_hash_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_method_call(struct vm * vm,
|
native_func_t * native_method_lookup(int native_hash_table_length,
|
||||||
|
struct hash_table_entry * native_hash_table,
|
||||||
struct constant * class_name_constant,
|
struct constant * class_name_constant,
|
||||||
struct constant * method_name_constant,
|
struct constant * method_name_constant,
|
||||||
struct constant * method_descriptor_constant,
|
struct constant * method_descriptor_constant)
|
||||||
uint32_t * args)
|
|
||||||
{
|
{
|
||||||
struct hash_table_entry * e = hash_table_find3(vm->native_hash_table.length,
|
struct hash_table_entry * e = hash_table_find3(native_hash_table_length,
|
||||||
vm->native_hash_table.entry,
|
native_hash_table,
|
||||||
class_name_constant->utf8.bytes,
|
class_name_constant->utf8.bytes,
|
||||||
class_name_constant->utf8.length,
|
class_name_constant->utf8.length,
|
||||||
method_name_constant->utf8.bytes,
|
method_name_constant->utf8.bytes,
|
||||||
@ -327,6 +326,5 @@ void native_method_call(struct vm * vm,
|
|||||||
assert(e != nullptr);
|
assert(e != nullptr);
|
||||||
assert(e->value != nullptr);
|
assert(e->value != nullptr);
|
||||||
|
|
||||||
native_func_t func = (native_func_t)e->value;
|
return(native_func_t *)e->value;
|
||||||
func(vm, args);
|
|
||||||
}
|
}
|
11
c/native_method.h
Normal file
11
c/native_method.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
|
struct hash_table_entry * native_init_hash_table(int * hash_table_length);
|
||||||
|
|
||||||
|
native_func_t * native_method_lookup(int native_hash_table_length,
|
||||||
|
struct hash_table_entry * native_hash_table,
|
||||||
|
struct constant * class_name_constant,
|
||||||
|
struct constant * method_name_constant,
|
||||||
|
struct constant * method_descriptor_constant);
|
23
c/vm.c
23
c/vm.c
@ -7,7 +7,6 @@
|
|||||||
#include "class_resolver.h"
|
#include "class_resolver.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "native.h"
|
|
||||||
#include "fatal.h"
|
#include "fatal.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "find_attribute.h"
|
#include "find_attribute.h"
|
||||||
@ -174,29 +173,9 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str
|
|||||||
args[nargs - i - 1] = value;
|
args[nargs - i - 1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugf("native: ");
|
|
||||||
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_entry->class_file->constant_pool[class_constant->class.name_index - 1];
|
|
||||||
assert(class_name_constant->tag == CONSTANT_Utf8);
|
|
||||||
debug_print__constant__utf8_string(class_name_constant);
|
|
||||||
debugs(" ");
|
|
||||||
struct constant * method_name_constant = &class_entry->class_file->constant_pool[method_entry->method_info->name_index - 1];
|
|
||||||
assert(method_name_constant->tag == CONSTANT_Utf8);
|
|
||||||
debug_print__constant__utf8_string(method_name_constant);
|
|
||||||
debugs(" ");
|
|
||||||
struct constant * method_descriptor_constant = &class_entry->class_file->constant_pool[method_entry->method_info->descriptor_index - 1];
|
|
||||||
assert(method_descriptor_constant->tag == CONSTANT_Utf8);
|
|
||||||
debug_print__constant__utf8_string(method_descriptor_constant);
|
|
||||||
debugc('\n');
|
|
||||||
|
|
||||||
int old_stack_ix = vm->current_frame->operand_stack_ix;
|
int old_stack_ix = vm->current_frame->operand_stack_ix;
|
||||||
|
|
||||||
native_method_call(vm,
|
method_entry->native_func(vm, args);
|
||||||
class_name_constant,
|
|
||||||
method_name_constant,
|
|
||||||
method_descriptor_constant,
|
|
||||||
args);
|
|
||||||
|
|
||||||
if (return_type != 'V') {
|
if (return_type != 'V') {
|
||||||
assert(old_stack_ix == vm->current_frame->operand_stack_ix - 1);
|
assert(old_stack_ix == vm->current_frame->operand_stack_ix - 1);
|
||||||
|
14
c/vm.h
14
c/vm.h
@ -3,20 +3,6 @@
|
|||||||
#include "frame_stack.h"
|
#include "frame_stack.h"
|
||||||
#include "class_file.h"
|
#include "class_file.h"
|
||||||
|
|
||||||
struct vm {
|
|
||||||
struct stack frame_stack;
|
|
||||||
struct stack data_stack;
|
|
||||||
struct frame * current_frame;
|
|
||||||
struct {
|
|
||||||
int length;
|
|
||||||
struct hash_table_entry * entry;
|
|
||||||
} class_hash_table;
|
|
||||||
struct {
|
|
||||||
int length;
|
|
||||||
struct hash_table_entry * entry;
|
|
||||||
} native_hash_table;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool vm_initialize_class(struct vm * vm, struct class_entry * class_entry);
|
bool vm_initialize_class(struct vm * vm, struct class_entry * class_entry);
|
||||||
void vm_special_method_call(struct vm * vm, struct class_entry * class_entry, struct method_entry * method_entry);
|
void vm_special_method_call(struct vm * vm, struct class_entry * class_entry, struct method_entry * method_entry);
|
||||||
void vm_static_method_call(struct vm * vm, struct class_entry * class_entry, struct method_entry * method_entry);
|
void vm_static_method_call(struct vm * vm, struct class_entry * class_entry, struct method_entry * method_entry);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user