work on method wrapper and native function support
This commit is contained in:
@@ -71,73 +71,72 @@ double get_memory_usage_mb() {
|
||||
#endif
|
||||
|
||||
ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
uint8_t from_register = pop_byte(translated, state);
|
||||
uint8_t source_location_index = pop_bytecode(translated, state);
|
||||
ArgonObject *original_object = state->registers[from_register];
|
||||
ArgonObject *original_object = state->call_instance->to_call;
|
||||
ArgonObject *object = original_object;
|
||||
int is_method =
|
||||
object->type == TYPE_METHOD || object->type == TYPE_NATIVE_METHOD;
|
||||
if (object->type != TYPE_FUNCTION && object->type != TYPE_NATIVE_FUNCTION && !is_method) {
|
||||
ArgonObject *call_method =
|
||||
get_field_for_class(get_field(object, "__class__", false), "__call__");
|
||||
if (object->type != TYPE_FUNCTION && object->type != TYPE_NATIVE_FUNCTION &&
|
||||
object->type != TYPE_METHOD) {
|
||||
ArgonObject *call_method = get_field_for_class(
|
||||
get_field(object, "__class__", false), "__call__", original_object);
|
||||
if (call_method) {
|
||||
object = call_method;
|
||||
is_method =
|
||||
object->type == TYPE_METHOD && object->type == TYPE_NATIVE_METHOD;
|
||||
}
|
||||
}
|
||||
if (is_method) {
|
||||
ArgonObject **new_call_args =
|
||||
malloc(sizeof(ArgonObject *) * (*state->call_args_length + 1));
|
||||
new_call_args[0] = original_object;
|
||||
if (*state->call_args_length > 0) {
|
||||
memcpy(new_call_args + 1, *state->call_args, *state->call_args_length);
|
||||
if (object->type == TYPE_METHOD) {
|
||||
ArgonObject *binding_object = get_field(object, "__binding__", false);
|
||||
if (binding_object) {
|
||||
ArgonObject **new_call_args = malloc(
|
||||
sizeof(ArgonObject *) * (state->call_instance->args_length + 1));
|
||||
new_call_args[0] = binding_object;
|
||||
if (state->call_instance->args_length > 0) {
|
||||
memcpy(new_call_args + 1, state->call_instance->args,
|
||||
state->call_instance->args_length);
|
||||
}
|
||||
free(state->call_instance->args);
|
||||
state->call_instance->args = new_call_args;
|
||||
state->call_instance->args_length++;
|
||||
}
|
||||
if (*state->call_args) {
|
||||
free(*state->call_args);
|
||||
}
|
||||
*state->call_args = new_call_args;
|
||||
(*state->call_args_length)++;
|
||||
ArgonObject *function_object = get_field(object, "__function__", false);
|
||||
if (function_object)
|
||||
object = function_object;
|
||||
}
|
||||
if (object->type == TYPE_FUNCTION || object->type == TYPE_METHOD) {
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
if (*state->call_args_length !=
|
||||
if (object->type == TYPE_FUNCTION) {
|
||||
if (state->call_instance->args_length !=
|
||||
object->value.argon_fn.number_of_parameters) {
|
||||
ArgonObject *type_object_name = get_field_for_class(
|
||||
get_field(object, "__class__", false), "__name__");
|
||||
ArgonObject *object_name = get_field_for_class(object, "__name__");
|
||||
get_field(object, "__class__", false), "__name__", original_object);
|
||||
ArgonObject *object_name = get_field_for_class(object, "__name__", original_object);
|
||||
return create_err(
|
||||
source_location->line, source_location->column,
|
||||
source_location->length, state->path, "Type Error",
|
||||
state->source_location.line, state->source_location.column,
|
||||
state->source_location.length, state->path, "Type Error",
|
||||
"%.*s %.*s takes %" PRIu64 " argument(s) but %" PRIu64 " was given",
|
||||
(int)type_object_name->value.as_str.length,
|
||||
type_object_name->value.as_str.data,
|
||||
(int)object_name->value.as_str.length, object_name->value.as_str.data,
|
||||
object->value.argon_fn.number_of_parameters,
|
||||
*state->call_args_length);
|
||||
state->call_instance->args_length);
|
||||
}
|
||||
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_instance->args_length; i++) {
|
||||
struct string_struct key = object->value.argon_fn.parameters[i];
|
||||
ArgonObject *value = (*state->call_args)[i];
|
||||
ArgonObject *value = (state->call_instance->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);
|
||||
}
|
||||
DArray bytecode_darray = {object->value.argon_fn.bytecode, sizeof(uint8_t),
|
||||
object->value.argon_fn.bytecode_length,
|
||||
object->value.argon_fn.bytecode_length, false};
|
||||
StackFrame new_stackFrame = {
|
||||
{translated->registerCount, NULL, bytecode_darray,
|
||||
object->value.argon_fn.source_locations, translated->constants,
|
||||
object->value.argon_fn.path},
|
||||
{translated->registerCount,
|
||||
NULL,
|
||||
{object->value.argon_fn.bytecode, sizeof(uint8_t),
|
||||
object->value.argon_fn.bytecode_length,
|
||||
object->value.argon_fn.bytecode_length, false},
|
||||
object->value.argon_fn.translated.constants,
|
||||
object->value.argon_fn.translated.path},
|
||||
{state->registers,
|
||||
0,
|
||||
state->path,
|
||||
object->value.argon_fn.translated.path,
|
||||
NULL,
|
||||
state->currentStackFramePointer,
|
||||
state->call_args,
|
||||
state->call_args_length,
|
||||
{},
|
||||
{}},
|
||||
scope,
|
||||
*state->currentStackFramePointer,
|
||||
@@ -153,13 +152,12 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
if ((*state->currentStackFramePointer)->depth >= 10000) {
|
||||
double logval = log10((double)(*state->currentStackFramePointer)->depth);
|
||||
if (floor(logval) == logval) {
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
double memoryUsage = get_memory_usage_mb();
|
||||
fprintf(stderr,
|
||||
"Warning: %s:%" PRIu64 ":%" PRIu64
|
||||
" the call stack depth has exceeded %" PRIu64,
|
||||
state->path, source_location->line, source_location->column,
|
||||
state->path, state->source_location.line,
|
||||
state->source_location.column,
|
||||
(*state->currentStackFramePointer)->depth);
|
||||
if (memoryUsage) {
|
||||
fprintf(stderr, ", memory usage at %f MB\n", memoryUsage);
|
||||
@@ -169,18 +167,22 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
}
|
||||
};
|
||||
return no_err;
|
||||
} else if (object->type == TYPE_NATIVE_FUNCTION || object->type == TYPE_NATIVE_METHOD) {
|
||||
} else if (object->type == TYPE_NATIVE_FUNCTION) {
|
||||
ArErr err = no_err;
|
||||
state->registers[0] = object->value.native_fn(*state->call_args_length,
|
||||
*state->call_args, &err);
|
||||
state->registers[0] = object->value.native_fn(
|
||||
state->call_instance->args_length, state->call_instance->args, &err);
|
||||
if (err.exists) {
|
||||
err.line = state->source_location.line;
|
||||
err.column = state->source_location.column;
|
||||
err.length = state->source_location.length;
|
||||
err.path = state->path;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
ArgonObject *type_object_name = get_field_for_class(
|
||||
get_field(original_object, "__class__", false), "__name__");
|
||||
return create_err(source_location->line, source_location->column,
|
||||
source_location->length, state->path, "Type Error",
|
||||
get_field(original_object, "__class__", false), "__name__", original_object);
|
||||
return create_err(state->source_location.line, state->source_location.column,
|
||||
state->source_location.length, state->path, "Type Error",
|
||||
"'%.*s' object is not callable",
|
||||
(int)type_object_name->value.as_str.length,
|
||||
type_object_name->value.as_str.data);
|
||||
|
||||
@@ -12,12 +12,10 @@ ArErr runtime_declaration(Translated *translated, RuntimeState *state,
|
||||
int64_t offset = pop_bytecode(translated, state);
|
||||
int64_t prehash = pop_bytecode(translated, state);
|
||||
int64_t from_register = pop_byte(translated, state);
|
||||
int64_t source_location_index = pop_bytecode(translated, state);
|
||||
uint64_t hash = runtime_hash(arena_get(&translated->constants, offset), length, prehash);
|
||||
ArgonObject * exists = hashmap_lookup_GC(stack->scope, hash);
|
||||
if (exists) {
|
||||
SourceLocation *source_location = darray_get(&translated->source_locations, source_location_index);
|
||||
return create_err(source_location->line, source_location->column, source_location->length, state->path, "Runtime Error", "Identifier '%.*s' has already been declared in the current scope", length, arena_get(&translated->constants, offset));
|
||||
return create_err(state->source_location.line, state->source_location.column, state->source_location.length, state->path, "Runtime Error", "Identifier '%.*s' has already been declared in the current scope", length, arena_get(&translated->constants, offset));
|
||||
}
|
||||
ArgonObject * key = new_string_object(arena_get(&translated->constants, offset), length);
|
||||
hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register], 0);
|
||||
|
||||
@@ -45,7 +45,6 @@ void darray_armem_resize(darray_armem *arr, size_t new_size) {
|
||||
}
|
||||
|
||||
if (new_capacity != arr->capacity) {
|
||||
printf("%zu\n", new_capacity_bytes);
|
||||
arr->data = ar_realloc(arr->data, new_capacity_bytes);
|
||||
if (!arr->data) {
|
||||
fprintf(stderr, "darray_armem_resize: reallocation failed\n");
|
||||
|
||||
@@ -14,6 +14,15 @@
|
||||
|
||||
ArgonObject *ARGON_FUNCTION_TYPE = NULL;
|
||||
|
||||
ArgonObject *create_argon_native_function(char*name, native_fn native_fn) {
|
||||
ArgonObject *object = new_object();
|
||||
add_field(object, "__class__", ARGON_FUNCTION_TYPE);
|
||||
object->type = TYPE_NATIVE_FUNCTION;
|
||||
add_field(object, "__name__", new_string_object(name, strlen(name)));
|
||||
object->value.native_fn = native_fn;
|
||||
return object;
|
||||
}
|
||||
|
||||
void load_argon_function(Translated *translated, RuntimeState *state,
|
||||
struct Stack *stack) {
|
||||
ArgonObject *object = new_object();
|
||||
@@ -22,8 +31,7 @@ void load_argon_function(Translated *translated, RuntimeState *state,
|
||||
uint64_t offset = pop_bytecode(translated, state);
|
||||
uint64_t length = pop_bytecode(translated, state);
|
||||
add_field(object, "__name__", new_string_object(arena_get(&translated->constants, offset), length));
|
||||
object->value.argon_fn.path = translated->path;
|
||||
object->value.argon_fn.source_locations = translated->source_locations;
|
||||
object->value.argon_fn.translated = *translated;
|
||||
object->value.argon_fn.number_of_parameters = pop_bytecode(translated, state);
|
||||
object->value.argon_fn.parameters =
|
||||
ar_alloc(object->value.argon_fn.number_of_parameters * sizeof(struct string_struct));
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
extern ArgonObject *ARGON_FUNCTION_TYPE;
|
||||
|
||||
ArgonObject *create_argon_native_function(char*name, native_fn native_fn);
|
||||
|
||||
ArgonObject *load_argon_function(Translated *translated, RuntimeState *state, struct Stack *stack);
|
||||
|
||||
#endif // FUNCTION_H
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "../../memory.h"
|
||||
#include "type/type.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
ArgonObject *BASE_CLASS = NULL;
|
||||
@@ -26,13 +27,32 @@ void add_field(ArgonObject *target, char *name, ArgonObject *object) {
|
||||
object, 0);
|
||||
}
|
||||
|
||||
ArgonObject *get_field_for_class(ArgonObject *target, char *name) {
|
||||
ArgonObject *bind_object_to_function(ArgonObject *object,
|
||||
ArgonObject *function) {
|
||||
ArgonObject *bound_method_wrapper = new_object();
|
||||
bound_method_wrapper->type = TYPE_METHOD;
|
||||
add_field(bound_method_wrapper, "__class__", ARGON_METHOD_TYPE);
|
||||
add_field(bound_method_wrapper, "__binding__", object);
|
||||
add_field(bound_method_wrapper, "__function__", function);
|
||||
ArgonObject *function_name = get_field(function, "__name__", false);
|
||||
if (function_name)
|
||||
add_field(bound_method_wrapper, "__name__", function_name);
|
||||
return bound_method_wrapper;
|
||||
}
|
||||
|
||||
ArgonObject *get_field_for_class(ArgonObject *target, char *name, ArgonObject *binding_object) {
|
||||
char *field = "__base__";
|
||||
while (target) {
|
||||
uint64_t hash = siphash64_bytes(name, strlen(name), siphash_key);
|
||||
ArgonObject *object = hashmap_lookup_GC(target->dict, hash);
|
||||
if (object)
|
||||
|
||||
if (object) {
|
||||
if (object->type == TYPE_FUNCTION ||
|
||||
object->type == TYPE_NATIVE_FUNCTION) {
|
||||
object = bind_object_to_function(binding_object, object);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
hash = siphash64_bytes(field, strlen(field), siphash_key);
|
||||
target = hashmap_lookup_GC(target->dict, hash);
|
||||
}
|
||||
@@ -41,14 +61,8 @@ ArgonObject *get_field_for_class(ArgonObject *target, char *name) {
|
||||
|
||||
ArgonObject *get_field(ArgonObject *target, char *name, bool recursive) {
|
||||
char *field = "__class__";
|
||||
while (target) {
|
||||
uint64_t hash = siphash64_bytes(name, strlen(name), siphash_key);
|
||||
ArgonObject *object = hashmap_lookup_GC(target->dict, hash);
|
||||
if (!recursive || object)
|
||||
return object;
|
||||
hash = siphash64_bytes(field, strlen(field), siphash_key);
|
||||
target = hashmap_lookup_GC(target->dict, hash);
|
||||
field = "__base__";
|
||||
}
|
||||
return NULL;
|
||||
ArgonObject *object = hashmap_lookup_GC(target->dict, siphash64_bytes(name, strlen(name), siphash_key));
|
||||
if (!recursive || object)
|
||||
return object;
|
||||
return get_field_for_class(hashmap_lookup_GC(target->dict, siphash64_bytes(field, strlen(field), siphash_key)), name, target);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ ArgonObject *new_object();
|
||||
|
||||
void add_field(ArgonObject *target, char *name, ArgonObject *object);
|
||||
|
||||
ArgonObject *get_field_for_class(ArgonObject *target, char *name);
|
||||
ArgonObject *get_field_for_class(ArgonObject *target, char *name, ArgonObject *binding_object);
|
||||
|
||||
ArgonObject *get_field(ArgonObject *target, char *name, bool recursive);
|
||||
|
||||
|
||||
@@ -25,11 +25,30 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
ArgonObject *ARGON_METHOD_TYPE;
|
||||
Stack *Global_Scope = NULL;
|
||||
|
||||
ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv,
|
||||
ArErr *err) {
|
||||
if (argc<1) {
|
||||
*err = create_err(0, 0, 0, "", "Runtime Error", "call missing self object.");
|
||||
return ARGON_NULL;
|
||||
}
|
||||
ArgonObject *self = argv[0];
|
||||
ArgonObject *self_name = get_field(argv[0], "__name__", true);
|
||||
|
||||
printf("type: %.*s\n", (int)self_name->value.as_str.length, self_name->value.as_str.data);
|
||||
return ARGON_NULL;
|
||||
}
|
||||
|
||||
void bootstrap_types() {
|
||||
BASE_CLASS = new_object();
|
||||
ARGON_TYPE_TYPE = new_object();
|
||||
add_field(ARGON_TYPE_TYPE, "__base__", BASE_CLASS);
|
||||
add_field(ARGON_TYPE_TYPE, "__class__", ARGON_TYPE_TYPE);
|
||||
add_field(ARGON_TYPE_TYPE, "__call__",
|
||||
create_argon_native_function(
|
||||
"__call__", ARGON_TYPE_TYPE___call__));
|
||||
|
||||
ARGON_NULL_TYPE = new_object();
|
||||
add_field(ARGON_NULL_TYPE, "__base__", BASE_CLASS);
|
||||
@@ -63,6 +82,25 @@ void bootstrap_types() {
|
||||
add_field(ARGON_FUNCTION_TYPE, "__base__", BASE_CLASS);
|
||||
add_field(ARGON_FUNCTION_TYPE, "__name__",
|
||||
new_string_object_null_terminated("function"));
|
||||
|
||||
ARGON_METHOD_TYPE = new_object();
|
||||
add_field(ARGON_METHOD_TYPE, "__base__", BASE_CLASS);
|
||||
add_field(ARGON_METHOD_TYPE, "__name__",
|
||||
new_string_object_null_terminated("method"));
|
||||
}
|
||||
|
||||
void add_to_scope(Stack *stack, char *name, ArgonObject *value) {
|
||||
size_t length = strlen(name);
|
||||
uint64_t hash =
|
||||
siphash64_bytes(name, length, siphash_key);
|
||||
ArgonObject *key = new_string_object(name, length);
|
||||
hashmap_insert_GC(stack->scope, hash, key, value, 0);
|
||||
}
|
||||
|
||||
void bootstrap_globals() {
|
||||
Global_Scope = create_scope(NULL);
|
||||
add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE);
|
||||
add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE);
|
||||
}
|
||||
|
||||
int compare_by_order(const void *a, const void *b) {
|
||||
@@ -72,7 +110,7 @@ int compare_by_order(const void *a, const void *b) {
|
||||
}
|
||||
|
||||
uint8_t pop_byte(Translated *translated, RuntimeState *state) {
|
||||
return *((uint8_t *)darray_get(&translated->bytecode, state->head++));
|
||||
return *((uint8_t *)darray_armem_get(&translated->bytecode, state->head++));
|
||||
}
|
||||
|
||||
uint64_t pop_bytecode(Translated *translated, RuntimeState *state) {
|
||||
@@ -120,8 +158,7 @@ ArErr load_variable(Translated *translated, RuntimeState *state,
|
||||
struct Stack *stack) {
|
||||
int64_t length = pop_bytecode(translated, state);
|
||||
int64_t offset = pop_bytecode(translated, state);
|
||||
int64_t prehash = pop_bytecode(translated, state);
|
||||
int64_t source_location_index = pop_bytecode(translated, state);
|
||||
uint64_t prehash = pop_bytecode(translated, state);
|
||||
uint64_t hash =
|
||||
runtime_hash(arena_get(&translated->constants, offset), length, prehash);
|
||||
struct Stack *current_stack = stack;
|
||||
@@ -133,12 +170,11 @@ ArErr load_variable(Translated *translated, RuntimeState *state,
|
||||
}
|
||||
current_stack = current_stack->prev;
|
||||
}
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
ArErr err = create_err(source_location->line, source_location->column,
|
||||
source_location->length, state->path, "Name Error",
|
||||
"name '%.*s' is not defined", (int)length,
|
||||
arena_get(&translated->constants, offset));
|
||||
ArErr err =
|
||||
create_err(state->source_location.line, state->source_location.column,
|
||||
state->source_location.length, state->path, "Name Error",
|
||||
"name '%.*s' is not defined", (int)length,
|
||||
arena_get(&translated->constants, offset));
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -200,22 +236,25 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
// free(array);
|
||||
*stack = (*stack)->prev;
|
||||
break;
|
||||
case OP_INIT_ARGS:;
|
||||
*state->call_args_length = pop_bytecode(translated, state);
|
||||
size_t size = *state->call_args_length * sizeof(ArgonObject *);
|
||||
if (*state->call_args) {
|
||||
*state->call_args = realloc(*state->call_args, size);
|
||||
} else {
|
||||
*state->call_args = checked_malloc(size);
|
||||
}
|
||||
case OP_INIT_CALL:;
|
||||
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));
|
||||
*state->call_instance = call_instance;
|
||||
break;
|
||||
case OP_INSERT_ARG:;
|
||||
to_register = pop_byte(translated, state);
|
||||
(*state->call_args)[pop_bytecode(translated, state)] =
|
||||
state->registers[to_register];
|
||||
size_t index = pop_bytecode(translated, state);
|
||||
(state->call_instance->args)[index] = state->registers[0];
|
||||
break;
|
||||
case OP_CALL:
|
||||
return run_call(translated, state);
|
||||
case OP_CALL:;
|
||||
ArErr err = run_call(translated, state);
|
||||
free(state->call_instance->args);
|
||||
call_instance = *state->call_instance;
|
||||
free(state->call_instance);
|
||||
state->call_instance = call_instance.previous;
|
||||
return err;
|
||||
// ArgonObject *object = state->registers[from_register];
|
||||
// char *field = "__class__";
|
||||
// uint64_t hash = siphash64_bytes(field, strlen(field), siphash_key);
|
||||
@@ -235,6 +274,11 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
// (int)class_name->value.as_str.length, class_name->value.as_str.data,
|
||||
// object);
|
||||
// }
|
||||
case OP_SOURCE_LOCATION:
|
||||
state->source_location = (SourceLocation){pop_bytecode(translated, state),
|
||||
pop_bytecode(translated, state),
|
||||
pop_bytecode(translated, state)};
|
||||
break;
|
||||
default:
|
||||
return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x",
|
||||
opcode);
|
||||
@@ -243,13 +287,13 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
}
|
||||
|
||||
RuntimeState init_runtime_state(Translated translated, char *path) {
|
||||
RuntimeState runtime = (RuntimeState){
|
||||
RuntimeState runtime = {
|
||||
checked_malloc(translated.registerCount * sizeof(ArgonObject *)),
|
||||
0,
|
||||
path,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
{0, 0, 0},
|
||||
{}};
|
||||
return runtime;
|
||||
}
|
||||
@@ -268,12 +312,6 @@ Stack *create_scope(Stack *prev) {
|
||||
ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
||||
state.head = 0;
|
||||
|
||||
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, 0};
|
||||
@@ -288,19 +326,18 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
||||
¤tStackFrame->state, ¤tStackFrame->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);
|
||||
}
|
||||
}
|
||||
|
||||
if (call_args)
|
||||
free(call_args);
|
||||
call_args = NULL;
|
||||
call_args_length = 0;
|
||||
|
||||
state.call_args = NULL;
|
||||
state.call_args_length = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -11,22 +11,38 @@
|
||||
#include "internals/dynamic_array_armem/darray_armem.h"
|
||||
#include "internals/hashmap/hashmap.h"
|
||||
|
||||
extern ArgonObject *ARGON_METHOD_TYPE;
|
||||
extern Stack *Global_Scope;
|
||||
|
||||
typedef struct StackFrame StackFrame;
|
||||
typedef struct RuntimeState RuntimeState;
|
||||
|
||||
typedef struct SourceLocation {
|
||||
uint64_t line;
|
||||
uint64_t column;
|
||||
uint64_t length;
|
||||
} SourceLocation;
|
||||
|
||||
typedef struct call_instance {
|
||||
struct call_instance *previous;
|
||||
ArgonObject *to_call;
|
||||
ArgonObject **args;
|
||||
size_t args_length;
|
||||
} call_instance;
|
||||
|
||||
typedef struct ErrorCatch {
|
||||
size_t jump_to;
|
||||
Stack *stack;
|
||||
StackFrame *stackFrame;
|
||||
} ErrorCatch;
|
||||
} ErrorCatch;
|
||||
|
||||
typedef struct RuntimeState {
|
||||
ArgonObject **registers;
|
||||
size_t head;
|
||||
char *path;
|
||||
call_instance *call_instance;
|
||||
StackFrame **currentStackFramePointer;
|
||||
ArgonObject*** call_args;
|
||||
size_t* call_args_length;
|
||||
SourceLocation source_location;
|
||||
DArray catch_errors; // ErrorCatch[]
|
||||
} RuntimeState;
|
||||
|
||||
@@ -46,6 +62,8 @@ extern struct hashmap *runtime_hash_table;
|
||||
|
||||
uint64_t runtime_hash(const void *data, size_t len, uint64_t prehash);
|
||||
|
||||
void bootstrap_globals();
|
||||
|
||||
uint8_t pop_byte(Translated *translated, RuntimeState *state);
|
||||
|
||||
uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
|
||||
|
||||
Reference in New Issue
Block a user