| ... | ... | @@ -310,6 +310,8 @@ static void destroy_instruction_src(IrInstSrc *inst) { |
| 310 | 310 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst)); |
| 311 | 311 | case IrInstSrcIdCallExtra: |
| 312 | 312 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst)); |
| 313 | case IrInstSrcIdAsyncCallExtra: |
| 314 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst)); |
| 313 | 315 | case IrInstSrcIdUnOp: |
| 314 | 316 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); |
| 315 | 317 | case IrInstSrcIdCondBr: |
| ... | ... | @@ -1173,6 +1175,10 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { |
| 1173 | 1175 | return IrInstSrcIdCallExtra; |
| 1174 | 1176 | } |
| 1175 | 1177 | |
| 1178 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) { |
| 1179 | return IrInstSrcIdAsyncCallExtra; |
| 1180 | } |
| 1181 | |
| 1176 | 1182 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { |
| 1177 | 1183 | return IrInstSrcIdConst; |
| 1178 | 1184 | } |
| ... | ... | @@ -2442,6 +2448,25 @@ static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode * |
| 2442 | 2448 | return &call_instruction->base; |
| 2443 | 2449 | } |
| 2444 | 2450 | |
| 2451 | static IrInstSrc *ir_build_async_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 2452 | CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc) |
| 2453 | { |
| 2454 | IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(irb, scope, source_node); |
| 2455 | call_instruction->modifier = modifier; |
| 2456 | call_instruction->fn_ref = fn_ref; |
| 2457 | call_instruction->ret_ptr = ret_ptr; |
| 2458 | call_instruction->new_stack = new_stack; |
| 2459 | call_instruction->args = args; |
| 2460 | call_instruction->result_loc = result_loc; |
| 2461 | |
| 2462 | ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 2463 | if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); |
| 2464 | ir_ref_instruction(new_stack, irb->current_basic_block); |
| 2465 | ir_ref_instruction(args, irb->current_basic_block); |
| 2466 | |
| 2467 | return &call_instruction->base; |
| 2468 | } |
| 2469 | |
| 2445 | 2470 | static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 2446 | 2471 | IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, |
| 2447 | 2472 | ResultLoc *result_loc) |
| ... | ... | @@ -6183,11 +6208,10 @@ static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *nod |
| 6183 | 6208 | static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, |
| 6184 | 6209 | LVal lval, ResultLoc *result_loc) |
| 6185 | 6210 | { |
| 6186 | | size_t arg_offset = 3; |
| 6187 | | if (call_node->data.fn_call_expr.params.length < arg_offset) { |
| 6211 | if (call_node->data.fn_call_expr.params.length != 4) { |
| 6188 | 6212 | add_node_error(irb->codegen, call_node, |
| 6189 | | buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, |
| 6190 | | arg_offset, call_node->data.fn_call_expr.params.length)); |
| 6213 | buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize, |
| 6214 | call_node->data.fn_call_expr.params.length)); |
| 6191 | 6215 | return irb->codegen->invalid_inst_src; |
| 6192 | 6216 | } |
| 6193 | 6217 | |
| ... | ... | @@ -6206,20 +6230,37 @@ static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *aw |
| 6206 | 6230 | if (fn_ref == irb->codegen->invalid_inst_src) |
| 6207 | 6231 | return fn_ref; |
| 6208 | 6232 | |
| 6209 | | size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; |
| 6210 | | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); |
| 6211 | | for (size_t i = 0; i < arg_count; i += 1) { |
| 6212 | | AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); |
| 6213 | | IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); |
| 6214 | | if (arg == irb->codegen->invalid_inst_src) |
| 6215 | | return arg; |
| 6216 | | args[i] = arg; |
| 6217 | | } |
| 6218 | | |
| 6219 | 6233 | CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; |
| 6220 | 6234 | bool is_async_call_builtin = true; |
| 6221 | | IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, |
| 6222 | | ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); |
| 6235 | AstNode *args_node = call_node->data.fn_call_expr.params.at(3); |
| 6236 | if (args_node->type == NodeTypeContainerInitExpr) { |
| 6237 | if (args_node->data.container_init_expr.kind == ContainerInitKindArray || |
| 6238 | args_node->data.container_init_expr.entries.length == 0) |
| 6239 | { |
| 6240 | size_t arg_count = args_node->data.container_init_expr.entries.length; |
| 6241 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); |
| 6242 | for (size_t i = 0; i < arg_count; i += 1) { |
| 6243 | AstNode *arg_node = args_node->data.container_init_expr.entries.at(i); |
| 6244 | IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); |
| 6245 | if (arg == irb->codegen->invalid_inst_src) |
| 6246 | return arg; |
| 6247 | args[i] = arg; |
| 6248 | } |
| 6249 | |
| 6250 | IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, |
| 6251 | ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); |
| 6252 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 6253 | } else { |
| 6254 | exec_add_error_node(irb->codegen, irb->exec, args_node, |
| 6255 | buf_sprintf("TODO: @asyncCall with anon struct literal")); |
| 6256 | return irb->codegen->invalid_inst_src; |
| 6257 | } |
| 6258 | } |
| 6259 | IrInstSrc *args = ir_gen_node(irb, args_node, scope); |
| 6260 | if (args == irb->codegen->invalid_inst_src) |
| 6261 | return args; |
| 6262 | |
| 6263 | IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, bytes, ret_ptr, args, result_loc); |
| 6223 | 6264 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 6224 | 6265 | } |
| 6225 | 6266 | |
| ... | ... | @@ -20236,7 +20277,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 20236 | 20277 | // Fork a scope of the function with known values for the parameters. |
| 20237 | 20278 | Scope *parent_scope = fn_entry->fndef_scope->base.parent; |
| 20238 | 20279 | ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); |
| 20239 | | impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count); |
| 20280 | |
| 20240 | 20281 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 20241 | 20282 | impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); |
| 20242 | 20283 | impl_fn->child_scope = &impl_fn->fndef_scope->base; |
| ... | ... | @@ -20719,40 +20760,101 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, |
| 20719 | 20760 | modifier, stack, stack_src, false, args_ptr, args_len, nullptr, result_loc); |
| 20720 | 20761 | } |
| 20721 | 20762 | |
| 20722 | | static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { |
| 20723 | | IrInstGen *args = instruction->args->child; |
| 20763 | static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_instr, CallModifier modifier, |
| 20764 | IrInstSrc *pass1_fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstGen **args_ptr, size_t args_len, ResultLoc *result_loc) |
| 20765 | { |
| 20766 | IrInstGen *fn_ref = pass1_fn_ref->child; |
| 20767 | if (type_is_invalid(fn_ref->value->type)) |
| 20768 | return ira->codegen->invalid_inst_gen; |
| 20769 | |
| 20770 | if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { |
| 20771 | ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall")); |
| 20772 | return ira->codegen->invalid_inst_gen; |
| 20773 | } |
| 20774 | |
| 20775 | ZigFn *fn = nullptr; |
| 20776 | if (instr_is_comptime(fn_ref)) { |
| 20777 | if (fn_ref->value->type->id == ZigTypeIdBoundFn) { |
| 20778 | assert(fn_ref->value->special == ConstValSpecialStatic); |
| 20779 | fn = fn_ref->value->data.x_bound_fn.fn; |
| 20780 | } else { |
| 20781 | fn = ir_resolve_fn(ira, fn_ref); |
| 20782 | } |
| 20783 | } |
| 20784 | |
| 20785 | IrInstGen *ret_ptr_uncasted = nullptr; |
| 20786 | if (ret_ptr != nullptr) { |
| 20787 | ret_ptr_uncasted = ret_ptr->child; |
| 20788 | if (type_is_invalid(ret_ptr_uncasted->value->type)) |
| 20789 | return ira->codegen->invalid_inst_gen; |
| 20790 | } |
| 20791 | |
| 20792 | ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; |
| 20793 | IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack->child, |
| 20794 | &new_stack->base, true, fn); |
| 20795 | if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) |
| 20796 | return ira->codegen->invalid_inst_gen; |
| 20797 | |
| 20798 | IrInstGen *result = ir_analyze_async_call(ira, source_instr, fn, fn_type, fn_ref, args_ptr, args_len, |
| 20799 | casted_new_stack, true, ret_ptr_uncasted, result_loc); |
| 20800 | return ir_finish_anal(ira, result); |
| 20801 | } |
| 20802 | |
| 20803 | static bool ir_extract_tuple_call_args(IrAnalyze *ira, IrInst *source_instr, IrInstGen *args, IrInstGen ***args_ptr, size_t *args_len) { |
| 20724 | 20804 | ZigType *args_type = args->value->type; |
| 20725 | 20805 | if (type_is_invalid(args_type)) |
| 20726 | | return ira->codegen->invalid_inst_gen; |
| 20806 | return false; |
| 20727 | 20807 | |
| 20728 | 20808 | if (args_type->id != ZigTypeIdStruct) { |
| 20729 | 20809 | ir_add_error(ira, &args->base, |
| 20730 | 20810 | buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); |
| 20731 | | return ira->codegen->invalid_inst_gen; |
| 20811 | return false; |
| 20732 | 20812 | } |
| 20733 | 20813 | |
| 20734 | | IrInstGen **args_ptr = nullptr; |
| 20735 | | size_t args_len = 0; |
| 20736 | | |
| 20737 | 20814 | if (is_tuple(args_type)) { |
| 20738 | | args_len = args_type->data.structure.src_field_count; |
| 20739 | | args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len); |
| 20740 | | for (size_t i = 0; i < args_len; i += 1) { |
| 20815 | *args_len = args_type->data.structure.src_field_count; |
| 20816 | *args_ptr = heap::c_allocator.allocate<IrInstGen *>(*args_len); |
| 20817 | for (size_t i = 0; i < *args_len; i += 1) { |
| 20741 | 20818 | TypeStructField *arg_field = args_type->data.structure.fields[i]; |
| 20742 | | args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field); |
| 20743 | | if (type_is_invalid(args_ptr[i]->value->type)) |
| 20744 | | return ira->codegen->invalid_inst_gen; |
| 20819 | (*args_ptr)[i] = ir_analyze_struct_value_field_value(ira, source_instr, args, arg_field); |
| 20820 | if (type_is_invalid((*args_ptr)[i]->value->type)) |
| 20821 | return false; |
| 20745 | 20822 | } |
| 20746 | 20823 | } else { |
| 20747 | 20824 | ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); |
| 20825 | return false; |
| 20826 | } |
| 20827 | return true; |
| 20828 | } |
| 20829 | |
| 20830 | static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { |
| 20831 | IrInstGen *args = instruction->args->child; |
| 20832 | IrInstGen **args_ptr = nullptr; |
| 20833 | size_t args_len = 0; |
| 20834 | if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) { |
| 20748 | 20835 | return ira->codegen->invalid_inst_gen; |
| 20749 | 20836 | } |
| 20837 | |
| 20750 | 20838 | IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, |
| 20751 | 20839 | instruction->fn_ref, args_ptr, args_len, instruction->result_loc); |
| 20752 | 20840 | heap::c_allocator.deallocate(args_ptr, args_len); |
| 20753 | 20841 | return result; |
| 20754 | 20842 | } |
| 20755 | 20843 | |
| 20844 | static IrInstGen *ir_analyze_instruction_async_call_extra(IrAnalyze *ira, IrInstSrcAsyncCallExtra *instruction) { |
| 20845 | IrInstGen *args = instruction->args->child; |
| 20846 | IrInstGen **args_ptr = nullptr; |
| 20847 | size_t args_len = 0; |
| 20848 | if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) { |
| 20849 | return ira->codegen->invalid_inst_gen; |
| 20850 | } |
| 20851 | |
| 20852 | IrInstGen *result = ir_analyze_async_call_extra(ira, &instruction->base.base, instruction->modifier, |
| 20853 | instruction->fn_ref, instruction->ret_ptr, instruction->new_stack, args_ptr, args_len, instruction->result_loc); |
| 20854 | heap::c_allocator.deallocate(args_ptr, args_len); |
| 20855 | return result; |
| 20856 | } |
| 20857 | |
| 20756 | 20858 | static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { |
| 20757 | 20859 | IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); |
| 20758 | 20860 | for (size_t i = 0; i < instruction->args_len; i += 1) { |
| ... | ... | @@ -31101,6 +31203,8 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc |
| 31101 | 31203 | return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); |
| 31102 | 31204 | case IrInstSrcIdCallExtra: |
| 31103 | 31205 | return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); |
| 31206 | case IrInstSrcIdAsyncCallExtra: |
| 31207 | return ir_analyze_instruction_async_call_extra(ira, (IrInstSrcAsyncCallExtra *)instruction); |
| 31104 | 31208 | case IrInstSrcIdBr: |
| 31105 | 31209 | return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); |
| 31106 | 31210 | case IrInstSrcIdCondBr: |
| ... | ... | @@ -31610,6 +31714,7 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { |
| 31610 | 31714 | case IrInstSrcIdDeclVar: |
| 31611 | 31715 | case IrInstSrcIdStorePtr: |
| 31612 | 31716 | case IrInstSrcIdCallExtra: |
| 31717 | case IrInstSrcIdAsyncCallExtra: |
| 31613 | 31718 | case IrInstSrcIdCall: |
| 31614 | 31719 | case IrInstSrcIdCallArgs: |
| 31615 | 31720 | case IrInstSrcIdReturn: |