@@ -986,7 +986,7 @@ static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstructio
986
986
987
987
static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
988
988
FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
989
- bool is_comptime, FnInline fn_inline)
989
+ bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator )
990
990
{
991
991
IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
992
992
call_instruction->fn_entry = fn_entry;
@@ -995,21 +995,25 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
995
995
call_instruction->fn_inline = fn_inline;
996
996
call_instruction->args = args;
997
997
call_instruction->arg_count = arg_count;
998
+ call_instruction->is_async = is_async;
999
+ call_instruction->async_allocator = async_allocator;
998
1000
999
1001
if (fn_ref)
1000
1002
ir_ref_instruction(fn_ref, irb->current_basic_block);
1001
1003
for (size_t i = 0; i < arg_count; i += 1)
1002
1004
ir_ref_instruction(args[i], irb->current_basic_block);
1005
+ if (async_allocator)
1006
+ ir_ref_instruction(async_allocator, irb->current_basic_block);
1003
1007
1004
1008
return &call_instruction->base;
1005
1009
}
1006
1010
1007
1011
static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,
1008
1012
FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1009
- bool is_comptime, FnInline fn_inline)
1013
+ bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator )
1010
1014
{
1011
1015
IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,
1012
- old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline);
1016
+ old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator );
1013
1017
ir_link_new_instruction(new_instruction, old_instruction);
1014
1018
return new_instruction;
1015
1019
}
@@ -3754,7 +3758,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3754
3758
}
3755
3759
FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
3756
3760
3757
- return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline);
3761
+ return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr );
3758
3762
}
3759
3763
case BuiltinFnIdTypeId:
3760
3764
{
@@ -3888,11 +3892,17 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
3888
3892
return args[i];
3889
3893
}
3890
3894
3891
- if (node->data.fn_call_expr.is_async) {
3892
- zig_panic("TODO ir_gen_fn_call for async fn calls");
3895
+ bool is_async = node->data.fn_call_expr.is_async;
3896
+ IrInstruction *async_allocator = nullptr;
3897
+ if (is_async) {
3898
+ if (node->data.fn_call_expr.async_allocator) {
3899
+ async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope);
3900
+ if (async_allocator == irb->codegen->invalid_instruction)
3901
+ return async_allocator;
3902
+ }
3893
3903
}
3894
3904
3895
- return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto);
3905
+ return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator );
3896
3906
}
3897
3907
3898
3908
static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -10584,6 +10594,11 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
10584
10594
buf_sprintf("exported function must specify calling convention"));
10585
10595
add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
10586
10596
} break;
10597
+ case CallingConventionAsync: {
10598
+ ErrorMsg *msg = ir_add_error(ira, target,
10599
+ buf_sprintf("exported function cannot be async"));
10600
+ add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
10601
+ } break;
10587
10602
case CallingConventionC:
10588
10603
case CallingConventionNaked:
10589
10604
case CallingConventionCold:
@@ -10963,6 +10978,13 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
10963
10978
}
10964
10979
return ira->codegen->builtin_types.entry_invalid;
10965
10980
}
10981
+ if (fn_type_id->cc == CallingConventionAsync && !call_instruction->is_async) {
10982
+ ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("must use async keyword to call async function"));
10983
+ if (fn_proto_node) {
10984
+ add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here"));
10985
+ }
10986
+ return ira->codegen->builtin_types.entry_invalid;
10987
+ }
10966
10988
10967
10989
10968
10990
if (fn_type_id->is_var_args) {
@@ -11258,7 +11280,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11258
11280
11259
11281
size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count;
11260
11282
IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
11261
- impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline);
11283
+ impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, false, nullptr );
11262
11284
11263
11285
TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;
11264
11286
ir_add_alloca(ira, new_call_instruction, return_type);
@@ -11324,12 +11346,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11324
11346
11325
11347
assert(next_arg_index == call_param_count);
11326
11348
11349
+ if (call_instruction->is_async) {
11350
+ zig_panic("TODO handle async fn call");
11351
+ }
11352
+
11327
11353
TypeTableEntry *return_type = fn_type_id->return_type;
11328
11354
if (type_is_invalid(return_type))
11329
11355
return ira->codegen->builtin_types.entry_invalid;
11330
11356
11331
11357
IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
11332
- fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline);
11358
+ fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr );
11333
11359
11334
11360
ir_add_alloca(ira, new_call_instruction, return_type);
11335
11361
return ir_finish_anal(ira, return_type);
@@ -16491,7 +16517,10 @@ static TypeTableEntry *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruc
16491
16517
}
16492
16518
16493
16519
static TypeTableEntry *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
16494
- IrInstruction *casted_target = ir_implicit_cast(ira, instruction->target->other, ira->codegen->builtin_types.entry_promise);
16520
+ IrInstruction *target_inst = instruction->target->other;
16521
+ if (type_is_invalid(target_inst->value.type))
16522
+ return ira->codegen->builtin_types.entry_invalid;
16523
+ IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise);
16495
16524
if (type_is_invalid(casted_target->value.type))
16496
16525
return ira->codegen->builtin_types.entry_invalid;
16497
16526
0 commit comments