aboutsummaryrefslogtreecommitdiff
path: root/src/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 39cbb00..228cb74 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -36,7 +36,8 @@ static CHECK_RESULT int create_default_type(amal_compiler *compiler, const char
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 = *lhs_expr;
+ expr->resolve_data.type.type = RESOLVED_TYPE_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);
}
@@ -123,6 +124,7 @@ 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);
@@ -204,7 +206,6 @@ static CHECK_RESULT int amal_compiler_load_in_this_thread(amal_compiler *compile
return result;
}
-/* TODO: Handle errors (stop parsing in all other threads and report errors/warnings) */
static void* thread_callback_parse_file(void *userdata) {
FileScopeReference *file_scope;
CompilerParserThreadUserData compiler_parser_userdata;
@@ -217,6 +218,11 @@ static void* thread_callback_parse_file(void *userdata) {
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));
@@ -324,6 +330,14 @@ static void* thread_callback_generic(void *userdata) {
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;
+ }
+
+ /* 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*))
break;
@@ -339,7 +353,7 @@ static void* thread_callback_generic(void *userdata) {
and the other threads will stop when they are done with the work they are currently working on.
*/
if(result != NULL) {
- cleanup_if_error(amal_mutex_lock(&compiler_userdata.compiler->mutex, "thread_callback_generic"));
+ 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;
@@ -424,11 +438,9 @@ static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self
int result;
void *thread_return_data;
ParserThreadData *parser_thread_data;
- bool work_failed;
assert(amal_thread_is_main());
thread_return_data = NULL;
- work_failed = bool_false;
for(;;) {
bool done;
/*
@@ -442,12 +454,11 @@ static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self
amal_mutex_tryunlock(&self->mutex);
if(result != 0)
goto cleanup;
- /* TODO: Cleanup remaining threads if join fails */
- cleanup_if_error(parser_thread_data_join(parser_thread_data, &thread_return_data));
+ /* 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) {
- /* TODO: Somehow exit running jobs */
amal_log_error("Failed, waiting for jobs to finish");
- work_failed = bool_true;
+ self->work_failed = bool_true;
}
}
@@ -458,7 +469,7 @@ static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self
result = AMAL_COMPILER_OK;
cleanup:
- if(work_failed)
+ if(self->work_failed)
result = AMAL_COMPILER_ERR;
return result;
}
@@ -545,6 +556,9 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
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) {