implement wide
This commit is contained in:
parent
f10429927b
commit
4f312ad42c
@ -170,6 +170,10 @@ struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** buff
|
||||
struct constant * class_name_constant = &class_file->constant_pool[class_constant->class.name_index - 1];
|
||||
assert(class_name_constant->tag == CONSTANT_Utf8);
|
||||
|
||||
debugf("hash table entry for class: ");
|
||||
print_utf8_string(class_name_constant);
|
||||
debugf("\n");
|
||||
|
||||
hash_table_add(class_hash_table_length,
|
||||
class_hash_table,
|
||||
class_name_constant->utf8.bytes,
|
||||
|
95
c/decode.c
95
c/decode.c
@ -99,11 +99,100 @@ static inline int32_t aligned_s4(const void * buf)
|
||||
#define LOOKUPSWITCH_NEXT_PC \
|
||||
(args + (2 * 4) + (npairs * 2 * 4))
|
||||
|
||||
#define WIDE_ARGS assert(false);
|
||||
#define WIDE_ARGS \
|
||||
uint32_t opcode = code[pc + 1]; \
|
||||
uint32_t index = _u2(&code[pc + 2]); \
|
||||
uint32_t wide_next_pc = pc + 4; \
|
||||
int32_t _const;
|
||||
|
||||
#define WIDE_PRINT_ARGS()
|
||||
#define WIDE_IMPL() \
|
||||
switch (opcode) { \
|
||||
case 21: /* iload */ \
|
||||
op_iload(vm, index); \
|
||||
break; \
|
||||
case 22: /* lload */ \
|
||||
op_lload(vm, index); \
|
||||
break; \
|
||||
case 23: /* fload */ \
|
||||
op_fload(vm, index); \
|
||||
break; \
|
||||
case 24: /* dload */ \
|
||||
op_dload(vm, index); \
|
||||
break; \
|
||||
case 25: /* aload */ \
|
||||
op_aload(vm, index); \
|
||||
break; \
|
||||
case 54: /* istore */ \
|
||||
op_istore(vm, index); \
|
||||
break; \
|
||||
case 56: /* fstore */ \
|
||||
op_fstore(vm, index); \
|
||||
break; \
|
||||
case 58: /* astore */ \
|
||||
op_astore(vm, index); \
|
||||
break; \
|
||||
case 55: /* lstore */ \
|
||||
op_lstore(vm, index); \
|
||||
break; \
|
||||
case 57: /* dstore */ \
|
||||
op_dstore(vm, index); \
|
||||
break; \
|
||||
case 169: /* ret */ \
|
||||
op_ret(vm, index); \
|
||||
break; \
|
||||
case 132: /* iinc */ \
|
||||
{ \
|
||||
_const = _s2(&code[pc + 4]); \
|
||||
op_iinc(vm, index, _const); \
|
||||
wide_next_pc = pc + 6; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
vm->current_frame->next_pc = wide_next_pc;
|
||||
|
||||
#define WIDE_NEXT_PC 0
|
||||
#define WIDE_PRINT_ARGS() \
|
||||
switch (opcode) { \
|
||||
case 21: /* iload */ \
|
||||
debugf(" iload %5d ", index); \
|
||||
break; \
|
||||
case 22: /* lload */ \
|
||||
debugf(" lload %5d ", index); \
|
||||
break; \
|
||||
case 23: /* fload */ \
|
||||
debugf(" fload %5d ", index); \
|
||||
break; \
|
||||
case 24: /* dload */ \
|
||||
debugf(" dload %5d ", index); \
|
||||
break; \
|
||||
case 25: /* aload */ \
|
||||
debugf(" aload %5d ", index); \
|
||||
break; \
|
||||
case 54: /* istore */ \
|
||||
debugf(" istore %5d ", index); \
|
||||
break; \
|
||||
case 56: /* fstore */ \
|
||||
debugf(" fstore %5d ", index); \
|
||||
break; \
|
||||
case 58: /* astore */ \
|
||||
debugf(" astore %5d ", index); \
|
||||
break; \
|
||||
case 55: /* lstore */ \
|
||||
debugf(" lstore %5d ", index); \
|
||||
break; \
|
||||
case 57: /* dstore */ \
|
||||
debugf(" dstore %5d ", index); \
|
||||
break; \
|
||||
case 169: /* ret */ \
|
||||
debugf(" ret %5d ", index); \
|
||||
break; \
|
||||
case 132: /* iinc */ \
|
||||
_const = _s2(&code[pc + 4]); \
|
||||
debugf(" iinc %5d %5d ", index, _const); \
|
||||
wide_next_pc = pc + 6; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define WIDE_NEXT_PC wide_next_pc
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
@ -890,7 +890,7 @@ uint32_t decode_print_instruction(const uint8_t * code, uint32_t pc)
|
||||
TABLESWITCH_ARGS;
|
||||
debugf("%4d: tableswitch {\n", pc);
|
||||
TABLESWITCH_PRINT_ARGS();
|
||||
debugf("}\n");
|
||||
debugf("}\n\n");
|
||||
return TABLESWITCH_NEXT_PC;
|
||||
}
|
||||
case 171: // lookupswitch
|
||||
@ -898,7 +898,7 @@ uint32_t decode_print_instruction(const uint8_t * code, uint32_t pc)
|
||||
LOOKUPSWITCH_ARGS;
|
||||
debugf("%4d: lookupswitch {\n", pc);
|
||||
LOOKUPSWITCH_PRINT_ARGS();
|
||||
debugf("}\n");
|
||||
debugf("}\n\n");
|
||||
return LOOKUPSWITCH_NEXT_PC;
|
||||
}
|
||||
case 172: // ireturn
|
||||
@ -1039,7 +1039,7 @@ uint32_t decode_print_instruction(const uint8_t * code, uint32_t pc)
|
||||
case 196: // wide
|
||||
{
|
||||
WIDE_ARGS;
|
||||
debugf("%4d: wide {\n", pc);
|
||||
debugf("%4d: wide {", pc);
|
||||
WIDE_PRINT_ARGS();
|
||||
debugf("}\n");
|
||||
return WIDE_NEXT_PC;
|
||||
@ -2330,8 +2330,7 @@ void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t p
|
||||
case 196: // wide
|
||||
{
|
||||
WIDE_ARGS;
|
||||
vm->current_frame->next_pc = WIDE_NEXT_PC;
|
||||
op_wide(vm);
|
||||
WIDE_IMPL();
|
||||
break;
|
||||
}
|
||||
case 197: // multianewarray
|
||||
|
49
c/execute.c
49
c/execute.c
@ -763,12 +763,12 @@ void op_getstatic(struct vm * vm, uint32_t index)
|
||||
|
||||
void op_goto(struct vm * vm, int32_t branch)
|
||||
{
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
|
||||
void op_goto_w(struct vm * vm, int32_t branch)
|
||||
{
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
|
||||
void op_i2b(struct vm * vm)
|
||||
@ -897,7 +897,7 @@ void op_if_acmpeq(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 == value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,7 +906,7 @@ void op_if_acmpne(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 != value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -915,7 +915,7 @@ void op_if_icmpeq(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 == value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,7 +924,7 @@ void op_if_icmpge(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 >= value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -933,7 +933,7 @@ void op_if_icmpgt(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 > value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,7 +942,7 @@ void op_if_icmple(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 <= value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -951,7 +951,7 @@ void op_if_icmplt(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 < value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ void op_if_icmpne(struct vm * vm, int32_t branch)
|
||||
int32_t value2 = operand_stack_pop_u32(vm->current_frame);
|
||||
int32_t value1 = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value1 != value2) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -968,7 +968,7 @@ void op_ifeq(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value == 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -976,7 +976,7 @@ void op_ifge(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value >= 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -984,7 +984,7 @@ void op_ifgt(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value > 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -992,7 +992,7 @@ void op_ifle(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value <= 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1000,7 +1000,7 @@ void op_iflt(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value < 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1008,7 +1008,7 @@ void op_ifne(struct vm * vm, int32_t branch)
|
||||
{
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
if (value != 0) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1016,7 +1016,7 @@ void op_ifnonnull(struct vm * vm, int32_t branch)
|
||||
{
|
||||
void * value = (void *)operand_stack_pop_u32(vm->current_frame);
|
||||
if (value != nullptr) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1024,7 +1024,7 @@ void op_ifnull(struct vm * vm, int32_t branch)
|
||||
{
|
||||
void * value = (void *)operand_stack_pop_u32(vm->current_frame);
|
||||
if (value == nullptr) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + branch;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + branch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1474,11 +1474,11 @@ void op_lookupswitch(struct vm * vm, int32_t defaultbyte, int32_t npairs, const
|
||||
int32_t match = BE_BSWAP32(table[i * 2]);
|
||||
if (key == match) {
|
||||
int32_t offset = BE_BSWAP32(table[i * 2 + 1]);
|
||||
vm->current_frame->pc = vm->current_frame->pc + offset;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + offset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
vm->current_frame->pc = vm->current_frame->pc + defaultbyte;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + defaultbyte;
|
||||
}
|
||||
|
||||
void op_lor(struct vm * vm)
|
||||
@ -1868,14 +1868,9 @@ void op_tableswitch(struct vm * vm, int32_t defaultbyte, int32_t lowbyte, int32_
|
||||
{
|
||||
int32_t index = operand_stack_pop_u32(vm->current_frame);
|
||||
if (index < lowbyte || index > highbyte) {
|
||||
vm->current_frame->pc = vm->current_frame->pc + defaultbyte;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + defaultbyte;
|
||||
} else {
|
||||
int32_t offset = BE_BSWAP32(table[index - lowbyte]);
|
||||
vm->current_frame->pc = vm->current_frame->pc + offset;
|
||||
vm->current_frame->next_pc = vm->current_frame->pc + offset;
|
||||
}
|
||||
}
|
||||
|
||||
void op_wide(struct vm * vm)
|
||||
{
|
||||
assert(!"op_wide");
|
||||
}
|
||||
|
@ -451,17 +451,20 @@ void vm_execute(struct vm * vm)
|
||||
assert(vm->current_frame->pc < vm->current_frame->code->code_length);
|
||||
print_vm_stack(vm);
|
||||
decode_print_instruction(vm->current_frame->code->code, vm->current_frame->pc);
|
||||
uint32_t old_pc = vm->current_frame->pc;
|
||||
struct method_info * old_method = vm->current_frame->method;
|
||||
//uint32_t old_pc = vm->current_frame->pc;
|
||||
//struct method_info * old_method = vm->current_frame->method;
|
||||
decode_execute_instruction(vm, vm->current_frame->code->code, vm->current_frame->pc);
|
||||
if (vm->frame_stack.ix == 1) {
|
||||
debugf("terminate\n");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
if (vm->current_frame->method == old_method && vm->current_frame->pc == old_pc) {
|
||||
// if the instruction did not branch, increment pc
|
||||
vm->current_frame->pc = vm->current_frame->next_pc;
|
||||
}
|
||||
*/
|
||||
vm->current_frame->pc = vm->current_frame->next_pc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,9 +69,6 @@ void hash_table_add(int hash_table_length,
|
||||
|
||||
uint8_t * key_copy = malloc_class_arena(key_length);
|
||||
for (int i = 0; i < key_length; i++) key_copy[i] = key[i];
|
||||
debugf("key copy: %p ", key_copy);
|
||||
print_key(key_copy, key_length);
|
||||
|
||||
e->key = key_copy;
|
||||
e->key_length = key_length;
|
||||
e->value = value;
|
||||
|
@ -119,11 +119,12 @@ def generate_print_fixed_width_instruction(instruction):
|
||||
yield f"return pc + {1 + instruction.arguments_size};"
|
||||
|
||||
def generate_print_variable_width_instruction(instruction):
|
||||
n = '' if instruction.mnemonic == "wide" else '\\n'
|
||||
mnemonic = instruction.mnemonic.ljust(13)
|
||||
yield f"{instruction.mnemonic.upper()}_ARGS;"
|
||||
yield f'debugf("%4d: {mnemonic} {{\\n", pc);'
|
||||
yield f'debugf("%4d: {mnemonic} {{{n}", pc);'
|
||||
yield f"{instruction.mnemonic.upper()}_PRINT_ARGS();"
|
||||
yield 'debugf("}\\n");'
|
||||
yield f'debugf("}}{n}\\n");'
|
||||
yield f"return {instruction.mnemonic.upper()}_NEXT_PC;"
|
||||
|
||||
def generate_print_decoder():
|
||||
@ -167,14 +168,18 @@ def generate_execute_fixed_width_instruction(instruction):
|
||||
|
||||
def generate_execute_variable_width_instruction(instruction):
|
||||
yield f"{instruction.mnemonic.upper()}_ARGS;"
|
||||
yield f"vm->current_frame->next_pc = {instruction.mnemonic.upper()}_NEXT_PC;"
|
||||
argument_values = ", ".join(
|
||||
argument
|
||||
for argument in instruction.arguments
|
||||
)
|
||||
if instruction.mnemonic != "wide":
|
||||
yield f"vm->current_frame->next_pc = {instruction.mnemonic.upper()}_NEXT_PC;"
|
||||
if argument_values:
|
||||
argument_values = ", " + argument_values
|
||||
yield f"op_{instruction.mnemonic}(vm{argument_values});"
|
||||
if instruction.mnemonic == "wide":
|
||||
yield "WIDE_IMPL();"
|
||||
else:
|
||||
yield f"op_{instruction.mnemonic}(vm{argument_values});"
|
||||
|
||||
def generate_execute_decoder():
|
||||
yield "void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t pc)"
|
||||
|
31
p/WideInstruction.java
Normal file
31
p/WideInstruction.java
Normal file
@ -0,0 +1,31 @@
|
||||
package p;
|
||||
|
||||
class WideInstruction {
|
||||
public static int largeVarIndex() {
|
||||
int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18,
|
||||
i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35,
|
||||
i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52,
|
||||
i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69,
|
||||
i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86,
|
||||
i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, j0, j1, j2, j3, j4,
|
||||
j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15, j16, j17, j18, j19, j20, j21, j22,
|
||||
j23, j24, j25, j26, j27, j28, j29, j30, j31, j32, j33, j34, j35, j36, j37, j38, j39,
|
||||
j40, j41, j42, j43, j44, j45, j46, j47, j48, j49, j50, j51, j52, j53, j54, j55, j56,
|
||||
j57, j58, j59, j60, j61, j62, j63, j64, j65, j66, j67, j68, j69, j70, j71, j72, j73,
|
||||
j74, j75, j76, j77, j78, j79, j80, j81, j82, j83, j84, j85, j86, j87, j88, j89, j90,
|
||||
j91, j92, j93, j94, j95, j96, j97, j98, j99, k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26,
|
||||
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) {
|
||||
k57 += 360;
|
||||
}
|
||||
|
||||
return k57;
|
||||
}
|
||||
|
||||
public static void main() {
|
||||
largeVarIndex();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user