From: Brendan Hansen Date: Tue, 12 Jan 2021 16:13:38 +0000 (-0600) Subject: finalized returning multiple values X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=5e7b969ad989c810d56b8ce918006a75147ec4a4;p=onyx.git finalized returning multiple values --- diff --git a/bin/onyx b/bin/onyx index c9a1216e..795bdb46 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 83880b4d..879d89a9 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1043,6 +1043,7 @@ static inline CallingConvention type_function_get_cc(Type* type) { if (type->Function.return_type->kind == Type_Kind_Struct) return CC_Return_Stack; if (type->Function.return_type->kind == Type_Kind_Slice) return CC_Return_Stack; if (type->Function.return_type->kind == Type_Kind_DynArray) return CC_Return_Stack; + if (type->Function.return_type->kind == Type_Kind_Compound) return CC_Return_Stack; return CC_Return_Wasm; } diff --git a/onyx.exe b/onyx.exe index b503b6cb..d254d18e 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 12f47cc2..03ffaf50 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1474,7 +1474,13 @@ CheckStatus check_block(AstBlock* block) { onyx_report_error((*value)->token->pos, "Unable to resolve type for local '%b'.", (*value)->token->text, (*value)->token->length); - return 1; + return Check_Error; + } + + if ((*value)->type->kind == Type_Kind_Compound) { + onyx_report_error((*value)->token->pos, + "Compound type not allowed as local variable type. Try splitting this into multiple variables."); + return Check_Error; } } @@ -1510,6 +1516,14 @@ CheckStatus check_overloaded_function(AstOverloadedFunction* func) { CheckStatus check_struct(AstStructType* s_node) { // NOTE: fills in the stcache type_build_from_ast(semstate.allocator, (AstType *) s_node); + if (s_node->stcache == NULL) return Check_Error; + + bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) { + if ((*smem)->type->kind == Type_Kind_Compound) { + onyx_report_error(s_node->token->pos, "Compound types are not allowed as struct member types."); + return Check_Error; + } + } return Check_Success; } @@ -1574,6 +1588,11 @@ CheckStatus check_function_header(AstFunction* func) { return Check_Error; } + if (local->type->kind == Type_Kind_Compound) { + onyx_report_error(param->local->token->pos, "Compound types are not allowed as parameter types. Try splitting this into multiple parameters."); + return Check_Error; + } + // NOTE: I decided to make parameter default values not type checked against // the actual parameter type. The actual type checking will happen in check_call // when the default value is used as an argument and then has to be checked against diff --git a/src/onyxclone.c b/src/onyxclone.c index dcb73be1..02200203 100644 --- a/src/onyxclone.c +++ b/src/onyxclone.c @@ -58,6 +58,7 @@ static inline i32 ast_kind_to_size(AstNode* node) { case Ast_Kind_Enum_Type: return sizeof(AstEnumType); case Ast_Kind_Type_Alias: return sizeof(AstTypeAlias); case Ast_Kind_Type_Raw_Alias: return sizeof(AstTypeRawAlias); + case Ast_Kind_Type_Compound: return sizeof(AstCompoundType); case Ast_Kind_Type_End: return 0; case Ast_Kind_Struct_Member: return sizeof(AstStructMember); case Ast_Kind_Enum_Value: return sizeof(AstEnumValue); @@ -89,6 +90,7 @@ static inline i32 ast_kind_to_size(AstNode* node) { case Ast_Kind_Switch: return sizeof(AstSwitch); case Ast_Kind_Switch_Case: return sizeof(AstSwitchCase); case Ast_Kind_Directive_Solidify: return sizeof(AstDirectiveSolidify); + case Ast_Kind_Compound: return sizeof(AstCompound); case Ast_Kind_Count: return 0; } @@ -342,6 +344,19 @@ AstNode* ast_clone(bh_allocator a, void* n) { break; } + case Ast_Kind_Type_Compound: { + AstCompoundType* cd = (AstCompoundType *) nn; + AstCompoundType* cs = (AstCompoundType *) node; + + cd->types = NULL; + bh_arr_new(global_heap_allocator, cd->types, bh_arr_length(cs->types)); + + bh_arr_each(AstType *, type, cs->types) { + bh_arr_push(cd->types, (AstType *) ast_clone(a, (AstNode *) *type)); + } + break; + } + case Ast_Kind_Function_Type: ((AstFunctionType *) nn)->return_type = (AstType *) ast_clone(a, ((AstFunctionType *) node)->return_type); ((AstFunctionType *) nn)->param_count = ((AstFunctionType *) node)->param_count; @@ -407,6 +422,19 @@ AstNode* ast_clone(bh_allocator a, void* n) { break; } + + case Ast_Kind_Compound: { + AstCompound* cd = (AstCompound *) nn; + AstCompound* cs = (AstCompound *) node; + + cd->exprs = NULL; + bh_arr_new(global_heap_allocator, cd->exprs, bh_arr_length(cs->exprs)); + + bh_arr_each(AstTyped *, expr, cs->exprs) { + bh_arr_push(cd->exprs, (AstTyped *) ast_clone(a, (AstNode *) *expr)); + } + break; + } } return nn; diff --git a/src/onyxparser.c b/src/onyxparser.c index e8e5a403..51277e20 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1441,6 +1441,30 @@ static void parse_polymorphic_variable(OnyxParser* parser, AstType*** next_inser } } +static AstType* parse_compound_type(OnyxParser* parser) { + AstType* first = parse_type(parser); + + if (parser->curr->type == ',') { + AstCompoundType* ctype = make_node(AstCompoundType, Ast_Kind_Type_Compound); + ctype->token = parser->curr; + + bh_arr_new(global_heap_allocator, ctype->types, 2); + bh_arr_push(ctype->types, first); + + while (parser->curr->type == ',') { + if (parser->hit_unexpected_token) return (AstType *) ctype; + consume_token(parser); + + bh_arr_push(ctype->types, parse_type(parser)); + } + + return (AstType *) ctype; + + } else { + return first; + } +} + // // '^' static AstType* parse_type(OnyxParser* parser) { @@ -1613,7 +1637,7 @@ static AstType* parse_type(OnyxParser* parser) { case '(': { expect_token(parser, '('); - *next_insertion = parse_type(parser); + *next_insertion = parse_compound_type(parser); next_insertion = NULL; expect_token(parser, ')'); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 5cc05d9c..ea0d9e8e 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -209,6 +209,14 @@ AstType* symres_type(AstType* type) { return type; } + if (type->kind == Ast_Kind_Type_Compound) { + AstCompoundType* ctype = (AstCompoundType *) type; + + bh_arr_each(AstType *, type, ctype->types) { + *type = symres_type(*type); + } + } + return type; } diff --git a/src/onyxtypes.c b/src/onyxtypes.c index e824988d..ed76107d 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -263,6 +263,7 @@ u32 type_size_of(Type* type) { case Type_Kind_Slice: return 8; case Type_Kind_VarArgs: return 8; case Type_Kind_DynArray: return 12; + case Type_Kind_Compound: return type->Compound.size; default: return 0; } } @@ -280,6 +281,7 @@ u32 type_alignment_of(Type* type) { case Type_Kind_Slice: return 4; case Type_Kind_VarArgs: return 4; case Type_Kind_DynArray: return 4; + case Type_Kind_Compound: return 8; // HACK default: return 1; } } @@ -523,6 +525,25 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { return type_build_from_ast(alloc, (AstType *) concrete); } + case Ast_Kind_Type_Compound: { + AstCompoundType* ctype = (AstCompoundType *) type_node; + + i64 type_count = bh_arr_length(ctype->types); + + Type* comp_type = bh_alloc(alloc, sizeof(Type) + sizeof(Type *) * type_count); + comp_type->kind = Type_Kind_Compound; + comp_type->Compound.size = 0; + comp_type->Compound.count = type_count; + + fori (i, 0, type_count) { + assert(ctype->types[i] != NULL); + comp_type->Compound.types[i] = type_build_from_ast(alloc, ctype->types[i]); + comp_type->Compound.size += type_size_of(comp_type->Compound.types[i]); + } + + return comp_type; + } + case Ast_Kind_Symbol: assert(("symbol node in type expression", 0)); return NULL; @@ -698,6 +719,21 @@ const char* type_get_name(Type* type) { return bh_aprintf(global_scratch_allocator, "%s", buf); } + case Type_Kind_Compound: { + char buf[512]; + fori (i, 0, 512) buf[i] = 0; + + strncat(buf, "(", 511); + fori (i, 0, type->Compound.count) { + strncat(buf, type_get_name(type->Compound.types[i]), 511); + if (i != type->Compound.count - 1) + strncat(buf, ", ", 511); + } + strncat(buf, ")", 511); + + return bh_aprintf(global_scratch_allocator, "%s", buf); + } + default: return "unknown"; } } @@ -900,7 +936,9 @@ b32 type_is_numeric(Type* type) { b32 type_is_compound(Type* type) { return type->kind != Type_Kind_Basic && type->kind != Type_Kind_Pointer - && type->kind != Type_Kind_Enum; + && type->kind != Type_Kind_Enum + && type->kind != Type_Kind_Function + && type->kind != Type_Kind_Array; } b32 type_is_simd(Type* type) { @@ -942,7 +980,7 @@ b32 type_is_structlike_strict(Type* type) { if (type->kind == Type_Kind_Struct) return 1; if (type->kind == Type_Kind_Slice) return 1; if (type->kind == Type_Kind_DynArray) return 1; - if (type->kind == Type_Kind_VarArgs) return 1; + if (type->kind == Type_Kind_VarArgs) return 1; return 0; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 5b3deb6b..24ff36ab 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -182,12 +182,25 @@ static u64 local_lookup_idx(LocalAllocator* la, u64 value) { #define WIL(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, { .l = data } })) #define WIP(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, { .p = data } })) #define EMIT_FUNC(kind, ...) static void emit_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, __VA_ARGS__) +#define STACK_SWAP(type1, type2) { \ + u64 t0 = local_raw_allocate(mod->local_alloc, type1); \ + u64 t1 = local_raw_allocate(mod->local_alloc, type2); \ + \ + WIL(WI_LOCAL_SET, t0); \ + WIL(WI_LOCAL_SET, t1); \ + WIL(WI_LOCAL_GET, t0); \ + WIL(WI_LOCAL_GET, t1); \ + \ + local_raw_free(mod->local_alloc, type1); \ + local_raw_free(mod->local_alloc, type2); \ + } EMIT_FUNC(function_body, AstFunction* fd); EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers); EMIT_FUNC(statement, AstNode* stmt); EMIT_FUNC(assignment, AstBinaryOp* assign); -EMIT_FUNC(assignment_of_array, AstBinaryOp* assign); +EMIT_FUNC(assignment_of_array, AstTyped* left, AstTyped* right); +EMIT_FUNC(compound_assignment, AstBinaryOp* assign); EMIT_FUNC(store_instruction, Type* type, u32 offset); EMIT_FUNC(load_instruction, Type* type, u32 offset); EMIT_FUNC(if, AstIfWhile* if_node); @@ -204,6 +217,7 @@ EMIT_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) EMIT_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return); EMIT_FUNC(local_location, AstLocal* local, u64* offset_return); EMIT_FUNC(memory_reservation_location, AstMemRes* memres); +EMIT_FUNC(location_return_offset, AstTyped* expr, u64* offset_return); EMIT_FUNC(location, AstTyped* expr); EMIT_FUNC(struct_load, Type* type, u64 offset); EMIT_FUNC(struct_lval, AstTyped* lval); @@ -324,7 +338,13 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { } if (assign->right->type->kind == Type_Kind_Array) { - emit_assignment_of_array(mod, &code, assign); + emit_assignment_of_array(mod, &code, assign->left, assign->right); + *pcode = code; + return; + } + + if (assign->right->type->kind == Type_Kind_Compound) { + emit_compound_assignment(mod, &code, assign); *pcode = code; return; } @@ -389,13 +409,13 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { *pcode = code; } -EMIT_FUNC(assignment_of_array, AstBinaryOp* assign) { +EMIT_FUNC(assignment_of_array, AstTyped* left, AstTyped* right) { bh_arr(WasmInstruction) code = *pcode; - Type* rtype = assign->right->type; + Type* rtype = right->type; assert(rtype->kind == Type_Kind_Array); - if (assign->right->kind == Ast_Kind_Array_Literal) { + if (right->kind == Ast_Kind_Array_Literal) { Type* elem_type = rtype; u32 elem_count = 1; while (elem_type->kind == Type_Kind_Array) { @@ -406,17 +426,17 @@ EMIT_FUNC(assignment_of_array, AstBinaryOp* assign) { u64 lptr_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32); - emit_location(mod, &code, assign->left); + emit_location(mod, &code, left); WIL(WI_LOCAL_SET, lptr_local); - AstArrayLiteral* al = (AstArrayLiteral *) assign->right; + AstArrayLiteral* al = (AstArrayLiteral *) right; fori (i, 0, elem_count) { - if (!type_is_structlike(elem_type)) + if (!type_is_compound(elem_type)) WIL(WI_LOCAL_GET, lptr_local); emit_expression(mod, &code, al->values[i]); - if (!type_is_structlike(elem_type)) { + if (!type_is_compound(elem_type)) { emit_store_instruction(mod, &code, elem_type, i * elem_size); } else { WIL(WI_LOCAL_GET, lptr_local); @@ -427,8 +447,8 @@ EMIT_FUNC(assignment_of_array, AstBinaryOp* assign) { local_raw_free(mod->local_alloc, WASM_TYPE_INT32); } else { - emit_location(mod, &code, assign->left); - emit_expression(mod, &code, assign->right); + emit_location(mod, &code, left); + emit_expression(mod, &code, right); emit_array_store(mod, &code, rtype, 0); } @@ -436,6 +456,42 @@ EMIT_FUNC(assignment_of_array, AstBinaryOp* assign) { return; } +EMIT_FUNC(compound_assignment, AstBinaryOp* assign) { + bh_arr(WasmInstruction) code = *pcode; + + emit_expression(mod, &code, assign->right); + + AstCompound* compound_lval = (AstCompound *) assign->left; + bh_arr_rev_each(AstTyped *, plval, compound_lval->exprs) { + AstTyped *lval = *plval; + + if (type_is_structlike_strict(lval->type)) { + emit_struct_lval(mod, &code, lval); + continue; + } + + if (lval->kind == Ast_Kind_Local || lval->kind == Ast_Kind_Param) { + if (bh_imap_get(&mod->local_map, (u64) lval) & LOCAL_IS_WASM) { + u64 localidx = bh_imap_get(&mod->local_map, (u64) lval); + WIL(WI_LOCAL_SET, localidx); + continue; + } + } + + u64 expr_tmp = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32); + WIL(WI_LOCAL_SET, expr_tmp); + u64 offset = 0; + emit_location_return_offset(mod, &code, lval, &offset); + WIL(WI_LOCAL_GET, expr_tmp); + + local_raw_free(mod->local_alloc, WASM_TYPE_INT32); + emit_store_instruction(mod, &code, lval->type, offset); + } + + *pcode = code; + return; +} + EMIT_FUNC(store_instruction, Type* type, u32 offset) { bh_arr(WasmInstruction) code = *pcode; @@ -449,6 +505,42 @@ EMIT_FUNC(store_instruction, Type* type, u32 offset) { return; } + if (type->kind == Type_Kind_Compound) { + u64 loc_tmp = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32); + WIL(WI_LOCAL_SET, loc_tmp); + + u32 placement = offset + type_size_of(type); + forir (i, type->Compound.count - 1, 0) { + Type* curr_type = type->Compound.types[i]; + placement -= type_size_of(curr_type); + + if (type_is_compound(curr_type)) { + if (bh_arr_last(code).type == WI_LOCAL_SET && (u64) bh_arr_last(code).data.l == loc_tmp) { + bh_arr_last(code).type = WI_LOCAL_TEE; + } else { + WIL(WI_LOCAL_GET, loc_tmp); + } + + emit_store_instruction(mod, &code, curr_type, placement); + } else { + WasmType wt = onyx_type_to_wasm_type(curr_type); + u64 tmp_idx = local_raw_allocate(mod->local_alloc, wt); + + WIL(WI_LOCAL_SET, tmp_idx); + WIL(WI_LOCAL_GET, loc_tmp); + WIL(WI_LOCAL_GET, tmp_idx); + + emit_store_instruction(mod, &code, curr_type, placement); + + local_raw_free(mod->local_alloc, wt); + } + } + + local_raw_free(mod->local_alloc, WASM_TYPE_INT32); + *pcode = code; + return; + } + if (type->kind == Type_Kind_Enum) { type = type->Enum.backing; } @@ -505,6 +597,23 @@ EMIT_FUNC(load_instruction, Type* type, u32 offset) { return; } + if (type->kind == Type_Kind_Compound) { + u64 loc_tmp = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32); + WIL(WI_LOCAL_TEE, loc_tmp); + + u32 accum_offset = offset; + fori (i, 0, type->Compound.count) { + if (i != 0) WIL(WI_LOCAL_GET, loc_tmp); + + emit_load_instruction(mod, &code, type->Compound.types[i], accum_offset); + accum_offset += type_size_of(type->Compound.types[i]); + } + + local_raw_free(mod->local_alloc, WASM_TYPE_INT32); + *pcode = code; + return; + } + if (type->kind == Type_Kind_Enum) { type = type->Enum.backing; } @@ -1223,8 +1332,8 @@ EMIT_FUNC(call, AstCall* call) { bh_arr_each(AstArgument *, parg, call->arg_arr) { AstArgument* arg = *parg; - b32 place_on_stack = 0; - b32 arg_is_struct = type_is_structlike(arg->value->type); + b32 place_on_stack = 0; + b32 arg_is_compound = type_is_compound(arg->value->type); if (arg->va_kind != VA_Kind_Not_VA) { if (vararg_offset == 0xffffffff) vararg_offset = stack_grow_amm; @@ -1232,7 +1341,7 @@ EMIT_FUNC(call, AstCall* call) { } if (type_get_param_pass(arg->value->type) == Param_Pass_By_Implicit_Pointer) place_on_stack = 1; - if (place_on_stack && !arg_is_struct) WID(WI_GLOBAL_GET, stack_top_idx); + if (place_on_stack && !arg_is_compound) WID(WI_GLOBAL_GET, stack_top_idx); if (stack_grow_amm != 0) { stack_top_store_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32); @@ -1255,7 +1364,7 @@ EMIT_FUNC(call, AstCall* call) { } if (place_on_stack) { - if (arg_is_struct) WID(WI_GLOBAL_GET, stack_top_idx); + if (arg_is_compound) WID(WI_GLOBAL_GET, stack_top_idx); emit_store_instruction(mod, &code, arg->value->type, stack_grow_amm); if (arg->va_kind != VA_Kind_Not_VA) vararg_count += 1; @@ -1951,7 +2060,7 @@ EMIT_FUNC(array_store, Type* type, u32 offset) { // greater than like 16 we output a loop that copies them? // - brendanfh 2020/12/16 fori (i, 0, elem_count) { - if (!type_is_structlike(elem_type)) + if (!type_is_compound(elem_type)) WIL(WI_LOCAL_GET, lptr_local); if (bh_arr_last(code).type == WI_LOCAL_SET && (u64) bh_arr_last(code).data.l == rptr_local) @@ -1960,7 +2069,7 @@ EMIT_FUNC(array_store, Type* type, u32 offset) { WIL(WI_LOCAL_GET, rptr_local); emit_load_instruction(mod, &code, elem_type, i * elem_size); - if (!type_is_structlike(elem_type)) { + if (!type_is_compound(elem_type)) { emit_store_instruction(mod, &code, elem_type, i * elem_size + offset); } else { WIL(WI_LOCAL_GET, lptr_local); @@ -1986,12 +2095,12 @@ EMIT_FUNC(array_literal, AstArrayLiteral* al) { u32 elem_size = type_size_of(al->type->Array.elem); fori (i, 0, al->type->Array.count) { - if (!type_is_structlike(al->type->Array.elem)) + if (!type_is_compound(al->type->Array.elem)) WIL(WI_LOCAL_GET, mod->stack_base_idx); emit_expression(mod, &code, al->values[i]); - if (!type_is_structlike(al->type->Array.elem)) { + if (!type_is_compound(al->type->Array.elem)) { emit_store_instruction(mod, &code, al->type->Array.elem, local_offset + i * elem_size); } else { WIL(WI_LOCAL_GET, mod->stack_base_idx); @@ -2016,52 +2125,38 @@ EMIT_FUNC(range_literal, AstRangeLiteral* range) { *pcode = code; } -EMIT_FUNC(location, AstTyped* expr) { +EMIT_FUNC(location_return_offset, AstTyped* expr, u64* offset_return) { bh_arr(WasmInstruction) code = *pcode; switch (expr->kind) { case Ast_Kind_Param: case Ast_Kind_Local: { - u64 offset = 0; - emit_local_location(mod, &code, (AstLocal *) expr, &offset); - if (offset != 0) { - WID(WI_I32_CONST, offset); - WI(WI_I32_ADD); - } + emit_local_location(mod, &code, (AstLocal *) expr, offset_return); break; } case Ast_Kind_Dereference: { emit_expression(mod, &code, ((AstDereference *) expr)->expr); + *offset_return = 0; break; } case Ast_Kind_Array_Access: { AstArrayAccess* aa = (AstArrayAccess *) expr; - u64 offset = 0; - emit_array_access_location(mod, &code, aa, &offset); - if (offset != 0) { - WID(WI_I32_CONST, offset); - WI(WI_I32_ADD); - } + emit_array_access_location(mod, &code, aa, offset_return); break; } case Ast_Kind_Field_Access: { AstFieldAccess* field = (AstFieldAccess *) expr; - - u64 offset = 0; - emit_field_access_location(mod, &code, field, &offset); - if (offset != 0) { - WID(WI_I32_CONST, offset); - WI(WI_I32_ADD); - } + emit_field_access_location(mod, &code, field, offset_return); break; } case Ast_Kind_Memres: { AstMemRes* memres = (AstMemRes *) expr; WID(WI_I32_CONST, memres->addr); + *offset_return = 0; break; } @@ -2074,6 +2169,19 @@ EMIT_FUNC(location, AstTyped* expr) { *pcode = code; } +EMIT_FUNC(location, AstTyped* expr) { + bh_arr(WasmInstruction) code = *pcode; + + u64 offset = 0; + emit_location_return_offset(mod, &code, expr, &offset); + if (offset != 0) { + WID(WI_I32_CONST, offset); + WI(WI_I32_ADD); + } + + *pcode = code; +} + EMIT_FUNC(expression, AstTyped* expr) { bh_arr(WasmInstruction) code = *pcode; @@ -2322,15 +2430,26 @@ EMIT_FUNC(expression, AstTyped* expr) { break; } + case Ast_Kind_Compound: { + AstCompound* compound = (AstCompound *) expr; + + bh_arr_each(AstTyped *, expr, compound->exprs) { + emit_expression(mod, &code, *expr); + } + break; + } + default: bh_printf("Unhandled case: %d\n", expr->kind); DEBUG_HERE; assert(0); } + // FIX: This is going to be wrong for structs and compound types. if (expr->flags & Ast_Flag_Expr_Ignored && - !type_results_in_void(expr->type)) + !type_results_in_void(expr->type)) { WI(WI_DROP); + } *pcode = code; } @@ -2415,7 +2534,7 @@ EMIT_FUNC(return, AstReturn* ret) { if (ret->expr) { if (mod->curr_cc == CC_Return_Stack) { - if (type_is_structlike_strict(ret->expr->type)) { + if (type_is_compound(ret->expr->type)) { emit_expression(mod, &code, ret->expr); WIL(WI_LOCAL_GET, mod->stack_base_idx);