diff --git a/app.py b/app.py index ca74a71..a77ebe7 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,6 @@ def f(): - f() + return g() +def g(): + return f -f() \ No newline at end of file +f()() \ No newline at end of file diff --git a/src/err.c b/src/err.c index a98c456..92b292c 100644 --- a/src/err.c +++ b/src/err.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef _WIN32 ssize_t getline(char **lineptr, size_t *n, FILE *stream) { @@ -111,11 +112,11 @@ void output_err(ArErr err) { dyefg(stderr, DYE_GRAY); fprintf(stderr, ":"); dyefg(stderr, DYE_YELLOW); - fprintf(stderr, "%lld", err.line); + fprintf(stderr, "%" PRIu64 , err.line); dyefg(stderr, DYE_GRAY); fprintf(stderr, ":"); dyefg(stderr, DYE_YELLOW); - fprintf(stderr, "%lld", err.column); + fprintf(stderr, "%" PRIu64, err.column); dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); fprintf(stderr, "\n"); @@ -123,7 +124,7 @@ void output_err(ArErr err) { if (file) { dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); - int line_number_width = snprintf(NULL, 0, "%lld", err.line); + int line_number_width = snprintf(NULL, 0, "%" PRIu64, err.line); char *buffer = NULL; size_t size = 0; int current_line = 1; @@ -154,7 +155,7 @@ void output_err(ArErr err) { err.column--; skipped_chars++; } - fprintf(stderr, " %lld | ", err.line); + fprintf(stderr, " %" PRIu64 " | ", err.line); if (err.length) { fprintf(stderr, "%.*s", (int)err.column - 1, line_starts); dyefg(stderr, DYE_RED); diff --git a/src/runtime/call/call.c b/src/runtime/call/call.c index e35aae7..5c471fa 100644 --- a/src/runtime/call/call.c +++ b/src/runtime/call/call.c @@ -7,6 +7,7 @@ #include "call.h" #include "../../hash_data/hash_data.h" #include "../objects/string/string.h" +#include #include #include #include @@ -73,9 +74,9 @@ void run_call(Translated *translated, RuntimeState *state) { ArgonObject *object = state->registers[from_register]; if (object->type == TYPE_FUNCTION) { Stack *scope = create_scope(object->value.argon_fn.stack); - for (size_t i = 0; i < state->call_args_length; i++) { + for (size_t i = 0; i < *state->call_args_length; i++) { struct string_struct key = object->value.argon_fn.parameters[i]; - ArgonObject *value = state->call_args[i]; + ArgonObject *value = (*state->call_args)[i]; uint64_t hash = siphash64_bytes(key.data, key.length, siphash_key); hashmap_insert_GC(scope->scope, hash, new_string_object(key.data, key.length), value, 0); @@ -94,6 +95,12 @@ void run_call(Translated *translated, RuntimeState *state) { *state->currentStackFramePointer, no_err, (*state->currentStackFramePointer)->depth + 1}; + if (((*state->currentStackFramePointer)->depth+1) % STACKFRAME_CHUNKS == 0) { + *state->currentStackFramePointer = checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS); + } else { + *state->currentStackFramePointer = *state->currentStackFramePointer + 1; + } + **state->currentStackFramePointer = new_stackFrame; if ((*state->currentStackFramePointer)->depth >= 10000) { double logval = log10((double)(*state->currentStackFramePointer)->depth); if (floor(logval) == logval) { @@ -101,7 +108,8 @@ void run_call(Translated *translated, RuntimeState *state) { darray_get(&translated->source_locations, source_location_index); double memoryUsage = get_memory_usage_mb(); fprintf(stderr, - "Warning: %s:%llu:%llu the call stack depth has exceeded %llu", + "Warning: %s:%" PRIu64 ":%" PRIu64 + " the call stack depth has exceeded %" PRIu64, state->path, source_location->line, source_location->column, (*state->currentStackFramePointer)->depth); if (memoryUsage) { @@ -112,7 +120,5 @@ void run_call(Translated *translated, RuntimeState *state) { } } }; - *state->currentStackFramePointer = checked_malloc(sizeof(StackFrame)); - **state->currentStackFramePointer = new_stackFrame; } } \ No newline at end of file diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 9b310c4..38623e8 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -8,8 +8,8 @@ #include "../err.h" #include "../hash_data/hash_data.h" #include "../translator/translator.h" -#include "declaration/declaration.h" #include "call/call.h" +#include "declaration/declaration.h" #include "internals/hashmap/hashmap.h" #include "objects/functions/functions.h" #include "objects/literals/literals.h" @@ -202,15 +202,15 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, break; case OP_INIT_ARGS:; size_t size = pop_bytecode(translated, state) * sizeof(ArgonObject *); - if (state->call_args) { - state->call_args = realloc(state->call_args, size); + if (*state->call_args) { + *state->call_args = realloc(*state->call_args, size); } else { - state->call_args = checked_malloc(size); + *state->call_args = checked_malloc(size); } break; case OP_INSERT_ARG:; to_register = pop_byte(translated, state); - state->call_args[pop_bytecode(translated, state)] = + (*state->call_args)[pop_bytecode(translated, state)] = state->registers[to_register]; break; case OP_CALL: @@ -249,14 +249,12 @@ RuntimeState init_runtime_state(Translated translated, char *path) { path, NULL, NULL, - 0}; + NULL}; return runtime; } void free_runtime_state(RuntimeState runtime_state) { free(runtime_state.registers); - if (runtime_state.call_args) - free(runtime_state.call_args); } Stack *create_scope(Stack *prev) { @@ -269,8 +267,15 @@ Stack *create_scope(Stack *prev) { ArErr runtime(Translated translated, RuntimeState state, Stack *stack) { state.head = 0; - StackFrame *currentStackFrame = checked_malloc(sizeof(StackFrame)); - *currentStackFrame = (StackFrame){translated, state, stack, NULL, no_err}; + ArgonObject **call_args = NULL; + size_t call_args_length = 0; + + state.call_args = &call_args; + state.call_args_length = &call_args_length; + + StackFrame *currentStackFrame = + checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS); + *currentStackFrame = (StackFrame){translated, state, stack, NULL, no_err, 0}; currentStackFrame->state.currentStackFramePointer = ¤tStackFrame; ArErr err = no_err; while (currentStackFrame) { @@ -284,8 +289,18 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) { StackFrame *tempStackFrame = currentStackFrame; err = currentStackFrame->err; currentStackFrame = currentStackFrame->previousStackFrame; - free(tempStackFrame); + if (tempStackFrame->depth % STACKFRAME_CHUNKS == 0) { + free(tempStackFrame); + } } + if (call_args) + free(call_args); + call_args = NULL; + call_args_length = 0; + + state.call_args = NULL; + state.call_args_length = NULL; + return err; } \ No newline at end of file diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 5d9e626..e2bcaf9 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -19,8 +19,8 @@ typedef struct RuntimeState { size_t head; char *path; StackFrame **currentStackFramePointer; - ArgonObject** call_args; - size_t call_args_length; + ArgonObject*** call_args; + size_t* call_args_length; } RuntimeState; typedef struct StackFrame { @@ -32,6 +32,8 @@ typedef struct StackFrame { uint64_t depth; } StackFrame; +#define STACKFRAME_CHUNKS 64 + void bootstrap_types(); extern struct hashmap *runtime_hash_table; diff --git a/testing.ar b/testing.ar index 93c6d33..c76956b 100644 --- a/testing.ar +++ b/testing.ar @@ -1,7 +1,5 @@ # SPDX-FileCopyrightText: 2025 William Bell # SPDX-License-Identifier: GPL-3.0-or-later -let f()=g() -let g()=h() -let h()=f() -f() \ No newline at end of file +let f()=f() +f()