cleaned up struct storing
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 25 Jan 2021 03:51:05 +0000 (21:51 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 25 Jan 2021 03:51:05 +0000 (21:51 -0600)
bin/onyx
include/onyxtypes.h
onyx.exe
src/onyxtypes.c
src/onyxutils.c
src/onyxwasm.c

index 421a057474234c719e9513365270a8347e3b414c..3e9179c3e47740a61c14df36d410adb6d5f6f4bc 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 16e71891a93e696e005e9a9278d0783a7f8017f4..d34277d37a189cad65745f973ce0a83f781d4d11 100644 (file)
@@ -73,6 +73,12 @@ typedef struct StructMember {
     b32 used : 1;
 } StructMember;
 
+typedef struct TypeWithOffset TypeWithOffset;
+struct TypeWithOffset {
+    Type* type;
+    u32   offset;
+};
+
 #define TYPE_KINDS \
     TYPE_KIND(Basic, TypeBasic)                                   \
     TYPE_KIND(Pointer, struct { TypeBasic base; Type *elem; })    \
@@ -90,10 +96,12 @@ typedef struct StructMember {
         bh_table(StructMember) members;                           \
         bh_arr(StructMember *) memarr;                            \
         bh_arr(struct AstPolySolution) poly_sln;                  \
+        bh_arr(TypeWithOffset) linear_members;                    \
     })                                                            \
     TYPE_KIND(Compound, struct {                                  \
         u32 count;                                                \
         u32 size;                                                 \
+        bh_arr(TypeWithOffset) linear_members;                    \
         Type* types[];                                            \
     })                                                            \
     TYPE_KIND(Array, struct { u32 size; u32 count; Type *elem; }) \
@@ -158,6 +166,8 @@ Type* type_make_slice(bh_allocator alloc, Type* of);
 Type* type_make_dynarray(bh_allocator alloc, Type* of);
 Type* type_make_varargs(bh_allocator alloc, Type* of);
 
+void build_linear_types_with_offset(Type* type, bh_arr(TypeWithOffset)* pdest, u32 offset);
+
 const char* type_get_unique_name(Type* type);
 const char* type_get_name(Type* type);
 u32 type_get_alignment_log2(Type* type);
@@ -165,6 +175,9 @@ u32 type_get_alignment_log2(Type* type);
 b32 type_lookup_member(Type* type, char* member, StructMember* smem);
 b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem);
 
+i32 type_linear_member_count(Type* type);
+b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two);
+
 b32 type_struct_is_simple(Type* type);
 
 b32 type_is_pointer(Type* type);
index 7bccf5503b710e2a994e3033b499f0494f6ce686..b36815665b60c2cab724552447a42c1d9978f2ab 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 32a881581c122b69029e677e267136bb1d1641f1..810af05125be81971304e9c0755b9e68efbbfa54 100644 (file)
@@ -461,6 +461,10 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             size = bh_max(s_node->min_size, size);
             s_type->Struct.size = size;
 
+            s_type->Struct.linear_members = NULL;
+            bh_arr_new(global_heap_allocator, s_type->Struct.linear_members, s_type->Struct.mem_count);
+            build_linear_types_with_offset(s_type, &s_type->Struct.linear_members, 0);
+
             return s_type;
         }
 
@@ -560,6 +564,10 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
 
             bh_align(comp_type->Compound.size, 4);
 
+            comp_type->Compound.linear_members = NULL;
+            bh_arr_new(global_heap_allocator, comp_type->Compound.linear_members, comp_type->Compound.count);
+            build_linear_types_with_offset(comp_type, &comp_type->Compound.linear_members, 0);
+
             return comp_type;
         }
 
@@ -611,6 +619,10 @@ Type* type_build_compound_type(bh_allocator alloc, AstCompound* compound) {
     }
     
     bh_align(comp_type->Compound.size, 4);
+    
+    comp_type->Compound.linear_members = NULL;
+    bh_arr_new(global_heap_allocator, comp_type->Compound.linear_members, comp_type->Compound.count);
+    build_linear_types_with_offset(comp_type, &comp_type->Compound.linear_members, 0);
 
     return comp_type;
 }
@@ -661,6 +673,34 @@ Type* type_make_varargs(bh_allocator alloc, Type* of) {
     return va_type;
 }
 
+void build_linear_types_with_offset(Type* type, bh_arr(TypeWithOffset)* pdest, u32 offset) {
+    if (type_is_structlike_strict(type)) {
+        u32 mem_count = type_structlike_mem_count(type);
+        StructMember smem;
+        fori (i, 0, mem_count) {
+            type_lookup_member_by_idx(type, i, &smem);
+            build_linear_types_with_offset(smem.type, pdest, offset + smem.offset);
+        }
+
+    } else if (type->kind == Type_Kind_Compound) {
+        u32 elem_offset = 0;
+        fori (i, 0, type->Compound.count) {
+            build_linear_types_with_offset(type->Compound.types[i], pdest, offset + elem_offset);
+            elem_offset += bh_max(type_size_of(type->Compound.types[i]), 4);
+        }
+
+    } else {
+        bh_arr(TypeWithOffset) dest = *pdest;
+
+        TypeWithOffset two;
+        two.type = type;
+        two.offset = offset;
+        bh_arr_push(dest, two);
+
+        *pdest = dest;
+    }
+}
+
 const char* type_get_unique_name(Type* type) {
     if (type == NULL) return "unknown";
 
@@ -897,6 +937,54 @@ b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem) {
     }
 }
 
