From 01ede15c6026678db40d8c69816ffec69f18a457 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 23 May 2023 22:06:03 -0500 Subject: [PATCH] added: debug info for tagged unions --- compiler/src/wasm_output.h | 17 +++++++++++++++++ interpreter/include/ovm_debug.h | 13 +++++++++++++ interpreter/src/debug/debug_info.c | 18 +++++++++++++++++- interpreter/src/debug/debug_runtime_values.c | 15 +++++++++++++++ tests/tagged_unions.onyx | 2 +- 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/compiler/src/wasm_output.h b/compiler/src/wasm_output.h index 7626f1f1..3d86f5f2 100644 --- a/compiler/src/wasm_output.h +++ b/compiler/src/wasm_output.h @@ -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, §ion_buff); + output_unsigned_integer(type->Union.alignment, §ion_buff); + + i32 var_count = bh_arr_length(type->Union.variants_ordered); + output_unsigned_integer(var_count, §ion_buff); + + fori (i, 0, var_count) { + char *name = type->Union.variants_ordered[i]->name; + output_name(name, strlen(name), §ion_buff); + + output_unsigned_integer(type->Union.variants_ordered[i]->type->id, §ion_buff); + } + + continue; + } + if (type->kind == Type_Kind_Function) { output_unsigned_integer(6, §ion_buff); output_unsigned_integer(type->Function.param_count, §ion_buff); diff --git a/interpreter/include/ovm_debug.h b/interpreter/include/ovm_debug.h index 4302d086..1d872cc0 100644 --- a/interpreter/include/ovm_debug.h +++ b/interpreter/include/ovm_debug.h @@ -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; diff --git a/interpreter/src/debug/debug_info.c b/interpreter/src/debug/debug_info.c index 99bc1f65..6b332c1c 100644 --- a/interpreter/src/debug/debug_info.c +++ b/interpreter/src/debug/debug_info.c @@ -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 +} diff --git a/interpreter/src/debug/debug_runtime_values.c b/interpreter/src/debug/debug_runtime_values.c index bed7fb85..e0106195 100644 --- a/interpreter/src/debug/debug_runtime_values.c +++ b/interpreter/src/debug/debug_runtime_values.c @@ -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; } } diff --git a/tests/tagged_unions.onyx b/tests/tagged_unions.onyx index 1ac7c60b..7592db53 100644 --- a/tests/tagged_unions.onyx +++ b/tests/tagged_unions.onyx @@ -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 { -- 2.25.1