| ... | @@ -310,6 +310,8 @@ static void destroy_instruction_src(IrInstSrc *inst) { | ... | @@ -310,6 +310,8 @@ static void destroy_instruction_src(IrInstSrc *inst) { |
| 310 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst)); | 310 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst)); |
| 311 | case IrInstSrcIdCallExtra: | 311 | case IrInstSrcIdCallExtra: |
| 312 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst)); | 312 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst)); |
| | 313 | case IrInstSrcIdAsyncCallExtra: |
| | 314 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst)); |
| 313 | case IrInstSrcIdUnOp: | 315 | case IrInstSrcIdUnOp: |
| 314 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); | 316 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); |
| 315 | case IrInstSrcIdCondBr: | 317 | case IrInstSrcIdCondBr: |
| ... | @@ -1173,6 +1175,10 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { | ... | @@ -1173,6 +1175,10 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { |
| 1173 | return IrInstSrcIdCallExtra; | 1175 | return IrInstSrcIdCallExtra; |
| 1174 | } | 1176 | } |
| 1175 | | 1177 | |
| | 1178 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) { |
| | 1179 | return IrInstSrcIdAsyncCallExtra; |
| | 1180 | } |
| | 1181 | |
| 1176 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { | 1182 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { |
| 1177 | return IrInstSrcIdConst; | 1183 | return IrInstSrcIdConst; |
| 1178 | } | 1184 | } |
| ... | @@ -2442,6 +2448,25 @@ static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode * | ... | @@ -2442,6 +2448,25 @@ static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode * |
| 2442 | return &call_instruction->base; | 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 | static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, | 2470 | static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 2446 | IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, | 2471 | IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, |
| 2447 | ResultLoc *result_loc) | 2472 | ResultLoc *result_loc) |
| ... | @@ -6183,11 +6208,10 @@ static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *nod | ... | @@ -6183,11 +6208,10 @@ static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *nod |
| 6183 | static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, | 6208 | static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, |
| 6184 | LVal lval, ResultLoc *result_loc) | 6209 | LVal lval, ResultLoc *result_loc) |
| 6185 | { | 6210 | { |
| 6186 | size_t arg_offset = 3; | 6211 | if (call_node->data.fn_call_expr.params.length != 4) { |
| 6187 | if (call_node->data.fn_call_expr.params.length < arg_offset) { | | |
| 6188 | add_node_error(irb->codegen, call_node, | 6212 | add_node_error(irb->codegen, call_node, |
| 6189 | buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, | 6213 | buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize, |
| 6190 | arg_offset, call_node->data.fn_call_expr.params.length)); | 6214 | call_node->data.fn_call_expr.params.length)); |
| 6191 | return irb->codegen->invalid_inst_src; | 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,20 +6230,37 @@ static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *aw |
| 6206 | if (fn_ref == irb->codegen->invalid_inst_src) | 6230 | if (fn_ref == irb->codegen->invalid_inst_src) |
| 6207 | return fn_ref; | 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 | CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; | 6233 | CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; |
| 6220 | bool is_async_call_builtin = true; | 6234 | bool is_async_call_builtin = true; |
| 6221 | IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, | 6235 | AstNode *args_node = call_node->data.fn_call_expr.params.at(3); |
| 6222 | ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); | 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 | return ir_lval_wrap(irb, scope, call, lval, result_loc); | 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,7 +20277,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 20236 | // Fork a scope of the function with known values for the parameters. | 20277 | // Fork a scope of the function with known values for the parameters. |
| 20237 | Scope *parent_scope = fn_entry->fndef_scope->base.parent; | 20278 | Scope *parent_scope = fn_entry->fndef_scope->base.parent; |
| 20238 | ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); | 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 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); | 20281 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 20241 | impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); | 20282 | impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); |
| 20242 | impl_fn->child_scope = &impl_fn->fndef_scope->base; | 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,40 +20760,101 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, |
| 20719 | modifier, stack, stack_src, false, args_ptr, args_len, nullptr, result_loc); | 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) { | 20763 | static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_instr, CallModifier modifier, |
| 20723 | IrInstGen *args = instruction->args->child; | 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 | ZigType *args_type = args->value->type; | 20804 | ZigType *args_type = args->value->type; |
| 20725 | if (type_is_invalid(args_type)) | 20805 | if (type_is_invalid(args_type)) |
| 20726 | return ira->codegen->invalid_inst_gen; | 20806 | return false; |
| 20727 | | 20807 | |
| 20728 | if (args_type->id != ZigTypeIdStruct) { | 20808 | if (args_type->id != ZigTypeIdStruct) { |
| 20729 | ir_add_error(ira, &args->base, | 20809 | ir_add_error(ira, &args->base, |
| 20730 | buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); | 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 | if (is_tuple(args_type)) { | 20814 | if (is_tuple(args_type)) { |
| 20738 | args_len = args_type->data.structure.src_field_count; | 20815 | *args_len = args_type->data.structure.src_field_count; |
| 20739 | args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len); | 20816 | *args_ptr = heap::c_allocator.allocate<IrInstGen *>(*args_len); |
| 20740 | for (size_t i = 0; i < args_len; i += 1) { | 20817 | for (size_t i = 0; i < *args_len; i += 1) { |
| 20741 | TypeStructField *arg_field = args_type->data.structure.fields[i]; | 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); | 20819 | (*args_ptr)[i] = ir_analyze_struct_value_field_value(ira, source_instr, args, arg_field); |
| 20743 | if (type_is_invalid(args_ptr[i]->value->type)) | 20820 | if (type_is_invalid((*args_ptr)[i]->value->type)) |
| 20744 | return ira->codegen->invalid_inst_gen; | 20821 | return false; |
| 20745 | } | 20822 | } |
| 20746 | } else { | 20823 | } else { |
| 20747 | ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); | 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 | return ira->codegen->invalid_inst_gen; | 20835 | return ira->codegen->invalid_inst_gen; |
| 20749 | } | 20836 | } |
| | 20837 | |
| 20750 | IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, | 20838 | IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, |
| 20751 | instruction->fn_ref, args_ptr, args_len, instruction->result_loc); | 20839 | instruction->fn_ref, args_ptr, args_len, instruction->result_loc); |
| 20752 | heap::c_allocator.deallocate(args_ptr, args_len); | 20840 | heap::c_allocator.deallocate(args_ptr, args_len); |
| 20753 | return result; | 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 | static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { | 20858 | static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { |
| 20757 | IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); | 20859 | IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); |
| 20758 | for (size_t i = 0; i < instruction->args_len; i += 1) { | 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,6 +31203,8 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc |
| 31101 | return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); | 31203 | return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); |
| 31102 | case IrInstSrcIdCallExtra: | 31204 | case IrInstSrcIdCallExtra: |
| 31103 | return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); | 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 | case IrInstSrcIdBr: | 31208 | case IrInstSrcIdBr: |
| 31105 | return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); | 31209 | return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); |
| 31106 | case IrInstSrcIdCondBr: | 31210 | case IrInstSrcIdCondBr: |
| ... | @@ -31610,6 +31714,7 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { | ... | @@ -31610,6 +31714,7 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { |
| 31610 | case IrInstSrcIdDeclVar: | 31714 | case IrInstSrcIdDeclVar: |
| 31611 | case IrInstSrcIdStorePtr: | 31715 | case IrInstSrcIdStorePtr: |
| 31612 | case IrInstSrcIdCallExtra: | 31716 | case IrInstSrcIdCallExtra: |
| | 31717 | case IrInstSrcIdAsyncCallExtra: |
| 31613 | case IrInstSrcIdCall: | 31718 | case IrInstSrcIdCall: |
| 31614 | case IrInstSrcIdCallArgs: | 31719 | case IrInstSrcIdCallArgs: |
| 31615 | case IrInstSrcIdReturn: | 31720 | case IrInstSrcIdReturn: |