diff --git a/lib/code.c b/lib/code.c index 3968e53..93e7123 100644 --- a/lib/code.c +++ b/lib/code.c @@ -47,7 +47,8 @@ TYC_RESULT code_load_bytecode(Code* code, uint8_t const* bytecode, size_t byteco if (bytecode_sz < 24) return T_ERR_BYTECODE_TOO_SMALL; - uint32_t magic = *(uint32_t const*) &bytecode[0]; + uint32_t magic; + memcpy(&magic, bytecode, sizeof(magic)); if (magic != MAGIC) return T_ERR_BYTECODE_INVALID_MAGIC; diff --git a/lib/expr.c b/lib/expr.c index 412df27..59552a5 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -24,7 +24,7 @@ BIN_OP(gte_int_int) { *r = create_value_from_bool(value_integer(a) >= value_int BIN_OP(and_int_int) { *r = create_value_integer(value_integer(a) & value_integer(b)); return T_OK; } BIN_OP(or_int_int) { *r = create_value_integer(value_integer(a) | value_integer(b)); return T_OK; } BIN_OP(xor_int_int) { *r = create_value_integer(value_integer(a) ^ value_integer(b)); return T_OK; } -BIN_OP(pow_int_int) { *r = create_value_integer(pow(value_integer(a), value_integer(b))); return T_OK; } +BIN_OP(pow_int_int) { *r = create_value_integer((int32_t) powl(value_integer(a), value_integer(b))); return T_OK; } BIN_OP(shl_int_int) { *r = create_value_integer(value_integer(a) << value_integer(b)); return T_OK; } BIN_OP(shr_int_int) { *r = create_value_integer(value_integer(a) >> value_integer(b)); return T_OK; } BIN_OP(mod_int_int) { *r = create_value_integer(value_integer(a) % value_integer(b)); return T_OK; } diff --git a/lib/vm.c b/lib/vm.c index c194dff..efe769d 100644 --- a/lib/vm.c +++ b/lib/vm.c @@ -227,9 +227,9 @@ static TYC_RESULT step(TycheVM* T) break; case TO_PUSHF: - if (inst.operand < 0 || inst.operand > code_n_functions(T->code)) + if (inst.operand < 0 || inst.operand > (int) code_n_functions(T->code)) return T_ERR_VALUE_OUT_OF_RANGE; - TRY(stack_push(T->stack, create_value_idx(TT_FUNCTION, inst.operand))) + TRY(stack_push(T->stack, create_value_idx(TT_FUNCTION, (uint32_t) inst.operand))) break; case TO_POP: @@ -243,7 +243,7 @@ static TYC_RESULT step(TycheVM* T) case TO_PUSHV: if (inst.operand <= 0) return T_ERR_VALUE_OUT_OF_RANGE; - for (size_t i = 0; i < inst.operand; ++i) + for (int i = 0; i < inst.operand; ++i) tyc_pushnil(T); break; @@ -287,6 +287,12 @@ static TYC_RESULT step(TycheVM* T) // function calls // + case TO_CALL: + if (inst.operand < 0) + return T_ERR_VALUE_OUT_OF_RANGE; + enter_function(T, (uint16_t) inst.operand); + break; + case TO_RET: TRY(stack_pop(T->stack, &a)) TRY(stack_pop_fp(T->stack)) diff --git a/test/code-tests.lua b/test/code-tests.lua index 0a8eda8..9cd0923 100644 --- a/test/code-tests.lua +++ b/test/code-tests.lua @@ -57,4 +57,22 @@ return { expected_stack_size = 1, expected_stack_top = 3, }, + { + name = "VM: functions", + code = [[ + .func 0 + pushf 1 + pushi 2 + pushi 3 + call 2 + ret + .func 1 + dupv 0 + dupv 1 + sub + ret + ]], + expected_stack_size = 1, + expected_stack_top = -1, + }, } \ No newline at end of file