fix memory being freed too early

This commit is contained in:
William Bell
2025-08-10 04:39:50 +01:00
parent 49b1c1858a
commit c71375c7a4
12 changed files with 126 additions and 73 deletions

View File

@@ -88,19 +88,17 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
object = call_method;
}
}
bool to_free_args = false;
if (object->type == TYPE_METHOD) {
ArgonObject *binding_object =
get_field(object, "__binding__", false, false);
if (binding_object) {
ArgonObject **new_call_args = malloc(sizeof(ArgonObject *) * (argc + 1));
ArgonObject **new_call_args = ar_alloc(sizeof(ArgonObject *) * (argc + 1));
new_call_args[0] = binding_object;
if (argc > 0) {
memcpy(new_call_args + 1, argv, argc * sizeof(ArgonObject *));
}
argv = new_call_args;
argc++;
to_free_args = true;
}
ArgonObject *function_object =
get_field(object, "__function__", false, false);
@@ -131,8 +129,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
hashmap_insert_GC(scope->scope, hash,
new_string_object(key.data, key.length), value, 0);
}
if (to_free_args)
free(argv);
StackFrame new_stackFrame = {
{object->value.argon_fn.translated.registerCount,
NULL,
@@ -157,7 +153,7 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
if (((*state->currentStackFramePointer)->depth + 1) % STACKFRAME_CHUNKS ==
0) {
*state->currentStackFramePointer =
checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
ar_alloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
} else {
*state->currentStackFramePointer = *state->currentStackFramePointer + 1;
}
@@ -185,8 +181,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
} else if (object->type == TYPE_NATIVE_FUNCTION) {
ArErr err = no_err;
state->registers[0] = object->value.native_fn(argc, argv, &err, state);
if (to_free_args)
free(argv);
if (err.exists && strlen(err.path) == 0) {
err.line = state->source_location.line;
err.column = state->source_location.column;
@@ -195,8 +189,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
}
return err;
}
if (to_free_args)
free(argv);
ArgonObject *type_object_name =
get_field_for_class(get_field(original_object, "__class__", false, false),
"__name__", original_object);

View File

@@ -123,7 +123,6 @@ void darray_armem_free(darray_armem *arr, void (*free_data)(void *)) {
free_data(element);
}
}
free(arr->data);
arr->data = NULL;
arr->size = 0;
arr->capacity = 0;

View File

