aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-07-25 14:26:32 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:37:04 +0200
commitb6b3760e19716c574ca9a0ec0bacfe5518b39f77 (patch)
tree76c2c04069d22d36550a62e4b5bb7878fcefb4fd /src
parent203fbb778e9cfe3aff8b4dee6da9a103a171ca0e (diff)
load function in progress
Diffstat (limited to 'src')
-rw-r--r--src/ast.c12
-rw-r--r--src/program.c42
-rw-r--r--src/std/buffer.c14
3 files changed, 59 insertions, 9 deletions
diff --git a/src/ast.c b/src/ast.c
index 504c1f9..f0bb528 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -1226,6 +1226,18 @@ void ast_resolve(Ast *self, AstCompilerContext *context) {
throw(AST_ERR);
}
+ /*
+ TODO: This could cause a deadlock if two different threads resolve the same expression at the same time
+ and self->parser is overwritten by one of the threads, and then if both of the threads try to
+ resolve another expression at the same time that this expression depends on,
+ then the same thread could get ownership of that expression (self->parser would be assigned to that thread)
+ or another thread steals it.
+ Then the other thread that had its self->parser stolen would be stuck in a recursive dependency
+ deadlock since in the above code, an error is only thrown if the parser belongs to the current thread.
+ A possible fix for this may be to add a check above that if any of the other thread has failed,
+ then this thread should fail as well.
+ */
+
self->resolve_data.status = AST_RESOLVING;
self->parser = context->parser;
switch(self->type) {
diff --git a/src/program.c b/src/program.c
index 31485ca..e53eb6b 100644
--- a/src/program.c
+++ b/src/program.c
@@ -523,6 +523,48 @@ static CHECK_RESULT int amal_program_read_instructions(amal_program *self, amal_
self->read_index += 3;
break;
}
+ case AMAL_OP_LOADF: {
+#if 0
+ u8 dst_reg = self->data.data[self->read_index];
+ u16 func_index;
+ am_memcpy(&func_index, self->data.data + self->read_index + sizeof(dst_reg), sizeof(func_index));
+
+ amal_program_get_header_function_by_index(self, import_index, func_index, &func_def);
+ assert(func_def.num_return_types == 1 && "TODO: Support 0 and more than 1 return values");
+ assert(self->return_value_index == 1);
+ dst_reg = self->return_values_stack[0];
+ self->return_value_index = 0;
+
+ /* func_offset will only be non-zero when the function has been decoded (FUNC_START) */
+ if(func_def.func_offset != ~(u32)0UL) {
+ /* TODO: Instead of pushing num args, push the sum of sizeof the last num_args */
+ return_if_error(amal_exec_call(executor, func_def.func_offset, dst_reg));
+ } else {
+ /*
+ The code for the function has not been generated yet (the function is defined after the current location).
+ Make a dummy call and replace the call target after the function has been generated
+ */
+ u64 key = deferred_func_call_get_key(self, import_index, func_index);
+ BufferView key_mem = create_buffer_view((char*)&key, sizeof(key));
+ u32 code_offset = amal_exec_get_code_offset(executor);
+
+ Buffer* deferred_func_call_list;
+ if(hash_map_get_ref(&self->deferred_func_calls, key_mem, (void**)&deferred_func_call_list))
+ return_if_error(buffer_append(deferred_func_call_list, &code_offset, sizeof(code_offset)));
+ else {
+ Buffer new_deferred_call_list;
+ return_if_error(buffer_init(&new_deferred_call_list, &self->allocator));
+ return_if_error(buffer_append(&new_deferred_call_list, &code_offset, sizeof(code_offset)));
+ return_if_error(hash_map_insert(&self->deferred_func_calls, key_mem, &new_deferred_call_list));
+ }
+ /* Dummy call to offset 0, offset will be replace later when the target function hits AMAL_OP_FUNC_START */
+ return_if_error(amal_exec_call(executor, 0, dst_reg));
+ }
+#endif
+ assert(bool_false);
+ self->read_index += 3;
+ break;
+ }
case AMAL_OP_ADD: {
return_if_error(amal_exec_add(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
self->read_index += 3;
diff --git a/src/std/buffer.c b/src/std/buffer.c
index dca3b26..4ec9c29 100644
--- a/src/std/buffer.c
+++ b/src/std/buffer.c
@@ -33,15 +33,11 @@ static CHECK_RESULT int buffer_ensure_capacity(Buffer *self, usize new_capacity)
return BUFFER_OK;
capacity = self->capacity;
- if(capacity == 0) {
- capacity = new_capacity;
- } else {
- double cap = capacity;
- const double new_cap = new_capacity;
- while(cap < new_cap) {
- cap *= 1.5;
- }
- capacity = cap;
+ if(capacity == 0)
+ capacity = 8;
+
+ while(capacity < new_capacity) {
+ capacity += (capacity >> 1);
}
if(am_realloc(self->data, capacity, &new_mem) != ALLOC_OK)