partial support for checkcast and instanceof on object arrays
This commit is contained in:
parent
49cc665f76
commit
e22f2e87e8
@ -12,6 +12,7 @@
|
|||||||
#include "field_size.h"
|
#include "field_size.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "fatal.h"
|
#include "fatal.h"
|
||||||
|
#include "parse_type.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)
|
||||||
{
|
{
|
||||||
@ -290,18 +291,18 @@ struct class_entry * class_resolver_lookup_class_from_class_index(int class_hash
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct constant * class_constant = &class_entry->class_file->constant_pool[class_index - 1];
|
struct constant * class_constant = &class_entry->class_file->constant_pool[class_index - 1];
|
||||||
#ifdef DEBUG
|
|
||||||
assert(class_constant->tag == CONSTANT_Class);
|
assert(class_constant->tag == CONSTANT_Class);
|
||||||
#endif
|
|
||||||
struct constant * class_name_constant = &class_entry->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];
|
||||||
#ifdef DEBUG
|
|
||||||
assert(class_name_constant->tag == CONSTANT_Utf8);
|
assert(class_name_constant->tag == CONSTANT_Utf8);
|
||||||
#endif
|
|
||||||
|
struct parse_type_ret parse_type_ret = parse_type(class_name_constant->utf8.bytes,
|
||||||
|
class_name_constant->utf8.length);
|
||||||
|
|
||||||
|
|
||||||
struct class_entry * _class_entry = class_resolver_lookup_class(class_hash_table_length,
|
struct class_entry * _class_entry = class_resolver_lookup_class(class_hash_table_length,
|
||||||
class_hash_table,
|
class_hash_table,
|
||||||
class_name_constant->utf8.bytes,
|
parse_type_ret.bytes,
|
||||||
class_name_constant->utf8.length);
|
parse_type_ret.length);
|
||||||
if (_class_entry != nullptr) {
|
if (_class_entry != nullptr) {
|
||||||
// cache the result
|
// cache the result
|
||||||
class_entry->attribute_entry[class_index - 1].class_entry = _class_entry;
|
class_entry->attribute_entry[class_index - 1].class_entry = _class_entry;
|
||||||
|
@ -38,11 +38,6 @@ struct class_entry {
|
|||||||
int32_t * static_fields;
|
int32_t * static_fields;
|
||||||
int32_t instance_fields_count;
|
int32_t instance_fields_count;
|
||||||
|
|
||||||
struct {
|
|
||||||
int length;
|
|
||||||
struct hash_table_entry * entry;
|
|
||||||
} interfaces;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int length;
|
int length;
|
||||||
struct hash_table_entry * entry;
|
struct hash_table_entry * entry;
|
||||||
|
36
c/execute.c
36
c/execute.c
@ -5,6 +5,8 @@
|
|||||||
#include "execute_helper.h"
|
#include "execute_helper.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "field_size.h"
|
#include "field_size.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "parse_type.h"
|
||||||
|
|
||||||
void op_aaload(struct vm * vm)
|
void op_aaload(struct vm * vm)
|
||||||
{
|
{
|
||||||
@ -190,7 +192,25 @@ void op_checkcast(struct vm * vm, uint32_t index)
|
|||||||
vm->current_frame->class_entry,
|
vm->current_frame->class_entry,
|
||||||
index);
|
index);
|
||||||
|
|
||||||
|
struct constant * class_constant = &vm->current_frame->class_entry->class_file->constant_pool[index - 1];
|
||||||
|
assert(class_constant->tag == CONSTANT_Class);
|
||||||
|
struct constant * class_name_constant = &vm->current_frame->class_entry->class_file->constant_pool[class_constant->class.name_index - 1];
|
||||||
|
assert(class_name_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
|
int depth = parse_type_array_depth(class_name_constant->utf8.bytes, class_name_constant->utf8.length);
|
||||||
|
while (depth-- > 0) {
|
||||||
|
if (objectref == nullptr || objectref[0] == 0)
|
||||||
|
assert(!"checkcast on null or zero-length array not implemented");
|
||||||
|
objectref = (int32_t *)objectref[1];
|
||||||
|
}
|
||||||
|
if (objectref == nullptr) {
|
||||||
|
assert(!"checkcast on array with null elements not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
||||||
|
debug_print__class_entry__class_name(index_class_entry);
|
||||||
|
debug_print__class_entry__class_name(class_entry);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
assert(class_entry != nullptr);
|
assert(class_entry != nullptr);
|
||||||
if (class_entry == index_class_entry) {
|
if (class_entry == index_class_entry) {
|
||||||
@ -1141,6 +1161,22 @@ void op_instanceof(struct vm * vm, uint32_t index)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct constant * class_constant = &vm->current_frame->class_entry->class_file->constant_pool[index - 1];
|
||||||
|
assert(class_constant->tag == CONSTANT_Class);
|
||||||
|
struct constant * class_name_constant = &vm->current_frame->class_entry->class_file->constant_pool[class_constant->class.name_index - 1];
|
||||||
|
assert(class_name_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
|
int depth = parse_type_array_depth(class_name_constant->utf8.bytes, class_name_constant->utf8.length);
|
||||||
|
printf("depth: %d\n", depth);
|
||||||
|
while (depth-- > 0) {
|
||||||
|
if (objectref == nullptr || objectref[0] == 0)
|
||||||
|
assert(!"instanceof on null or zero-length array not implemented");
|
||||||
|
objectref = (int32_t *)objectref[1];
|
||||||
|
}
|
||||||
|
if (objectref == nullptr) {
|
||||||
|
assert(!"instanceof on array with null elements not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
bool value = false;
|
bool value = false;
|
||||||
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
||||||
while (true) {
|
while (true) {
|
||||||
|
34
c/parse_type.c
Normal file
34
c/parse_type.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "assert.h"
|
||||||
|
#include "parse_type.h"
|
||||||
|
|
||||||
|
struct parse_type_ret parse_type(uint8_t * bytes, uint32_t length)
|
||||||
|
{
|
||||||
|
if (bytes[length - 1] != ';') {
|
||||||
|
assert(bytes[0] != '[');
|
||||||
|
return (struct parse_type_ret){ bytes, length };
|
||||||
|
}
|
||||||
|
|
||||||
|
int ix = 0;
|
||||||
|
while (bytes[ix] == '[') {
|
||||||
|
ix += 1;
|
||||||
|
}
|
||||||
|
assert(bytes[ix] == 'L');
|
||||||
|
ix += 1;
|
||||||
|
|
||||||
|
return (struct parse_type_ret){ &bytes[ix], length - ix - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_type_array_depth(uint8_t * bytes, uint32_t length)
|
||||||
|
{
|
||||||
|
if (bytes[length - 1] != ';') {
|
||||||
|
assert(bytes[0] != '[');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ix = 0;
|
||||||
|
while (bytes[ix] == '[') {
|
||||||
|
ix += 1;
|
||||||
|
}
|
||||||
|
assert(bytes[ix] == 'L');
|
||||||
|
return ix;
|
||||||
|
}
|
11
c/parse_type.h
Normal file
11
c/parse_type.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct parse_type_ret {
|
||||||
|
uint8_t * bytes;
|
||||||
|
uint32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parse_type_ret parse_type(uint8_t * bytes, uint32_t length);
|
||||||
|
int parse_type_array_depth(uint8_t * bytes, uint32_t length);
|
3
java.mk
3
java.mk
@ -19,7 +19,8 @@ OBJ = \
|
|||||||
c/unparse.o \
|
c/unparse.o \
|
||||||
c/native.o \
|
c/native.o \
|
||||||
c/debug.o \
|
c/debug.o \
|
||||||
c/fatal.o
|
c/fatal.o \
|
||||||
|
c/parse_type.o
|
||||||
|
|
||||||
MAIN_DREAMCAST_OBJ = \
|
MAIN_DREAMCAST_OBJ = \
|
||||||
c/sh7091_scif.o \
|
c/sh7091_scif.o \
|
||||||
|
@ -20,7 +20,25 @@ class CheckCastTest {
|
|||||||
return cc instanceof Cat;
|
return cc instanceof Cat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean arrayTest() {
|
||||||
|
Dog[][] d = new Dog[1][1];
|
||||||
|
Cat[][] c = new Cat[1][1];
|
||||||
|
Animal[][] da = d;
|
||||||
|
Animal[][] ca = c;
|
||||||
|
//Cat[][] cc = (Cat[][])da;
|
||||||
|
Cat[][] cc = (Cat[][])ca;
|
||||||
|
return cc instanceof Cat[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean arrayTest2() {
|
||||||
|
Cat[] c = new Cat[1];
|
||||||
|
c[0] = new Cat();
|
||||||
|
return c instanceof Cat[];
|
||||||
|
}
|
||||||
|
|
||||||
public static void main() {
|
public static void main() {
|
||||||
test();
|
//test();
|
||||||
|
arrayTest2();
|
||||||
|
//System.out.println(arrayTest());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user