From: Brendan Hansen Date: Sun, 10 Dec 2023 02:25:16 +0000 (-0600) Subject: fixed: nested array literals causes a segfault X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=db9c7b18261c12045cee7468a8ec35e2a4029d8d;p=onyx.git fixed: nested array literals causes a segfault --- diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 95b51ef3..d47696c8 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -892,6 +892,41 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { *pcode = code; } +static void flatten_nested_array_literals_for_emit_helper(bh_arr(AstTyped *) *poutput, AstArrayLiteral *al) { + u32 elem_count = al->type->Array.count; + + if (al->type->Array.elem->kind == Type_Kind_Array) { + fori (i, 0, elem_count) { + flatten_nested_array_literals_for_emit_helper(poutput, (AstArrayLiteral *) al->values[i]); + } + + } else { + bh_arr(AstTyped *) output = *poutput; + fori (i, 0, elem_count) { + bh_arr_push(output, al->values[i]); + } + *poutput = output; + } +} + +static bh_arr(AstTyped *) flatten_nested_array_literals_for_emit(AstArrayLiteral *al, Type **elem_type) { + u32 ec = 1; + Type *et = al->type; + + while (et->kind == Type_Kind_Array) { + ec *= et->Array.count; + et = et->Array.elem; + } + + *elem_type = et; + + bh_arr(AstTyped *) result = NULL; + bh_arr_new(global_heap_allocator, result, ec); + flatten_nested_array_literals_for_emit_helper(&result, al); + + return result; +} + EMIT_FUNC(assignment_of_array, AstTyped* left, AstTyped* right) { bh_arr(WasmInstruction) code = *pcode; @@ -899,27 +934,30 @@ EMIT_FUNC(assignment_of_array, AstTyped* left, AstTyped* right) { assert(rtype->kind == Type_Kind_Array); if (right->kind == Ast_Kind_Array_Literal) { - Type* elem_type = rtype; - u32 elem_count = 1; - while (elem_type->kind == Type_Kind_Array) { - elem_count *= elem_type->Array.count; - elem_type = elem_type->Array.elem; - } + AstArrayLiteral* al = (AstArrayLiteral *) right; + + Type* elem_type; + bh_arr(AstTyped *) values = flatten_nested_array_literals_for_emit(al, &elem_type); + + u32 elem_count = bh_arr_length(values); u32 elem_size = type_size_of(elem_type); u64 lptr_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_PTR); emit_location(mod, &code, left); - WIL(left->token, WI_LOCAL_SET, lptr_local); + WIL(left->token, WI_LOCAL_TEE, lptr_local); - AstArrayLiteral* al = (AstArrayLiteral *) right; fori (i, 0, elem_count) { - WIL(left->token, WI_LOCAL_GET, lptr_local); - emit_expression(mod, &code, al->values[i]); + if (i != 0) { + WIL(left->token, WI_LOCAL_GET, lptr_local); + } + + emit_expression(mod, &code, values[i]); emit_store_instruction(mod, &code, elem_type, i * elem_size); } local_raw_free(mod->local_alloc, WASM_TYPE_PTR); + bh_arr_free(values); } else { u64 offset = 0; diff --git a/tests/nested_array_literals.onyx b/tests/nested_array_literals.onyx new file mode 100644 index 00000000..8ce8a037 --- /dev/null +++ b/tests/nested_array_literals.onyx @@ -0,0 +1,23 @@ + +use core {*} + +main :: () { + x := ([3] i32).[ + .[1, 2, 3], + .[4, 5, 6], + .[7, 8, 9] + ]; + + printf("{}\n", x); + + takes_a_nested_array(([4] i32).[ + .[ 0, 1, 2, 3 ], + .[ 1, 2, 3, 4 ], + .[ 2, 3, 4, 5 ], + ]); +} + +takes_a_nested_array :: (arr: [3] [4] i32) { + println(arr); +} + diff --git a/tests/nested_array_literals.txt b/tests/nested_array_literals.txt new file mode 100644 index 00000000..5f97376e --- /dev/null +++ b/tests/nested_array_literals.txt @@ -0,0 +1,2 @@ +[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] +[ [ 0, 1, 2, 3 ], [ 1, 2, 3, 4 ], [ 2, 3, 4, 5 ] ]