aboutsummaryrefslogtreecommitdiff
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
parent203fbb778e9cfe3aff8b4dee6da9a103a171ca0e (diff)
load function in progress
-rw-r--r--README.md6
-rwxr-xr-xbuild.sh5
-rw-r--r--src/ast.c12
-rw-r--r--src/program.c42
-rw-r--r--src/std/buffer.c14
-rw-r--r--std/io.amal2
6 files changed, 69 insertions, 12 deletions
diff --git a/README.md b/README.md
index 16f5252..4b12d62 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/build.sh b/build.sh
index 144ae2f..ce704cb 100755
--- a/build.sh
+++ b/build.sh
@@ -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
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)
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
+}