+i32 type_linear_member_count(Type* type) {
+    switch (type->kind) {
+        case Type_Kind_Slice:
+        case Type_Kind_VarArgs:  return 2;
+        case Type_Kind_DynArray: return 3;
+        case Type_Kind_Compound: return bh_arr_length(type->Compound.linear_members);
+        case Type_Kind_Struct:   return bh_arr_length(type->Struct.linear_members);
+        default: return 0; 
+    }
+}
+
+b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
+    switch (type->kind) {
+        case Type_Kind_Slice:
+        case Type_Kind_VarArgs: {
+            if (idx == 0) { 
+                two->type = type->Slice.ptr_to_data;
+                two->offset = 0;
+            }
+            if (idx == 1) {
+                two->type = &basic_types[Basic_Kind_U32];
+                two->offset = 8;
+            }
+
+            return 1;
+        }
+        case Type_Kind_DynArray: {
+            if (idx == 0) { 
+                two->type = type->DynArray.ptr_to_data;
+                two->offset = 0;
+            }
+            if (idx == 1) {
+                two->type = &basic_types[Basic_Kind_U32];
+                two->offset = 8;
+            }
+            if (idx == 2) {
+                two->type = &basic_types[Basic_Kind_U32];
+                two->offset = 12;
+            }
+
+            return 1;
+        }
+        case Type_Kind_Compound: *two = type->Compound.linear_members[idx]; return 1;
+        case Type_Kind_Struct:   *two = type->Struct.linear_members[idx];   return 1;
+        default: return 0; 
+    }
+}
+
 b32 type_struct_is_simple(Type* type) {
     if (type->kind != Type_Kind_Struct) return 0;
 
index 6baf25ca21c24f3813fe7cccfe80e733a36f2361..c8e7630836e755ab0caef15aba7b82613159940a 100644 (file)
@@ -485,7 +485,7 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type
 
             case Ast_Kind_Type_Compound: {
                 if (elem.actual->kind != Type_Kind_Compound) break;
-                if (bh_arr_length(elem.actual->Compound.types) != bh_arr_length(((AstCompoundType *) elem.type_expr)->types)) break;
+                if (elem.actual->Compound.count != (u32) bh_arr_length(((AstCompoundType *) elem.type_expr)->types)) break;
 
                 AstCompoundType* ct = (AstCompoundType *) elem.type_expr;
 
index 3979338784b4d61a7e822f9f702ab538bd0bb6fd..6df6946dc33836fb0d19076ce8bfbedd57fa700e 100644 (file)
@@ -1994,35 +1994,35 @@ EMIT_FUNC(struct_store, Type* type, u64 offset) {
     u64 loc_idx = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
     WIL(WI_LOCAL_SET, loc_idx);
 
-    StructMember smem;
+    bh_arr(u64) temp_locals = NULL;
+    bh_arr_new(global_heap_allocator, temp_locals, 4);
 
-    u32 mem_count = type_structlike_mem_count(type);
-    forir (i, mem_count - 1, 0) {
-        type_lookup_member_by_idx(type, i, &smem);
+    TypeWithOffset two;
 
-        if (type_is_structlike_strict(smem.type)) {
-            if (bh_arr_last(code).type == WI_LOCAL_SET && (u64) bh_arr_last(code).data.l == loc_idx) {
-                bh_arr_last(code).type = WI_LOCAL_TEE;
-            } else {
-                WIL(WI_LOCAL_GET, loc_idx);
-            }
+    u32 elem_count = type_linear_member_count(type);
+    forir (i, elem_count - 1, 0) {
+        type_linear_member_lookup(type, i, &two);
 
-            emit_struct_store(mod, &code, smem.type, offset + smem.offset);
+        WasmType wt = onyx_type_to_wasm_type(two.type);
+        u64 tmp_idx = local_raw_allocate(mod->local_alloc, wt);
 
-        } else {
-            WasmType wt = onyx_type_to_wasm_type(smem.type);
-            u64 tmp_idx = local_raw_allocate(mod->local_alloc, wt);
+        bh_arr_push(temp_locals, tmp_idx);
+        WIL(WI_LOCAL_SET, tmp_idx);
+    }
 
-            WIL(WI_LOCAL_SET, tmp_idx);
-            WIL(WI_LOCAL_GET, loc_idx);
-            WIL(WI_LOCAL_GET, tmp_idx);
+    fori (i, 0, elem_count) {
+        type_linear_member_lookup(type, i, &two);
 
-            emit_store_instruction(mod, &code, smem.type, offset + smem.offset);
+        u64 tmp_idx = bh_arr_pop(temp_locals); 
+        WIL(WI_LOCAL_GET, loc_idx);
+        WIL(WI_LOCAL_GET, tmp_idx);
+        emit_store_instruction(mod, &code, two.type, offset + two.offset);
 
-            local_raw_free(mod->local_alloc, wt);
-        }
+        WasmType wt = onyx_type_to_wasm_type(two.type);
+        local_raw_free(mod->local_alloc, wt);
     }
 
+    bh_arr_free(temp_locals);
     local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
 
     *pcode = code;