aboutsummaryrefslogtreecommitdiff
path: root/src/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c390
1 files changed, 98 insertions, 292 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 803515b..fd9e4ae 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -25,37 +25,40 @@ static usize strnlen(const char *str, usize max_length) {
}
/* TODO: Allow to specify size and members? */
-static CHECK_RESULT int create_default_type(amal_compiler *compiler, const char *name, LhsExpr **lhs_expr) {
+static CHECK_RESULT int create_default_type(amal_compiler *compiler, const char *name, amal_default_type **default_type) {
StructDecl *struct_decl;
Ast *expr;
+ LhsExpr *lhs_expr;
return_if_error(arena_allocator_alloc(&compiler->allocator, sizeof(StructDecl), (void**)&struct_decl));
return_if_error(structdecl_init(struct_decl, &compiler->root_scope, &compiler->allocator));
- return_if_error(arena_allocator_alloc(&compiler->allocator, sizeof(LhsExpr), (void**)lhs_expr));
- lhsexpr_init(*lhs_expr, DECL_FLAG_EXTERN | DECL_FLAG_PUB | DECL_FLAG_CONST, create_buffer_view(name, strnlen(name, PATH_MAX)));
- return_if_error(ast_create(&compiler->allocator, struct_decl, AST_STRUCT_DECL, &(*lhs_expr)->rhs_expr));
- return_if_error(ast_create(&compiler->allocator, *lhs_expr, AST_LHS, &expr));
+ return_if_error(arena_allocator_alloc(&compiler->allocator, sizeof(amal_default_type), (void**)default_type));
+ lhs_expr = &(*default_type)->lhs_expr;
+
+ lhsexpr_init(lhs_expr, DECL_FLAG_EXTERN | DECL_FLAG_PUB | DECL_FLAG_CONST, create_buffer_view(name, strnlen(name, PATH_MAX)));
+ return_if_error(ast_create(&compiler->allocator, struct_decl, AST_STRUCT_DECL, &lhs_expr->rhs_expr));
+ return_if_error(ast_create(&compiler->allocator, lhs_expr, AST_LHS, &expr));
expr->resolve_data.type.type = RESOLVED_TYPE_LHS_EXPR;
- expr->resolve_data.type.value.lhs_expr = *lhs_expr;
+ expr->resolve_data.type.value.lhs_expr = lhs_expr;
expr->resolve_data.status = AST_RESOLVED;
return scope_add_child(&compiler->root_scope, expr);
}
static CHECK_RESULT int init_default_types(amal_compiler *compiler) {
- return_if_error(create_default_type(compiler, "i8", (LhsExpr**)&compiler->default_types.i8));
- return_if_error(create_default_type(compiler, "i16", (LhsExpr**)&compiler->default_types.i16));
- return_if_error(create_default_type(compiler, "i32", (LhsExpr**)&compiler->default_types.i32));
- return_if_error(create_default_type(compiler, "i64", (LhsExpr**)&compiler->default_types.i64));
- return_if_error(create_default_type(compiler, "u8", (LhsExpr**)&compiler->default_types.u8));
- return_if_error(create_default_type(compiler, "u16", (LhsExpr**)&compiler->default_types.u16));
- return_if_error(create_default_type(compiler, "u32", (LhsExpr**)&compiler->default_types.u32));
- return_if_error(create_default_type(compiler, "u64", (LhsExpr**)&compiler->default_types.u64));
- return_if_error(create_default_type(compiler, "isize", (LhsExpr**)&compiler->default_types.isize));
- return_if_error(create_default_type(compiler, "usize", (LhsExpr**)&compiler->default_types.usize));
- return_if_error(create_default_type(compiler, "f32", (LhsExpr**)&compiler->default_types.f32));
- return_if_error(create_default_type(compiler, "f64", (LhsExpr**)&compiler->default_types.f64));
- return_if_error(create_default_type(compiler, "str", (LhsExpr**)&compiler->default_types.str));
+ return_if_error(create_default_type(compiler, "i8", &compiler->default_types.i8));
+ return_if_error(create_default_type(compiler, "i16", &compiler->default_types.i16));
+ return_if_error(create_default_type(compiler, "i32", &compiler->default_types.i32));
+ return_if_error(create_default_type(compiler, "i64", &compiler->default_types.i64));
+ return_if_error(create_default_type(compiler, "u8", &compiler->default_types.u8));
+ return_if_error(create_default_type(compiler, "u16", &compiler->default_types.u16));
+ return_if_error(create_default_type(compiler, "u32", &compiler->default_types.u32));
+ return_if_error(create_default_type(compiler, "u64", &compiler->default_types.u64));
+ return_if_error(create_default_type(compiler, "isize", &compiler->default_types.isize));
+ return_if_error(create_default_type(compiler, "usize", &compiler->default_types.usize));
+ return_if_error(create_default_type(compiler, "f32", &compiler->default_types.f32));
+ return_if_error(create_default_type(compiler, "f64", &compiler->default_types.f64));
+ return_if_error(create_default_type(compiler, "str", &compiler->default_types.str));
compiler->default_types.arithmetic_types[0] = compiler->default_types.i8;
compiler->default_types.arithmetic_types[1] = compiler->default_types.u8;
@@ -86,11 +89,10 @@ static CHECK_RESULT int init_default_types(amal_compiler *compiler) {
bool is_arithmetic_type(LhsExpr *expr, amal_compiler *compiler) {
usize i;
- const amal_default_types *default_types;
- default_types = &compiler->default_types;
+ const amal_default_types *default_types = &compiler->default_types;
for(i = 0; i < NUM_ARITHMETIC_TYPES; ++i) {
- if(expr == (LhsExpr*)default_types->arithmetic_types[i])
+ if(expr == &default_types->arithmetic_types[i]->lhs_expr)
return bool_true;
}
return bool_false;
@@ -103,19 +105,6 @@ void amal_compiler_options_init(amal_compiler_options *self) {
}
static CHECK_RESULT int amal_compiler_init(amal_compiler *self, const amal_compiler_options *options, amal_program *program) {
- int i;
-
- self->usable_thread_count = options ? options->num_threads : 0;
- if(self->usable_thread_count == 0) {
- self->usable_thread_count = amal_get_usable_thread_count();
- if(self->usable_thread_count == 0) {
- amal_log_warning("Unable to get the number of threads available on the system, using 1 thread.");
- amal_log_warning("You can override the number of threads used by setting compiler option for number of thread to use.");
- self->usable_thread_count = 1;
- }
- }
- amal_log_info("Using %d threads", self->usable_thread_count);
-
am_memset(&self->allocator, 0, sizeof(self->allocator));
am_memset(&self->root_scope, 0, sizeof(self->root_scope));
if(options)
@@ -124,20 +113,13 @@ static CHECK_RESULT int amal_compiler_init(amal_compiler *self, const amal_compi
amal_compiler_options_init(&self->options);
self->program = program;
self->started = bool_false;
- self->work_failed = bool_false;
- self->generic_work_object_index = 0;
- amal_mutex_init(&self->mutex);
+ return_if_error(thread_pool_init(&self->stage_task_thread_pool, options ? options->num_threads : 0));
+ return_if_error(amal_mutex_init(&self->mutex));
return_if_error(arena_allocator_init(&self->allocator));
cleanup_if_error(scope_init(&self->root_scope, NULL, &self->allocator));
cleanup_if_error(buffer_init(&self->parsers, &self->allocator));
- cleanup_if_error(buffer_init(&self->queued_files, &self->allocator));
cleanup_if_error(hash_map_init(&self->file_scopes, &self->allocator, sizeof(FileScopeReference*), hash_map_compare_string, amal_hash_string));
- cleanup_if_error(arena_allocator_alloc(&self->allocator,
- self->usable_thread_count * sizeof(ParserThreadData),
- (void**)&self->threads));
- for(i = 0; i < self->usable_thread_count; ++i)
- cleanup_if_error(parser_thread_data_init(&self->threads[i]));
cleanup_if_error(init_default_types(self));
return AMAL_COMPILER_OK;
@@ -147,11 +129,13 @@ static CHECK_RESULT int amal_compiler_init(amal_compiler *self, const amal_compi
}
void amal_compiler_deinit(amal_compiler *self) {
- int i;
- for(i = 0; i < self->usable_thread_count; ++i) {
- parser_thread_data_deinit(&self->threads[i]);
+ Parser **parser = buffer_begin(&self->parsers);
+ Parser **parser_end = buffer_end(&self->parsers);
+ for(; parser != parser_end; ++parser) {
+ if((*parser)->allocator)
+ arena_allocator_deinit((*parser)->allocator);
}
-
+ thread_pool_deinit(&self->stage_task_thread_pool);
amal_mutex_deinit(&self->mutex);
arena_allocator_deinit(&self->allocator);
}
@@ -165,13 +149,11 @@ typedef enum {
typedef struct {
amal_compiler *compiler;
- ParserThreadData *parser_thread_data;
FileScopeReference *file_scope;
} CompilerParserThreadUserData;
typedef struct {
amal_compiler *compiler;
- ParserThreadData *parser_thread_data;
Parser *parser;
ThreadWorkType work_type;
} CompilerGenericThreadUserData;
@@ -184,19 +166,25 @@ typedef struct {
ThreadWorkType type;
} ThreadWorkData;
-static CHECK_RESULT int amal_compiler_load_in_this_thread(amal_compiler *compiler, FileScopeReference *file_scope, ArenaAllocator *allocator) {
+static CHECK_RESULT int amal_compiler_load_in_this_thread(amal_compiler *compiler, FileScopeReference *file_scope) {
Parser *parser;
int result;
BufferView filepath;
+ ArenaAllocator *parser_allocator;
result = AMAL_COMPILER_ERR;
+ cleanup_if_error(amal_mutex_lock(&compiler->mutex, "amal_compiler_load_in_this_thread, create arena allocator"));
+ return_if_error(arena_allocator_alloc(&compiler->allocator, sizeof(ArenaAllocator), (void**)&parser_allocator));
+ amal_mutex_tryunlock(&compiler->mutex);
+ return_if_error(arena_allocator_init(parser_allocator));
+
filepath = create_buffer_view(file_scope->canonical_path.data, file_scope->canonical_path.size);
amal_log_info("Started parsing %.*s", filepath.size, filepath.data);
- return_if_error(arena_allocator_alloc(allocator, sizeof(Parser), (void**)&parser));
- return_if_error(parser_init(parser, compiler, allocator));
+ return_if_error(arena_allocator_alloc(parser_allocator, sizeof(Parser), (void**)&parser));
+ return_if_error(parser_init(parser, compiler, parser_allocator));
file_scope->parser = parser;
return_if_error(parser_parse_file(parser, filepath));
- cleanup_if_error(amal_mutex_lock(&compiler->mutex, "amal_compiler_load_in_this_thread"));
+ cleanup_if_error(amal_mutex_lock(&compiler->mutex, "amal_compiler_load_in_this_thread, add parser"));
cleanup_if_error(buffer_append(&compiler->parsers, &parser, sizeof(parser)));
amal_log_info("Finished parsing %.*s", filepath.size, filepath.data);
result = AMAL_COMPILER_OK;
@@ -206,51 +194,12 @@ static CHECK_RESULT int amal_compiler_load_in_this_thread(amal_compiler *compile
return result;
}
-static void* thread_callback_parse_file(void *userdata) {
- FileScopeReference *file_scope;
- CompilerParserThreadUserData compiler_parser_userdata;
- void *result;
- assert(!amal_thread_is_main());
-
- am_memcpy(&compiler_parser_userdata, userdata, sizeof(compiler_parser_userdata));
+static int thread_callback_parse_file(void *userdata) {
+ int result;
+ CompilerParserThreadUserData *compiler_parser_userdata = userdata;
+ result = amal_compiler_load_in_this_thread(compiler_parser_userdata->compiler,
+ compiler_parser_userdata->file_scope);
am_free(userdata);
- file_scope = compiler_parser_userdata.file_scope;
- result = (void*)AMAL_COMPILER_ERR;
- for(;;) {
- int has_next;
- /* Abort job if another job failed */
- if(compiler_parser_userdata.compiler->work_failed) {
- result = (void*)AMAL_COMPILER_WORK_FAIL_ABORT;
- goto cleanup;
- }
- cleanup_if_error(amal_compiler_load_in_this_thread(compiler_parser_userdata.compiler,
- file_scope,
- &compiler_parser_userdata.parser_thread_data->allocator));
- cleanup_if_error(amal_mutex_lock(&compiler_parser_userdata.compiler->mutex, "thread_callback_parse_file"));
- has_next = buffer_pop(&compiler_parser_userdata.compiler->queued_files, &file_scope, sizeof(FileScopeReference*));
- amal_mutex_tryunlock(&compiler_parser_userdata.compiler->mutex);
- if(has_next != 0)
- break;
- }
- result = NULL;
-
- cleanup:
- /*
- To stop all other parsers from working cleanly, we simply clear the file queue,
- and the other threads will stop when they are done with the file they are currently parsing.
- */
- if(result != NULL) {
- ignore_result_int(amal_mutex_lock(&compiler_parser_userdata.compiler->mutex, "thread_callback_parse_file"));
- buffer_clear(&compiler_parser_userdata.compiler->queued_files);
- }
- /*
- There can be a data race between writing to this and when this is read in @amal_compiler_load_file_join_threads.
- This is intentional and it's ok, because the join_threads function checks against this status is guaranteed at this point
- to not be a certain value that it checks for. Writing to an int is atomic.
- TODO: Verify this is ok on all platforms.
- */
- compiler_parser_userdata.parser_thread_data->status = PARSER_THREAD_STATUS_IDLE;
- amal_mutex_tryunlock(&compiler_parser_userdata.compiler->mutex);
return result;
}
@@ -302,195 +251,72 @@ static CHECK_RESULT int thread_generate_bytecode(Parser *parser) {
return result;
}
-/* TODO: Handle errors (stop work in all other threads and report errors/warnings) */
-static void* thread_callback_generic(void *userdata) {
- CompilerGenericThreadUserData compiler_userdata;
- Parser *parser;
- void *result;
- assert(!amal_thread_is_main());
-
- am_memcpy(&compiler_userdata, userdata, sizeof(compiler_userdata));
- am_free(userdata);
- parser = compiler_userdata.parser;
- result = (void*)AMAL_COMPILER_ERR;
- for(;;) {
- /* TODO: stop work in all other threads on failure */
- switch(compiler_userdata.work_type) {
- case THREAD_WORK_PARSE: {
- assert(bool_false && "Thread work type can't ge 'parse' for generic work");
- break;
- }
- case THREAD_WORK_RESOLVE_AST:
- cleanup_if_error(thread_resolve_ast(compiler_userdata.compiler, parser));
- break;
- case THREAD_WORK_GENERATE_SSA:
- cleanup_if_error(thread_generate_ssa(parser));
- break;
- case THREAD_WORK_GENERATE_BYTECODE:
- cleanup_if_error(thread_generate_bytecode(parser));
- break;
- }
-
- /* Abort job if another job failed */
- if(compiler_userdata.compiler->work_failed) {
- result = (void*)AMAL_COMPILER_WORK_FAIL_ABORT;
- goto cleanup;
+static int thread_callback_generic(void *userdata) {
+ int result;
+ CompilerGenericThreadUserData *compiler_userdata = userdata;
+ switch(compiler_userdata->work_type) {
+ case THREAD_WORK_PARSE: {
+ assert(bool_false && "Thread work type can't be 'parse' for generic work");
+ break;
}
-
- /* Find next job */
- cleanup_if_error(amal_mutex_lock(&compiler_userdata.compiler->mutex, "thread_callback_generic"));
- if(compiler_userdata.compiler->generic_work_object_index + 1 >= (int)buffer_get_size(&compiler_userdata.compiler->parsers, Parser*))
+ case THREAD_WORK_RESOLVE_AST:
+ result = thread_resolve_ast(compiler_userdata->compiler, compiler_userdata->parser);
+ break;
+ case THREAD_WORK_GENERATE_SSA:
+ result = thread_generate_ssa(compiler_userdata->parser);
+ break;
+ case THREAD_WORK_GENERATE_BYTECODE:
+ result = thread_generate_bytecode(compiler_userdata->parser);
break;
- ++compiler_userdata.compiler->generic_work_object_index;
- parser = *(Parser**)buffer_get(&compiler_userdata.compiler->parsers, compiler_userdata.compiler->generic_work_object_index, sizeof(parser));
- amal_mutex_tryunlock(&compiler_userdata.compiler->mutex);
- }
- result = NULL;
-
- cleanup:
- /*
- To stop all other worker threads cleanly, we simply say we are done with all work in the queue,
- and the other threads will stop when they are done with the work they are currently working on.
- */
- if(result != NULL) {
- ignore_result_int(amal_mutex_lock(&compiler_userdata.compiler->mutex, "thread_callback_generic"));
- compiler_userdata.compiler->generic_work_object_index = (int)buffer_get_size(&compiler_userdata.compiler->parsers, Parser*);
}
- compiler_userdata.parser_thread_data->status = PARSER_THREAD_STATUS_IDLE;
- amal_mutex_tryunlock(&compiler_userdata.compiler->mutex);
+ am_free(userdata);
return result;
}
-static CHECK_RESULT int amal_compiler_select_thread_for_work(amal_compiler *self, ThreadWorkData work_data, ParserThreadData **thread_selected) {
- int i;
- int result;
- ParserThreadData *parser_thread_data;
- void *thread_user_data;
- thread_user_data = NULL;
- *thread_selected = NULL;
- result = AMAL_COMPILER_OK;
-
- cleanup_if_error(amal_mutex_lock(&self->mutex, "amal_compiler_select_thread_for_work"));
- for(i = 0; i < self->usable_thread_count; ++i) {
- parser_thread_data = &self->threads[i];
- if(parser_thread_data->status == PARSER_THREAD_STATUS_RUNNING)
- continue;
-
- switch(work_data.type) {
- case THREAD_WORK_PARSE: {
- CompilerParserThreadUserData *userdata;
- cleanup_if_error(am_malloc(sizeof(CompilerParserThreadUserData), (void**)&userdata));
- thread_user_data = userdata;
- userdata->compiler = self;
- userdata->parser_thread_data = parser_thread_data;
- userdata->file_scope = work_data.value.file_scope;
- result = parser_thread_data_start(parser_thread_data, thread_callback_parse_file, userdata);
- break;
- }
- case THREAD_WORK_RESOLVE_AST:
- case THREAD_WORK_GENERATE_SSA:
- case THREAD_WORK_GENERATE_BYTECODE: {
- CompilerGenericThreadUserData *userdata;
- cleanup_if_error(am_malloc(sizeof(CompilerGenericThreadUserData), (void**)&userdata));
- thread_user_data = userdata;
- userdata->compiler = self;
- userdata->parser_thread_data = parser_thread_data;
- userdata->parser = work_data.value.parser;
- userdata->work_type = work_data.type;
- ++self->generic_work_object_index;
- result = parser_thread_data_start(parser_thread_data, thread_callback_generic, userdata);
- break;
- }
+static CHECK_RESULT int amal_compiler_add_task(amal_compiler *self, ThreadWorkData work_data) {
+ void *thread_user_data = NULL;
+ int result = AMAL_COMPILER_OK;
+
+ switch(work_data.type) {
+ case THREAD_WORK_PARSE: {
+ CompilerParserThreadUserData *userdata;
+ cleanup_if_error(am_malloc(sizeof(CompilerParserThreadUserData), (void**)&userdata));
+ thread_user_data = userdata;
+ userdata->compiler = self;
+ userdata->file_scope = work_data.value.file_scope;
+ result = thread_pool_add_task(&self->stage_task_thread_pool, thread_callback_parse_file, userdata);
+ break;
+ }
+ case THREAD_WORK_RESOLVE_AST:
+ case THREAD_WORK_GENERATE_SSA:
+ case THREAD_WORK_GENERATE_BYTECODE: {
+ CompilerGenericThreadUserData *userdata;
+ cleanup_if_error(am_malloc(sizeof(CompilerGenericThreadUserData), (void**)&userdata));
+ thread_user_data = userdata;
+ userdata->compiler = self;
+ userdata->parser = work_data.value.parser;
+ userdata->work_type = work_data.type;
+ result = thread_pool_add_task(&self->stage_task_thread_pool, thread_callback_generic, userdata);
+ break;
}
- *thread_selected = parser_thread_data;
- break;
}
cleanup:
if(result != 0)
am_free(thread_user_data);
- amal_mutex_tryunlock(&self->mutex);
- return result;
-}
-
-static CHECK_RESULT bool amal_compiler_check_all_threads_done(amal_compiler *self) {
- int i;
- bool result;
- result = bool_false;
-
- cleanup_if_error(amal_mutex_lock(&self->mutex, "amal_compiler_check_all_threads_done"));
- for(i = 0; i < self->usable_thread_count; ++i) {
- ParserThreadData *parser_thread_data;
- parser_thread_data = &self->threads[i];
- if(parser_thread_data->status == PARSER_THREAD_STATUS_RUNNING) {
- goto cleanup;
- }
- }
-
- result = bool_true;
- cleanup:
- amal_mutex_tryunlock(&self->mutex);
- return result;
-}
-
-static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self) {
- int i;
- int result;
- void *thread_return_data;
- ParserThreadData *parser_thread_data;
-
- assert(amal_thread_is_main());
- thread_return_data = NULL;
- for(;;) {
- bool done;
- /*
- Joining running threads. After checking one running thread another one might start up,
- so this is mostly to wait for threads to finish and to sleep without doing work.
- The check after that (amal_compiler_all_threads_done) check that all threads are done correctly
- */
- for(i = 0; i < self->usable_thread_count; ++i) {
- result = amal_mutex_lock(&self->mutex, "amal_compiler_load_file_join_threads, waiting for workers");
- parser_thread_data = &self->threads[i];
- amal_mutex_tryunlock(&self->mutex);
- if(result != 0)
- goto cleanup;
- /* TODO: What to do if join fails? */
- ignore_result_int(parser_thread_data_join(parser_thread_data, &thread_return_data));
- if(thread_return_data != NULL) {
- amal_log_error("Failed, waiting for jobs to finish");
- self->work_failed = bool_true;
- }
- }
-
- done = amal_compiler_check_all_threads_done(self);
- if(done)
- break;
- }
-
- result = AMAL_COMPILER_OK;
- cleanup:
- if(self->work_failed)
- result = AMAL_COMPILER_ERR;
return result;
}
static CHECK_RESULT int amal_compiler_dispatch_generic(amal_compiler *self, ThreadWorkType work_type) {
- Parser **parser;
- Parser **parser_end;
- parser = buffer_begin(&self->parsers);
- parser_end = buffer_end(&self->parsers);
- self->generic_work_object_index = 0;
+ Parser **parser = buffer_begin(&self->parsers);
+ Parser **parser_end = buffer_end(&self->parsers);
for(; parser != parser_end; ++parser) {
- ParserThreadData *thread_selected;
ThreadWorkData thread_work_data;
thread_work_data.type = work_type;
thread_work_data.value.parser = *parser;
- return_if_error(amal_compiler_select_thread_for_work(self, thread_work_data, &thread_selected));
- /* After all threads have been used, they will handle using the remaining parsers or stop if there is an error */
- if(!thread_selected)
- break;
+ return_if_error(amal_compiler_add_task(self, thread_work_data));
}
- return amal_compiler_load_file_join_threads(self);
+ return thread_pool_join_all_tasks(&self->stage_task_thread_pool) ? 0 : -1;
}
static CHECK_RESULT int amal_compiler_generate_program(amal_compiler *self) {
@@ -498,10 +324,8 @@ static CHECK_RESULT int amal_compiler_generate_program(amal_compiler *self) {
TODO: Copying the bytecode to the program can be done using multiple threads.
Use self->threads for that.
*/
- Parser **parser;
- Parser **parser_end;
- parser = buffer_begin(&self->parsers);
- parser_end = buffer_end(&self->parsers);
+ Parser **parser = buffer_begin(&self->parsers);
+ Parser **parser_end = buffer_end(&self->parsers);
for(; parser != parser_end; ++parser) {
return_if_error(amal_program_append_bytecode(self->program, &(*parser)->bytecode));
}
@@ -580,15 +404,10 @@ static CHECK_RESULT int validate_main_func(FileScopeReference *main_file_scope,
}
int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath, FileScopeReference **file_scope) {
- int result;
- ParserThreadData *parser_thread_data;
ThreadWorkData thread_work_data;
bool main_job;
bool new_entry;
- if(self->work_failed)
- return AMAL_COMPILER_WORK_FAIL_ABORT;
-
return_if_error(try_create_file_scope(self, filepath, file_scope, &new_entry));
assert(file_scope && *file_scope && (*file_scope)->canonical_path.data);
if(!new_entry) {
@@ -596,7 +415,6 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
return 0;
}
- result = AMAL_COMPILER_ERR;
thread_work_data.type = THREAD_WORK_PARSE;
thread_work_data.value.file_scope = *file_scope;
main_job = bool_false;
@@ -607,7 +425,7 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
main_job = bool_true;
}
- return_if_error(amal_compiler_select_thread_for_work(self, thread_work_data, &parser_thread_data));
+ return_if_error(amal_compiler_add_task(self, thread_work_data));
if(main_job) {
/*doc(Compiler flow)
@@ -619,8 +437,8 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
*/
LhsExpr *main_func;
- return_if_error(amal_compiler_load_file_join_threads(self));
- assert(amal_compiler_check_all_threads_done(self));
+ if(!thread_pool_join_all_tasks(&self->stage_task_thread_pool))
+ return -1;
amal_log_info("Finished parsing all files, resolving AST");
return_if_error(validate_main_func(*file_scope, &main_func));
@@ -631,15 +449,12 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
main_func->decl_flags |= DECL_FLAG_EXPORT;
return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_RESOLVE_AST));
- assert(amal_compiler_check_all_threads_done(self));
amal_log_info("Finished resolving AST, generating SSA");
return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_SSA));
- assert(amal_compiler_check_all_threads_done(self));
amal_log_info("Finished generating SSA");
return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_BYTECODE));
- assert(amal_compiler_check_all_threads_done(self));
amal_log_info("Finished generating bytecode");
return_if_error(amal_compiler_generate_program(self));
@@ -648,14 +463,5 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
return AMAL_COMPILER_OK;
}
- if(parser_thread_data)
- return AMAL_COMPILER_OK;
-
- cleanup_if_error(amal_mutex_lock(&self->mutex, "amal_compiler_load_file"));
- cleanup_if_error(buffer_append(&self->queued_files, file_scope, sizeof(FileScopeReference*)));
- result = AMAL_COMPILER_OK;
-
- cleanup:
- amal_mutex_tryunlock(&self->mutex);
- return result;
+ return 0;
}