static void execute(MVM_VirtualMachine *mvm, Function *func, MVM_Byte *code, int code_size) { int base; MVM_Executable *exe; int pc; //MVM_Value ret; pc = mvm->pc; exe = mvm->current_executable; while (pc < code_size) { /*printf("%s sp(%d)\t\n", mvm_opcode_info[code[pc]].mnemonic, mvm->stack.stack_pointer);*/ switch (code[pc]) { case MVM_PUSH_INT_1BYTE: STI_WRITE(mvm, 0, code[pc+1]); //printf("int byte %d\n",code[pc+1]); mvm->stack.stack_pointer++; pc += 2; break; case MVM_PUSH_INT_2BYTE: STI_WRITE(mvm, 0, GET_2BYTE_INT(&code[pc+1])); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_INT: STI_WRITE(mvm, 0, exe->constant_pool[GET_2BYTE_INT(&code[pc+1])].u.c_integer); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_DOUBLE_0: STD_WRITE(mvm, 0, 0.0); mvm->stack.stack_pointer++; pc++; break; case MVM_PUSH_DOUBLE_1: STD_WRITE(mvm, 0, 1.0); mvm->stack.stack_pointer++; pc++; break; case MVM_PUSH_DOUBLE: STD_WRITE(mvm, 0, exe->constant_pool[GET_2BYTE_INT(&code[pc+1])].u.c_decimal); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_STRING: STO_WRITE(mvm, 0, mvm_literal_to_mvm_string_i(mvm, exe->constant_pool [GET_2BYTE_INT(&code [pc+1])] .u.c_string)); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_NULL: STO_WRITE(mvm, 0, NULL); mvm->stack.stack_pointer++; pc++; break; case MVM_PUSH_STACK_INT: STI_WRITE(mvm, 0, STI_I(mvm, base + GET_2BYTE_INT(&code[pc+1]))); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_STACK_DOUBLE: STD_WRITE(mvm, 0, STD_I(mvm, base + GET_2BYTE_INT(&code[pc+1]))); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_STACK_OBJECT: STO_WRITE(mvm, 0, STO_I(mvm, base + GET_2BYTE_INT(&code[pc+1]))); mvm->stack.stack_pointer++; pc += 3; break; case MVM_POP_STACK_INT: STI_WRITE_I(mvm, base + GET_2BYTE_INT(&code[pc+1]), STI(mvm, -1)); mvm->stack.stack_pointer--; pc += 3; break; case MVM_POP_STACK_DOUBLE: STD_WRITE_I(mvm, base + GET_2BYTE_INT(&code[pc+1]), STD(mvm, -1)); mvm->stack.stack_pointer--; pc += 3; break; case MVM_POP_STACK_OBJECT: STO_WRITE_I(mvm, base + GET_2BYTE_INT(&code[pc+1]), STO(mvm, -1)); mvm->stack.stack_pointer--; pc += 3; break; case MVM_PUSH_STATIC_INT: STI_WRITE(mvm, 0, mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])] .int_value); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_STATIC_DOUBLE: STD_WRITE(mvm, 0, mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])] .double_value); mvm->stack.stack_pointer++; pc += 3; break; case MVM_PUSH_STATIC_OBJECT: STO_WRITE(mvm, 0,mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])].object); mvm->stack.stack_pointer++; pc += 3; break; case MVM_POP_STATIC_INT: mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])].int_value = STI(mvm, -1); mvm->stack.stack_pointer--; pc += 3; break; case MVM_POP_STATIC_DOUBLE: mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])] .double_value = STD(mvm, -1); mvm->stack.stack_pointer--; pc += 3; break; case MVM_POP_STATIC_OBJECT: mvm->static_v.variable[GET_2BYTE_INT(&code[pc+1])].object = STO(mvm, -1); mvm->stack.stack_pointer--; pc += 3; break; case MVM_PUSH_ARRAY_INT: { MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); int int_value; restore_pc(mvm, exe, func, pc); int_value = MVM_array_get_int(mvm, array, index); STI_WRITE(mvm, -2, int_value); mvm->stack.stack_pointer--; pc++; break; } case MVM_PUSH_ARRAY_DOUBLE: { MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); double double_value; restore_pc(mvm, exe, func, pc); double_value = MVM_array_get_double(mvm, array, index); STD_WRITE(mvm, -2, double_value); mvm->stack.stack_pointer--; pc++; break; } case MVM_PUSH_ARRAY_OBJECT: { MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); MVM_Object *object; restore_pc(mvm, exe, func, pc); object = MVM_array_get_object(mvm, array, index); STO_WRITE(mvm, -2, object); mvm->stack.stack_pointer--; pc++; break; } case MVM_POP_ARRAY_INT: { int value = STI(mvm, -3); MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); restore_pc(mvm, exe, func, pc); MVM_array_set_int(mvm, array, index, value); mvm->stack.stack_pointer -= 3; pc++; break; } case MVM_POP_ARRAY_DOUBLE: { double value = STD(mvm, -3); MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); restore_pc(mvm, exe, func, pc); MVM_array_set_double(mvm, array, index, value); mvm->stack.stack_pointer -= 3; pc++; break; } case MVM_POP_ARRAY_OBJECT: { MVM_Object *value = STO(mvm, -3); MVM_Object *array = STO(mvm, -2); int index = STI(mvm, -1); restore_pc(mvm, exe, func, pc); MVM_array_set_object(mvm, array, index, value); mvm->stack.stack_pointer -= 3; pc++; break; } case MVM_PUSH_FIELD_INT: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); //check_null_pointer(exe, func, pc, obj); STI_WRITE(mvm, -1, obj->u.class_object.field[index].int_value); pc += 3; break; } case MVM_PUSH_FIELD_DOUBLE: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); //check_null_pointer(exe, func, pc, obj); STD_WRITE(mvm, -1, obj->u.class_object.field[index].double_value); pc += 3; break; } case MVM_PUSH_FIELD_OBJECT: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); //check_null_pointer(exe, func, pc, obj); STO_WRITE(mvm, -1, obj->u.class_object.field[index].object); pc += 3; break; } case MVM_POP_FIELD_INT: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); obj->u.class_object.field[index].int_value = STI(mvm, -2); mvm->stack.stack_pointer -= 2; pc += 3; break; } case MVM_POP_FIELD_DOUBLE: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); obj->u.class_object.field[index].double_value = STD(mvm, -2); mvm->stack.stack_pointer -= 2; pc += 3; break; } case MVM_POP_FIELD_OBJECT: { MVM_Object *obj = STO(mvm, -1); int index = GET_2BYTE_INT(&code[pc+1]); //check_null_pointer(exe, func, pc, obj); obj->u.class_object.field[index].object = STO(mvm, -2); mvm->stack.stack_pointer -= 2; pc += 3; break; } case MVM_ADD_INT: STI(mvm, -2) = STI(mvm, -2) + STI(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_ADD_DOUBLE: STD(mvm, -2) = STD(mvm, -2) + STD(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_ADD_STRING: STO(mvm, -2) = chain_string(mvm, STO(mvm, -2), STO(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_SUB_INT: STI(mvm, -2) = STI(mvm, -2) - STI(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_SUB_DOUBLE: STD(mvm, -2) = STD(mvm, -2) - STD(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_MUL_INT: STI(mvm, -2) = STI(mvm, -2) * STI(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_MUL_DOUBLE: STD(mvm, -2) = STD(mvm, -2) * STD(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_DIV_INT: if (STI(mvm, -1) == 0) { //mvm_error(exe, func, pc, DIVISION_BY_ZERO_ERR, // MESSAGE_ARGUMENT_END); } STI(mvm, -2) = STI(mvm, -2) / STI(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_DIV_DOUBLE: STD(mvm, -2) = STD(mvm, -2) / STD(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_MOD_INT: STI(mvm, -2) = STI(mvm, -2) % STI(mvm, -1); mvm->stack.stack_pointer--; pc++; break; case MVM_MOD_DOUBLE: STD(mvm, -2) = fmod(STD(mvm, -2), STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_MINUS_INT: STI(mvm, -1) = -STI(mvm, -1); pc++; break; case MVM_MINUS_DOUBLE: STD(mvm, -1) = -STD(mvm, -1); pc++; break; case MVM_INCREMENT: STI(mvm, -1)++; pc++; break; case MVM_DECREMENT: STI(mvm, -1)--; pc++; break; case MVM_CAST_INT_TO_DOUBLE: STD(mvm, -1) = (double)STI(mvm, -1); pc++; break; case MVM_CAST_DOUBLE_TO_INT: STI(mvm, -1) = (int)STD(mvm, -1); pc++; break; case MVM_CAST_BOOLEAN_TO_STRING: if (STI(mvm, -1)) { STO_WRITE(mvm, -1, mvm_literal_to_mvm_string_i(mvm, TRUE_STRING)); } else { STO_WRITE(mvm, -1, mvm_literal_to_mvm_string_i(mvm, FALSE_STRING)); } pc++; break; case MVM_CAST_INT_TO_STRING: { char buf[LINE_BUF_SIZE]; MVM_Char *str; sprintf(buf, "%d", STI(mvm, -1)); restore_pc(mvm, exe, func, pc); str = str_alloc(buf); STO_WRITE(mvm, -1, mvm_create_mvm_string_i(mvm, str)); pc++; break; } case MVM_CAST_DOUBLE_TO_STRING: { char buf[LINE_BUF_SIZE]; MVM_Char *str; sprintf(buf, "%f", STD(mvm, -1)); restore_pc(mvm, exe, func, pc); str = str_alloc(buf); STO_WRITE(mvm, -1, mvm_create_mvm_string_i(mvm, str)); pc++; break; } case MVM_EQ_INT: STI(mvm, -2) = (STI(mvm, -2) == STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_EQ_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) == STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_EQ_OBJECT: STI_WRITE(mvm, -2, STO(mvm, -2) == STO(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_EQ_STRING: STI_WRITE(mvm, -2, !strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string)); mvm->stack.stack_pointer--; pc++; break; case MVM_GT_INT: STI(mvm, -2) = (STI(mvm, -2) > STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_GT_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) > STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_GT_STRING: STI_WRITE(mvm, -2, strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string) > 0); mvm->stack.stack_pointer--; pc++; break; case MVM_GE_INT: STI(mvm, -2) = (STI(mvm, -2) >= STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_GE_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) >= STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_GE_STRING: STI_WRITE(mvm, -2, strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string) >= 0); mvm->stack.stack_pointer--; pc++; break; case MVM_LT_INT: STI(mvm, -2) = (STI(mvm, -2) < STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LT_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) < STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LT_STRING: STI_WRITE(mvm, -2, strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string) < 0); mvm->stack.stack_pointer--; pc++; break; case MVM_LE_INT: STI(mvm, -2) = (STI(mvm, -2) <= STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LE_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) <= STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LE_STRING: STI_WRITE(mvm, -2, strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string) <= 0); mvm->stack.stack_pointer--; pc++; break; case MVM_NE_INT: STI(mvm, -2) = (STI(mvm, -2) != STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_NE_DOUBLE: STI(mvm, -2) = (STD(mvm, -2) != STD(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_NE_OBJECT: STI_WRITE(mvm, -2, STO(mvm, -2) != STO(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_NE_STRING: STI_WRITE(mvm, -2, strcmp(STO(mvm, -2)->u.string.string, STO(mvm, -1)->u.string.string) != 0); mvm->stack.stack_pointer--; pc++; break; case MVM_LOGICAL_AND: STI(mvm, -2) = (STI(mvm, -2) && STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LOGICAL_OR: STI(mvm, -2) = (STI(mvm, -2) || STI(mvm, -1)); mvm->stack.stack_pointer--; pc++; break; case MVM_LOGICAL_NOT: STI(mvm, -1) = !STI(mvm, -1); pc++; break; case MVM_POP: mvm->stack.stack_pointer--; pc++; break; case MVM_DUPLICATE: mvm->stack.stack[mvm->stack.stack_pointer] = mvm->stack.stack[mvm->stack.stack_pointer-1]; mvm->stack.stack_pointer++; pc++; break; case MVM_JUMP: pc = GET_2BYTE_INT(&code[pc+1]); break; case MVM_JUMP_IF_TRUE: if (STI(mvm, -1)) { pc = GET_2BYTE_INT(&code[pc+1]); } else { pc += 3; } mvm->stack.stack_pointer--; break; case MVM_JUMP_IF_FALSE: if (!STI(mvm, -1)) { pc = GET_2BYTE_INT(&code[pc+1]); } else { pc += 3; } mvm->stack.stack_pointer--; break; case MVM_PUSH_FUNCTION: STI_WRITE(mvm, 0, GET_2BYTE_INT(&code[pc+1])); mvm->stack.stack_pointer++; pc += 3; break; case MVM_INVOKE: { int func_idx = STI(mvm, -1); if (mvm->function[func_idx].kind == NATIVE_FUNCTION) { invoke_native_function(mvm, &mvm->function[func_idx], &mvm->stack.stack_pointer); pc++; } else { invoke_minic_function(mvm, &func, &mvm->function[func_idx], &code, &code_size, &pc, &mvm->stack.stack_pointer, &base, &exe); } break; } case MVM_RETURN: return_function(mvm, &func, &code, &code_size, &pc, &mvm->stack.stack_pointer, &base, &exe); break; case MVM_NEW_ARRAY: { int dim = code[pc+1]; MVM_TypeSpecifier *type = &exe->type_specifier[GET_2BYTE_INT(&code[pc+2])]; MVM_Object *array; restore_pc(mvm, exe, func, pc); array = create_array(mvm, dim, type); mvm->stack.stack_pointer -= dim; STO_WRITE(mvm, 0, array); mvm->stack.stack_pointer++; pc += 4; break; } case MVM_NEW_ARRAY_LITERAL_INT: /* FALLTHRU */ { int size = GET_2BYTE_INT(&code[pc+1]); MVM_Object *array; restore_pc(mvm, exe, func, pc); array = create_array_literal_int(mvm, size); mvm->stack.stack_pointer -= size; STO_WRITE(mvm, 0, array); mvm->stack.stack_pointer++; pc += 3; break; } case MVM_NEW_ARRAY_LITERAL_DOUBLE: /* FALLTHRU */ { int size = GET_2BYTE_INT(&code[pc+1]); MVM_Object *array; restore_pc(mvm, exe, func, pc); array = create_array_literal_double(mvm, size); mvm->stack.stack_pointer -= size; STO_WRITE(mvm, 0, array); mvm->stack.stack_pointer++; pc += 3; break; } case MVM_NEW_ARRAY_LITERAL_OBJECT: /* FALLTHRU */ { int size = GET_2BYTE_INT(&code[pc+1]); MVM_Object *array; restore_pc(mvm, exe, func, pc); array = create_array_literal_object(mvm, size); mvm->stack.stack_pointer -= size; STO_WRITE(mvm, 0, array); mvm->stack.stack_pointer++; pc += 3; break; } default: break; } /* MEM_check_all_blocks(); */ } //return ret; }
int main(void){ printf("%d\n",return_function(3)); return 0; }