Пример #1
0
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;
}
Пример #2
0
int main(void){
	printf("%d\n",return_function(3));
	return 0;
}