From 1e41b058a5ce0cf22301808fda7d4ec46132283b Mon Sep 17 00:00:00 2001 From: renk Date: Sat, 8 Feb 2025 20:17:26 -0300 Subject: [PATCH 1/4] clean code --- include/jvm.h | 48 +++++++----------------------- src/interpreter.c | 76 +++++++++++------------------------------------ 2 files changed, 28 insertions(+), 96 deletions(-) diff --git a/include/jvm.h b/include/jvm.h index 5791ac3..0698c0b 100644 --- a/include/jvm.h +++ b/include/jvm.h @@ -197,9 +197,14 @@ typedef enum { LLOAD_2 = 0x1c, LLOAD_3 = 0x1d, LNEG = 0x74, - - + LADD = 0x61, + LSUB = 0x65, + LMUL = 0x69, + LDIV = 0x6d, + LREM = 0x71, + DREM = 0x73, + // Stores ISTORE = 0x36, @@ -212,23 +217,11 @@ typedef enum { LSTORE = 0x37, FSTORE = 0x38, -// TODO: implement, prepare for 64 bits manipulation DSTORE = 0x39, DSTORE_0 = 0x47, DSTORE_1 = 0x48, DSTORE_2 = 0x49, DSTORE_3 = 0x4a, - - -// long - LADD = 0x61, - LSUB = 0x65, - LMUL = 0x69, - LDIV = 0x6d, - LREM = 0x71, - DREM = 0x73, - - // Stack POP = 0x57, @@ -250,14 +243,8 @@ typedef enum { // Method invocation INVOKEDYNAMIC = 0xBA, - - INSTANCEOF = 0xBF, - - - - IF_ICMPEQ = 0x9F, // branch todo IFEQ = 0x99, @@ -266,39 +253,26 @@ typedef enum { IFGE = 0x9C, IFGT = 0x9D, IFLE = 0x9E, - - // todo + IF_ICMPEQ = 0x9F, + LDC2_W = 0x14, - // GETSTATIC = 0xB2, - - // INVOKEVIRTUAL = 0xB6, + DSUB = 0x67, DMUL = 0x6B, DDIV = 0x6F, DNEG = 0x77, - // todo cat2 files? DCMPL = 0X97, DCMPG = 0X98, D2F = 0X90, D2I = 0X8E, D2L = 0X8F, -// IFLE = 0X9E -// (INVALID OPCODE) = 0XBD - - - // MISSING TODO IMPLEMENT FOR DOUBLE_ARITMETICA -//! LDC2_W = 0x14 -// GETSTATIC = 0xB2 -// INVOKEVIRTUAL = 0xB6 -// NEW = 0xB1 - INVOKESPECIAL = 0xB7, CHECKCAST = 0xC0, - // Return IRETURN = 0xB1, + RETURN = 0xb1, } Bytecode; diff --git a/src/interpreter.c b/src/interpreter.c index 83ef42c..6377900 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -167,7 +167,6 @@ static void handle_dload(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack value.low = locals[index]; value.high = locals[index + 1]; operand_stack_push_cat2(stack, value); - fprintf("DLOAD %d: Loaded %d\n", index, value.double_); //#comment *pc += 2; } @@ -176,7 +175,6 @@ static void handle_dload_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSta value.low = locals[1]; value.high = locals[1 + 1]; operand_stack_push_cat2(stack, value); - fprintf("DLOAD %d: Loaded %d\n", 1, value.double_); //#comment *pc += 2; } @@ -185,7 +183,6 @@ static void handle_dload_2(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSta value.low = locals[2]; value.high = locals[2 + 1]; operand_stack_push_cat2(stack, value); - fprintf("DLOAD %d: Loaded %d\n", 2, value.double_); //#comment *pc += 2; } @@ -194,7 +191,6 @@ static void handle_dload_3(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSta value.low = locals[3]; value.high = locals[3 + 1]; operand_stack_push_cat2(stack, value); - fprintf("DLOAD %d: Loaded %d\n", 3, value.double_); //#comment *pc += 2; } @@ -267,7 +263,7 @@ static void handle_ldiv(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack Cat2 val1 = operand_stack_pop_cat2(stack); if (val2.long_ == 0) { fprintf(stderr, "Divisão por zero\n"); - return; // Ou lançar uma exceção + return; } Cat2 result; result.long_ = val1.long_ / val2.long_; @@ -279,8 +275,8 @@ static void handle_lrem(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack Cat2 val2 = operand_stack_pop_cat2(stack); Cat2 val1 = operand_stack_pop_cat2(stack); if (val2.long_ == 0) { - fprintf(stderr, "Resto da divisão por zero\n"); - return; // Ou lançar uma exceção + fprintf(stderr, "Divisão por zero\n"); + return; } Cat2 result; result.long_ = val1.long_ % val2.long_; @@ -325,9 +321,8 @@ static void handle_drem(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack } // Carregamento de Constantes (long e double) -// que isso static void handle_lconst(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - int64_t value = bytecode[*pc] - LCONST_0; // 0 ou 1 + int64_t value = bytecode[*pc] - LCONST_0; Cat2 cat2; cat2.long_ = value; operand_stack_push_cat2(stack, cat2); @@ -335,14 +330,13 @@ static void handle_lconst(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStac } static void handle_dconst(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - double value = bytecode[*pc] - DCONST_0; // 0.0 ou 1.0 + double value = bytecode[*pc] - DCONST_0; Cat2 cat2; cat2.double_ = value; operand_stack_push_cat2(stack, cat2); (*pc)++; } -// todo testar acima static void handle_ldc2_w(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { uint16_t index = (bytecode[(*pc) + 1] << 8) | bytecode[(*pc) + 2]; @@ -359,15 +353,12 @@ static void handle_ldc2_w(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStac Cat2 cat2; cat2.double_ = value; operand_stack_push_cat2(stack, cat2); - fprintf(stderr, "ldc2_w: %d", value); } else if (constant_pool_entry->tag == CONSTANT_Long) { int64_t value = constant_pool_entry->info.Long.bytes; Cat2 cat2; cat2.long_ = value; operand_stack_push_cat2(stack, cat2); - fprintf(stderr, "ldc2_w: %d", value); } else { - fprintf(stderr, "ldc2_w: Constant pool entry is not a double or long\n"); return; } @@ -404,43 +395,10 @@ static void handle_iconst_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSt (*pc)++; } -static void handle_invokespecial(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - uint16_t index = (bytecode[*pc + 1] << 8) | bytecode[*pc + 2]; - *pc += 3; // Advance pc *before* invoking - - cp_info *methodref = &jvm->class_file.constant_pool[index - 1]; - if (methodref->tag == CONSTANT_Methodref) { - invoke_method(jvm, methodref); // Use the existing invoke_method - } -} - -//! df is this todo ! -static void handle_checkcast(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - uint16_t index = (bytecode[(*pc) + 1] << 8) | bytecode[(*pc) + 2]; - int32_t objref; - operand_stack_pop(stack, &objref); - - if (objref == 0) { // null is always an instance of any class - operand_stack_push(stack, objref); - *pc += 3; - return; - } - - Object *obj = (Object *)(intptr_t)objref; - cp_info *class_info = &jvm->class_file.constant_pool[index - 1]; - - if (class_info->tag == CONSTANT_Class) { - // Basic check, more detailed type checking might be needed. - operand_stack_push(stack, objref); - *pc += 3; - } else { - fprintf(stderr, "checkcast: invalid constant pool entry\n"); - } -} static void handle_return(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - (*pc)++; // Increment pc before returning + (*pc)++; } static void handle_laload(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { @@ -479,7 +437,6 @@ static void handle_dstore(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStac locals[index] = value; operand_stack_pop(stack, &value); locals[index] = value; - fprintf("DSTORE %d: Stored %d\n", index, value); *pc += 2; } @@ -487,7 +444,6 @@ static void handle_dstore_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSt Cat2 value = operand_stack_pop_cat2(stack); locals[1] = value.high; locals[2] = value.low; - fprintf("DSTORE %d: Stored %d\n", 1, value); (*pc)++; } @@ -495,7 +451,6 @@ static void handle_dstore_2(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSt Cat2 value = operand_stack_pop_cat2(stack); locals[2] = value.high; locals[3] = value.low; - fprintf("DSTORE %d: Stored %d\n", 2, value); (*pc)++; } @@ -503,19 +458,15 @@ static void handle_dstore_3(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSt Cat2 value = operand_stack_pop_cat2(stack); locals[3] = value.high; locals[4] = value.low; - fprintf("DSTORE %d: Stored %d\n", 3, value); (*pc)++; } - -//! todo fix? +// todo check if this is correct static void handle_lastore(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { Cat2 value = operand_stack_pop_cat2(stack); int32_t index, arrayref; operand_stack_pop(stack, &index); operand_stack_pop(stack, &arrayref); - fprintf(stderr, "todo fix lastore", index, arrayref); //! - Array *array = (Array*)(intptr_t)arrayref; if (!array || index < 0 || index >= array->length || array->type != ARRAY_TYPE_LONG) { // Handle ArrayIndexOutOfBoundsException @@ -557,9 +508,7 @@ static void handle_ddiv(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack Cat2 val1 = operand_stack_pop_cat2(stack); if (val2.double_ == 0.0) { - fprintf(stderr, "ArithmeticException: Division by zero\n"); - // Handle the exception - fprintf(stderr, "ArrayIndexOutOfBoundsException\n"); + fprintf(stderr, "Division by zero\n"); return; } @@ -818,6 +767,15 @@ static void handle_invokevirtual(JVM *jvm, uint8_t *bytecode, uint32_t *pc, Oper static instruction_handler instruction_table[256] = {0}; // Initialize all to NULL static void init_instruction_table(void) { + + instruction_table[INVOKEVIRTUAL] = handle_invokevirtual; + instruction_table[LNEG] = handle_lneg; + instruction_table[DSTORE] = handle_dstore; + instruction_table[RETURN] = handle_return; + instruction_table[ICONST_1] = handle_iconst_1; + instruction_table[IFNE] = handle_ifne; + instruction_table[IF_ICMPEQ] = handle_if_icmpeq; + instruction_table[NOP] = handle_nop; instruction_table[ICONST_M1] = handle_iconst; instruction_table[ICONST_0] = handle_iconst; From a7cd1fc6e1514c8ca14cc050b004a3131bd3b53f Mon Sep 17 00:00:00 2001 From: renk Date: Sat, 8 Feb 2025 20:39:24 -0300 Subject: [PATCH 2/4] simplify code --- src/interpreter.c | 85 +++++++++-------------------------------------- 1 file changed, 15 insertions(+), 70 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 6377900..d18d583 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -162,6 +162,7 @@ static void handle_fload_2(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandSta // Load/Store operations static void handle_dload(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { + uint8_t opcode = bytecode[*pc]; uint8_t index = bytecode[(*pc) + 1]; Cat2 value; value.low = locals[index]; @@ -170,30 +171,6 @@ static void handle_dload(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *pc += 2; } -static void handle_dload_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.low = locals[1]; - value.high = locals[1 + 1]; - operand_stack_push_cat2(stack, value); - *pc += 2; -} - -static void handle_dload_2(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.low = locals[2]; - value.high = locals[2 + 1]; - operand_stack_push_cat2(stack, value); - *pc += 2; -} - -static void handle_dload_3(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.low = locals[3]; - value.high = locals[3 + 1]; - operand_stack_push_cat2(stack, value); - *pc += 2; -} - static void handle_istore(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { uint8_t index = bytecode[(*pc) + 1]; int32_t value; @@ -390,12 +367,6 @@ static void handle_ifne(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack } } -static void handle_iconst_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - operand_stack_push(stack, 1); - (*pc)++; -} - - static void handle_return(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { (*pc)++; @@ -611,42 +582,18 @@ static void handle_lcmp(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack } static void handle_lload(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - uint8_t index = bytecode[(*pc) + 1]; -// todo check load order + uint8_t opcode = bytecode[*pc]; + uint8_t index; + if(opcode == LLOAD) + index = bytecode[(*pc) + 1]; + else + index = opcode - LLOAD_0; operand_stack_push(stack, locals[index]); operand_stack_push(stack, locals[index + 1]); - *pc += 2; } -static void handle_lload_0(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.long_ = *((int64_t*)&locals[0]); - operand_stack_push_cat2(stack, value); - (*pc)++; -} -static void handle_lload_1(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.long_ = *((int64_t*)&locals[1]); - operand_stack_push_cat2(stack, value); - (*pc)++; -} -static void handle_lload_2(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.long_ = *((int64_t*)&locals[2]); - operand_stack_push_cat2(stack, value); - (*pc)++; -} -static void handle_lload_3(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { - Cat2 value; - value.long_ = *((int64_t*)&locals[3]); - operand_stack_push_cat2(stack, value); - (*pc)++; -} - - - static void handle_lneg(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack *stack, int32_t *locals) { Cat2 value = operand_stack_pop_cat2(stack); value.long_ = -value.long_; @@ -772,7 +719,6 @@ static void init_instruction_table(void) { instruction_table[LNEG] = handle_lneg; instruction_table[DSTORE] = handle_dstore; instruction_table[RETURN] = handle_return; - instruction_table[ICONST_1] = handle_iconst_1; instruction_table[IFNE] = handle_ifne; instruction_table[IF_ICMPEQ] = handle_if_icmpeq; @@ -801,9 +747,9 @@ static void init_instruction_table(void) { instruction_table[DADD] = handle_dadd; instruction_table[DLOAD] = handle_dload; - instruction_table[DLOAD_1] = handle_dload_1; - instruction_table[DLOAD_2] = handle_dload_2; - instruction_table[DLOAD_3] = handle_dload_3; + instruction_table[DLOAD_1] = handle_dload; + instruction_table[DLOAD_2] = handle_dload; + instruction_table[DLOAD_3] = handle_dload; instruction_table[DREM] = handle_drem; instruction_table[DSUB] = handle_dsub; instruction_table[DMUL] = handle_dmul; @@ -824,13 +770,12 @@ static void init_instruction_table(void) { instruction_table[LCONST_0] = handle_lconst; instruction_table[LCONST_1] = handle_lconst; - instruction_table[LLOAD]; - instruction_table[LLOAD_0] = handle_lload_0; - instruction_table[LLOAD_1] = handle_lload_1; - instruction_table[LLOAD_2] = handle_lload_2; - instruction_table[LLOAD_3] = handle_lload_3; - instruction_table[LLOAD] = handle_lload; + instruction_table[LLOAD_0] = handle_lload; + instruction_table[LLOAD_1] = handle_lload; + instruction_table[LLOAD_2] = handle_lload; + instruction_table[LLOAD_3] = handle_lload; + instruction_table[LCMP] = handle_lcmp; instruction_table[LASTORE] = handle_lastore; instruction_table[LAND] = handle_land; From 8a5d5b774d884466b7bb9693c81fde659fe2ca62 Mon Sep 17 00:00:00 2001 From: renk Date: Sat, 8 Feb 2025 21:02:58 -0300 Subject: [PATCH 3/4] minor simplify code --- src/interpreter.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index d0e9f9e..aac3ffb 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -839,10 +839,6 @@ bool test_op_stack_empty(OperandStack *stack); bool test_op_stack_overflow(OperandStack *stack); bool test_op_stack_underflow(OperandStack *stack); -Cat2 pop_cat2_from_op_stack(); -Cat2 push_cat2_to_op_stack( uint32_t HighBytes, uint32_t LowBytes); - - const char* get_utf8_from_constant_pool(ClassFile *class_file, uint16_t index) { if (!validate_constant_pool_index(class_file, index)) { return NULL; From e5641a73a883e6942f5b90331cc4cc03f34a08ec Mon Sep 17 00:00:00 2001 From: renk Date: Sat, 8 Feb 2025 21:13:42 -0300 Subject: [PATCH 4/4] drem frem improvements: use is_nan is_inf --- src/interpreter.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index aac3ffb..4f5f718 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -5,7 +5,10 @@ #include #include #include -#include // pro handle_drem + +// pro DREM e FREM +#define IS_NAN(x) ((*(uint64_t*)&(x) & 0x7FF8000000000000ULL) == 0x7FF8000000000000ULL) +#define IS_INF(x) (((*(uint64_t*)&(x) & 0x7FF0000000000000ULL) == 0x7FF0000000000000ULL) && !IS_NAN(x)) #define CONSTANT_Class 7 @@ -272,19 +275,19 @@ static void handle_drem(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack double value2 = val2.double_; - if (isnan(value1) || isnan(value2) || isinf(value1) || value2 == 0.0 || isinf(value2)) { + if (IS_NAN(value1) || IS_NAN(value2) || IS_INF(value1) || value2 == 0.0 || IS_INF(value2)) { fprintf(stderr, "!!Operando invalido (drem)\n"); (*pc)++; return; } - if (value1 == 0.0 && !isinf(value2) && value2 != 0.0) { + if (value1 == 0.0 && !IS_INF(value2) && value2 != 0.0) { operand_stack_push_cat2(stack, val1); (*pc)++; return; } - if (!isinf(value1) && isinf(value2)) { + if (!IS_INF(value1) && IS_INF(value2)) { operand_stack_push_cat2(stack, val1); (*pc)++; return; @@ -506,9 +509,7 @@ static void handle_dcmpl(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack Cat2 val1 = operand_stack_pop_cat2(stack); int32_t result; - if (isnan(val1.double_) || isnan(val2.double_)) { - result = -1; - } else if (val1.double_ > val2.double_) { + if (val1.double_ > val2.double_) { result = 1; } else if (val1.double_ == val2.double_) { result = 0; @@ -525,7 +526,7 @@ static void handle_dcmpg(JVM *jvm, uint8_t *bytecode, uint32_t *pc, OperandStack Cat2 val1 = operand_stack_pop_cat2(stack); int32_t result; - if (isnan(val1.double_) || isnan(val2.double_)) { + if (IS_NAN(val1.double_) || IS_NAN(val2.double_)) { result = 1; } else if (val1.double_ > val2.double_) { result = 1;