diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-07-25 14:26:32 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-07-25 14:37:04 +0200 |
commit | b6b3760e19716c574ca9a0ec0bacfe5518b39f77 (patch) | |
tree | 76c2c04069d22d36550a62e4b5bb7878fcefb4fd | |
parent | 203fbb778e9cfe3aff8b4dee6da9a103a171ca0e (diff) |
load function in progress
-rw-r--r-- | README.md | 6 | ||||
-rwxr-xr-x | build.sh | 5 | ||||
-rw-r--r-- | src/ast.c | 12 | ||||
-rw-r--r-- | src/program.c | 42 | ||||
-rw-r--r-- | src/std/buffer.c | 14 | ||||
-rw-r--r-- | std/io.amal | 2 |
6 files changed, 69 insertions, 12 deletions
@@ -70,6 +70,10 @@ All branch targets should be 16-byte aligned. * Implement pub for imports and show compile error when using non-pub symbols in pub closures/structs/etc. * Use a list instead of a hash map for variable lookup, since the list will be small most of the time. * Optimize buffer_append by returning pre-allocated space which can be used directly, instead of adding data to a variable and then copying it to the buffer. +* Use instructions such as CMPXCHG8B to optimize operations such as `if(a == b) a = c;`. +* Do not allow (re)assigning to variables in global scope. This wouldn't be consistent since files are parsed asynchronously so the order wouldn't be deterministic. +* Compile error if a variable has the same name as a keyword. +* Only allow importing files that has .amal extension, this also fixes the issue where windows has illegal filenames such as aux, nul, etc. Also do the same for the main file. # Documents Documents are located under doc. The file doc/Documentation.md is generated from source files by running doc/doc_extract.py but there is no need to run this script unless you are modifying documentation in the source. @@ -78,4 +82,4 @@ Define `AMAL_MUTEX_DEBUG` in src/thread.c to enable mutex debugging.\ Set `PEDANTIC` environment variable to 1 before compiling to enable pedantic mode.\ Set `SANITIZE_ADDRESS` environment variable to 1 before compiling to run compile with asan.\ Set `SANITIZE_THREAD` environment variable to 1 before compiling to run compile with tsan.\ -Set `SCAN_BUILD` environment variable to 1 before compiling to run scan-build on the source files.
\ No newline at end of file +Set `SCAN_BUILD` environment variable to 1 before compiling to run scan-build on the source files. @@ -23,7 +23,7 @@ else fi if [ -z "$CC" ]; then - CC=cc + CC=gcc fi CFLAGS="-Wall -Wextra -Werror -Wno-format-security -Wno-error=attributes -Wno-attributes -Wnull-dereference -std=c89 -D_GNU_SOURCE" @@ -81,6 +81,9 @@ build_test() { build_release() { CFLAGS="$CFLAGS -O2 -DNDEBUG -s" + # TODO: -static -flto + # LIBS="-static $LIBS" also remove below -shared -fPIC + # CFLAGS="$CFLAGS -flto" BUILD_ARGS="$source_files $CFLAGS $LIBS -shared -fPIC -o libamalgam.so" set -x @@ -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) diff --git a/std/io.amal b/std/io.amal index ea0845f..81626f6 100644 --- a/std/io.amal +++ b/std/io.amal @@ -3,4 +3,4 @@ extern const printf: fn(fmt: &c_char, ...) c_int; pub const print1 = fn(fmt: str) i32 { return printf(fmt); -}
\ No newline at end of file +} |