added: debug info for tagged unions
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 24 May 2023 03:06:03 +0000 (22:06 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 24 May 2023 03:06:03 +0000 (22:06 -0500)
compiler/src/wasm_output.h
interpreter/include/ovm_debug.h
interpreter/src/debug/debug_info.c
interpreter/src/debug/debug_runtime_values.c
tests/tagged_unions.onyx

index 7626f1f1e3577c4539424741fd15203844f1836c..3d86f5f2c6d224a14c5f8beb6c55d8a9028225df 100644 (file)
@@ -986,6 +986,23 @@ static i32 output_ovm_debug_sections(OnyxWasmModule* module, bh_buffer* buff) {
             //     continue;
             // }
 
+            if (type->kind == Type_Kind_Union) {
+                output_unsigned_integer(9, &section_buff);
+                output_unsigned_integer(type->Union.alignment, &section_buff);
+
+                i32 var_count = bh_arr_length(type->Union.variants_ordered);
+                output_unsigned_integer(var_count, &section_buff);
+
+                fori (i, 0, var_count) {
+                    char *name = type->Union.variants_ordered[i]->name;
+                    output_name(name, strlen(name), &section_buff);
+                    
+                    output_unsigned_integer(type->Union.variants_ordered[i]->type->id, &section_buff);
+                }
+
+                continue;
+            }
+
             if (type->kind == Type_Kind_Function) {
                 output_unsigned_integer(6, &section_buff);
                 output_unsigned_integer(type->Function.param_count, &section_buff);
index 4302d086605e78f59e193c00d3bc8dd3ad3cb55c..1d872cc07287711aacd9d41622b4b5956f569eaa 100644 (file)
@@ -58,6 +58,7 @@ typedef enum debug_type_kind_t {
     debug_type_kind_function  = 6,
     debug_type_kind_slice     = 7,
     debug_type_kind_enum      = 8,
+    debug_type_kind_union     = 9,
 } debug_type_kind_t;
 
 typedef enum debug_type_primitive_kind_t {
@@ -133,6 +134,17 @@ typedef struct debug_type_enum_t {
     debug_type_enum_value_t *values;
 } debug_type_enum_t;
 
+typedef struct debug_type_union_variant_t {
+    char *name;
+    u32 type;
+} debug_type_union_variant_t;
+
+typedef struct debug_type_union_t {
+    u32 tag_size;
+    u32 variant_count;
+    debug_type_union_variant_t *variants;
+} debug_type_union_t;
+
 typedef struct debug_type_info_t {
     u32 id;
     char *name;
@@ -148,6 +160,7 @@ typedef struct debug_type_info_t {
         debug_type_function_t  function;
         debug_type_slice_t     slice;
         debug_type_enum_t      enumeration;
+        debug_type_union_t     onion;
     };
 } debug_type_info_t;
 
index 99bc1f6531bcfa28007e34f16ea342219d2bdb0d..6b332c1c7011c9e196560c7dcbbdb4f151783820 100644 (file)
@@ -204,6 +204,22 @@ void debug_info_import_type_info(debug_info_t *info, u8 *data, u32 len) {
                 }
                 break;
 
+            case debug_type_kind_union:
+                type.onion.tag_size = uleb128_to_uint(data, &offset);
+                type.onion.variant_count = uleb128_to_uint(data, &offset);
+                type.onion.variants = bh_alloc_array(info->alloc, debug_type_union_variant_t, type.onion.variant_count);
+                
+                fori (i, 0, type.onion.variant_count) {
+                    u32 name_length = uleb128_to_uint(data, &offset);
+                    type.onion.variants[i].name = bh_alloc_array(info->alloc, char, name_length + 1);
+                    memcpy(type.onion.variants[i].name, data + offset, name_length);
+                    type.onion.variants[i].name[name_length] = 0;
+                    offset += name_length;
+                    
+                    type.onion.variants[i].type = uleb128_to_uint(data, &offset);
+                }
+                break;
+
             // Error handling
             default: assert(("Unrecognized type kind", 0));
         }
@@ -293,4 +309,4 @@ bool debug_info_lookup_func(debug_info_t *info, u32 func_id, debug_func_info_t *
     if (func_id > (u32) bh_arr_length(info->funcs)) return false;
     *out = info->funcs[func_id];
     return true;
-}
\ No newline at end of file
+}
index bed7fb85aaeaea262f6ef042105b1346fda30f1b..e0106195d4e3df931bacaa32024721361124bf97 100644 (file)
@@ -182,6 +182,21 @@ static void append_value_from_memory_with_type(debug_runtime_value_builder_t *bu
             break;
         }
 
+        case debug_type_kind_union: {
+            u32 variant = *(u32 *) base;
+            if (variant == 0) {
+                WRITE("unknown_variant");
+
+            } else {
+                debug_type_union_variant_t *uv = &type->onion.variants[variant - 1];
+
+                WRITE_FORMAT("%s(", uv->name); 
+                append_value_from_memory_with_type(builder, bh_pointer_add(base, type->onion.tag_size), uv->type);
+                WRITE(")");
+            }
+            break;
+        }
+
         default: WRITE("(unknown)"); break;
     }
 }
index 1ac7c60bc61aaa5e60dcba22cfb38d239c852c9c..7592db53b7998e9fe5e089abffe882e768073dd7 100644 (file)
@@ -97,7 +97,7 @@ linked_list_example :: () {
     print_links :: (l: &Link) {
         walker := l;
         while true {
-            switch *walker {
+            switch walker {
                 case .End do break break;
 
                 case .Next => &next {