@@ -114,6 +114,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
114
114
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
115
115
static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
116
116
IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type);
117
+ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
118
+ VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr);
117
119
118
120
ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
119
121
assert(const_val->type->id == TypeTableEntryIdPointer);
@@ -2491,8 +2493,11 @@ static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *sou
2491
2493
return &instruction->base;
2492
2494
}
2493
2495
2494
- static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2496
+ static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node,
2497
+ ImplicitAllocatorId id)
2498
+ {
2495
2499
IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node);
2500
+ instruction->id = id;
2496
2501
2497
2502
return &instruction->base;
2498
2503
}
@@ -6081,15 +6086,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6081
6086
6082
6087
FnTableEntry *fn_entry = exec_fn_entry(irb->exec);
6083
6088
bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
6089
+ IrInstruction *coro_id;
6084
6090
IrInstruction *u8_ptr_type;
6085
6091
IrInstruction *const_bool_false;
6086
- IrInstruction *coro_size;
6087
- IrInstruction *coro_id;
6088
- IrInstruction *coro_promise_ptr;
6089
6092
IrInstruction *coro_result_field_ptr;
6090
- IrInstruction *coro_mem_ptr;
6091
6093
TypeTableEntry *return_type;
6092
6094
Buf *result_ptr_field_name;
6095
+ VariableTableEntry *coro_size_var;
6093
6096
if (is_async) {
6094
6097
// create the coro promise
6095
6098
const_bool_false = ir_build_const_bool(irb, scope, node, false);
@@ -6099,17 +6102,21 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6099
6102
return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
6100
6103
IrInstruction *promise_init = ir_build_const_promise_init(irb, scope, node, return_type);
6101
6104
ir_build_var_decl(irb, scope, node, promise_var, nullptr, nullptr, promise_init);
6102
- coro_promise_ptr = ir_build_var_ptr(irb, scope, node, promise_var, false, false);
6105
+ IrInstruction * coro_promise_ptr = ir_build_var_ptr(irb, scope, node, promise_var, false, false);
6103
6106
6104
6107
u8_ptr_type = ir_build_const_type(irb, scope, node,
6105
6108
get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));
6106
6109
IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);
6107
6110
coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr);
6108
- coro_size = ir_build_coro_size(irb, scope, node);
6109
- irb->exec->implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node);
6111
+ coro_size_var = ir_create_var(irb, node, scope, nullptr, false, false, true, const_bool_false);
6112
+ IrInstruction *coro_size = ir_build_coro_size(irb, scope, node);
6113
+ ir_build_var_decl(irb, scope, node, coro_size_var, nullptr, nullptr, coro_size);
6114
+ IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
6115
+ ImplicitAllocatorIdArg);
6116
+ irb->exec->coro_allocator_var = ir_create_var(irb, node, scope, nullptr, true, true, true, const_bool_false);
6117
+ ir_build_var_decl(irb, scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr);
6110
6118
Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
6111
- IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr,
6112
- alloc_field_name);
6119
+ IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name);
6113
6120
IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr);
6114
6121
IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, scope, node, alloc_fn, coro_size);
6115
6122
IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, scope, node, maybe_coro_mem_ptr);
@@ -6122,7 +6129,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6122
6129
ir_build_return(irb, scope, node, undef);
6123
6130
6124
6131
ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
6125
- coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, maybe_coro_mem_ptr);
6132
+ IrInstruction * coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, maybe_coro_mem_ptr);
6126
6133
irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem_ptr);
6127
6134
6128
6135
Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
@@ -6200,15 +6207,20 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6200
6207
IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
6201
6208
6202
6209
Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);
6203
- IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr,
6204
- free_field_name);
6210
+ IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
6211
+ ImplicitAllocatorIdLocalVar);
6212
+ IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, free_field_name);
6205
6213
IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
6206
6214
IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
6215
+ IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
6216
+ IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_mem_ptr_maybe);
6207
6217
IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
6218
+ IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var, true, false);
6219
+ IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
6208
6220
IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false);
6209
6221
size_t arg_count = 2;
6210
6222
IrInstruction **args = allocate<IrInstruction *>(arg_count);
6211
- args[0] = irb->exec-> implicit_allocator_ptr; // self
6223
+ args[0] = implicit_allocator_ptr; // self
6212
6224
args[1] = mem_slice; // old_mem
6213
6225
ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
6214
6226
@@ -11229,7 +11241,7 @@ static TypeTableEntry *ir_analyze_instruction_error_union(IrAnalyze *ira,
11229
11241
return ira->codegen->builtin_types.entry_type;
11230
11242
}
11231
11243
11232
- IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr) {
11244
+ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id ) {
11233
11245
FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
11234
11246
if (parent_fn_entry == nullptr) {
11235
11247
ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available"));
@@ -11243,9 +11255,26 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
11243
11255
}
11244
11256
11245
11257
assert(parent_fn_type->async_allocator_type != nullptr);
11246
- IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, source_instr->source_node);
11247
- result->value.type = parent_fn_type->async_allocator_type;
11248
- return result;
11258
+
11259
+ switch (id) {
11260
+ case ImplicitAllocatorIdArg:
11261
+ {
11262
+ IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope,
11263
+ source_instr->source_node, ImplicitAllocatorIdArg);
11264
+ result->value.type = parent_fn_type->async_allocator_type;
11265
+ return result;
11266
+ }
11267
+ case ImplicitAllocatorIdLocalVar:
11268
+ {
11269
+ VariableTableEntry *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;
11270
+ assert(coro_allocator_var != nullptr);
11271
+ IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var, true, false);
11272
+ IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst);
11273
+ assert(result->value.type != nullptr);
11274
+ return result;
11275
+ }
11276
+ }
11277
+ zig_unreachable();
11249
11278
}
11250
11279
11251
11280
static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, FnTableEntry *fn_entry, TypeTableEntry *fn_type,
@@ -11805,7 +11834,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11805
11834
}
11806
11835
IrInstruction *uncasted_async_allocator_inst;
11807
11836
if (call_instruction->async_allocator == nullptr) {
11808
- uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base);
11837
+ uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base,
11838
+ ImplicitAllocatorIdLocalVar);
11809
11839
if (type_is_invalid(uncasted_async_allocator_inst->value.type))
11810
11840
return ira->codegen->builtin_types.entry_invalid;
11811
11841
} else {
@@ -11927,7 +11957,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11927
11957
if (call_instruction->is_async) {
11928
11958
IrInstruction *uncasted_async_allocator_inst;
11929
11959
if (call_instruction->async_allocator == nullptr) {
11930
- uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base);
11960
+ uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base,
11961
+ ImplicitAllocatorIdLocalVar);
11931
11962
if (type_is_invalid(uncasted_async_allocator_inst->value.type))
11932
11963
return ira->codegen->builtin_types.entry_invalid;
11933
11964
} else {
@@ -17189,7 +17220,7 @@ static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstr
17189
17220
}
17190
17221
17191
17222
static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {
17192
- IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base);
17223
+ IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base, instruction->id );
17193
17224
ir_link_new_instruction(result, &instruction->base);
17194
17225
return result->value.type;
17195
17226
}
0 commit comments