small bugfix with deferred statements with fallthrough
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 13 May 2021 16:24:27 +0000 (11:24 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 13 May 2021 16:24:27 +0000 (11:24 -0500)
bin/onyx
docs/bugs
src/onyx.c
src/onyxchecker.c
src/onyxwasm.c
tests/bugs/fallthrough_defer_interaction [new file with mode: 0644]
tests/bugs/fallthrough_defer_interaction.onyx [new file with mode: 0644]

index 8a4a22b5baa9e29efa78a617d8852f076d8da238..1d0686ecadee73de6a8551e4c62e2e1f711ea6b4 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 01468a4c9b20b5239426e54d3f4aea6b0764dce5..6bffad62bdb26a9ec73345488eaede47572d92f3 100644 (file)
--- 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.
index beb0a4982b671177201db43ed6cb36133c8095f2..ec2396b4f2c74e3766e14c9c98a1ee4fca607af6 100644 (file)
@@ -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);
index 404e2a771bd8d484d9261ba3785466d4a521bcf0..6cab4d82b192f5b026b0564f5542c056aed4bf04 100644 (file)
@@ -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);
         }
index 143d0e19d06044438ba5f16654e4c7e531692088..c0cf375814ab5c210220382b880e69338120cf42 100644 (file)
@@ -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 (file)
index 0000000..8823e0d
--- /dev/null
@@ -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 (file)
index 0000000..f57c9a7
--- /dev/null
@@ -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