implement multianewarray
This commit is contained in:
parent
4f312ad42c
commit
168c0abbae
@ -9,6 +9,7 @@
|
||||
#include "debug_class_file.h"
|
||||
#include "memory_allocator.h"
|
||||
#include "printf.h"
|
||||
#include "field_size.h"
|
||||
|
||||
static void class_resolver_create_interfaces_hash_table(struct class_entry * class_entry)
|
||||
{
|
||||
@ -23,29 +24,13 @@ static void class_resolver_create_interfaces_hash_table(struct class_entry * cla
|
||||
*/
|
||||
}
|
||||
|
||||
static int 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)
|
||||
{
|
||||
struct constant * field_descriptor_constant = &class_file->constant_pool[field_info->descriptor_index - 1];
|
||||
#ifdef DEBUG
|
||||
assert(field_descriptor_constant->tag == CONSTANT_Utf8);
|
||||
#endif
|
||||
|
||||
switch (field_descriptor_constant->utf8.bytes[0]) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case '[':
|
||||
return 1;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'J':
|
||||
return 2;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
return field_size(field_descriptor_constant->utf8.bytes[0]);
|
||||
}
|
||||
|
||||
static int32_t class_resolver_create_fields_hash_table(struct class_entry * class_entry)
|
||||
@ -72,10 +57,10 @@ static int32_t class_resolver_create_fields_hash_table(struct class_entry * clas
|
||||
|
||||
if (field_info->access_flags & FIELD_ACC_STATIC) {
|
||||
field_entry[i].static_index = static_index;
|
||||
static_index += field_size(class_file, field_info);
|
||||
static_index += field_info_field_size(class_file, field_info);
|
||||
} else {
|
||||
field_entry[i].instance_index = instance_index;
|
||||
instance_index += field_size(class_file, field_info);
|
||||
instance_index += field_info_field_size(class_file, field_info);
|
||||
}
|
||||
field_entry[i].field_info = field_info;
|
||||
|
||||
|
39
c/execute.c
39
c/execute.c
@ -4,6 +4,7 @@
|
||||
#include "class_resolver.h"
|
||||
#include "execute_helper.h"
|
||||
#include "printf.h"
|
||||
#include "field_size.h"
|
||||
|
||||
void op_aaload(struct vm * vm)
|
||||
{
|
||||
@ -1596,9 +1597,45 @@ void op_monitorexit(struct vm * vm)
|
||||
assert(!"op_monitorexit");
|
||||
}
|
||||
|
||||
static int32_t * _multiarray(int32_t * dims, int num_dimensions, int level, uint8_t * type)
|
||||
{
|
||||
int32_t count = dims[level];
|
||||
int32_t element_size = field_size_array(*type);
|
||||
int32_t size = element_size * count + 4;
|
||||
int32_t * arrayref = memory_allocate(size);
|
||||
arrayref[0] = count;
|
||||
|
||||
int32_t u32_count = (size - 4 + 3) / 4;
|
||||
for (int i = 0; i < u32_count; i++) {
|
||||
if (level == num_dimensions - 1) {
|
||||
arrayref[i + 1] = 0;
|
||||
} else {
|
||||
assert(*type == '[');
|
||||
arrayref[1 + i] = (int32_t)_multiarray(dims, num_dimensions, level + 1, type + 1);
|
||||
}
|
||||
}
|
||||
return arrayref;
|
||||
}
|
||||
|
||||
void op_multianewarray(struct vm * vm, uint32_t index, uint32_t dimensions)
|
||||
{
|
||||
assert(!"op_multianewarray");
|
||||
struct constant * class_constant = &vm->current_frame->class_entry->class_file->constant_pool[index - 1];
|
||||
assert(class_constant->tag == CONSTANT_Class);
|
||||
struct constant * type_constant = &vm->current_frame->class_entry->class_file->constant_pool[class_constant->class.name_index - 1];
|
||||
assert(type_constant->tag == CONSTANT_Utf8);
|
||||
|
||||
// The run-time constant pool entry at the index must be a symbolic reference
|
||||
// to a class, array, or interface type
|
||||
uint8_t * type = type_constant->utf8.bytes;
|
||||
assert(*type == '[');
|
||||
|
||||
assert(dimensions > 0);
|
||||
int32_t dims[dimensions];
|
||||
for (int i = 0; i < dimensions; i++) {
|
||||
dims[dimensions - i - 1] = operand_stack_pop_u32(vm->current_frame);
|
||||
}
|
||||
int32_t * arrayref = _multiarray(dims, dimensions, 0, type + 1);
|
||||
operand_stack_push_u32(vm->current_frame, (uint32_t)arrayref);
|
||||
}
|
||||
|
||||
void op_new(struct vm * vm, uint32_t index)
|
||||
|
43
c/field_size.h
Normal file
43
c/field_size.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
static inline int field_size(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case '[':
|
||||
return 1;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'J':
|
||||
return 2;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int field_size_array(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'Z': [[fallthrough]]; // boolean
|
||||
case 'B': // byte
|
||||
return 1;
|
||||
case 'C': [[fallthrough]]; // char
|
||||
case 'S': // short
|
||||
return 2;
|
||||
case 'F': [[fallthrough]]; // float
|
||||
case 'I': [[fallthrough]]; // int
|
||||
case 'L': [[fallthrough]]; // classref
|
||||
case '[': // arrayref
|
||||
return 4;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'J':
|
||||
return 8;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
19
p/MultiArray.java
Normal file
19
p/MultiArray.java
Normal file
@ -0,0 +1,19 @@
|
||||
package p;
|
||||
|
||||
class MultiArray {
|
||||
static int test() {
|
||||
byte[][][] arr = new byte[10][20][30];
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 20; j++) {
|
||||
for (int k = 0; k < 30; k++) {
|
||||
arr[i][j][k] = (byte)(i * j * k);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr[2][9][4];
|
||||
}
|
||||
|
||||
public static void main() {
|
||||
test();
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ class WideInstruction {
|
||||
k27, k28, k29, k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k40, k41, k42, k43,
|
||||
k44, k45, k46, k47, k48, k49, k50, k51, k52, k53, k54, k55, k56, k57 = 42;
|
||||
|
||||
for (int i = 0; i < 256; i += 1024) {
|
||||
for (int i = 0; i < 2560; i += 1024) {
|
||||
k57 += 360;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user