From: Brendan Hansen Date: Thu, 13 May 2021 16:24:27 +0000 (-0500) Subject: small bugfix with deferred statements with fallthrough X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=141d9286c1e7f98b669018cab469db1842b408d9;p=onyx.git small bugfix with deferred statements with fallthrough --- diff --git a/bin/onyx b/bin/onyx index 8a4a22b5..1d0686ec 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/docs/bugs b/docs/bugs index 01468a4c..6bffad62 100644 --- a/docs/bugs +++ b/docs/bugs @@ -71,6 +71,8 @@ List of known bugs: [ ] Why are character literals signed???? +[X] `fallthrough` in a for loop does not emit deferred statments correctly. + List of things to change: [X] Currently, there is no way to use the initialized members of a structure without using a struct literal. There should be a initialize intrinsic procedure that takes a pointer to anything and initializes it. diff --git a/src/onyx.c b/src/onyx.c index beb0a498..ec2396b4 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -209,7 +209,7 @@ static void context_free() { // NOTE: This should not be called until immediately before using the return value. // This function can return a static variable which will change if this is called // another time. -brendanfh 2020/10/09 -static char* lookup_included_file(char* filename) { +static char* lookup_included_file(char* filename, char* relative_to) { static char path[256]; fori (i, 0, 256) path[i] = 0; @@ -285,7 +285,7 @@ static void process_load_entity(Entity* ent) { AstInclude* include = ent->include; if (include->kind == Ast_Kind_Load_File) { - char* filename = lookup_included_file(include->name); + char* filename = lookup_included_file(include->name, NULL); char* formatted_name = bh_strdup(global_heap_allocator, filename); process_source_file(formatted_name, include->token->pos); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 404e2a77..6cab4d82 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -62,7 +62,9 @@ static inline void fill_in_array_count(AstType* type_node) { if (type_node->kind == Ast_Kind_Array_Type) { if (((AstArrayType *) type_node)->count_expr) { + // CLEANUP: The return value is not checked on this call. check_expression(&((AstArrayType *) type_node)->count_expr); + resolve_expression_type(((AstArrayType *) type_node)->count_expr); } } @@ -76,7 +78,9 @@ static inline void fill_in_poly_call_args(AstType* type_node) { bh_arr_each(AstNode *, param, pctype->params) { if (!node_is_type(*param)) { + // CLEANUP: The return value is not checked on this call. check_expression((AstTyped **) param); + resolve_expression_type((AstTyped *) *param); fill_in_type((AstTyped *) *param); } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 143d0e19..c0cf3758 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -338,6 +338,8 @@ EMIT_FUNC_NO_ARGS(leave_structured_block) { EMIT_FUNC(structured_jump, AstJump* jump) { bh_arr(WasmInstruction) code = *pcode; + // :CLEANUP These numbers should become constants because they are shared with + // enter_structured_block's definitions. static const u8 wants[Jump_Type_Count] = { 1, 2, 3 }; u64 labelidx = 0; @@ -359,7 +361,9 @@ EMIT_FUNC(structured_jump, AstJump* jump) { if (bh_arr_length(mod->deferred_stmts) != 0) { i32 i = bh_arr_length(mod->deferred_stmts) - 1; - while (i >= 0 && mod->deferred_stmts[i].depth >= labelidx) { + i32 d = bh_arr_length(mod->structured_jump_target) - (labelidx + 1); + + while (i >= 0 && mod->deferred_stmts[i].depth > d) { emit_deferred_stmt(mod, &code, mod->deferred_stmts[i]); i--; } diff --git a/tests/bugs/fallthrough_defer_interaction b/tests/bugs/fallthrough_defer_interaction new file mode 100644 index 00000000..8823e0dc --- /dev/null +++ b/tests/bugs/fallthrough_defer_interaction @@ -0,0 +1,12 @@ +1234 +World +1234 +World +1234 +World +1234 +World +1234 +World +Closing the iterator +Default case diff --git a/tests/bugs/fallthrough_defer_interaction.onyx b/tests/bugs/fallthrough_defer_interaction.onyx new file mode 100644 index 00000000..f57c9a78 --- /dev/null +++ b/tests/bugs/fallthrough_defer_interaction.onyx @@ -0,0 +1,44 @@ +#load "core/std" + +use package core + +custom_iterator :: () -> Iterator(i32) { + + next :: (data: rawptr) -> (i32, bool) { + return 1234, true; + } + + close :: (data: rawptr) { + println("Closing the iterator"); + } + + return .{ + data = null, + next = next, + close = close, + }; +} + +main :: (args: [] cstr) { + + switch 10 { + case 5 do println("Never"); + + case 10 { + count := 5; + for i: custom_iterator() { + println(i); + defer println("World"); + + count -= 1; + + // :FIXEDBUG This was were it was breaking; the iterator close didn't run here. + if count == 0 do fallthrough; + } + } + + case #default { + println("Default case"); + } + } +} \ No newline at end of file