| author | |
| committer | |
| log | 05bf666eb690d1a1328234cc408960133dba9563 |
| tree | ebb2780706cb5b84d0502872d321838319bc9d6f |
| parent | 40dbcd09da27a271c5d1b0990e712bd2b2bfe68d |
See #7273 files changed, 49 insertions(+), 9 deletions(-)
src/analyze.cpp+29-5| ... | @@ -986,20 +986,25 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -986,20 +986,25 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 986 | if (!skip_debug_info) { | 986 | if (!skip_debug_info) { |
| 987 | bool first_arg_return = calling_convention_does_first_arg_return(fn_type_id->cc) && | 987 | bool first_arg_return = calling_convention_does_first_arg_return(fn_type_id->cc) && |
| 988 | handle_is_ptr(fn_type_id->return_type); | 988 | handle_is_ptr(fn_type_id->return_type); |
| 989 | bool is_async = fn_type_id->cc == CallingConventionAsync; | ||
| 989 | bool prefix_arg_error_return_trace = g->have_err_ret_tracing && | 990 | bool prefix_arg_error_return_trace = g->have_err_ret_tracing && |
| 990 | (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || | 991 | (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || |
| 991 | fn_type_id->return_type->id == TypeTableEntryIdErrorSet); | 992 | fn_type_id->return_type->id == TypeTableEntryIdErrorSet); |
| 992 | // +1 for maybe making the first argument the return value | 993 | // +1 for maybe making the first argument the return value |
| 993 | // +1 for maybe last argument the error return trace | 994 | // +1 for maybe first argument the error return trace |
| 994 | LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(2 + fn_type_id->param_count); | 995 | // +2 for maybe arguments async allocator and error code pointer |
| 996 | LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(4 + fn_type_id->param_count); | ||
| 995 | // +1 because 0 is the return type and | 997 | // +1 because 0 is the return type and |
| 996 | // +1 for maybe making first arg ret val and | 998 | // +1 for maybe making first arg ret val and |
| 997 | // +1 for maybe last argument the error return trace | 999 | // +1 for maybe first argument the error return trace |
| 998 | ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(3 + fn_type_id->param_count); | 1000 | // +2 for maybe arguments async allocator and error code pointer |
| 1001 | ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(5 + fn_type_id->param_count); | ||
| 999 | param_di_types[0] = fn_type_id->return_type->di_type; | 1002 | param_di_types[0] = fn_type_id->return_type->di_type; |
| 1000 | size_t gen_param_index = 0; | 1003 | size_t gen_param_index = 0; |
| 1001 | TypeTableEntry *gen_return_type; | 1004 | TypeTableEntry *gen_return_type; |
| 1002 | if (!type_has_bits(fn_type_id->return_type)) { | 1005 | if (is_async) { |
| 1006 | gen_return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false); | ||
| 1007 | } else if (!type_has_bits(fn_type_id->return_type)) { | ||
| 1003 | gen_return_type = g->builtin_types.entry_void; | 1008 | gen_return_type = g->builtin_types.entry_void; |
| 1004 | } else if (first_arg_return) { | 1009 | } else if (first_arg_return) { |
| 1005 | TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false); | 1010 | TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false); |
| ... | @@ -1020,6 +1025,25 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -1020,6 +1025,25 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1020 | // after the gen_param_index += 1 because 0 is the return type | 1025 | // after the gen_param_index += 1 because 0 is the return type |
| 1021 | param_di_types[gen_param_index] = gen_type->di_type; | 1026 | param_di_types[gen_param_index] = gen_type->di_type; |
| 1022 | } | 1027 | } |
| 1028 | if (is_async) { | ||
| 1029 | { | ||
| 1030 | // async allocator param | ||
| 1031 | TypeTableEntry *gen_type = fn_type_id->async_allocator_type; | ||
| 1032 | gen_param_types[gen_param_index] = gen_type->type_ref; | ||
| 1033 | gen_param_index += 1; | ||
| 1034 | // after the gen_param_index += 1 because 0 is the return type | ||
| 1035 | param_di_types[gen_param_index] = gen_type->di_type; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | { | ||
| 1039 | // error code pointer | ||
| 1040 | TypeTableEntry *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false); | ||
| 1041 | gen_param_types[gen_param_index] = gen_type->type_ref; | ||
| 1042 | gen_param_index += 1; | ||
| 1043 | // after the gen_param_index += 1 because 0 is the return type | ||
| 1044 | param_di_types[gen_param_index] = gen_type->di_type; | ||
| 1045 | } | ||
| 1046 | } | ||
| 1023 | 1047 | ||
| 1024 | fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count); | 1048 | fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count); |
| 1025 | for (size_t i = 0; i < fn_type_id->param_count; i += 1) { | 1049 | for (size_t i = 0; i < fn_type_id->param_count; i += 1) { |
src/codegen.cpp+18-4| ... | @@ -2521,13 +2521,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -2521,13 +2521,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2521 | } | 2521 | } |
| 2522 | 2522 | ||
| 2523 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; | 2523 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| 2524 | if (fn_type_id->cc == CallingConventionAsync) { | ||
| 2525 | zig_panic("TODO codegen async function call"); | ||
| 2526 | } | ||
| 2527 | 2524 | ||
| 2528 | TypeTableEntry *src_return_type = fn_type_id->return_type; | 2525 | TypeTableEntry *src_return_type = fn_type_id->return_type; |
| 2529 | bool ret_has_bits = type_has_bits(src_return_type); | 2526 | bool ret_has_bits = type_has_bits(src_return_type); |
| 2530 | bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type); | 2527 | |
| 2528 | bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) && | ||
| 2529 | calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc); | ||
| 2531 | bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdErrorSet); | 2530 | bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdErrorSet); |
| 2532 | size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0); | 2531 | size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0); |
| 2533 | bool is_var_args = fn_type_id->is_var_args; | 2532 | bool is_var_args = fn_type_id->is_var_args; |
| ... | @@ -2541,6 +2540,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -2541,6 +2540,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2541 | gen_param_values[gen_param_index] = g->cur_err_ret_trace_val; | 2540 | gen_param_values[gen_param_index] = g->cur_err_ret_trace_val; |
| 2542 | gen_param_index += 1; | 2541 | gen_param_index += 1; |
| 2543 | } | 2542 | } |
| 2543 | if (instruction->is_async) { | ||
| 2544 | gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator); | ||
| 2545 | gen_param_index += 1; | ||
| 2546 | |||
| 2547 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, ""); | ||
| 2548 | LLVMBuildStore(g->builder, LLVMConstNull(g->builtin_types.entry_global_error_set->type_ref), err_val_ptr); | ||
| 2549 | gen_param_values[gen_param_index] = err_val_ptr; | ||
| 2550 | gen_param_index += 1; | ||
| 2551 | } | ||
| 2544 | for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { | 2552 | for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { |
| 2545 | IrInstruction *param_instruction = instruction->args[call_i]; | 2553 | IrInstruction *param_instruction = instruction->args[call_i]; |
| 2546 | TypeTableEntry *param_type = param_instruction->value.type; | 2554 | TypeTableEntry *param_type = param_instruction->value.type; |
| ... | @@ -2578,6 +2586,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -2578,6 +2586,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2578 | } | 2586 | } |
| 2579 | } | 2587 | } |
| 2580 | 2588 | ||
| 2589 | if (instruction->is_async) { | ||
| 2590 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, ""); | ||
| 2591 | LLVMBuildStore(g->builder, result, payload_ptr); | ||
| 2592 | return instruction->tmp_ptr; | ||
| 2593 | } | ||
| 2594 | |||
| 2581 | if (src_return_type->id == TypeTableEntryIdUnreachable) { | 2595 | if (src_return_type->id == TypeTableEntryIdUnreachable) { |
| 2582 | return LLVMBuildUnreachable(g->builder); | 2596 | return LLVMBuildUnreachable(g->builder); |
| 2583 | } else if (!ret_has_bits) { | 2597 | } else if (!ret_has_bits) { |
src/ir.cpp+2| ... | @@ -11775,6 +11775,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -11775,6 +11775,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11775 | if (call_instruction->is_async) { | 11775 | if (call_instruction->is_async) { |
| 11776 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count, async_allocator_inst); | 11776 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 11777 | ir_link_new_instruction(result, &call_instruction->base); | 11777 | ir_link_new_instruction(result, &call_instruction->base); |
| 11778 | ir_add_alloca(ira, result, result->value.type); | ||
| 11778 | return ir_finish_anal(ira, result->value.type); | 11779 | return ir_finish_anal(ira, result->value.type); |
| 11779 | } | 11780 | } |
| 11780 | 11781 | ||
| ... | @@ -11862,6 +11863,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -11862,6 +11863,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11862 | 11863 | ||
| 11863 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count, async_allocator_inst); | 11864 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count, async_allocator_inst); |
| 11864 | ir_link_new_instruction(result, &call_instruction->base); | 11865 | ir_link_new_instruction(result, &call_instruction->base); |
| 11866 | ir_add_alloca(ira, result, result->value.type); | ||
| 11865 | return ir_finish_anal(ira, result->value.type); | 11867 | return ir_finish_anal(ira, result->value.type); |
| 11866 | } | 11868 | } |
| 11867 | 11869 |