fix buffer overflow seg fault when using cache
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
let i = 10000
|
||||
while (i) do
|
||||
i=i-1
|
||||
let f(i) = do
|
||||
while (i) i=i-1
|
||||
f(1e6)
|
||||
@@ -48,10 +48,10 @@ typedef struct {
|
||||
} Translated;
|
||||
|
||||
struct string_struct {
|
||||
char *data;
|
||||
uint64_t prehash;
|
||||
uint64_t hash;
|
||||
bool hash_computed;
|
||||
char *data;
|
||||
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->registerCount = register_count;
|
||||
|
||||
arena_resize(&translated_dest->constants, constantsSize);
|
||||
|
||||
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.translated.constants,
|
||||
object->value.argon_fn.translated.path},
|
||||
{state->registers,
|
||||
{ar_alloc(object->value.argon_fn.translated.registerCount * sizeof(ArgonObject *)),
|
||||
0,
|
||||
object->value.argon_fn.translated.path,
|
||||
NULL,
|
||||
@@ -156,10 +156,11 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
||||
if (CStackFrame) {
|
||||
runtime(new_stackFrame.translated, new_stackFrame.state,
|
||||
new_stackFrame.stack, err);
|
||||
state->registers[0] = new_stackFrame.state.registers[0];
|
||||
} else {
|
||||
*state->currentStackFramePointer =
|
||||
ar_alloc(sizeof(StackFrame));
|
||||
**state->currentStackFramePointer = new_stackFrame;
|
||||
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||
*currentStackFrame = new_stackFrame;
|
||||
*state->currentStackFramePointer = currentStackFrame;
|
||||
if ((*state->currentStackFramePointer)->depth >= 10000) {
|
||||
double logval =
|
||||
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) ||
|
||||
(a < 0 && b < 0 && a < INT64_MIN - b);
|
||||
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_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) ||
|
||||
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
||||
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_init(a_GMP);
|
||||
@@ -436,25 +436,27 @@ void create_ARGON_NUMBER_TYPE() {
|
||||
add_builtin_field(
|
||||
ARGON_NUMBER_TYPE, __string__,
|
||||
create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __new__,
|
||||
add_builtin_field(
|
||||
ARGON_NUMBER_TYPE, __new__,
|
||||
create_argon_native_function("__new__", ARGON_NUMBER_TYPE___new__));
|
||||
add_builtin_field(
|
||||
ARGON_NUMBER_TYPE, __number__,
|
||||
create_argon_native_function("__number__", ARGON_NUMBER_TYPE___number__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __boolean__,
|
||||
create_argon_native_function("__boolean__",
|
||||
ARGON_NUMBER_TYPE___boolean__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __add__,
|
||||
create_argon_native_function(
|
||||
"__boolean__", ARGON_NUMBER_TYPE___boolean__));
|
||||
add_builtin_field(
|
||||
ARGON_NUMBER_TYPE, __add__,
|
||||
create_argon_native_function("__add__", ARGON_NUMBER_TYPE___add__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __subtract__,
|
||||
create_argon_native_function("__subtract__",
|
||||
ARGON_NUMBER_TYPE___subtract__));
|
||||
create_argon_native_function(
|
||||
"__subtract__", ARGON_NUMBER_TYPE___subtract__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __multiply__,
|
||||
create_argon_native_function("__multiply__",
|
||||
ARGON_NUMBER_TYPE___multiply__));
|
||||
create_argon_native_function(
|
||||
"__multiply__", ARGON_NUMBER_TYPE___multiply__));
|
||||
add_builtin_field(ARGON_NUMBER_TYPE, __division__,
|
||||
create_argon_native_function("__division__",
|
||||
ARGON_NUMBER_TYPE___division__));
|
||||
create_argon_native_function(
|
||||
"__division__", ARGON_NUMBER_TYPE___division__));
|
||||
init_small_ints();
|
||||
}
|
||||
|
||||
@@ -573,6 +575,19 @@ ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) {
|
||||
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) {
|
||||
int64_t i64 = 0;
|
||||
bool is_int64 = double_to_int64(d, &i64);
|
||||
@@ -602,7 +617,7 @@ void load_number(Translated *translated, RuntimeState *state) {
|
||||
uint8_t is_int64 = pop_byte(translated, state);
|
||||
if (is_int64) {
|
||||
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;
|
||||
}
|
||||
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_int64(int64_t i64);
|
||||
|
||||
#endif // RUNTIME_NUMBER_H
|
||||
@@ -18,7 +18,7 @@ ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash,
|
||||
ArgonObject *object = new_object();
|
||||
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
||||
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->value.as_str.data = ar_alloc_atomic(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);
|
||||
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,
|
||||
@@ -463,7 +463,7 @@ ArgonObject *ARGON_NULL_TYPE___number__(size_t argc, ArgonObject **argv,
|
||||
*err = create_err(0, 0, 0, "", "Runtime Error",
|
||||
"__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,
|
||||
ArErr *err, RuntimeState *state) {
|
||||
@@ -494,8 +494,10 @@ void bootstrap_types() {
|
||||
ARGON_BOOL_TYPE = new_object();
|
||||
add_builtin_field(ARGON_BOOL_TYPE, __base__, BASE_CLASS);
|
||||
ARGON_TRUE = new_object();
|
||||
ARGON_TRUE->type = TYPE_BOOL;
|
||||
add_builtin_field(ARGON_TRUE, __class__, ARGON_BOOL_TYPE);
|
||||
ARGON_FALSE = new_object();
|
||||
ARGON_FALSE->type = TYPE_BOOL;
|
||||
add_builtin_field(ARGON_FALSE, __class__, ARGON_BOOL_TYPE);
|
||||
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);
|
||||
size_t length = 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;
|
||||
}
|
||||
|
||||
@@ -715,8 +718,7 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION};
|
||||
_state.head = 0;
|
||||
|
||||
StackFrame *currentStackFrame =
|
||||
ar_alloc(sizeof(StackFrame));
|
||||
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||
*currentStackFrame = (StackFrame){_translated, _state, stack, NULL, 0};
|
||||
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
||||
while (currentStackFrame) {
|
||||
@@ -819,8 +821,8 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
}
|
||||
DO_ADDITION: {
|
||||
uint8_t registerA = pop_byte(translated, state);
|
||||
uint64_t registerB = pop_byte(translated, state);
|
||||
uint64_t registerC = pop_byte(translated, state);
|
||||
uint8_t registerB = pop_byte(translated, state);
|
||||
uint8_t registerC = pop_byte(translated, state);
|
||||
|
||||
ArgonObject *valueA = state->registers[registerA];
|
||||
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) ||
|
||||
(a < 0 && b < 0 && a < INT64_MIN - b);
|
||||
if (!gonna_overflow) {
|
||||
state->registers[registerC] =
|
||||
new_number_object_from_num_and_den(a + b, 1);
|
||||
state->registers[registerC] = new_number_object_from_int64(a + b);
|
||||
continue;
|
||||
}
|
||||
mpq_t a_GMP, b_GMP;
|
||||
@@ -874,12 +875,14 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
}
|
||||
|
||||
ArgonObject *args[] = {valueA, valueB};
|
||||
state->registers[registerC] = ARGON_ADDITION_FUNCTION(2, args, err, state);
|
||||
goto START;
|
||||
DO_SUBTRACTION:;
|
||||
registerA = pop_byte(translated, state);
|
||||
registerB = pop_byte(translated, state);
|
||||
registerC = pop_byte(translated, state);
|
||||
state->registers[registerC] =
|
||||
ARGON_ADDITION_FUNCTION(2, args, err, state);
|
||||
continue;
|
||||
}
|
||||
DO_SUBTRACTION: {
|
||||
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 *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) ||
|
||||
(neg_a < 0 && b < 0 && b < INT64_MIN - neg_a);
|
||||
if (!gonna_overflow) {
|
||||
state->registers[registerC] =
|
||||
new_number_object_from_num_and_den(a - b, 1);
|
||||
state->registers[registerC] = new_number_object_from_int64(a - b);
|
||||
continue;
|
||||
}
|
||||
mpq_t a_GMP, b_GMP;
|
||||
@@ -939,6 +941,9 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ArgonObject *result = currentStackFrame->state.registers[0];
|
||||
currentStackFrame = currentStackFrame->previousStackFrame;
|
||||
if(currentStackFrame) currentStackFrame->state.registers[0] = result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user