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 "debug.h"
|
||||
#include "fatal.h"
|
||||
#include "parse_type.h"
|
||||
|
||||
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];
|
||||
#ifdef DEBUG
|
||||
assert(class_constant->tag == CONSTANT_Class);
|
||||
#endif
|
||||
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);
|
||||
#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,
|
||||
class_hash_table,
|
||||
class_name_constant->utf8.bytes,
|
||||
class_name_constant->utf8.length);
|
||||
parse_type_ret.bytes,
|
||||
parse_type_ret.length);
|
||||
if (_class_entry != nullptr) {
|
||||
// cache the result
|
||||
class_entry->attribute_entry[class_index - 1].class_entry = _class_entry;
|
||||
|
@ -38,11 +38,6 @@ struct class_entry {
|
||||
int32_t * static_fields;
|
||||
int32_t instance_fields_count;
|
||||
|
||||
struct {
|
||||
int length;
|
||||
struct hash_table_entry * entry;
|
||||
} interfaces;
|
||||
|
||||
struct {
|
||||
int length;
|
||||
struct hash_table_entry * entry;
|
||||
|
36
c/execute.c
36
c/execute.c
@ -5,6 +5,8 @@
|
||||
#include "execute_helper.h"
|
||||
#include "printf.h"
|
||||
#include "field_size.h"
|
||||
#include "debug.h"
|
||||
#include "parse_type.h"
|
||||
|
||||
void op_aaload(struct vm * vm)
|
||||
{
|
||||
@ -190,7 +192,25 @@ void op_checkcast(struct vm * vm, uint32_t index)
|
||||
vm->current_frame->class_entry,
|
||||
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];
|
||||
debug_print__class_entry__class_name(index_class_entry);
|
||||
debug_print__class_entry__class_name(class_entry);
|
||||
|
||||
while (true) {
|
||||
assert(class_entry != nullptr);
|
||||
if (class_entry == index_class_entry) {
|
||||
@ -1141,6 +1161,22 @@ void op_instanceof(struct vm * vm, uint32_t index)
|
||||
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;
|
||||
struct class_entry * class_entry = (struct class_entry *)objectref[0];
|
||||
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/native.o \
|
||||
c/debug.o \
|
||||
c/fatal.o
|
||||
c/fatal.o \
|
||||
c/parse_type.o
|
||||
|
||||
MAIN_DREAMCAST_OBJ = \
|
||||
c/sh7091_scif.o \
|
||||
|
@ -20,7 +20,25 @@ class CheckCastTest {
|
||||
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() {
|
||||
test();
|
||||
//test();
|
||||
arrayTest2();
|
||||
//System.out.println(arrayTest());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user