diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast.c | 12 | ||||
-rw-r--r-- | src/program.c | 42 | ||||
-rw-r--r-- | src/std/buffer.c | 14 |
3 files changed, 59 insertions, 9 deletions
@@ -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) |