aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-02-25 02:47:31 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-02-25 02:47:31 -0500
commit05bf666eb690d1a1328234cc408960133dba9563 (patch)
treeebb2780706cb5b84d0502872d321838319bc9d6f /src/codegen.cpp
parent40dbcd09da27a271c5d1b0990e712bd2b2bfe68d (diff)
downloadzig-05bf666eb690d1a1328234cc408960133dba9563.tar.gz
zig-05bf666eb690d1a1328234cc408960133dba9563.zip
codegen for calling an async function
See #727
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 6b1a2513c7..ec14d85064 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2521,13 +2521,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
- if (fn_type_id->cc == CallingConventionAsync) {
- zig_panic("TODO codegen async function call");
- }
TypeTableEntry *src_return_type = fn_type_id->return_type;
bool ret_has_bits = type_has_bits(src_return_type);
- bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);
+
+ bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) &&
+ calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc);
bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdErrorSet);
size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0);
bool is_var_args = fn_type_id->is_var_args;
@@ -2541,6 +2540,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
gen_param_values[gen_param_index] = g->cur_err_ret_trace_val;
gen_param_index += 1;
}
+ if (instruction->is_async) {
+ gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator);
+ gen_param_index += 1;
+
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
+ LLVMBuildStore(g->builder, LLVMConstNull(g->builtin_types.entry_global_error_set->type_ref), err_val_ptr);
+ gen_param_values[gen_param_index] = err_val_ptr;
+ gen_param_index += 1;
+ }
for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
IrInstruction *param_instruction = instruction->args[call_i];
TypeTableEntry *param_type = param_instruction->value.type;
@@ -2578,6 +2586,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
}
+ if (instruction->is_async) {
+ LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
+ LLVMBuildStore(g->builder, result, payload_ptr);
+ return instruction->tmp_ptr;
+ }
+
if (src_return_type->id == TypeTableEntryIdUnreachable) {
return LLVMBuildUnreachable(g->builder);
} else if (!ret_has_bits) {