@@ -15,7 +15,8 @@
struct hashmap_GC *createHashmap_GC() {
size_t size = 8;
struct hashmap_GC *t = (struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
struct hashmap_GC *t =
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
t->size = size;
t->order = 1;
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
@@ -41,13 +42,15 @@ void resize_hashmap_GC(struct hashmap_GC *t) {
struct node_GC *temp = old_list[i];
while (temp) {
hashmap_insert_GC(t, temp->hash, temp->key, temp->val,
temp->order); // Will increment count
temp->order); // Will increment count
temp = temp->next;
}
}
}
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) { return hash & (t->size - 1); }
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) {
return hash & (t->size - 1);
}
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
int pos = hashCode_GC(t, hash);
@@ -72,7 +75,7 @@ int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
}
void hashmap_insert_GC(struct hashmap_GC *t, uint64_t hash, void *key,
void *val, size_t order) {
void *val, size_t order) {
if (!order) {
order = t->order++;
}

View File

@@ -63,6 +63,7 @@ ArgonObject *get_field_for_class_l(ArgonObject *target, char *name,
ArgonObject *get_field_l(ArgonObject *target, char *name, size_t length,
bool recursive, bool disable_method_wrapper) {
if(!target|| !target->dict) return NULL;
char *field = "__class__";
size_t field_size = strlen(field);
ArgonObject *object = hashmap_lookup_GC(

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "term.h"
#include <stddef.h>
#include <stdio.h>
#include "../../call/call.h"
ArgonObject *term_log(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state) {
for (size_t i = 0; i < argc; i++) {
if (i != 0)
printf(" ");
ArgonObject *string_convert_method = get_field_for_class(
get_field(argv[i], "__class__", false, false), "__string__", argv[i]);
if (string_convert_method) {
ArgonObject *string_object =
argon_call(string_convert_method, 0, NULL, err, state);
fwrite(string_object->value.as_str.data, sizeof(char),
string_object->value.as_str.length, stdout);
}
}
printf("\n");
return ARGON_NULL;
}

View File

@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef runtime_term_H
#define runtime_term_H
#include "../../objects/literals/literals.h"
#include "../../objects/object.h"
#include "../../runtime.h"
ArgonObject *term_log(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state);
#endif // runtime_term_H

View File

@@ -8,6 +8,7 @@
#include "../err.h"
#include "../hash_data/hash_data.h"
#include "../translator/translator.h"
#include "access/access.h"
#include "call/call.h"
#include "declaration/declaration.h"
#include "internals/hashmap/hashmap.h"
@@ -15,8 +16,8 @@
#include "objects/literals/literals.h"
#include "objects/object.h"
#include "objects/string/string.h"
#include "objects/term/term.h"
#include "objects/type/type.h"
#include "access/access.h"
#include <fcntl.h>
#include <gc/gc.h>
#include <inttypes.h>
@@ -29,7 +30,7 @@
ArgonObject *ARGON_METHOD_TYPE;
Stack *Global_Scope = NULL;
ArgonObject*ACCESS_FUNCTION;
ArgonObject *ACCESS_FUNCTION;
ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
@@ -108,6 +109,23 @@ ArgonObject *BASE_CLASS___init__(size_t argc, ArgonObject **argv, ArErr *err,
return ARGON_NULL;
}
ArgonObject *BASE_CLASS___string__(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state) {
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__string__ expects 1 arguments, got %" PRIu64, argc);
}
ArgonObject *object_name = get_field_for_class(argv[0], "__name__", NULL);
ArgonObject *class_name = get_field_for_class(
get_field(argv[0], "__class__", false, false), "__name__", NULL);
char buffer[100];
snprintf(buffer, sizeof(buffer), "<%.*s %.*s at %p>", (int)class_name->value.as_str.length, class_name->value.as_str.data, (int)object_name->value.as_str.length, object_name->value.as_str.data,argv[0]);
return new_string_object_null_terminated(buffer);
}
ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
if (argc != 2) {
@@ -128,11 +146,11 @@ ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
argon_call(string_convert_method, 0, NULL, err, state);
if (err->exists)
return ARGON_NULL;
object->value.as_str.data =
self->value.as_str.data =
ar_alloc_atomic(string_object->value.as_str.length);
memcpy(object->value.as_str.data, string_object->value.as_str.data,
memcpy(self->value.as_str.data, string_object->value.as_str.data,
string_object->value.as_str.length);
object->value.as_str.length = string_object->value.as_str.length;
self->value.as_str.length = string_object->value.as_str.length;
}
return ARGON_NULL;
}
@@ -165,7 +183,7 @@ ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__init__ expects 1 arguments, got %" PRIu64, argc);
"__string__ expects 1 arguments, got %" PRIu64, argc);
}
return argv[0];
}
@@ -218,6 +236,8 @@ void bootstrap_types() {
create_argon_native_function("__new__", BASE_CLASS___new__));
add_field(BASE_CLASS, "__init__",
create_argon_native_function("__init__", BASE_CLASS___new__));
add_field(BASE_CLASS, "__string__",
create_argon_native_function("__string__", BASE_CLASS___string__));
add_field(ARGON_TYPE_TYPE, "__call__",
create_argon_native_function("__call__", ARGON_TYPE_TYPE___call__));
add_field(
@@ -228,7 +248,8 @@ void bootstrap_types() {
create_argon_native_function("__string__", ARGON_STRING_TYPE___string__));
add_field(ARGON_BOOL_TYPE, "__new__",
create_argon_native_function("__new__", ARGON_BOOL_TYPE___new__));
ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION", ARGON_TYPE_TYPE___get_attr__);
ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION",
ARGON_TYPE_TYPE___get_attr__);
}
void add_to_scope(Stack *stack, char *name, ArgonObject *value) {
@@ -243,6 +264,11 @@ void bootstrap_globals() {
add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE);
add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE);
add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE);
ArgonObject *argon_term = new_object();
add_field(argon_term, "__init__", ARGON_NULL);
add_field(argon_term, "log", create_argon_native_function("log", term_log));
add_to_scope(Global_Scope, "term", argon_term);
}
int compare_by_order(const void *a, const void *b) {
@@ -340,8 +366,9 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
case OP_BOOL:;
ArErr err = no_err;
uint8_t to_register = pop_byte(translated, state);
ArgonObject* args[] = {ARGON_BOOL_TYPE, state->registers[0]};
state->registers[to_register] = ARGON_BOOL_TYPE___new__(2, args, &err, state);
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
state->registers[to_register] =
ARGON_BOOL_TYPE___new__(2, args, &err, state);
return err;
case OP_JUMP_IF_FALSE:;
uint8_t from_register = pop_byte(translated, state);
@@ -384,8 +411,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
size_t length = pop_bytecode(translated, state);
call_instance call_instance = {
state->call_instance, state->registers[0],
checked_malloc(length * sizeof(ArgonObject *)), length};
state->call_instance = checked_malloc(sizeof(call_instance));
ar_alloc(length * sizeof(ArgonObject *)), length};
state->call_instance = ar_alloc(sizeof(call_instance));
*state->call_instance = call_instance;
break;
case OP_INSERT_ARG:;
@@ -394,12 +421,9 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
break;
case OP_CALL:;
err = run_call(state->call_instance->to_call,
state->call_instance->args_length,
state->call_instance->args, state, false);
free(state->call_instance->args);
call_instance = *state->call_instance;
free(state->call_instance);
state->call_instance = call_instance.previous;
state->call_instance->args_length,
state->call_instance->args, state, false);
state->call_instance = (*state->call_instance).previous;
return err;
// ArgonObject *object = state->registers[from_register];
// char *field = "__class__";
@@ -426,7 +450,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
pop_bytecode(translated, state)};
break;
case OP_LOAD_BOOL:
state->registers[0] = pop_byte(translated, state)?ARGON_TRUE:ARGON_FALSE;
state->registers[0] =
pop_byte(translated, state) ? ARGON_TRUE : ARGON_FALSE;
break;
case OP_LOAD_ACCESS_FUNCTION:
state->registers[0] = ACCESS_FUNCTION;
@@ -440,7 +465,7 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
RuntimeState init_runtime_state(Translated translated, char *path) {
RuntimeState runtime = {
checked_malloc(translated.registerCount * sizeof(ArgonObject *)),
ar_alloc(translated.registerCount * sizeof(ArgonObject *)),
0,
path,
NULL,
@@ -450,10 +475,6 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
return runtime;
}
void free_runtime_state(RuntimeState runtime_state) {
free(runtime_state.registers);
}
Stack *create_scope(Stack *prev) {
Stack *stack = ar_alloc(sizeof(Stack));
stack->scope = createHashmap_GC();
@@ -465,7 +486,7 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
state.head = 0;
StackFrame *currentStackFrame =
checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
ar_alloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
*currentStackFrame = (StackFrame){translated, state, stack, NULL, 0};
currentStackFrame->state.currentStackFramePointer = &currentStackFrame;
ArErr err = no_err;
@@ -477,19 +498,7 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
run_instruction(&currentStackFrame->translated,
&currentStackFrame->state, &currentStackFrame->stack);
}
StackFrame *tempStackFrame = currentStackFrame;
while (currentStackFrame->state.call_instance) {
free(currentStackFrame->state.call_instance->args);
call_instance call_instance = *currentStackFrame->state.call_instance;
free(currentStackFrame->state.call_instance);
currentStackFrame->state.call_instance = call_instance.previous;
}
currentStackFrame = currentStackFrame->previousStackFrame;
if (tempStackFrame->depth % STACKFRAME_CHUNKS == 0) {
free(tempStackFrame);
}
}
return err;
}

View File

@@ -73,8 +73,6 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
RuntimeState init_runtime_state(Translated translated, char *path);
void free_runtime_state(RuntimeState runtime_state);
Stack *create_scope(Stack *prev);
ArErr runtime(Translated translated, RuntimeState state, Stack *stack);