break stack frames into chunks
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
|
ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
|
||||||
@@ -111,11 +112,11 @@ void output_err(ArErr err) {
|
|||||||
dyefg(stderr, DYE_GRAY);
|
dyefg(stderr, DYE_GRAY);
|
||||||
fprintf(stderr, ":");
|
fprintf(stderr, ":");
|
||||||
dyefg(stderr, DYE_YELLOW);
|
dyefg(stderr, DYE_YELLOW);
|
||||||
fprintf(stderr, "%lld", err.line);
|
fprintf(stderr, "%" PRIu64 , err.line);
|
||||||
dyefg(stderr, DYE_GRAY);
|
dyefg(stderr, DYE_GRAY);
|
||||||
fprintf(stderr, ":");
|
fprintf(stderr, ":");
|
||||||
dyefg(stderr, DYE_YELLOW);
|
dyefg(stderr, DYE_YELLOW);
|
||||||
fprintf(stderr, "%lld", err.column);
|
fprintf(stderr, "%" PRIu64, err.column);
|
||||||
dye_style(stderr, DYE_STYLE_RESET);
|
dye_style(stderr, DYE_STYLE_RESET);
|
||||||
dyefg(stderr, DYE_RESET);
|
dyefg(stderr, DYE_RESET);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@@ -123,7 +124,7 @@ void output_err(ArErr err) {
|
|||||||
if (file) {
|
if (file) {
|
||||||
dye_style(stderr, DYE_STYLE_RESET);
|
dye_style(stderr, DYE_STYLE_RESET);
|
||||||
dyefg(stderr, DYE_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;
|
char *buffer = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int current_line = 1;
|
int current_line = 1;
|
||||||
@@ -154,7 +155,7 @@ void output_err(ArErr err) {
|
|||||||
err.column--;
|
err.column--;
|
||||||
skipped_chars++;
|
skipped_chars++;
|
||||||
}
|
}
|
||||||
fprintf(stderr, " %lld | ", err.line);
|
fprintf(stderr, " %" PRIu64 " | ", err.line);
|
||||||
if (err.length) {
|
if (err.length) {
|
||||||
fprintf(stderr, "%.*s", (int)err.column - 1, line_starts);
|
fprintf(stderr, "%.*s", (int)err.column - 1, line_starts);
|
||||||
dyefg(stderr, DYE_RED);
|
dyefg(stderr, DYE_RED);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "call.h"
|
#include "call.h"
|
||||||
#include "../../hash_data/hash_data.h"
|
#include "../../hash_data/hash_data.h"
|
||||||
#include "../objects/string/string.h"
|
#include "../objects/string/string.h"
|
||||||
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -73,9 +74,9 @@ void run_call(Translated *translated, RuntimeState *state) {
|
|||||||
ArgonObject *object = state->registers[from_register];
|
ArgonObject *object = state->registers[from_register];
|
||||||
if (object->type == TYPE_FUNCTION) {
|
if (object->type == TYPE_FUNCTION) {
|
||||||
Stack *scope = create_scope(object->value.argon_fn.stack);
|
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];
|
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);
|
uint64_t hash = siphash64_bytes(key.data, key.length, siphash_key);
|
||||||
hashmap_insert_GC(scope->scope, hash,
|
hashmap_insert_GC(scope->scope, hash,
|
||||||
new_string_object(key.data, key.length), value, 0);
|
new_string_object(key.data, key.length), value, 0);
|
||||||
@@ -94,6 +95,12 @@ void run_call(Translated *translated, RuntimeState *state) {
|
|||||||
*state->currentStackFramePointer,
|
*state->currentStackFramePointer,
|
||||||
no_err,
|
no_err,
|
||||||
(*state->currentStackFramePointer)->depth + 1};
|
(*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) {
|
if ((*state->currentStackFramePointer)->depth >= 10000) {
|
||||||
double logval = log10((double)(*state->currentStackFramePointer)->depth);
|
double logval = log10((double)(*state->currentStackFramePointer)->depth);
|
||||||
if (floor(logval) == logval) {
|
if (floor(logval) == logval) {
|
||||||
@@ -101,7 +108,8 @@ void run_call(Translated *translated, RuntimeState *state) {
|
|||||||
darray_get(&translated->source_locations, source_location_index);
|
darray_get(&translated->source_locations, source_location_index);
|
||||||
double memoryUsage = get_memory_usage_mb();
|
double memoryUsage = get_memory_usage_mb();
|
||||||
fprintf(stderr,
|
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->path, source_location->line, source_location->column,
|
||||||
(*state->currentStackFramePointer)->depth);
|
(*state->currentStackFramePointer)->depth);
|
||||||
if (memoryUsage) {
|
if (memoryUsage) {
|
||||||
@@ -112,7 +120,5 @@ void run_call(Translated *translated, RuntimeState *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*state->currentStackFramePointer = checked_malloc(sizeof(StackFrame));
|
|
||||||
**state->currentStackFramePointer = new_stackFrame;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#include "../err.h"
|
#include "../err.h"
|
||||||
#include "../hash_data/hash_data.h"
|
#include "../hash_data/hash_data.h"
|
||||||
#include "../translator/translator.h"
|
#include "../translator/translator.h"
|
||||||
#include "declaration/declaration.h"
|
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
|
#include "declaration/declaration.h"
|
||||||
#include "internals/hashmap/hashmap.h"
|
#include "internals/hashmap/hashmap.h"
|
||||||
#include "objects/functions/functions.h"
|
#include "objects/functions/functions.h"
|
||||||
#include "objects/literals/literals.h"
|
#include "objects/literals/literals.h"
|
||||||
@@ -202,15 +202,15 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
break;
|
break;
|
||||||
case OP_INIT_ARGS:;
|
case OP_INIT_ARGS:;
|
||||||
size_t size = pop_bytecode(translated, state) * sizeof(ArgonObject *);
|
size_t size = pop_bytecode(translated, state) * sizeof(ArgonObject *);
|
||||||
if (state->call_args) {
|
if (*state->call_args) {
|
||||||
state->call_args = realloc(state->call_args, size);
|
*state->call_args = realloc(*state->call_args, size);
|
||||||
} else {
|
} else {
|
||||||
state->call_args = checked_malloc(size);
|
*state->call_args = checked_malloc(size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_INSERT_ARG:;
|
case OP_INSERT_ARG:;
|
||||||
to_register = pop_byte(translated, state);
|
to_register = pop_byte(translated, state);
|
||||||
state->call_args[pop_bytecode(translated, state)] =
|
(*state->call_args)[pop_bytecode(translated, state)] =
|
||||||
state->registers[to_register];
|
state->registers[to_register];
|
||||||
break;
|
break;
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
@@ -249,14 +249,12 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
|
|||||||
path,
|
path,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
0};
|
NULL};
|
||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_runtime_state(RuntimeState runtime_state) {
|
void free_runtime_state(RuntimeState runtime_state) {
|
||||||
free(runtime_state.registers);
|
free(runtime_state.registers);
|
||||||
if (runtime_state.call_args)
|
|
||||||
free(runtime_state.call_args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack *create_scope(Stack *prev) {
|
Stack *create_scope(Stack *prev) {
|
||||||
@@ -269,8 +267,15 @@ Stack *create_scope(Stack *prev) {
|
|||||||
ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
||||||
state.head = 0;
|
state.head = 0;
|
||||||
|
|
||||||
StackFrame *currentStackFrame = checked_malloc(sizeof(StackFrame));
|
ArgonObject **call_args = NULL;
|
||||||
*currentStackFrame = (StackFrame){translated, state, stack, NULL, no_err};
|
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;
|
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
||||||
ArErr err = no_err;
|
ArErr err = no_err;
|
||||||
while (currentStackFrame) {
|
while (currentStackFrame) {
|
||||||
@@ -284,8 +289,18 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
|||||||
StackFrame *tempStackFrame = currentStackFrame;
|
StackFrame *tempStackFrame = currentStackFrame;
|
||||||
err = currentStackFrame->err;
|
err = currentStackFrame->err;
|
||||||
currentStackFrame = currentStackFrame->previousStackFrame;
|
currentStackFrame = currentStackFrame->previousStackFrame;
|
||||||
|
if (tempStackFrame->depth % STACKFRAME_CHUNKS == 0) {
|
||||||
free(tempStackFrame);
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -19,8 +19,8 @@ typedef struct RuntimeState {
|
|||||||
size_t head;
|
size_t head;
|
||||||
char *path;
|
char *path;
|
||||||
StackFrame **currentStackFramePointer;
|
StackFrame **currentStackFramePointer;
|
||||||
ArgonObject** call_args;
|
ArgonObject*** call_args;
|
||||||
size_t call_args_length;
|
size_t* call_args_length;
|
||||||
} RuntimeState;
|
} RuntimeState;
|
||||||
|
|
||||||
typedef struct StackFrame {
|
typedef struct StackFrame {
|
||||||
@@ -32,6 +32,8 @@ typedef struct StackFrame {
|
|||||||
uint64_t depth;
|
uint64_t depth;
|
||||||
} StackFrame;
|
} StackFrame;
|
||||||
|
|
||||||
|
#define STACKFRAME_CHUNKS 64
|
||||||
|
|
||||||
void bootstrap_types();
|
void bootstrap_types();
|
||||||
|
|
||||||
extern struct hashmap *runtime_hash_table;
|
extern struct hashmap *runtime_hash_table;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
# SPDX-FileCopyrightText: 2025 William Bell
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
let f()=g()
|
let f()=f()
|
||||||
let g()=h()
|
|
||||||
let h()=f()
|
|
||||||
f()
|
f()
|
||||||
Reference in New Issue
Block a user