bugfixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 24 Dec 2022 03:22:39 +0000 (21:22 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 24 Dec 2022 03:22:39 +0000 (21:22 -0600)
16 files changed:
compiler/include/astnodes.h
compiler/src/checker.c
compiler/src/onyx.c
compiler/src/symres.c
core/container/array.onyx
core/hash/hash.onyx
core/misc/any_utils.onyx
core/std.onyx
interpreter/include/ovm_debug.h
interpreter/include/ovm_wasm.h
interpreter/src/debug/debug_thread.c
interpreter/src/vm/vm.c
interpreter/src/wasm/config.c
interpreter/src/wasm/engine.c
scripts/onyx-pkg.onyx
shared/lib/linux_x86_64/lib/libovmwasm.so

index 3ad0178279d20bba41514581a86af7d068b46018..f6bb55b9717605d1a7095450030e473ed5cc6bc7 100644 (file)
@@ -1625,7 +1625,7 @@ struct Context {
     // present in this list when generating CTags.
     bh_arr(AstNode *) tag_locations;
 
-    b32 cycle_almost_detected : 1;
+    u32 cycle_almost_detected : 2;
     b32 cycle_detected : 1;
 };
 
index 23462ce0986d2aa688c0f3da675c005fab45250f..12171d0080fdfef451e37abd6db37397aeb61bed 100644 (file)
@@ -2161,7 +2161,9 @@ CheckStatus check_insert_directive(AstDirectiveInsert** pinsert) {
     AstCodeBlock* code_block = (AstCodeBlock *) insert->code_expr;
     code_block = (AstCodeBlock *) strip_aliases((AstNode *) code_block);
 
-    assert(code_block->kind == Ast_Kind_Code_Block);
+    if (code_block->kind != Ast_Kind_Code_Block) {
+        ERROR(insert->token->pos, "Expected compile-time known expression of type 'Code'.");
+    }
 
     AstNode* cloned_block = ast_clone(context.ast_alloc, code_block->code);
     cloned_block->next = insert->next;
index 82982019d915970bff25f43770b81a4ee3ebae4f..f7ff50d753d6eddd0b4e9099ded885cc5d8b545e 100644 (file)
@@ -672,10 +672,10 @@ static i32 onyx_compile() {
                 if (ent->macro_attempts > highest_watermark) {
                     entity_heap_insert_existing(&context.entities, ent);
 
-                    if (context.cycle_almost_detected) {
+                    if (context.cycle_almost_detected == 3) {
                         dump_cycles();
                     } else {
-                        context.cycle_almost_detected = 1;
+                        context.cycle_almost_detected += 1;
                     }
                 }
             }
index 341a12880f425b7aa85e208ca923d5fdc3d8afc1..ea997211ada2e1bef04aaf2bc3e359964a4f5090 100644 (file)
@@ -362,7 +362,7 @@ static SymresStatus symres_field_access(AstFieldAccess** fa) {
         }
     }
     else if (force_a_lookup) {
-        if (context.cycle_detected || context.cycle_almost_detected) {
+        if (context.cycle_detected || context.cycle_almost_detected >= 2) {
             onyx_report_error((*fa)->token->pos, Error_Critical, "'%b' does not exist here. This is a bad error message.",
                 (*fa)->token->text,
                 (*fa)->token->length);
@@ -909,7 +909,7 @@ static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid) {
 static SymresStatus symres_directive_defined(AstDirectiveDefined** pdefined) {
     AstDirectiveDefined* defined = *pdefined;
 
-    b32 has_to_be_resolved = context.cycle_almost_detected;
+    b32 has_to_be_resolved = context.cycle_almost_detected >= 1;
 
     onyx_errors_disable();
     resolved_a_symbol = 0;
index c5aa3020b85563d3c3806df36a20d6757e0829a8..6c3655e32de7d205903a0556449fdeb62fb53a6b 100644 (file)
@@ -244,6 +244,8 @@ Untyped_Array :: struct {
 
 // Things that work with slices and arrays
 
+use core.intrinsics.types {type_is_struct}
+
 transplant :: (arr: [] $T, old_index: i32, new_index: i32) -> bool {
     if old_index < 0 || old_index >= arr.count do return false;
     if new_index < 0 || new_index >= arr.count do return false;
@@ -477,32 +479,44 @@ map :: #match #locked {
     macro (arr: [] $T, data: $R, f: (T, R) -> T)       do for ^it: arr do *it = f(*it, data);,
 }
 
-every :: #match #locked {
-    macro (arr: [] $T, predicate: (T) -> bool) -> bool {
-        every :: every
-        return every(arr, #(predicate(it)));
-    },
+every :: #match #local {}
 
-    macro (arr: [] $T, predicate_body: Code) -> bool {
-        for arr {
-            if !(#unquote predicate_body) do return false;
-        }
-        return true;
+#overload
+every :: macro (arr: [] $T, predicate: (T) -> bool) -> bool {
+    every :: every
+    return every(arr, #(predicate(it)));
+}
+
+#overload
+every :: macro (arr: [] $T, predicate_body: Code) -> bool {
+    for arr {
+        if !(#unquote predicate_body) do return false;
     }
+    return true;
 }
 
-some :: #match #locked {
-    macro (arr: [] $T, predicate: (T) -> bool) -> bool {
-        some :: some
-        return every(arr, #(predicate(it)));
-    },
+some :: #match #local {}
 
-    macro (arr: [] $T, predicate_body: Code) -> bool {
-        for arr {
-            if #unquote predicate_body do return true;
-        }
-        return false;
+#overload
+some :: macro (arr: [] $T, predicate: (T) -> bool) -> bool {
+    some :: some
+    return every(arr, #(predicate(it)));
+}
+
+#overload
+some :: macro (arr: [] $T/type_is_struct, predicate_body: Code) -> bool {
+    for ^ arr {
+        if #unquote predicate_body do return true;
     }
+    return false;
+}
+
+#overload
+some :: macro (arr: [] $T, predicate_body: Code) -> bool {
+    for arr {
+        if #unquote predicate_body do return true;
+    }
+    return false;
 }
 
 fill :: (arr: [] $T, value: T) {
@@ -540,7 +554,7 @@ find :: (arr: [] $T, value: T) -> i32 {
 }
 
 #overload
-find :: macro (arr: [] $T, pred: Code) -> i32 {
+find :: macro (arr: [] $T/type_is_struct, pred: Code) -> i32 {
     for i: arr.count {
         it := ^arr[i];
         if #unquote pred do return i;
@@ -549,6 +563,16 @@ find :: macro (arr: [] $T, pred: Code) -> i32 {
     return -1;
 }
 
+#overload
+find :: macro (arr: [] $T, pred: Code) -> i32 {
+    for i: arr.count {
+        it := arr[i];
+        if #unquote pred do return i;
+    }
+
+    return -1;
+}
+
 find_ptr :: (arr: [] $T, value: T) -> ^T {
     for ^it: arr {
         if value == *it do return it;
@@ -563,9 +587,18 @@ first :: #match #locked {
         return first(arr, #(predicate(it)));
     },
 
+    macro (arr: [] $T/type_is_struct, predicate_body: Code) -> ^T {
+        for ^ arr {
+            if #unquote predicate_body do return it;
+        }
+
+        return null;
+    },
+
     macro (arr: [] $T, predicate_body: Code) -> ^T {
         // This is to preserve the semantics that "it" is
-        // not a pointer (same as contains)
+        // not a pointer (same as contains), when T is not a
+        // structure.
         for ^it_ptr: arr {
             it := *it_ptr;
             if #unquote predicate_body do return it_ptr;
index 433f553b93b856c5a547054db9059b4d38c218db..95ee4f2cbc50492a1e34300d1963cc3ae97bd10d 100644 (file)
@@ -1,7 +1,14 @@
 package core.hash
 
 to_u32 :: #match {
+    // Does this need to have a higher precedence value?
+    // Because if I wanted to have a custom type as the key
+    // of a map that only looks at some of the members of the
+    // struct to determine its hash, that would not be possible
+    // as any pointer would match this case instead of the actual
+    // one defined for the type...
     (key: rawptr) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
+
     (key: i8)     -> u32 { return ~~ key; },
     (key: i16)    -> u32 { return 0x9ce7 ^ cast(u32) key; },
     (key: i32)    -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
index 5355145489d3a02519e38dc43192e5d761295571..a001914397b2b68ef0fab891f9d09eead5880b96 100644 (file)
@@ -11,8 +11,12 @@ use runtime.info {
     get_struct_member
 }
 
-use core { iter, array }
+use core { iter, array, string }
 
+// Either to_any or as_any will work. I prefer `as_any` because
+// much of the rest of the standard library uses `as_...` for
+// conversion.
+as_any :: to_any
 to_any :: macro (x: ^$T) => any.{x, T};
 
 any_as :: (a: any, $T: type_expr) -> ^T {
@@ -57,6 +61,27 @@ any_selector :: (v: any, member_name: str) -> any {
     return .{null, void};
 }
 
+// This selector works with selecting "foo.bar.joe"
+any_nested_selector :: (v: any, member_name: str) -> any {
+    t := get_type_info(v.type);
+    if t.kind != .Struct do return .{};
+
+    part_name, next_name := string.bisect(member_name, #char ".");
+
+    member := get_struct_member(v.type, part_name);
+    if member {
+        if next_name {
+            return any_nested_selector(any.{cast(^u8) v.data + member.offset, member.type}, next_name);
+        }
+
+        return any.{
+            cast(^u8, v.data) + member.offset, member.type
+        };
+    }
+
+    return .{null, void};
+}
+
 any_to_map :: (v: any) -> (Map(str, any), success: bool) {
     vals := v;
     if get_type_info(vals.type).kind == .Pointer {
index 7d226994bd2e159a3ec2e44a4388c3f83e4cf297..ae198e29a0efa18de0803e104df0cd320f2e82bc 100644 (file)
@@ -46,10 +46,8 @@ package core
 #load "./test/testing"
 
 #load "./misc/arg_parse"
-#load "./misc/any_utils"
 #load "./misc/method_ops"
 
-#local runtime :: package runtime
 #if runtime.runtime == .Wasi || runtime.runtime == .Onyx {
     #load "./os/file"
     #load "./os/os"
@@ -85,6 +83,7 @@ package core
 
     #load "./encoding/base64"
     #load "./encoding/csv"
+    #load "./misc/any_utils"
 }
 
 #if runtime.Multi_Threading_Enabled {
index a6b53e9f6c45bdc33636d4beaee2c5fcaafa6872..07501a54751e4e1ed4d4892be68982f6d0e7900f 100644 (file)
@@ -284,6 +284,8 @@ typedef struct debug_state_t {
     bh_arena tmp_arena;
     bh_allocator tmp_alloc;
 
+    char *listen_path;
+
     debug_info_t *info;
     struct ovm_engine_t *ovm_engine;
 
index 71bb19c1b348d02ea9a3ecceb220039f5498b83c..0dac195e9c6acf120c5f444f99f20a66301bc52b 100644 (file)
@@ -9,9 +9,11 @@
 
 struct wasm_config_t {
     bool debug_enabled;
+    char *listen_path;
 };
 
 void wasm_config_enable_debug(wasm_config_t *config, bool enabled);
+void wasm_config_set_listen_path(wasm_config_t *config, char *listen_path);
 
 struct wasm_engine_t {
     wasm_config_t *config;
index eee4ec6036cdee9d0b28fb7f854f5c313df556b6..176956475ec8d7a9eef99f7709fe6b5d479da2b5 100644 (file)
@@ -465,8 +465,8 @@ void *__debug_thread_entry(void * data) {
 
     struct sockaddr_un local_addr, remote_addr;
     local_addr.sun_family = AF_UNIX;
-    strcpy(local_addr.sun_path, "/tmp/ovm-debug.0000"); // TODO: Make this dynamic so mulitple servers can exist at a time.
-    unlink(local_addr.sun_path);                        // TODO: Remove this line for the same reason.
+    strcpy(local_addr.sun_path, debug->listen_path); // TODO: Make this dynamic so mulitple servers can exist at a time.
+    unlink(local_addr.sun_path);                     // TODO: Remove this line for the same reason.
     int len = strlen(local_addr.sun_path) + sizeof(local_addr.sun_family);
     bind(debug->listen_socket_fd, (struct sockaddr *)&local_addr, len);
     
index a877ab803481d6ba5e76c0d35073c767f940109d..3ae337638fc3e2d1f626cf034f865a4c8e29c86c 100644 (file)
@@ -741,7 +741,7 @@ static void __ovm_debug_hook(ovm_engine_t *engine, ovm_state_t *state) {
 
 #define OVMI_FUNC_NAME(n) ovmi_exec_debug_##n
 #define OVMI_DISPATCH_NAME ovmi_debug_dispatch
-#define OVMI_DEBUG_HOOK if (state->debug) __ovm_debug_hook(state->engine, state)
+#define OVMI_DEBUG_HOOK __ovm_debug_hook(state->engine, state)
 #define OVMI_EXCEPTION_HOOK __ovm_trigger_exception(state)
 #include "./vm_instrs.h"
 
index 07ea4741a2a0f12312f780e594af7c6c7aa7da7d..bd8801e302e1dd5128f43ff39e29e39cfb013888 100644 (file)
@@ -4,6 +4,7 @@
 wasm_config_t *wasm_config_new() {
     wasm_config_t *config = malloc(sizeof(*config));
     config->debug_enabled = false;
+    config->listen_path   = "/tmp/ovm-debug.0000";
     return config;
 }
 
@@ -15,4 +16,7 @@ void wasm_config_enable_debug(wasm_config_t *config, bool enabled) {
     config->debug_enabled = enabled;
 }
 
+void wasm_config_set_listen_path(wasm_config_t *config, char *listen_path) {
+    config->listen_path = listen_path;
+}
 
index db4fbeab468cd2c204ab430e8153080067aa3a1a..666779a73bb174f4543d8ca5bd457bc90d83e416 100644 (file)
@@ -23,6 +23,8 @@ wasm_engine_t *wasm_engine_new_with_config(wasm_config_t *config) {
         engine->engine->debug = debug;
 
         debug_host_init(engine->engine->debug, engine->engine);
+        debug->listen_path = config->listen_path;
+
         debug_host_start(engine->engine->debug);
     }
 
index fb8168063891e3987a945ca638a165e900a262e3..d7d39f5a2e8674d17a1cfe14c67f8a5866eac056 100644 (file)
@@ -42,22 +42,24 @@ main :: (args: [] cstr) {
 
     command_procedures := runtime.info.get_procedures_with_tag(Command);
     defer delete(^command_procedures);
-    for command_procedures {
-        if it.tag.command == command {
-            if it.tag.require_config_file {
-                if !load_config_file() {
-                    eprintf("Failed to open {}.\n", global_arguments.config_file);
-                    os.exit(1);
-                }
 
-                loaded_config_file = true;
-            }
+    command_tag := array.first(command_procedures, #(it.tag.command == command));
+    if !command_tag {
+        run_help_command(arguments);
+        return;
+    }
 
-            assert(it.type == #type ([] cstr) -> void, "BAD TYPE FOR COMMAND PROCEDURE!");
-            (*cast(^([] cstr) -> void) ^it.func)(arguments);
-            break;
+    if command_tag.tag.require_config_file {
+        if !load_config_file() {
+            eprintf("Failed to open {}.\n", global_arguments.config_file);
+            os.exit(1);
         }
+
+        loaded_config_file = true;
     }
+
+    assert(command_tag.type == #type ([] cstr) -> void, "BAD TYPE FOR COMMAND PROCEDURE!");
+    (*cast(^([] cstr) -> void) ^command_tag.func)(arguments);
 }
 
 Command :: struct {
@@ -334,7 +336,7 @@ run_sync_command :: (args: [] cstr) {
 package-or-url   Git repository name or package name on disk to remove.
 """
 }
-run_rebuild_command :: (args: [] cstr) {
+run_rebuild_command :: (args: [] cstr)  {
     if args.count < 1 {
         eprintf("Expected package name.");
         return;
@@ -446,6 +448,11 @@ run_test_command :: (args: [] cstr) {
     }
 }
 
+#tag Command.{ "new", "Create a new project from an installed template." }
+run_new_command :: (args: [] cstr) {
+
+}
+
 
 #local {
     #if runtime.compiler_os == .Linux {
@@ -741,6 +748,8 @@ Git :: struct {
         version_str := tprintf("v{}", version);
         full_dest   := tprintf("{}/{}", config.config.lib_source_directory, ".cloned");
 
+        os.remove_directory(full_dest);
+
         // Use 'git clone' to clone the bare minimum amount to get the released version.
         git_proc    := os.process_spawn(git_path, .["clone", "--depth", "1", "-b", version_str, repo, full_dest]);
         result      := os.process_wait(^git_proc);
index 0cfe7fceedc7bf769a375c0abd6a956a4599558e..2ba9dcbaa903b195338370a3ee6b3508dab5af4e 100755 (executable)
Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