fix buffer overflow seg fault when using cache
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
let i = 10000
|
let f(i) = do
|
||||||
while (i) do
|
while (i) i=i-1
|
||||||
i=i-1
|
f(1e6)
|
||||||
@@ -48,10 +48,10 @@ typedef struct {
|
|||||||
} Translated;
|
} Translated;
|
||||||
|
|
||||||
struct string_struct {
|
struct string_struct {
|
||||||
char *data;
|
|
||||||
uint64_t prehash;
|
uint64_t prehash;
|
||||||
uint64_t hash;
|
uint64_t hash;
|
||||||
bool hash_computed;
|
bool hash_computed;
|
||||||
|
char *data;
|
||||||
size_t length;
|
size_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,9 @@ int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash,
|
|||||||
|
|
||||||
*translated_dest = init_translator(source_path);
|
*translated_dest = init_translator(source_path);
|
||||||
|
|
||||||
|
|
||||||
|
translated_dest->registerCount = register_count;
|
||||||
|
|
||||||
arena_resize(&translated_dest->constants, constantsSize);
|
arena_resize(&translated_dest->constants, constantsSize);
|
||||||
|
|
||||||
if (fread(translated_dest->constants.data, 1, constantsSize, bytecode_file) !=
|
if (fread(translated_dest->constants.data, 1, constantsSize, bytecode_file) !=
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
object->value.argon_fn.bytecode_length, false},
|
object->value.argon_fn.bytecode_length, false},
|
||||||
object->value.argon_fn.translated.constants,
|
object->value.argon_fn.translated.constants,
|
||||||
object->value.argon_fn.translated.path},
|
object->value.argon_fn.translated.path},
|
||||||
{state->registers,
|
{ar_alloc(object->value.argon_fn.translated.registerCount * sizeof(ArgonObject *)),
|
||||||
0,
|
0,
|
||||||
object->value.argon_fn.translated.path,
|
object->value.argon_fn.translated.path,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -156,10 +156,11 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
if (CStackFrame) {
|
if (CStackFrame) {
|
||||||
runtime(new_stackFrame.translated, new_stackFrame.state,
|
runtime(new_stackFrame.translated, new_stackFrame.state,
|
||||||
new_stackFrame.stack, err);
|
new_stackFrame.stack, err);
|
||||||
|
state->registers[0] = new_stackFrame.state.registers[0];
|
||||||
} else {
|
} else {
|
||||||
*state->currentStackFramePointer =
|
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||||
ar_alloc(sizeof(StackFrame));
|
*currentStackFrame = new_stackFrame;
|
||||||
**state->currentStackFramePointer = new_stackFrame;
|
*state->currentStackFramePointer = currentStackFrame;
|
||||||
if ((*state->currentStackFramePointer)->depth >= 10000) {
|
if ((*state->currentStackFramePointer)->depth >= 10000) {
|
||||||
double logval =
|
double logval =
|
||||||
log10((double)(*state->currentStackFramePointer)->depth);
|
log10((double)(*state->currentStackFramePointer)->depth);
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ ArgonObject *ARGON_NUMBER_TYPE___add__(size_t argc, ArgonObject **argv,
|
|||||||
bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) ||
|
bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) ||
|
||||||
(a < 0 && b < 0 && a < INT64_MIN - b);
|
(a < 0 && b < 0 && a < INT64_MIN - b);
|
||||||
if (!gonna_overflow) {
|
if (!gonna_overflow) {
|
||||||
return new_number_object_from_num_and_den(a + b, 1);
|
return new_number_object_from_int64(a + b);
|
||||||
}
|
}
|
||||||
mpq_t a_GMP, b_GMP;
|
mpq_t a_GMP, b_GMP;
|
||||||
mpq_init(a_GMP);
|
mpq_init(a_GMP);
|
||||||
@@ -165,7 +165,7 @@ ArgonObject *ARGON_NUMBER_TYPE___subtract__(size_t argc, ArgonObject **argv,
|
|||||||
bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) ||
|
bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) ||
|
||||||
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
||||||
if (!gonna_overflow) {
|
if (!gonna_overflow) {
|
||||||
return new_number_object_from_num_and_den(a - b, 1);
|
return new_number_object_from_int64(a - b);
|
||||||
}
|
}
|
||||||
mpq_t a_GMP, b_GMP;
|
mpq_t a_GMP, b_GMP;
|
||||||
mpq_init(a_GMP);
|
mpq_init(a_GMP);
|
||||||
@@ -414,11 +414,11 @@ ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv,
|
|||||||
|
|
||||||
#define small_ints_min -256
|
#define small_ints_min -256
|
||||||
#define small_ints_max 256
|
#define small_ints_max 256
|
||||||
ArgonObject small_ints[small_ints_max-small_ints_min+1];
|
ArgonObject small_ints[small_ints_max - small_ints_min + 1];
|
||||||
|
|
||||||
void init_small_ints() {
|
void init_small_ints() {
|
||||||
for (int64_t i = 0; i <= small_ints_max-small_ints_min; i++) {
|
for (int64_t i = 0; i <= small_ints_max - small_ints_min; i++) {
|
||||||
int64_t n = i+small_ints_min;
|
int64_t n = i + small_ints_min;
|
||||||
small_ints[i].type = TYPE_NUMBER;
|
small_ints[i].type = TYPE_NUMBER;
|
||||||
small_ints[i].dict = createHashmap_GC();
|
small_ints[i].dict = createHashmap_GC();
|
||||||
add_builtin_field(&small_ints[i], __class__, ARGON_NUMBER_TYPE);
|
add_builtin_field(&small_ints[i], __class__, ARGON_NUMBER_TYPE);
|
||||||
@@ -432,29 +432,31 @@ void init_small_ints() {
|
|||||||
void create_ARGON_NUMBER_TYPE() {
|
void create_ARGON_NUMBER_TYPE() {
|
||||||
ARGON_NUMBER_TYPE = new_object();
|
ARGON_NUMBER_TYPE = new_object();
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __name__,
|
add_builtin_field(ARGON_NUMBER_TYPE, __name__,
|
||||||
new_string_object_null_terminated("number"));
|
new_string_object_null_terminated("number"));
|
||||||
add_builtin_field(
|
add_builtin_field(
|
||||||
ARGON_NUMBER_TYPE, __string__,
|
ARGON_NUMBER_TYPE, __string__,
|
||||||
create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__));
|
create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __new__,
|
add_builtin_field(
|
||||||
create_argon_native_function("__new__", ARGON_NUMBER_TYPE___new__));
|
ARGON_NUMBER_TYPE, __new__,
|
||||||
|
create_argon_native_function("__new__", ARGON_NUMBER_TYPE___new__));
|
||||||
add_builtin_field(
|
add_builtin_field(
|
||||||
ARGON_NUMBER_TYPE, __number__,
|
ARGON_NUMBER_TYPE, __number__,
|
||||||
create_argon_native_function("__number__", ARGON_NUMBER_TYPE___number__));
|
create_argon_native_function("__number__", ARGON_NUMBER_TYPE___number__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __boolean__,
|
add_builtin_field(ARGON_NUMBER_TYPE, __boolean__,
|
||||||
create_argon_native_function("__boolean__",
|
create_argon_native_function(
|
||||||
ARGON_NUMBER_TYPE___boolean__));
|
"__boolean__", ARGON_NUMBER_TYPE___boolean__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __add__,
|
add_builtin_field(
|
||||||
create_argon_native_function("__add__", ARGON_NUMBER_TYPE___add__));
|
ARGON_NUMBER_TYPE, __add__,
|
||||||
|
create_argon_native_function("__add__", ARGON_NUMBER_TYPE___add__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __subtract__,
|
add_builtin_field(ARGON_NUMBER_TYPE, __subtract__,
|
||||||
create_argon_native_function("__subtract__",
|
create_argon_native_function(
|
||||||
ARGON_NUMBER_TYPE___subtract__));
|
"__subtract__", ARGON_NUMBER_TYPE___subtract__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __multiply__,
|
add_builtin_field(ARGON_NUMBER_TYPE, __multiply__,
|
||||||
create_argon_native_function("__multiply__",
|
create_argon_native_function(
|
||||||
ARGON_NUMBER_TYPE___multiply__));
|
"__multiply__", ARGON_NUMBER_TYPE___multiply__));
|
||||||
add_builtin_field(ARGON_NUMBER_TYPE, __division__,
|
add_builtin_field(ARGON_NUMBER_TYPE, __division__,
|
||||||
create_argon_native_function("__division__",
|
create_argon_native_function(
|
||||||
ARGON_NUMBER_TYPE___division__));
|
"__division__", ARGON_NUMBER_TYPE___division__));
|
||||||
init_small_ints();
|
init_small_ints();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,7 +536,7 @@ ArgonObject *new_number_object(mpq_t number) {
|
|||||||
int64_t i64 = 0;
|
int64_t i64 = 0;
|
||||||
bool is_int64 = mpq_to_int64(number, &i64);
|
bool is_int64 = mpq_to_int64(number, &i64);
|
||||||
if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) {
|
if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) {
|
||||||
return &small_ints[i64-small_ints_min];
|
return &small_ints[i64 - small_ints_min];
|
||||||
}
|
}
|
||||||
ArgonObject *object = new_object();
|
ArgonObject *object = new_object();
|
||||||
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
||||||
@@ -552,7 +554,7 @@ ArgonObject *new_number_object(mpq_t number) {
|
|||||||
|
|
||||||
ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) {
|
ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) {
|
||||||
if (d == 1 && n >= small_ints_min && n <= small_ints_max) {
|
if (d == 1 && n >= small_ints_min && n <= small_ints_max) {
|
||||||
return &small_ints[n-small_ints_min];
|
return &small_ints[n - small_ints_min];
|
||||||
}
|
}
|
||||||
ArgonObject *object = new_object();
|
ArgonObject *object = new_object();
|
||||||
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
||||||
@@ -573,11 +575,24 @@ ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgonObject *new_number_object_from_int64(int64_t i64) {
|
||||||
|
if (i64 >= small_ints_min && i64 <= small_ints_max) {
|
||||||
|
return &small_ints[i64 - small_ints_min];
|
||||||
|
}
|
||||||
|
ArgonObject *object = new_object();
|
||||||
|
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
||||||
|
object->type = TYPE_NUMBER;
|
||||||
|
object->value.as_number.is_int64 = true;
|
||||||
|
object->value.as_number.n.i64 = i64;
|
||||||
|
object->as_bool = i64;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
ArgonObject *new_number_object_from_double(double d) {
|
ArgonObject *new_number_object_from_double(double d) {
|
||||||
int64_t i64 = 0;
|
int64_t i64 = 0;
|
||||||
bool is_int64 = double_to_int64(d, &i64);
|
bool is_int64 = double_to_int64(d, &i64);
|
||||||
if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) {
|
if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) {
|
||||||
return &small_ints[i64-small_ints_min];
|
return &small_ints[i64 - small_ints_min];
|
||||||
}
|
}
|
||||||
ArgonObject *object = new_object();
|
ArgonObject *object = new_object();
|
||||||
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
add_builtin_field(object, __class__, ARGON_NUMBER_TYPE);
|
||||||
@@ -602,7 +617,7 @@ void load_number(Translated *translated, RuntimeState *state) {
|
|||||||
uint8_t is_int64 = pop_byte(translated, state);
|
uint8_t is_int64 = pop_byte(translated, state);
|
||||||
if (is_int64) {
|
if (is_int64) {
|
||||||
state->registers[to_register] =
|
state->registers[to_register] =
|
||||||
new_number_object_from_num_and_den(pop_bytecode(translated, state), 1);
|
new_number_object_from_int64(pop_bytecode(translated, state));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t num_size = pop_bytecode(translated, state);
|
size_t num_size = pop_bytecode(translated, state);
|
||||||
|
|||||||
@@ -22,4 +22,6 @@ ArgonObject *new_number_object_from_double(double d);
|
|||||||
|
|
||||||
ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d);
|
ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d);
|
||||||
|
|
||||||
|
ArgonObject *new_number_object_from_int64(int64_t i64);
|
||||||
|
|
||||||
#endif // RUNTIME_NUMBER_H
|
#endif // RUNTIME_NUMBER_H
|
||||||
@@ -18,7 +18,7 @@ ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash,
|
|||||||
ArgonObject *object = new_object();
|
ArgonObject *object = new_object();
|
||||||
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
||||||
add_builtin_field(object, field_length,
|
add_builtin_field(object, field_length,
|
||||||
new_number_object_from_num_and_den(length, 1));
|
new_number_object_from_int64(length));
|
||||||
object->type = TYPE_STRING;
|
object->type = TYPE_STRING;
|
||||||
object->value.as_str.data = ar_alloc_atomic(length);
|
object->value.as_str.data = ar_alloc_atomic(length);
|
||||||
memcpy(object->value.as_str.data, data, length);
|
memcpy(object->value.as_str.data, data, length);
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ ArgonObject *ARGON_BOOL_TYPE___number__(size_t argc, ArgonObject **argv,
|
|||||||
"__number__ expects 1 arguments, got %" PRIu64, argc);
|
"__number__ expects 1 arguments, got %" PRIu64, argc);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
return new_number_object_from_num_and_den(argv[0] == ARGON_TRUE, 1);
|
return new_number_object_from_int64(argv[0] == ARGON_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
|
ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
|
||||||
@@ -463,7 +463,7 @@ ArgonObject *ARGON_NULL_TYPE___number__(size_t argc, ArgonObject **argv,
|
|||||||
*err = create_err(0, 0, 0, "", "Runtime Error",
|
*err = create_err(0, 0, 0, "", "Runtime Error",
|
||||||
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
|
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
|
||||||
}
|
}
|
||||||
return new_number_object_from_num_and_den(0, 1);
|
return new_number_object_from_int64(0);
|
||||||
}
|
}
|
||||||
ArgonObject *ARGON_NULL_TYPE___string__(size_t argc, ArgonObject **argv,
|
ArgonObject *ARGON_NULL_TYPE___string__(size_t argc, ArgonObject **argv,
|
||||||
ArErr *err, RuntimeState *state) {
|
ArErr *err, RuntimeState *state) {
|
||||||
@@ -494,8 +494,10 @@ void bootstrap_types() {
|
|||||||
ARGON_BOOL_TYPE = new_object();
|
ARGON_BOOL_TYPE = new_object();
|
||||||
add_builtin_field(ARGON_BOOL_TYPE, __base__, BASE_CLASS);
|
add_builtin_field(ARGON_BOOL_TYPE, __base__, BASE_CLASS);
|
||||||
ARGON_TRUE = new_object();
|
ARGON_TRUE = new_object();
|
||||||
|
ARGON_TRUE->type = TYPE_BOOL;
|
||||||
add_builtin_field(ARGON_TRUE, __class__, ARGON_BOOL_TYPE);
|
add_builtin_field(ARGON_TRUE, __class__, ARGON_BOOL_TYPE);
|
||||||
ARGON_FALSE = new_object();
|
ARGON_FALSE = new_object();
|
||||||
|
ARGON_FALSE->type = TYPE_BOOL;
|
||||||
add_builtin_field(ARGON_FALSE, __class__, ARGON_BOOL_TYPE);
|
add_builtin_field(ARGON_FALSE, __class__, ARGON_BOOL_TYPE);
|
||||||
ARGON_NULL->as_bool = false;
|
ARGON_NULL->as_bool = false;
|
||||||
|
|
||||||
@@ -626,7 +628,8 @@ static inline void load_const(Translated *translated, RuntimeState *state) {
|
|||||||
uint64_t to_register = pop_byte(translated, state);
|
uint64_t to_register = pop_byte(translated, state);
|
||||||
size_t length = pop_bytecode(translated, state);
|
size_t length = pop_bytecode(translated, state);
|
||||||
uint64_t offset = pop_bytecode(translated, state);
|
uint64_t offset = pop_bytecode(translated, state);
|
||||||
ArgonObject *object = new_string_object(arena_get(&translated->constants, offset), length, 0, 0);
|
ArgonObject *object = new_string_object(
|
||||||
|
arena_get(&translated->constants, offset), length, 0, 0);
|
||||||
state->registers[to_register] = object;
|
state->registers[to_register] = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,8 +718,7 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION};
|
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION};
|
||||||
_state.head = 0;
|
_state.head = 0;
|
||||||
|
|
||||||
StackFrame *currentStackFrame =
|
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||||
ar_alloc(sizeof(StackFrame));
|
|
||||||
*currentStackFrame = (StackFrame){_translated, _state, stack, NULL, 0};
|
*currentStackFrame = (StackFrame){_translated, _state, stack, NULL, 0};
|
||||||
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
||||||
while (currentStackFrame) {
|
while (currentStackFrame) {
|
||||||
@@ -819,8 +821,8 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
}
|
}
|
||||||
DO_ADDITION: {
|
DO_ADDITION: {
|
||||||
uint8_t registerA = pop_byte(translated, state);
|
uint8_t registerA = pop_byte(translated, state);
|
||||||
uint64_t registerB = pop_byte(translated, state);
|
uint8_t registerB = pop_byte(translated, state);
|
||||||
uint64_t registerC = pop_byte(translated, state);
|
uint8_t registerC = pop_byte(translated, state);
|
||||||
|
|
||||||
ArgonObject *valueA = state->registers[registerA];
|
ArgonObject *valueA = state->registers[registerA];
|
||||||
ArgonObject *valueB = state->registers[registerB];
|
ArgonObject *valueB = state->registers[registerB];
|
||||||
@@ -833,8 +835,7 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) ||
|
bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) ||
|
||||||
(a < 0 && b < 0 && a < INT64_MIN - b);
|
(a < 0 && b < 0 && a < INT64_MIN - b);
|
||||||
if (!gonna_overflow) {
|
if (!gonna_overflow) {
|
||||||
state->registers[registerC] =
|
state->registers[registerC] = new_number_object_from_int64(a + b);
|
||||||
new_number_object_from_num_and_den(a + b, 1);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mpq_t a_GMP, b_GMP;
|
mpq_t a_GMP, b_GMP;
|
||||||
@@ -873,13 +874,15 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgonObject *args[] = {valueA, valueB};
|
ArgonObject *args[] = {valueA, valueB};
|
||||||
state->registers[registerC] = ARGON_ADDITION_FUNCTION(2, args, err, state);
|
state->registers[registerC] =
|
||||||
goto START;
|
ARGON_ADDITION_FUNCTION(2, args, err, state);
|
||||||
DO_SUBTRACTION:;
|
continue;
|
||||||
registerA = pop_byte(translated, state);
|
}
|
||||||
registerB = pop_byte(translated, state);
|
DO_SUBTRACTION: {
|
||||||
registerC = pop_byte(translated, state);
|
uint8_t registerA = pop_byte(translated, state);
|
||||||
|
uint8_t registerB = pop_byte(translated, state);
|
||||||
|
uint8_t registerC = pop_byte(translated, state);
|
||||||
|
|
||||||
ArgonObject *valueA = state->registers[registerA];
|
ArgonObject *valueA = state->registers[registerA];
|
||||||
ArgonObject *valueB = state->registers[registerB];
|
ArgonObject *valueB = state->registers[registerB];
|
||||||
@@ -893,8 +896,7 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) ||
|
bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) ||
|
||||||
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
||||||
if (!gonna_overflow) {
|
if (!gonna_overflow) {
|
||||||
state->registers[registerC] =
|
state->registers[registerC] = new_number_object_from_int64(a - b);
|
||||||
new_number_object_from_num_and_den(a - b, 1);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mpq_t a_GMP, b_GMP;
|
mpq_t a_GMP, b_GMP;
|
||||||
@@ -939,6 +941,9 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgonObject *result = currentStackFrame->state.registers[0];
|
||||||
currentStackFrame = currentStackFrame->previousStackFrame;
|
currentStackFrame = currentStackFrame->previousStackFrame;
|
||||||
|
if(currentStackFrame) currentStackFrame->state.registers[0] = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user