fix buffer overflow seg fault when using cache

This commit is contained in:
William Bell
2025-09-02 18:35:43 +01:00
parent 571efe46b7
commit c2e0cdc6d6
8 changed files with 75 additions and 49 deletions

View File

@@ -1,3 +1,3 @@
let i = 10000
while (i) do
i=i-1
let f(i) = do
while (i) i=i-1
f(1e6)

View File

@@ -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;
};

View File

@@ -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) !=

View 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);

View File

@@ -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);
@@ -414,11 +414,11 @@ ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv,
#define small_ints_min -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() {
for (int64_t i = 0; i <= small_ints_max-small_ints_min; i++) {
int64_t n = i+small_ints_min;
for (int64_t i = 0; i <= small_ints_max - small_ints_min; i++) {
int64_t n = i + small_ints_min;
small_ints[i].type = TYPE_NUMBER;
small_ints[i].dict = createHashmap_GC();
add_builtin_field(&small_ints[i], __class__, ARGON_NUMBER_TYPE);
@@ -432,29 +432,31 @@ void init_small_ints() {
void create_ARGON_NUMBER_TYPE() {
ARGON_NUMBER_TYPE = new_object();
add_builtin_field(ARGON_NUMBER_TYPE, __name__,
new_string_object_null_terminated("number"));
new_string_object_null_terminated("number"));
add_builtin_field(
ARGON_NUMBER_TYPE, __string__,
create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__));
add_builtin_field(ARGON_NUMBER_TYPE, __new__,
create_argon_native_function("__new__", 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("__add__", 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();
}
@@ -534,7 +536,7 @@ ArgonObject *new_number_object(mpq_t number) {
int64_t i64 = 0;
bool is_int64 = mpq_to_int64(number, &i64);
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();
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) {
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();
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;
}
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);
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();
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);
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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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 = &currentStackFrame;
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;
@@ -873,13 +874,15 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
continue;
}
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);
ArgonObject *args[] = {valueA, valueB};
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;
}
}