authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-27 17:46:13-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-27 17:46:13-05:00
log138d6f909321fb4fddeaa172357336c384c64eda
treee7a2ade11ed965e9e24f38e9b5c8e5d51c5eade5
parent132e604aa399a3bcb91996e550cf8972bd88422c

revert workaround for alloc and free as coro params

reverts 4ac6c4d6bfb8f7ada2799ddb5ce3a9797be0518d the workaround didn't work

5 files changed, 55 insertions(+), 165 deletions(-)

src/all_types.hpp-10
...@@ -2210,8 +2210,6 @@ struct IrInstructionCall {...@@ -2210,8 +2210,6 @@ struct IrInstructionCall {
2210 bool is_async;2210 bool is_async;
22112211
2212 IrInstruction *async_allocator;2212 IrInstruction *async_allocator;
2213 IrInstruction *alloc_fn;
2214 IrInstruction *free_fn;
2215};2213};
22162214
2217struct IrInstructionConst {2215struct IrInstructionConst {
...@@ -2852,16 +2850,8 @@ struct IrInstructionCancel {...@@ -2852,16 +2850,8 @@ struct IrInstructionCancel {
2852 IrInstruction *target;2850 IrInstruction *target;
2853};2851};
28542852
2855enum ImplicitAllocatorId {
2856 ImplicitAllocatorIdContext,
2857 ImplicitAllocatorIdAlloc,
2858 ImplicitAllocatorIdFree,
2859};
2860
2861struct IrInstructionGetImplicitAllocator {2853struct IrInstructionGetImplicitAllocator {
2862 IrInstruction base;2854 IrInstruction base;
2863
2864 ImplicitAllocatorId id;
2865};2855};
28662856
2867struct IrInstructionCoroId {2857struct IrInstructionCoroId {
src/analyze.cpp+4-30
...@@ -1006,13 +1006,13 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1006,13 +1006,13 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1006 fn_type_id->return_type->id == TypeTableEntryIdErrorSet);1006 fn_type_id->return_type->id == TypeTableEntryIdErrorSet);
1007 // +1 for maybe making the first argument the return value1007 // +1 for maybe making the first argument the return value
1008 // +1 for maybe first argument the error return trace1008 // +1 for maybe first argument the error return trace
1009 // +4 for maybe arguments async allocator and error code pointer1009 // +2 for maybe arguments async allocator and error code pointer
1010 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(6 + fn_type_id->param_count);1010 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(4 + fn_type_id->param_count);
1011 // +1 because 0 is the return type and1011 // +1 because 0 is the return type and
1012 // +1 for maybe making first arg ret val and1012 // +1 for maybe making first arg ret val and
1013 // +1 for maybe first argument the error return trace1013 // +1 for maybe first argument the error return trace
1014 // +4 for maybe arguments async allocator and error code pointer1014 // +2 for maybe arguments async allocator and error code pointer
1015 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(7 + fn_type_id->param_count);1015 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(5 + fn_type_id->param_count);
1016 param_di_types[0] = fn_type_id->return_type->di_type;1016 param_di_types[0] = fn_type_id->return_type->di_type;
1017 size_t gen_param_index = 0;1017 size_t gen_param_index = 0;
1018 TypeTableEntry *gen_return_type;1018 TypeTableEntry *gen_return_type;
...@@ -1052,32 +1052,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1052,32 +1052,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1052 param_di_types[gen_param_index] = gen_type->di_type;1052 param_di_types[gen_param_index] = gen_type->di_type;
1053 }1053 }
10541054
1055 {
1056 // async alloc fn param
1057 assert(fn_type_id->async_allocator_type->id == TypeTableEntryIdPointer);
1058 TypeTableEntry *struct_type = fn_type_id->async_allocator_type->data.pointer.child_type;
1059 TypeStructField *alloc_fn_field = find_struct_type_field(struct_type, buf_create_from_str("allocFn"));
1060 assert(alloc_fn_field->type_entry->id == TypeTableEntryIdFn);
1061 TypeTableEntry *gen_type = alloc_fn_field->type_entry;
1062 gen_param_types[gen_param_index] = gen_type->type_ref;
1063 gen_param_index += 1;
1064 // after the gen_param_index += 1 because 0 is the return type
1065 param_di_types[gen_param_index] = gen_type->di_type;
1066 }
1067
1068 {
1069 // async free fn param
1070 assert(fn_type_id->async_allocator_type->id == TypeTableEntryIdPointer);
1071 TypeTableEntry *struct_type = fn_type_id->async_allocator_type->data.pointer.child_type;
1072 TypeStructField *free_fn_field = find_struct_type_field(struct_type, buf_create_from_str("freeFn"));
1073 assert(free_fn_field->type_entry->id == TypeTableEntryIdFn);
1074 TypeTableEntry *gen_type = free_fn_field->type_entry;
1075 gen_param_types[gen_param_index] = gen_type->type_ref;
1076 gen_param_index += 1;
1077 // after the gen_param_index += 1 because 0 is the return type
1078 param_di_types[gen_param_index] = gen_type->di_type;
1079 }
1080
1081 {1055 {
1082 // error code pointer1056 // error code pointer
1083 TypeTableEntry *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);1057 TypeTableEntry *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
src/codegen.cpp+8-22
...@@ -2673,15 +2673,15 @@ static bool get_prefix_arg_err_ret_stack(CodeGen *g, TypeTableEntry *src_return_...@@ -2673,15 +2673,15 @@ static bool get_prefix_arg_err_ret_stack(CodeGen *g, TypeTableEntry *src_return_
2673}2673}
26742674
2675static size_t get_async_allocator_arg_index(CodeGen *g, TypeTableEntry *src_return_type) {2675static size_t get_async_allocator_arg_index(CodeGen *g, TypeTableEntry *src_return_type) {
2676 // 0 1 2 3 4 52676 // 0 1 2 3
2677 // err_ret_stack allocator_ptr alloc free err_code other_args...2677 // err_ret_stack allocator_ptr err_code other_args...
2678 return get_prefix_arg_err_ret_stack(g, src_return_type) ? 1 : 0;2678 return get_prefix_arg_err_ret_stack(g, src_return_type) ? 1 : 0;
2679}2679}
26802680
2681static size_t get_async_err_code_arg_index(CodeGen *g, TypeTableEntry *src_return_type) {2681static size_t get_async_err_code_arg_index(CodeGen *g, TypeTableEntry *src_return_type) {
2682 // 0 1 2 3 4 52682 // 0 1 2 3
2683 // err_ret_stack allocator_ptr alloc free err_code other_args...2683 // err_ret_stack allocator_ptr err_code other_args...
2684 return 3 + get_async_allocator_arg_index(g, src_return_type);2684 return 1 + get_async_allocator_arg_index(g, src_return_type);
2685}2685}
26862686
2687static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {2687static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
...@@ -2704,8 +2704,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -2704,8 +2704,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
2704 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) &&2704 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) &&
2705 calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc);2705 calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc);
2706 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, src_return_type);2706 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, src_return_type);
2707 // +4 for the async args2707 // +2 for the async args
2708 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0) + 4;2708 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0) + 2;
2709 bool is_var_args = fn_type_id->is_var_args;2709 bool is_var_args = fn_type_id->is_var_args;
2710 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);2710 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
2711 size_t gen_param_index = 0;2711 size_t gen_param_index = 0;
...@@ -2721,12 +2721,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -2721,12 +2721,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
2721 gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator);2721 gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator);
2722 gen_param_index += 1;2722 gen_param_index += 1;
27232723
2724 gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->alloc_fn);
2725 gen_param_index += 1;
2726
2727 gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->free_fn);
2728 gen_param_index += 1;
2729
2730 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");2724 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
2731 LLVMBuildStore(g->builder, LLVMConstNull(g->builtin_types.entry_global_error_set->type_ref), err_val_ptr);2725 LLVMBuildStore(g->builder, LLVMConstNull(g->builtin_types.entry_global_error_set->type_ref), err_val_ptr);
2732 gen_param_values[gen_param_index] = err_val_ptr;2726 gen_param_values[gen_param_index] = err_val_ptr;
...@@ -3308,15 +3302,7 @@ static LLVMValueRef ir_render_get_implicit_allocator(CodeGen *g, IrExecutable *e...@@ -3308,15 +3302,7 @@ static LLVMValueRef ir_render_get_implicit_allocator(CodeGen *g, IrExecutable *e
3308{3302{
3309 TypeTableEntry *src_return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;3303 TypeTableEntry *src_return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
3310 size_t allocator_arg_index = get_async_allocator_arg_index(g, src_return_type);3304 size_t allocator_arg_index = get_async_allocator_arg_index(g, src_return_type);
3311 switch (instruction->id) {3305 return LLVMGetParam(g->cur_fn_val, allocator_arg_index);
3312 case ImplicitAllocatorIdContext:
3313 return LLVMGetParam(g->cur_fn_val, allocator_arg_index + 0);
3314 case ImplicitAllocatorIdAlloc:
3315 return LLVMGetParam(g->cur_fn_val, allocator_arg_index + 1);
3316 case ImplicitAllocatorIdFree:
3317 return LLVMGetParam(g->cur_fn_val, allocator_arg_index + 2);
3318 }
3319 zig_unreachable();
3320}3306}
33213307
3322static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {3308static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
src/ir.cpp+42-90
...@@ -1066,7 +1066,7 @@ static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstructio...@@ -1066,7 +1066,7 @@ static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstructio
10661066
1067static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,1067static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
1068 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,1068 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1069 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *alloc_fn, IrInstruction *free_fn)1069 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator)
1070{1070{
1071 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);1071 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
1072 call_instruction->fn_entry = fn_entry;1072 call_instruction->fn_entry = fn_entry;
...@@ -1077,8 +1077,6 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1077,8 +1077,6 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1077 call_instruction->arg_count = arg_count;1077 call_instruction->arg_count = arg_count;
1078 call_instruction->is_async = is_async;1078 call_instruction->is_async = is_async;
1079 call_instruction->async_allocator = async_allocator;1079 call_instruction->async_allocator = async_allocator;
1080 call_instruction->alloc_fn = alloc_fn;
1081 call_instruction->free_fn = free_fn;
10821080
1083 if (fn_ref)1081 if (fn_ref)
1084 ir_ref_instruction(fn_ref, irb->current_basic_block);1082 ir_ref_instruction(fn_ref, irb->current_basic_block);
...@@ -1086,20 +1084,16 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1086,20 +1084,16 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1086 ir_ref_instruction(args[i], irb->current_basic_block);1084 ir_ref_instruction(args[i], irb->current_basic_block);
1087 if (async_allocator)1085 if (async_allocator)
1088 ir_ref_instruction(async_allocator, irb->current_basic_block);1086 ir_ref_instruction(async_allocator, irb->current_basic_block);
1089 if (alloc_fn)
1090 ir_ref_instruction(alloc_fn, irb->current_basic_block);
1091 if (free_fn)
1092 ir_ref_instruction(free_fn, irb->current_basic_block);
10931087
1094 return &call_instruction->base;1088 return &call_instruction->base;
1095}1089}
10961090
1097static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,1091static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,
1098 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,1092 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1099 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *alloc_fn, IrInstruction *free_fn)1093 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator)
1100{1094{
1101 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,1095 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,
1102 old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator, alloc_fn, free_fn);1096 old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator);
1103 ir_link_new_instruction(new_instruction, old_instruction);1097 ir_link_new_instruction(new_instruction, old_instruction);
1104 return new_instruction;1098 return new_instruction;
1105}1099}
...@@ -2501,9 +2495,8 @@ static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *sou...@@ -2501,9 +2495,8 @@ static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *sou
2501 return &instruction->base;2495 return &instruction->base;
2502}2496}
25032497
2504static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, ImplicitAllocatorId id) {2498static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2505 IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node);2499 IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node);
2506 instruction->id = id;
25072500
2508 return &instruction->base;2501 return &instruction->base;
2509}2502}
...@@ -3977,7 +3970,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3977,7 +3970,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3977 }3970 }
3978 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;3971 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
39793972
3980 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr, nullptr);3973 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);
3981 }3974 }
3982 case BuiltinFnIdTypeId:3975 case BuiltinFnIdTypeId:
3983 {3976 {
...@@ -4113,25 +4106,15 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node...@@ -4113,25 +4106,15 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
41134106
4114 bool is_async = node->data.fn_call_expr.is_async;4107 bool is_async = node->data.fn_call_expr.is_async;
4115 IrInstruction *async_allocator = nullptr;4108 IrInstruction *async_allocator = nullptr;
4116 IrInstruction *alloc_fn = nullptr;
4117 IrInstruction *free_fn = nullptr;
4118 if (is_async) {4109 if (is_async) {
4119 if (node->data.fn_call_expr.async_allocator) {4110 if (node->data.fn_call_expr.async_allocator) {
4120 async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope);4111 async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope);
4121 if (async_allocator == irb->codegen->invalid_instruction)4112 if (async_allocator == irb->codegen->invalid_instruction)
4122 return async_allocator;4113 return async_allocator;
4123
4124 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
4125 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, async_allocator, alloc_field_name);
4126 alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr);
4127
4128 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);
4129 IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, async_allocator, free_field_name);
4130 free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
4131 }4114 }
4132 }4115 }
41334116
4134 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator, alloc_fn, free_fn);4117 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);
4135}4118}
41364119
4137static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {4120static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -6113,16 +6096,20 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6113,16 +6096,20 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6113 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);6096 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);
6114 coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr);6097 coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr);
6115 IrInstruction *coro_size = ir_build_coro_size(irb, scope, node);6098 IrInstruction *coro_size = ir_build_coro_size(irb, scope, node);
6116 irb->exec->implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, ImplicitAllocatorIdContext);6099 irb->exec->implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node);
6117 IrInstruction *alloc_fn = ir_build_get_implicit_allocator(irb, scope, node, ImplicitAllocatorIdAlloc);6100 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
6118 IrInstruction *alignment = ir_build_const_u29(irb, scope, node, get_coro_frame_align_bytes(irb->codegen));6101 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr,
6102 alloc_field_name);
6103 IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr);
6104 IrInstruction *alignment = ir_build_const_u29(irb, scope, node,
6105 get_coro_frame_align_bytes(irb->codegen));
6119 size_t arg_count = 3;6106 size_t arg_count = 3;
6120 IrInstruction **args = allocate<IrInstruction *>(arg_count);6107 IrInstruction **args = allocate<IrInstruction *>(arg_count);
6121 args[0] = irb->exec->implicit_allocator_ptr; // self6108 args[0] = irb->exec->implicit_allocator_ptr; // self
6122 args[1] = coro_size; // byte_count6109 args[1] = coro_size; // byte_count
6123 args[2] = alignment; // alignment6110 args[2] = alignment; // alignment
6124 IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false,6111 IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false,
6125 FnInlineAuto, false, nullptr, nullptr, nullptr);6112 FnInlineAuto, false, nullptr);
6126 IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false);6113 IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false);
6127 IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result);6114 IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result);
6128 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError");6115 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError");
...@@ -6216,12 +6203,15 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6216,12 +6203,15 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6216 incoming_values[1] = const_bool_true;6203 incoming_values[1] = const_bool_true;
6217 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);6204 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
62186205
6219 IrInstruction *free_fn = ir_build_get_implicit_allocator(irb, scope, node, ImplicitAllocatorIdFree);6206 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);
6207 IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr,
6208 free_field_name);
6209 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
6220 size_t arg_count = 2;6210 size_t arg_count = 2;
6221 IrInstruction **args = allocate<IrInstruction *>(arg_count);6211 IrInstruction **args = allocate<IrInstruction *>(arg_count);
6222 args[0] = irb->exec->implicit_allocator_ptr; // self6212 args[0] = irb->exec->implicit_allocator_ptr; // self
6223 args[1] = ir_build_load_ptr(irb, scope, node, coro_unwrapped_mem_ptr); // old_mem6213 args[1] = ir_build_load_ptr(irb, scope, node, coro_unwrapped_mem_ptr); // old_mem
6224 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr, nullptr);6214 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
62256215
6226 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");6216 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
6227 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "Return");6217 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "Return");
...@@ -11240,7 +11230,7 @@ static TypeTableEntry *ir_analyze_instruction_error_union(IrAnalyze *ira,...@@ -11240,7 +11230,7 @@ static TypeTableEntry *ir_analyze_instruction_error_union(IrAnalyze *ira,
11240 return ira->codegen->builtin_types.entry_type;11230 return ira->codegen->builtin_types.entry_type;
11241}11231}
1124211232
11243IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) {11233IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr) {
11244 FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);11234 FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
11245 if (parent_fn_entry == nullptr) {11235 if (parent_fn_entry == nullptr) {
11246 ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available"));11236 ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available"));
...@@ -11254,39 +11244,27 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i...@@ -11254,39 +11244,27 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
11254 }11244 }
1125511245
11256 assert(parent_fn_type->async_allocator_type != nullptr);11246 assert(parent_fn_type->async_allocator_type != nullptr);
11257 IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, source_instr->source_node, id);11247 IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, source_instr->source_node);
11258 switch (id) {11248 result->value.type = parent_fn_type->async_allocator_type;
11259 case ImplicitAllocatorIdContext:
11260 result->value.type = parent_fn_type->async_allocator_type;
11261 break;
11262 case ImplicitAllocatorIdAlloc:
11263 {
11264 assert(parent_fn_type->async_allocator_type->id == TypeTableEntryIdPointer);
11265 TypeTableEntry *struct_type = parent_fn_type->async_allocator_type->data.pointer.child_type;
11266 TypeStructField *alloc_fn_field = find_struct_type_field(struct_type, buf_create_from_str(ASYNC_ALLOC_FIELD_NAME));
11267 assert(alloc_fn_field->type_entry->id == TypeTableEntryIdFn);
11268 result->value.type = alloc_fn_field->type_entry;
11269 break;
11270 }
11271 case ImplicitAllocatorIdFree:
11272 {
11273 assert(parent_fn_type->async_allocator_type->id == TypeTableEntryIdPointer);
11274 TypeTableEntry *struct_type = parent_fn_type->async_allocator_type->data.pointer.child_type;
11275 TypeStructField *free_fn_field = find_struct_type_field(struct_type, buf_create_from_str(ASYNC_FREE_FIELD_NAME));
11276 assert(free_fn_field->type_entry->id == TypeTableEntryIdFn);
11277 result->value.type = free_fn_field->type_entry;
11278 break;
11279 }
11280 }
11281 return result;11249 return result;
11282}11250}
1128311251
11284static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, FnTableEntry *fn_entry, TypeTableEntry *fn_type,11252static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, FnTableEntry *fn_entry, TypeTableEntry *fn_type,
11285 IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst, IrInstruction *alloc_fn, IrInstruction *free_fn)11253 IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst)
11286{11254{
11255 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
11256 //Buf *free_field_name = buf_create_from_str("freeFn");
11287 assert(async_allocator_inst->value.type->id == TypeTableEntryIdPointer);11257 assert(async_allocator_inst->value.type->id == TypeTableEntryIdPointer);
11258 TypeTableEntry *container_type = async_allocator_inst->value.type->data.pointer.child_type;
11259 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, alloc_field_name, &call_instruction->base,
11260 async_allocator_inst, container_type);
11261 if (type_is_invalid(field_ptr_inst->value.type)) {
11262 return ira->codegen->invalid_instruction;
11263 }
11264 TypeTableEntry *ptr_to_alloc_fn_type = field_ptr_inst->value.type;
11265 assert(ptr_to_alloc_fn_type->id == TypeTableEntryIdPointer);
1128811266
11289 TypeTableEntry *alloc_fn_type = alloc_fn->value.type;11267 TypeTableEntry *alloc_fn_type = ptr_to_alloc_fn_type->data.pointer.child_type;
11290 if (alloc_fn_type->id != TypeTableEntryIdFn) {11268 if (alloc_fn_type->id != TypeTableEntryIdFn) {
11291 ir_add_error(ira, &call_instruction->base,11269 ir_add_error(ira, &call_instruction->base,
11292 buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name)));11270 buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name)));
...@@ -11305,7 +11283,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c...@@ -11305,7 +11283,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
11305 TypeTableEntry *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);11283 TypeTableEntry *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1130611284
11307 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,11285 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,
11308 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, alloc_fn, free_fn);11286 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst);
11309 result->value.type = async_return_type;11287 result->value.type = async_return_type;
11310 return result;11288 return result;
11311}11289}
...@@ -11828,7 +11806,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -11828,7 +11806,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11828 }11806 }
11829 IrInstruction *uncasted_async_allocator_inst;11807 IrInstruction *uncasted_async_allocator_inst;
11830 if (call_instruction->async_allocator == nullptr) {11808 if (call_instruction->async_allocator == nullptr) {
11831 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, ImplicitAllocatorIdContext);11809 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base);
11832 if (type_is_invalid(uncasted_async_allocator_inst->value.type))11810 if (type_is_invalid(uncasted_async_allocator_inst->value.type))
11833 return ira->codegen->builtin_types.entry_invalid;11811 return ira->codegen->builtin_types.entry_invalid;
11834 } else {11812 } else {
...@@ -11872,16 +11850,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -11872,16 +11850,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1187211850
11873 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count;11851 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count;
11874 if (call_instruction->is_async) {11852 if (call_instruction->is_async) {
11875 IrInstruction *alloc_fn = call_instruction->alloc_fn->other;
11876 if (type_is_invalid(alloc_fn->value.type))
11877 return ira->codegen->builtin_types.entry_invalid;
11878
11879 IrInstruction *free_fn = call_instruction->free_fn->other;
11880 if (type_is_invalid(free_fn->value.type))
11881 return ira->codegen->builtin_types.entry_invalid;
11882
11883 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count,11853 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count,
11884 async_allocator_inst, alloc_fn, free_fn);11854 async_allocator_inst);
11885 ir_link_new_instruction(result, &call_instruction->base);11855 ir_link_new_instruction(result, &call_instruction->base);
11886 ir_add_alloca(ira, result, result->value.type);11856 ir_add_alloca(ira, result, result->value.type);
11887 return ir_finish_anal(ira, result->value.type);11857 return ir_finish_anal(ira, result->value.type);
...@@ -11890,7 +11860,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -11890,7 +11860,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
11890 assert(async_allocator_inst == nullptr);11860 assert(async_allocator_inst == nullptr);
11891 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,11861 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
11892 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,11862 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,
11893 call_instruction->is_async, nullptr, nullptr, nullptr);11863 call_instruction->is_async, nullptr);
1189411864
11895 ir_add_alloca(ira, new_call_instruction, return_type);11865 ir_add_alloca(ira, new_call_instruction, return_type);
1189611866
...@@ -11957,40 +11927,22 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -11957,40 +11927,22 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1195711927
11958 if (call_instruction->is_async) {11928 if (call_instruction->is_async) {
11959 IrInstruction *uncasted_async_allocator_inst;11929 IrInstruction *uncasted_async_allocator_inst;
11960 IrInstruction *uncasted_alloc_fn_inst;
11961 IrInstruction *uncasted_free_fn_inst;
11962 if (call_instruction->async_allocator == nullptr) {11930 if (call_instruction->async_allocator == nullptr) {
11963 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, ImplicitAllocatorIdContext);11931 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base);
11964 if (type_is_invalid(uncasted_async_allocator_inst->value.type))11932 if (type_is_invalid(uncasted_async_allocator_inst->value.type))
11965 return ira->codegen->builtin_types.entry_invalid;11933 return ira->codegen->builtin_types.entry_invalid;
11966
11967 uncasted_alloc_fn_inst = ir_get_implicit_allocator(ira, &call_instruction->base, ImplicitAllocatorIdAlloc);
11968 if (type_is_invalid(uncasted_alloc_fn_inst->value.type))
11969 return ira->codegen->builtin_types.entry_invalid;
11970
11971 uncasted_free_fn_inst = ir_get_implicit_allocator(ira, &call_instruction->base, ImplicitAllocatorIdFree);
11972 if (type_is_invalid(uncasted_free_fn_inst->value.type))
11973 return ira->codegen->builtin_types.entry_invalid;
11974 } else {11934 } else {
11975 uncasted_async_allocator_inst = call_instruction->async_allocator->other;11935 uncasted_async_allocator_inst = call_instruction->async_allocator->other;
11976 if (type_is_invalid(uncasted_async_allocator_inst->value.type))11936 if (type_is_invalid(uncasted_async_allocator_inst->value.type))
11977 return ira->codegen->builtin_types.entry_invalid;11937 return ira->codegen->builtin_types.entry_invalid;
1197811938
11979 uncasted_alloc_fn_inst = call_instruction->alloc_fn->other;
11980 if (type_is_invalid(uncasted_alloc_fn_inst->value.type))
11981 return ira->codegen->builtin_types.entry_invalid;
11982
11983 uncasted_free_fn_inst = call_instruction->free_fn->other;
11984 if (type_is_invalid(uncasted_free_fn_inst->value.type))
11985 return ira->codegen->builtin_types.entry_invalid;
11986
11987 }11939 }
11988 IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type);11940 IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type);
11989 if (type_is_invalid(async_allocator_inst->value.type))11941 if (type_is_invalid(async_allocator_inst->value.type))
11990 return ira->codegen->builtin_types.entry_invalid;11942 return ira->codegen->builtin_types.entry_invalid;
1199111943
11992 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count,11944 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count,
11993 async_allocator_inst, uncasted_alloc_fn_inst, uncasted_free_fn_inst);11945 async_allocator_inst);
11994 ir_link_new_instruction(result, &call_instruction->base);11946 ir_link_new_instruction(result, &call_instruction->base);
11995 ir_add_alloca(ira, result, result->value.type);11947 ir_add_alloca(ira, result, result->value.type);
11996 return ir_finish_anal(ira, result->value.type);11948 return ir_finish_anal(ira, result->value.type);
...@@ -11998,7 +11950,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -11998,7 +11950,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1199811950
1199911951
12000 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,11952 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
12001 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, nullptr, nullptr);11953 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr);
1200211954
12003 ir_add_alloca(ira, new_call_instruction, return_type);11955 ir_add_alloca(ira, new_call_instruction, return_type);
12004 return ir_finish_anal(ira, return_type);11956 return ir_finish_anal(ira, return_type);
...@@ -17238,7 +17190,7 @@ static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstr...@@ -17238,7 +17190,7 @@ static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstr
17238}17190}
1723917191
17240static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {17192static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {
17241 IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base, instruction->id);17193 IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base);
17242 ir_link_new_instruction(result, &instruction->base);17194 ir_link_new_instruction(result, &instruction->base);
17243 return result->value.type;17195 return result->value.type;
17244}17196}
src/ir_print.cpp+1-13
...@@ -1027,19 +1027,7 @@ static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {...@@ -1027,19 +1027,7 @@ static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {
1027}1027}
10281028
1029static void ir_print_get_implicit_allocator(IrPrint *irp, IrInstructionGetImplicitAllocator *instruction) {1029static void ir_print_get_implicit_allocator(IrPrint *irp, IrInstructionGetImplicitAllocator *instruction) {
1030 fprintf(irp->f, "@getImplicitAllocator(");1030 fprintf(irp->f, "@getImplicitAllocator()");
1031 switch (instruction->id) {
1032 case ImplicitAllocatorIdContext:
1033 fprintf(irp->f, "Context");
1034 break;
1035 case ImplicitAllocatorIdAlloc:
1036 fprintf(irp->f, "Alloc");
1037 break;
1038 case ImplicitAllocatorIdFree:
1039 fprintf(irp->f, "Free");
1040 break;
1041 }
1042 fprintf(irp->f, ")");
1043}1031}
10441032
1045static void ir_print_coro_id(IrPrint *irp, IrInstructionCoroId *instruction) {1033static void ir_print_coro_id(IrPrint *irp, IrInstructionCoroId *instruction) {