From: Brendan Hansen Date: Wed, 11 Jan 2023 20:09:22 +0000 (-0600) Subject: code cleanup and devious bug fixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8cf35e11e4bbc47fb593fb283ee776796689f216;p=onyx.git code cleanup and devious bug fixes --- diff --git a/compiler/src/checker.c b/compiler/src/checker.c index d8fa6066..1b6888a8 100644 --- a/compiler/src/checker.c +++ b/compiler/src/checker.c @@ -719,6 +719,7 @@ CheckStatus check_call(AstCall** pcall) { filename->kind = Ast_Kind_StrLit; filename->token = str_token; filename->data_id = 0; + filename->type_node = builtin_string_type; add_entities_for_node(NULL, (AstNode *) filename, NULL, NULL); callsite->filename = filename; @@ -2150,7 +2151,10 @@ CheckStatus check_expression(AstTyped** pexpr) { retval = check_directive_export_name((AstDirectiveExportName *) expr); break; - case Ast_Kind_StrLit: break; + case Ast_Kind_StrLit: + if (expr->type == NULL) YIELD(expr->token->pos, "Waiting to know string literals type. This is a weird one...") ; + break; + case Ast_Kind_File_Contents: break; case Ast_Kind_Overloaded_Function: break; case Ast_Kind_Enum_Value: break; @@ -3403,6 +3407,7 @@ void check_entity(Entity* ent) { case Entity_Type_Enum_Value: cs = check_expression(&ent->enum_value->value); break; case Entity_Type_Process_Directive: cs = check_process_directive((AstNode *) ent->expr); break; + case Entity_Type_String_Literal: case Entity_Type_Expression: cs = check_expression(&ent->expr); resolve_expression_type(ent->expr); diff --git a/compiler/src/types.c b/compiler/src/types.c index db6d5b70..6498d188 100644 --- a/compiler/src/types.c +++ b/compiler/src/types.c @@ -1336,21 +1336,6 @@ i32 type_get_idx_of_linear_member_with_offset(Type* type, u32 offset) { } } -/*b32 type_struct_is_simple(Type* type) { - if (type->kind != Type_Kind_Struct) return 0; - - b32 is_simple = 1; - bh_arr_each(StructMember *, mem, type->Struct.memarr) { - if (type_linear_member_count((*mem)->type) != 1 - (*mem)->type->kind == Type_Kind_Array) { - is_simple = 0; - break; - } - } - - return is_simple; -}*/ - b32 type_is_pointer(Type* type) { if (type == NULL) return 0; return type->kind == Type_Kind_Pointer; diff --git a/compiler/src/utils.c b/compiler/src/utils.c index 61b47677..e5b42d5b 100644 --- a/compiler/src/utils.c +++ b/compiler/src/utils.c @@ -948,6 +948,9 @@ typedef enum ArgState { TypeMatch check_arguments_against_type(Arguments* args, TypeFunction* func_type, VarArgKind* va_kind, OnyxToken* location, char* func_name, OnyxError* error) { + // In this function, if error is not NULL, then it is assumed that permanent changes can + // be made. Otherwise, permanent changes should be avoided; only detecting issues should be done. + b32 permanent = location != NULL; if (func_name == NULL) func_name = "UNKNOWN FUNCTION"; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 1855cdc6..44732b71 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -36,11 +36,6 @@ static b32 onyx_type_is_stored_in_memory(Type *type) { static WasmType onyx_type_to_wasm_type(Type* type) { if (onyx_type_is_stored_in_memory(type)) { - /*if (type_linear_member_count(type) == 1) { - return onyx_type_to_wasm_type(type->Struct.linear_members[0].type); - }*/ - - // :StructAsm return WASM_TYPE_PTR; } @@ -486,6 +481,7 @@ enum StructuredBlockType { #endif #define EMIT_FUNC(kind, ...) static void emit_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, __VA_ARGS__) +#define EMIT_FUNC_RETURNING(ret_type, kind, ...) static ret_type emit_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, __VA_ARGS__) #define EMIT_FUNC_NO_ARGS(kind) static void emit_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode) #define STACK_SWAP(token, type1, type2) { \ u64 t0 = local_raw_allocate(mod->local_alloc, type1); \ @@ -502,56 +498,59 @@ enum StructuredBlockType { #define SUBMIT_PATCH(patch_arr, offset) bh_arr_push((patch_arr), ((PatchInfo) { bh_arr_length(code) - offset })) #define NEXT_DATA_ID(mod) ((u32) bh_arr_length((mod)->data) + 1) -EMIT_FUNC(function_body, AstFunction* fd); -EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers); -EMIT_FUNC(statement, AstNode* stmt); -EMIT_FUNC(local_allocation, AstTyped* stmt); +EMIT_FUNC(function_body, AstFunction* fd); +EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers); +EMIT_FUNC(statement, AstNode* stmt); +EMIT_FUNC_RETURNING(u64, local_allocation, AstTyped* stmt); EMIT_FUNC_NO_ARGS(free_local_allocations); -EMIT_FUNC(data_relocation, u32 data_id); -EMIT_FUNC(assignment, 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(flip_and_store_instruction, AstTyped *lval, OnyxToken *token); -EMIT_FUNC(generic_store_instruction, AstTyped *lval, OnyxToken *token); -EMIT_FUNC(load_instruction, Type* type, u32 offset); -EMIT_FUNC(load_with_ignored_instruction, Type* type, u32 offset, i32 ignored_value_count); -EMIT_FUNC(if, AstIfWhile* if_node); -EMIT_FUNC(while, AstIfWhile* while_node); -EMIT_FUNC(for, AstFor* for_node); -EMIT_FUNC(switch, AstSwitch* switch_node); -EMIT_FUNC(defer, AstDefer* defer); -EMIT_FUNC(defer_code, WasmInstruction* deferred_code, u32 code_count); -EMIT_FUNC(deferred_stmt, DeferredStmt deferred_stmt); +EMIT_FUNC(data_relocation, u32 data_id); +EMIT_FUNC(assignment, 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(flip_and_store_instruction, AstTyped *lval, OnyxToken *token); +EMIT_FUNC(generic_store_instruction, AstTyped *lval, OnyxToken *token); +EMIT_FUNC(load_instruction, Type* type, u32 offset); +EMIT_FUNC(load_with_ignored_instruction, Type* type, u32 offset, i32 ignored_value_count); +EMIT_FUNC(if, AstIfWhile* if_node); +EMIT_FUNC(while, AstIfWhile* while_node); +EMIT_FUNC(for, AstFor* for_node); +EMIT_FUNC(switch, AstSwitch* switch_node); +EMIT_FUNC(defer, AstDefer* defer); +EMIT_FUNC(defer_code, WasmInstruction* deferred_code, u32 code_count); +EMIT_FUNC(deferred_stmt, DeferredStmt deferred_stmt); EMIT_FUNC_NO_ARGS(deferred_stmts); -EMIT_FUNC(remove_directive, AstDirectiveRemove* remove); -EMIT_FUNC(binop, AstBinaryOp* binop); -EMIT_FUNC(unaryop, AstUnaryOp* unop); -EMIT_FUNC(call, AstCall* call); -EMIT_FUNC(intrinsic_call, AstCall* call); -EMIT_FUNC(subscript_location, AstSubscript* sub, 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(compound_load, Type* type, u64 offset, i32 ignored_value_count); -EMIT_FUNC(compound_store, Type* type, u64 offset, b32 location_first); -EMIT_FUNC(struct_store, Type* type, u32 offset); -EMIT_FUNC(struct_literal, AstStructLiteral* sl); -EMIT_FUNC(struct_as_separate_values, Type *type, u32 offset); -EMIT_FUNC(array_store, Type* type, u32 offset); -EMIT_FUNC(array_literal, AstArrayLiteral* al); -EMIT_FUNC(range_literal, AstRangeLiteral* range); +EMIT_FUNC(remove_directive, AstDirectiveRemove* remove); +EMIT_FUNC(binop, AstBinaryOp* binop); +EMIT_FUNC(unaryop, AstUnaryOp* unop); +EMIT_FUNC(call, AstCall* call); +EMIT_FUNC(intrinsic_call, AstCall* call); +EMIT_FUNC(subscript_location, AstSubscript* sub, 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(compound_load, Type* type, u64 offset, i32 ignored_value_count); +EMIT_FUNC(compound_store, Type* type, u64 offset, b32 location_first); +EMIT_FUNC(struct_store, Type* type, u32 offset); +EMIT_FUNC(struct_literal, AstStructLiteral* sl); +EMIT_FUNC(struct_as_separate_values, Type *type, u32 offset); +EMIT_FUNC(array_store, Type* type, u32 offset); +EMIT_FUNC(array_literal, AstArrayLiteral* al); +EMIT_FUNC(range_literal, AstRangeLiteral* range); EMIT_FUNC_NO_ARGS(load_slice); -EMIT_FUNC(if_expression, AstIfExpression* if_expr); -EMIT_FUNC(do_block, AstDoBlock* doblock); -EMIT_FUNC(expression, AstTyped* expr); -EMIT_FUNC(cast, AstUnaryOp* cast); -EMIT_FUNC(return, AstReturn* ret); -EMIT_FUNC(stack_enter, u64 stacksize); -EMIT_FUNC(zero_value, WasmType wt); -EMIT_FUNC(zero_value_for_type, Type* type, OnyxToken* where, AstTyped *alloc_node); +EMIT_FUNC(if_expression, AstIfExpression* if_expr); +EMIT_FUNC(do_block, AstDoBlock* doblock); +EMIT_FUNC(expression, AstTyped* expr); +EMIT_FUNC(cast, AstUnaryOp* cast); +EMIT_FUNC(return, AstReturn* ret); +EMIT_FUNC(stack_enter, u64 stacksize); +EMIT_FUNC(zero_value, WasmType wt); +EMIT_FUNC(zero_value_for_type, Type* type, OnyxToken* where, AstTyped *alloc_node); +EMIT_FUNC(stack_address, u32 offset, OnyxToken *token); +EMIT_FUNC(values_into_contiguous_memory, u64 base_ptr_local, Type *type, u32 offset, i32 value_count, AstTyped **values); + EMIT_FUNC(enter_structured_block, StructuredBlockType sbt, OnyxToken* block_token); EMIT_FUNC_NO_ARGS(leave_structured_block); @@ -733,7 +732,7 @@ EMIT_FUNC(statement, AstNode* stmt) { *pcode = code; } -EMIT_FUNC(local_allocation, AstTyped* stmt) { +EMIT_FUNC_RETURNING(u64, local_allocation, AstTyped* stmt) { // // If the statement does not have a type, it should not // be emitted. The only case this should be used by is @@ -742,7 +741,7 @@ EMIT_FUNC(local_allocation, AstTyped* stmt) { if (stmt->type == NULL) { assert(stmt->kind == Ast_Kind_Local); onyx_report_warning(stmt->token->pos, "Unused local variable with unassigned type."); - return; + return 0; } u64 local_idx = local_allocate(mod->local_alloc, stmt); @@ -780,6 +779,8 @@ EMIT_FUNC(local_allocation, AstTyped* stmt) { .depth = bh_arr_length(mod->structured_jump_target), .expr = stmt, })); + + return local_idx; } EMIT_FUNC_NO_ARGS(free_local_allocations) { @@ -813,21 +814,32 @@ EMIT_FUNC(data_relocation, u32 data_id) { *pcode = code; } -EMIT_FUNC(assignment, AstBinaryOp* assign) { +EMIT_FUNC(stack_address, u32 offset, OnyxToken *token) { bh_arr(WasmInstruction) code = *pcode; + WIL(token, WI_LOCAL_GET, mod->stack_base_idx); + + if (offset > 0) { + WIL(token, WI_PTR_CONST, offset); + WI(token, WI_PTR_ADD); + } + + *pcode = code; +} + +EMIT_FUNC(assignment, AstBinaryOp* assign) { if (assign->right->type->kind == Type_Kind_Array) { - emit_assignment_of_array(mod, &code, assign->left, assign->right); - *pcode = code; + emit_assignment_of_array(mod, pcode, assign->left, assign->right); return; } if (assign->right->type->kind == Type_Kind_Compound) { - emit_compound_assignment(mod, &code, assign); - *pcode = code; + emit_compound_assignment(mod, pcode, assign); return; } + bh_arr(WasmInstruction) code = *pcode; + AstTyped* lval = assign->left; if (lval->kind == Ast_Kind_Local || lval->kind == Ast_Kind_Param) { @@ -849,23 +861,6 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { } } - /* - if (lval->kind == Ast_Kind_Field_Access) { - // :StructAsm - // This code was never right anyway... - AstFieldAccess* fa = (AstFieldAccess *) lval; - if (fa->expr->kind == Ast_Kind_Param && type_is_structlike_strict(fa->expr->type)) { - emit_expression(mod, &code, assign->right); - - u64 localidx = bh_imap_get(&mod->local_map, (u64) fa->expr); - WIL(assign->token, WI_LOCAL_SET, localidx + fa->idx); - - *pcode = code; - return; - } - } - */ - if (lval->kind == Ast_Kind_Global) { emit_expression(mod, &code, assign->right); @@ -876,6 +871,23 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { return; } + if (assign->right->kind == Ast_Kind_Struct_Literal && onyx_type_is_stored_in_memory(assign->right->type)) { + u64 offset = 0; + emit_location_return_offset(mod, &code, lval, &offset); + + u64 base_ptr_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_PTR); + WIL(NULL, WI_LOCAL_SET, base_ptr_local); + + AstStructLiteral *sl = (AstStructLiteral *) assign->right; + emit_values_into_contiguous_memory(mod, &code, base_ptr_local, + assign->right->type, offset, bh_arr_length(sl->args.values), sl->args.values); + + local_raw_free(mod->local_alloc, WASM_TYPE_PTR); + + *pcode = code; + return; + } + u64 offset = 0; emit_location_return_offset(mod, &code, lval, &offset); emit_expression(mod, &code, assign->right); @@ -968,13 +980,6 @@ EMIT_FUNC(store_instruction, Type* type, u32 offset) { return; } - /* - if (type->kind == Type_Kind_Struct) { - assert(bh_arr_length(type->Struct.linear_members) == 1); - type = type->Struct.linear_members[0].type; - } - */ - if (type->kind == Type_Kind_Enum) type = type->Enum.backing; if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type; if (type->kind == Type_Kind_Function) type = &basic_types[Basic_Kind_U32]; @@ -1091,13 +1096,6 @@ EMIT_FUNC(load_instruction, Type* type, u32 offset) { return; } - /* - if (type->kind == Type_Kind_Struct) { - assert(bh_arr_length(type->Struct.linear_members) == 1); - type = type->Struct.linear_members[0].type; - } - */ - if (type->kind == Type_Kind_Enum) type = type->Enum.backing; if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type; if (type->kind == Type_Kind_Function) type = &basic_types[Basic_Kind_U32]; @@ -2015,8 +2013,10 @@ EMIT_FUNC(call, AstCall* call) { if (arg->va_kind == VA_Kind_Not_VA) { // Non-variadic arguments on the stack need a pointer to them placed on the WASM stack. WIL(call_token, WI_LOCAL_GET, stack_top_store_local); - WID(call_token, WI_PTR_CONST, reserve_size); - WI(call_token, WI_PTR_ADD); + if (reserve_size > 0) { + WID(call_token, WI_PTR_CONST, reserve_size); + WI(call_token, WI_PTR_ADD); + } } if (arg->va_kind == VA_Kind_Any) { @@ -2024,28 +2024,33 @@ EMIT_FUNC(call, AstCall* call) { vararg_any_types[vararg_count - 1] = arg->value->type->id; } + reserve_size += type_size_of(arg->value->type); + if (arg->pass_as_any) { - u32 arg_size = type_size_of(arg->value->type); + Type *any_type = type_build_from_ast(context.ast_alloc, builtin_any_type); + assert(any_type); + + u32 arg_size = type_size_of(any_type); u64 ugly_temporary = local_raw_allocate(mod->local_alloc, WASM_TYPE_PTR); WIL(call_token, WI_LOCAL_SET, ugly_temporary); WIL(call_token, WI_LOCAL_GET, stack_top_store_local); WIL(call_token, WI_LOCAL_GET, ugly_temporary); - emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Rawptr], reserve_size + arg_size + 0); + emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Rawptr], reserve_size + 0); WIL(call_token, WI_LOCAL_GET, stack_top_store_local); WID(call_token, WI_I32_CONST, arg->value->type->id); - emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], reserve_size + arg_size + 4); + emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], reserve_size + 4); + local_raw_free(mod->local_alloc, WASM_TYPE_PTR); + WIL(call_token, WI_LOCAL_GET, stack_top_store_local); - WIL(call_token, WI_I32_CONST, reserve_size + arg_size); + WIL(call_token, WI_I32_CONST, reserve_size); WI(call_token, WI_I32_ADD); - reserve_size += 2 * POINTER_SIZE; + reserve_size += arg_size; } - - reserve_size += type_size_of(arg->value->type); } } @@ -2179,16 +2184,12 @@ EMIT_FUNC(method_call, AstBinaryOp *mcall) { // Create a local variable to store the result of the lookup. AstLocal *tmp_local = make_local_with_type(context.ast_alloc, NULL, (*object)->type); tmp_local->flags |= Ast_Flag_Decl_Followed_By_Init; - emit_local_allocation(mod, &code, (AstTyped *) tmp_local); - - // - // Lookup information about the local variable. - u64 tmp_local_idx = bh_imap_get(&mod->local_map, (u64) tmp_local); + u64 tmp_local_idx = emit_local_allocation(mod, &code, (AstTyped *) tmp_local); b32 tmp_is_wasm_local = (b32) ((tmp_local_idx & LOCAL_IS_WASM) != 0); - u64 offset = 0; // // Do the common assignment pattern found everywhere else. + u64 offset = 0; if (!tmp_is_wasm_local) emit_local_location(mod, &code, tmp_local, &offset); emit_expression(mod, &code, (AstTyped *) *object); @@ -2752,9 +2753,15 @@ EMIT_FUNC(memory_reservation_location, AstMemRes* memres) { if (memres->threadlocal) { u64 tls_base_idx = bh_imap_get(&mod->index_map, (u64) &builtin_tls_base); - WID(NULL, WI_PTR_CONST, memres->tls_offset); - WIL(NULL, WI_GLOBAL_GET, tls_base_idx); - WI(NULL, WI_PTR_ADD); + + if (memres->tls_offset > 0) { + WID(NULL, WI_PTR_CONST, memres->tls_offset); + WIL(NULL, WI_GLOBAL_GET, tls_base_idx); + WI(NULL, WI_PTR_ADD); + + } else { + WIL(NULL, WI_GLOBAL_GET, tls_base_idx); + } } else { // :ProperLinking @@ -2854,6 +2861,26 @@ EMIT_FUNC(compound_store, Type* type, u64 offset, b32 location_first) { *pcode = code; } +EMIT_FUNC(values_into_contiguous_memory, u64 base_ptr_local, Type *type, u32 offset, i32 value_count, AstTyped **values) { + bh_arr(WasmInstruction) code = *pcode; + + assert(onyx_type_is_stored_in_memory(type)); + assert(value_count == type_structlike_mem_count(type)); + + StructMember smem; + fori (i, 0, value_count) { + type_lookup_member_by_idx(type, i, &smem); + + // CLEANUP: When emitting a structure literal inside of a structure literal, + // there should be a separate path taken to reduce the amount of redundant memory. + WIL(NULL, WI_LOCAL_GET, base_ptr_local); + emit_expression(mod, &code, values[i]); + emit_store_instruction(mod, &code, values[i]->type, smem.offset + offset); + } + + *pcode = code; +} + EMIT_FUNC(struct_literal, AstStructLiteral* sl) { bh_arr(WasmInstruction) code = *pcode; @@ -2866,31 +2893,12 @@ EMIT_FUNC(struct_literal, AstStructLiteral* sl) { return; } - emit_local_allocation(mod, &code, (AstTyped *) sl); - - u64 local_offset = (u64) bh_imap_get(&mod->local_map, (u64) sl); + u64 local_offset = emit_local_allocation(mod, &code, (AstTyped *) sl); assert((local_offset & LOCAL_IS_WASM) == 0); - i32 idx = 0; - StructMember smem; - bh_arr_each(AstTyped *, val, sl->args.values) { - type_lookup_member_by_idx(sl->type, idx, &smem); - - // CLEANUP: When emitting a structure literal inside of a structure literal, - // there should be a separate path taken to reduce the amount of redundant memory. - WIL(sl->token, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, *val); - emit_store_instruction(mod, &code, (*val)->type, smem.offset + local_offset); - - idx += 1; - } - - WIL(sl->token, WI_LOCAL_GET, mod->stack_base_idx); - - if (local_offset > 0) { - WIL(sl->token, WI_PTR_CONST, local_offset); - WI(sl->token, WI_PTR_ADD); - } + emit_values_into_contiguous_memory(mod, &code, mod->stack_base_idx, + sl->type, local_offset, bh_arr_length(sl->args.values), sl->args.values); + emit_stack_address(mod, &code, local_offset, sl->token); *pcode = code; } @@ -3078,9 +3086,7 @@ EMIT_FUNC(array_store, Type* type, u32 offset) { EMIT_FUNC(array_literal, AstArrayLiteral* al) { bh_arr(WasmInstruction) code = *pcode; - emit_local_allocation(mod, &code, (AstTyped *) al); - - u64 local_offset = (u64) bh_imap_get(&mod->local_map, (u64) al); + u64 local_offset = emit_local_allocation(mod, &code, (AstTyped *) al); assert((local_offset & LOCAL_IS_WASM) == 0); assert(al->type->kind == Type_Kind_Array); @@ -3105,22 +3111,12 @@ EMIT_FUNC(array_literal, AstArrayLiteral* al) { EMIT_FUNC(range_literal, AstRangeLiteral* range) { bh_arr(WasmInstruction) code = *pcode; - // nocheckin TODO ABSTRACT THIS PATTERN!!!!!!!!!! - emit_local_allocation(mod, &code, (AstTyped *) range); - u64 local_offset = (u64) bh_imap_get(&mod->local_map, (u64) range); + u64 local_offset = emit_local_allocation(mod, &code, (AstTyped *) range); assert((local_offset & LOCAL_IS_WASM) == 0); - WIL(range->token, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, range->low); - emit_store_instruction(mod, &code, &basic_types[Basic_Kind_I32], local_offset + 0); - - WIL(range->token, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, range->high); - emit_store_instruction(mod, &code, &basic_types[Basic_Kind_I32], local_offset + 4); - - WIL(range->token, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, range->step); - emit_store_instruction(mod, &code, &basic_types[Basic_Kind_I32], local_offset + 8); + AstTyped *values[] = { range->low, range->high, range->step }; + emit_values_into_contiguous_memory(mod, &code, mod->stack_base_idx, + range->type, local_offset, 3, values); WIL(range->token, WI_LOCAL_GET, mod->stack_base_idx); @@ -3601,27 +3597,12 @@ EMIT_FUNC(expression, AstTyped* expr) { case Ast_Kind_Call_Site: { AstCallSite* callsite = (AstCallSite *) expr; - emit_local_allocation(mod, &code, (AstTyped *) callsite); - - u64 local_offset = (u64) bh_imap_get(&mod->local_map, (u64) callsite); + u64 local_offset = emit_local_allocation(mod, &code, (AstTyped *) callsite); assert((local_offset & LOCAL_IS_WASM) == 0); - StructMember smem; - - type_lookup_member_by_idx(callsite->type, 0, &smem); - WIL(NULL, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, (AstTyped *) callsite->filename); - emit_store_instruction(mod, &code, smem.type, local_offset + smem.offset); - - type_lookup_member_by_idx(callsite->type, 1, &smem); - WIL(NULL, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, (AstTyped *) callsite->line); - emit_store_instruction(mod, &code, smem.type, local_offset + smem.offset); - - type_lookup_member_by_idx(callsite->type, 2, &smem); - WIL(NULL, WI_LOCAL_GET, mod->stack_base_idx); - emit_expression(mod, &code, (AstTyped *) callsite->column); - emit_store_instruction(mod, &code, smem.type, local_offset + smem.offset); + AstTyped *values[] = { (AstTyped *) callsite->filename, (AstTyped *) callsite->line, (AstTyped *) callsite->column }; + emit_values_into_contiguous_memory(mod, &code, mod->stack_base_idx, + callsite->type, local_offset, 3, values); WIL(NULL, WI_LOCAL_GET, mod->stack_base_idx); @@ -3838,6 +3819,15 @@ EMIT_FUNC(return, AstReturn* ret) { } else { emit_expression(mod, &code, ret->expr); + + if (onyx_type_is_stored_in_memory(ret->expr->type)) { + u64 stack_top_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_top); + + WID(NULL, WI_GLOBAL_GET, stack_top_idx); + WID(NULL, WI_PTR_CONST, type_size_of(ret->expr->type)); + WI(NULL, WI_PTR_ADD); + WID(NULL, WI_GLOBAL_SET, stack_top_idx); + } } } @@ -3969,8 +3959,7 @@ static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft) { } - // :StructAsm - else if (type_is_structlike_strict(*param_type)) { + else if (onyx_type_is_multiple_wasm_values(*param_type)) { u32 mem_count = type_structlike_mem_count(*param_type); StructMember smem; @@ -4091,7 +4080,6 @@ static void emit_function(OnyxWasmModule* mod, AstFunction* fd) { bh_arr_each(AstParam, param, fd->params) { switch (type_get_param_pass(param->local->type)) { case Param_Pass_By_Value: { - // :StructAsm if (type_is_structlike_strict(param->local->type)) { debug_introduce_symbol(mod, param->local->token, DSL_REGISTER, localidx | LOCAL_IS_WASM, param->local->type); bh_imap_put(&mod->local_map, (u64) param->local, localidx | LOCAL_IS_WASM); @@ -4102,7 +4090,6 @@ static void emit_function(OnyxWasmModule* mod, AstFunction* fd) { // fallthrough } - // :StructAsm case Param_Pass_By_Implicit_Pointer: { debug_introduce_symbol(mod, param->local->token, DSL_REGISTER, localidx | LOCAL_IS_WASM, param->local->type); bh_imap_put(&mod->local_map, (u64) param->local, localidx++ | LOCAL_IS_WASM); diff --git a/core/container/iter.onyx b/core/container/iter.onyx index ed58561d..4015d4e3 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -966,26 +966,18 @@ generator_no_copy :: (ctx: ^$Ctx, gen: (^Ctx) -> ($T, bool), close: (^Ctx) -> vo if thread_count != 0 { dist := distributor(iter); - t_data := Thread_Data(iter.Iter_Type, Ctx).{ - iter = ^dist, - data = thread_data, - }; + t_data := ^.{iter = ^dist, data = thread_data}; threads := alloc.array_from_stack(thread.Thread, thread_count - 1); - for^ threads do thread.spawn(it, ^t_data, #solidify thread_function {body=body}); + for^ threads do thread.spawn(it, t_data, #solidify thread_function {body=body}); - thread_function(^t_data, body); + thread_function(t_data, body); for^ threads do thread.join(it); dist.close(dist.data); } - Thread_Data :: struct (T: type_expr, Ctx: type_expr) { - iter: ^Iterator(T); - data: ^Ctx; - } - - thread_function :: (__data: ^Thread_Data, $body: Code) { + thread_function :: (__data: ^$T, $body: Code) { thread_data := __data.data; for #no_close *__data.iter { #unquote body; diff --git a/core/runtime/common.onyx b/core/runtime/common.onyx index 6ffc3497..a3db48da 100644 --- a/core/runtime/common.onyx +++ b/core/runtime/common.onyx @@ -40,7 +40,7 @@ __runtime_initialize :: () { // Use this procedure to initialize everything needed in the // standard library when you are dropped directly into a function. -__thread_initialize :: macro () { +__thread_initialize :: () { use core.intrinsics.onyx { __initialize } // This should only be true for the main thread. diff --git a/scripts/run_tests.onyx b/scripts/run_tests.onyx index 60790cfb..eafb1cb4 100644 --- a/scripts/run_tests.onyx +++ b/scripts/run_tests.onyx @@ -100,7 +100,7 @@ main :: (args) => { failed_tests: ^[..] str; failed_tests_mutex: sync.Mutex; } - exec_context := init(Execution_Context); + exec_context := Execution_Context.{}; exec_context.compile_only = settings.compile_only; failed_tests := make([..] str); @@ -143,6 +143,11 @@ main :: (args) => { // Error running the test case print_color(.Red, "[{}] Error '{}' in test case {}.\n{}", context.thread_id, exit, it.source_file, output); thread_data.at_least_one_test_failed = true; + + sync.critical_section(^thread_data.failed_tests_mutex) { + array.push(thread_data.failed_tests, it.source_file); + } + continue; }