From: Brendan Hansen Date: Mon, 25 Jan 2021 03:51:05 +0000 (-0600) Subject: cleaned up struct storing X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=003a15c35dedd47f30d31c6eb0783fe3ff28880c;p=onyx.git cleaned up struct storing --- diff --git a/bin/onyx b/bin/onyx index 421a0574..3e9179c3 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxtypes.h b/include/onyxtypes.h index 16e71891..d34277d3 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -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); diff --git a/onyx.exe b/onyx.exe index 7bccf550..b3681566 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 32a88158..810af051 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -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; diff --git a/src/onyxutils.c b/src/onyxutils.c index 6baf25ca..c8e76308 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 39793387..6df6946d 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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;