| ... | ... | @@ -265,6 +265,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction |
| 265 | 265 | static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 266 | 266 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); |
| 267 | 267 | static ResultLoc *no_result_loc(void); |
| 268 | static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value); |
| 268 | 269 | |
| 269 | 270 | static void destroy_instruction(IrInstruction *inst) { |
| 270 | 271 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| ... | ... | @@ -289,6 +290,8 @@ static void destroy_instruction(IrInstruction *inst) { |
| 289 | 290 | return destroy(reinterpret_cast<IrInstructionCast *>(inst), name); |
| 290 | 291 | case IrInstructionIdCallSrc: |
| 291 | 292 | return destroy(reinterpret_cast<IrInstructionCallSrc *>(inst), name); |
| 293 | case IrInstructionIdCallExtra: |
| 294 | return destroy(reinterpret_cast<IrInstructionCallExtra *>(inst), name); |
| 292 | 295 | case IrInstructionIdCallGen: |
| 293 | 296 | return destroy(reinterpret_cast<IrInstructionCallGen *>(inst), name); |
| 294 | 297 | case IrInstructionIdUnOp: |
| ... | ... | @@ -705,6 +708,13 @@ static bool is_opt_err_set(ZigType *ty) { |
| 705 | 708 | (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); |
| 706 | 709 | } |
| 707 | 710 | |
| 711 | static bool is_tuple(ZigType *type) { |
| 712 | return type->id == ZigTypeIdStruct && type->data.structure.decl_node != nullptr && |
| 713 | type->data.structure.decl_node->type == NodeTypeContainerInitExpr && |
| 714 | (type->data.structure.decl_node->data.container_init_expr.kind == ContainerInitKindArray || |
| 715 | type->data.structure.decl_node->data.container_init_expr.entries.length == 0); |
| 716 | } |
| 717 | |
| 708 | 718 | static bool is_slice(ZigType *type) { |
| 709 | 719 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| 710 | 720 | } |
| ... | ... | @@ -968,6 +978,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { |
| 968 | 978 | return IrInstructionIdCallSrc; |
| 969 | 979 | } |
| 970 | 980 | |
| 981 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallExtra *) { |
| 982 | return IrInstructionIdCallExtra; |
| 983 | } |
| 984 | |
| 971 | 985 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { |
| 972 | 986 | return IrInstructionIdCallGen; |
| 973 | 987 | } |
| ... | ... | @@ -1891,30 +1905,42 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1891 | 1905 | return &instruction->base; |
| 1892 | 1906 | } |
| 1893 | 1907 | |
| 1908 | static IrInstruction *ir_build_call_extra(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1909 | IrInstruction *options, IrInstruction *fn_ref, IrInstruction *args, ResultLoc *result_loc) |
| 1910 | { |
| 1911 | IrInstructionCallExtra *call_instruction = ir_build_instruction<IrInstructionCallExtra>(irb, scope, source_node); |
| 1912 | call_instruction->options = options; |
| 1913 | call_instruction->fn_ref = fn_ref; |
| 1914 | call_instruction->args = args; |
| 1915 | call_instruction->result_loc = result_loc; |
| 1916 | |
| 1917 | ir_ref_instruction(options, irb->current_basic_block); |
| 1918 | ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1919 | ir_ref_instruction(args, irb->current_basic_block); |
| 1920 | |
| 1921 | return &call_instruction->base; |
| 1922 | } |
| 1923 | |
| 1894 | 1924 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1895 | 1925 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1896 | | bool is_comptime, FnInline fn_inline, CallModifier modifier, bool is_async_call_builtin, |
| 1926 | IrInstruction *ret_ptr, CallModifier modifier, bool is_async_call_builtin, |
| 1897 | 1927 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1898 | 1928 | { |
| 1899 | 1929 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1900 | 1930 | call_instruction->fn_entry = fn_entry; |
| 1901 | 1931 | call_instruction->fn_ref = fn_ref; |
| 1902 | | call_instruction->is_comptime = is_comptime; |
| 1903 | | call_instruction->fn_inline = fn_inline; |
| 1904 | 1932 | call_instruction->args = args; |
| 1905 | 1933 | call_instruction->arg_count = arg_count; |
| 1906 | 1934 | call_instruction->modifier = modifier; |
| 1907 | 1935 | call_instruction->is_async_call_builtin = is_async_call_builtin; |
| 1908 | 1936 | call_instruction->new_stack = new_stack; |
| 1909 | 1937 | call_instruction->result_loc = result_loc; |
| 1938 | call_instruction->ret_ptr = ret_ptr; |
| 1910 | 1939 | |
| 1911 | 1940 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1912 | 1941 | for (size_t i = 0; i < arg_count; i += 1) |
| 1913 | 1942 | ir_ref_instruction(args[i], irb->current_basic_block); |
| 1914 | | if (modifier == CallModifierAsync && new_stack != nullptr) { |
| 1915 | | // in this case the arg at the end is the return pointer |
| 1916 | | ir_ref_instruction(args[arg_count], irb->current_basic_block); |
| 1917 | | } |
| 1943 | if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); |
| 1918 | 1944 | if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); |
| 1919 | 1945 | |
| 1920 | 1946 | return &call_instruction->base; |
| ... | ... | @@ -1922,7 +1948,7 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s |
| 1922 | 1948 | |
| 1923 | 1949 | static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1924 | 1950 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1925 | | FnInline fn_inline, CallModifier modifier, IrInstruction *new_stack, bool is_async_call_builtin, |
| 1951 | CallModifier modifier, IrInstruction *new_stack, bool is_async_call_builtin, |
| 1926 | 1952 | IrInstruction *result_loc, ZigType *return_type) |
| 1927 | 1953 | { |
| 1928 | 1954 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| ... | ... | @@ -1930,7 +1956,6 @@ static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *so |
| 1930 | 1956 | call_instruction->base.value->type = return_type; |
| 1931 | 1957 | call_instruction->fn_entry = fn_entry; |
| 1932 | 1958 | call_instruction->fn_ref = fn_ref; |
| 1933 | | call_instruction->fn_inline = fn_inline; |
| 1934 | 1959 | call_instruction->args = args; |
| 1935 | 1960 | call_instruction->arg_count = arg_count; |
| 1936 | 1961 | call_instruction->modifier = modifier; |
| ... | ... | @@ -5054,10 +5079,7 @@ static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *a |
| 5054 | 5079 | return fn_ref; |
| 5055 | 5080 | |
| 5056 | 5081 | size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; |
| 5057 | | |
| 5058 | | // last "arg" is return pointer |
| 5059 | | IrInstruction **args = allocate<IrInstruction*>(arg_count + 1); |
| 5060 | | |
| 5082 | IrInstruction **args = allocate<IrInstruction*>(arg_count); |
| 5061 | 5083 | for (size_t i = 0; i < arg_count; i += 1) { |
| 5062 | 5084 | AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); |
| 5063 | 5085 | IrInstruction *arg = ir_gen_node(irb, arg_node, scope); |
| ... | ... | @@ -5066,12 +5088,10 @@ static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *a |
| 5066 | 5088 | args[i] = arg; |
| 5067 | 5089 | } |
| 5068 | 5090 | |
| 5069 | | args[arg_count] = ret_ptr; |
| 5070 | | |
| 5071 | 5091 | CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; |
| 5072 | 5092 | bool is_async_call_builtin = true; |
| 5073 | | IrInstruction *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, false, |
| 5074 | | FnInlineAuto, modifier, is_async_call_builtin, bytes, result_loc); |
| 5093 | IrInstruction *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, |
| 5094 | ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); |
| 5075 | 5095 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 5076 | 5096 | } |
| 5077 | 5097 | |
| ... | ... | @@ -6015,10 +6035,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 6015 | 6035 | if (args[i] == irb->codegen->invalid_instruction) |
| 6016 | 6036 | return args[i]; |
| 6017 | 6037 | } |
| 6018 | | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 6038 | CallModifier modifier = (builtin_fn->id == BuiltinFnIdInlineCall) ? |
| 6039 | CallModifierAlwaysInline : CallModifierNeverInline; |
| 6019 | 6040 | |
| 6020 | | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 6021 | | fn_inline, CallModifierNone, false, nullptr, result_loc); |
| 6041 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, |
| 6042 | nullptr, modifier, false, nullptr, result_loc); |
| 6022 | 6043 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 6023 | 6044 | } |
| 6024 | 6045 | case BuiltinFnIdNewStackCall: |
| ... | ... | @@ -6050,10 +6071,36 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 6050 | 6071 | return args[i]; |
| 6051 | 6072 | } |
| 6052 | 6073 | |
| 6053 | | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 6054 | | FnInlineAuto, CallModifierNone, false, new_stack, result_loc); |
| 6074 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, |
| 6075 | nullptr, CallModifierNone, false, new_stack, result_loc); |
| 6055 | 6076 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 6056 | 6077 | } |
| 6078 | case BuiltinFnIdCall: { |
| 6079 | // Cast the options parameter to the options type |
| 6080 | ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); |
| 6081 | IrInstruction *options_type_inst = ir_build_const_type(irb, scope, node, options_type); |
| 6082 | ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); |
| 6083 | |
| 6084 | AstNode *options_node = node->data.fn_call_expr.params.at(0); |
| 6085 | IrInstruction *options_inner = ir_gen_node_extra(irb, options_node, scope, |
| 6086 | LValNone, &result_loc_cast->base); |
| 6087 | if (options_inner == irb->codegen->invalid_instruction) |
| 6088 | return options_inner; |
| 6089 | IrInstruction *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); |
| 6090 | |
| 6091 | AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); |
| 6092 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| 6093 | if (fn_ref == irb->codegen->invalid_instruction) |
| 6094 | return fn_ref; |
| 6095 | |
| 6096 | AstNode *args_node = node->data.fn_call_expr.params.at(2); |
| 6097 | IrInstruction *args = ir_gen_node(irb, args_node, scope); |
| 6098 | if (args == irb->codegen->invalid_instruction) |
| 6099 | return args; |
| 6100 | |
| 6101 | IrInstruction *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); |
| 6102 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 6103 | } |
| 6057 | 6104 | case BuiltinFnIdAsyncCall: |
| 6058 | 6105 | return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); |
| 6059 | 6106 | case BuiltinFnIdTypeId: |
| ... | ... | @@ -6395,8 +6442,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 6395 | 6442 | args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); |
| 6396 | 6443 | } |
| 6397 | 6444 | |
| 6398 | | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 6399 | | FnInlineAuto, node->data.fn_call_expr.modifier, false, nullptr, result_loc); |
| 6445 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, nullptr, |
| 6446 | node->data.fn_call_expr.modifier, false, nullptr, result_loc); |
| 6400 | 6447 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 6401 | 6448 | } |
| 6402 | 6449 | |
| ... | ... | @@ -14102,9 +14149,7 @@ static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, Atomic |
| 14102 | 14149 | if (type_is_invalid(value->value->type)) |
| 14103 | 14150 | return false; |
| 14104 | 14151 | |
| 14105 | | ZigValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); |
| 14106 | | assert(atomic_order_val->type->id == ZigTypeIdMetaType); |
| 14107 | | ZigType *atomic_order_type = atomic_order_val->data.x_type; |
| 14152 | ZigType *atomic_order_type = get_builtin_type(ira->codegen, "AtomicOrder"); |
| 14108 | 14153 | |
| 14109 | 14154 | IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); |
| 14110 | 14155 | if (type_is_invalid(casted_value->value->type)) |
| ... | ... | @@ -14122,9 +14167,7 @@ static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, Atomi |
| 14122 | 14167 | if (type_is_invalid(value->value->type)) |
| 14123 | 14168 | return false; |
| 14124 | 14169 | |
| 14125 | | ZigValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); |
| 14126 | | assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); |
| 14127 | | ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; |
| 14170 | ZigType *atomic_rmw_op_type = get_builtin_type(ira->codegen, "AtomicRmwOp"); |
| 14128 | 14171 | |
| 14129 | 14172 | IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); |
| 14130 | 14173 | if (type_is_invalid(casted_value->value->type)) |
| ... | ... | @@ -14142,9 +14185,7 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, Glob |
| 14142 | 14185 | if (type_is_invalid(value->value->type)) |
| 14143 | 14186 | return false; |
| 14144 | 14187 | |
| 14145 | | ZigValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); |
| 14146 | | assert(global_linkage_val->type->id == ZigTypeIdMetaType); |
| 14147 | | ZigType *global_linkage_type = global_linkage_val->data.x_type; |
| 14188 | ZigType *global_linkage_type = get_builtin_type(ira->codegen, "GlobalLinkage"); |
| 14148 | 14189 | |
| 14149 | 14190 | IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); |
| 14150 | 14191 | if (type_is_invalid(casted_value->value->type)) |
| ... | ... | @@ -14162,9 +14203,7 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod |
| 14162 | 14203 | if (type_is_invalid(value->value->type)) |
| 14163 | 14204 | return false; |
| 14164 | 14205 | |
| 14165 | | ZigValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); |
| 14166 | | assert(float_mode_val->type->id == ZigTypeIdMetaType); |
| 14167 | | ZigType *float_mode_type = float_mode_val->data.x_type; |
| 14206 | ZigType *float_mode_type = get_builtin_type(ira->codegen, "FloatMode"); |
| 14168 | 14207 | |
| 14169 | 14208 | IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); |
| 14170 | 14209 | if (type_is_invalid(casted_value->value->type)) |
| ... | ... | @@ -16972,11 +17011,11 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst |
| 16972 | 17011 | return ir_const_void(ira, &instruction->base); |
| 16973 | 17012 | } |
| 16974 | 17013 | |
| 16975 | | static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 16976 | | ZigType *fn_ret_type) |
| 17014 | static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstruction *source_instr, |
| 17015 | ZigType *fn_ret_type, bool is_async_call_builtin, IrInstruction **args_ptr, size_t args_len, |
| 17016 | IrInstruction *ret_ptr_uncasted) |
| 16977 | 17017 | { |
| 16978 | | ir_assert(call_instruction->is_async_call_builtin, &call_instruction->base); |
| 16979 | | IrInstruction *ret_ptr_uncasted = call_instruction->args[call_instruction->arg_count]->child; |
| 17018 | ir_assert(is_async_call_builtin, source_instr); |
| 16980 | 17019 | if (type_is_invalid(ret_ptr_uncasted->value->type)) |
| 16981 | 17020 | return ira->codegen->invalid_instruction; |
| 16982 | 17021 | if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { |
| ... | ... | @@ -16986,9 +17025,10 @@ static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstructionCal |
| 16986 | 17025 | return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); |
| 16987 | 17026 | } |
| 16988 | 17027 | |
| 16989 | | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| 17028 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstruction *source_instr, ZigFn *fn_entry, |
| 16990 | 17029 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 16991 | | IrInstruction *casted_new_stack) |
| 17030 | IrInstruction *casted_new_stack, bool is_async_call_builtin, IrInstruction *ret_ptr_uncasted, |
| 17031 | ResultLoc *call_result_loc) |
| 16992 | 17032 | { |
| 16993 | 17033 | if (fn_entry == nullptr) { |
| 16994 | 17034 | if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { |
| ... | ... | @@ -17003,19 +17043,20 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc |
| 17003 | 17043 | } |
| 17004 | 17044 | if (casted_new_stack != nullptr) { |
| 17005 | 17045 | ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; |
| 17006 | | IrInstruction *ret_ptr = get_async_call_result_loc(ira, call_instruction, fn_ret_type); |
| 17046 | IrInstruction *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, |
| 17047 | casted_args, arg_count, ret_ptr_uncasted); |
| 17007 | 17048 | if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) |
| 17008 | 17049 | return ira->codegen->invalid_instruction; |
| 17009 | 17050 | |
| 17010 | 17051 | ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); |
| 17011 | 17052 | |
| 17012 | | IrInstructionCallGen *call_gen = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 17013 | | arg_count, casted_args, FnInlineAuto, CallModifierAsync, casted_new_stack, |
| 17014 | | call_instruction->is_async_call_builtin, ret_ptr, anyframe_type); |
| 17053 | IrInstructionCallGen *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, |
| 17054 | arg_count, casted_args, CallModifierAsync, casted_new_stack, |
| 17055 | is_async_call_builtin, ret_ptr, anyframe_type); |
| 17015 | 17056 | return &call_gen->base; |
| 17016 | 17057 | } else { |
| 17017 | 17058 | ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); |
| 17018 | | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 17059 | IrInstruction *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, |
| 17019 | 17060 | frame_type, nullptr, true, true, false); |
| 17020 | 17061 | if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { |
| 17021 | 17062 | return result_loc; |
| ... | ... | @@ -17023,9 +17064,9 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc |
| 17023 | 17064 | result_loc = ir_implicit_cast(ira, result_loc, get_pointer_to_type(ira->codegen, frame_type, false)); |
| 17024 | 17065 | if (type_is_invalid(result_loc->value->type)) |
| 17025 | 17066 | return ira->codegen->invalid_instruction; |
| 17026 | | return &ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 17027 | | casted_args, FnInlineAuto, CallModifierAsync, casted_new_stack, |
| 17028 | | call_instruction->is_async_call_builtin, result_loc, frame_type)->base; |
| 17067 | return &ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, |
| 17068 | casted_args, CallModifierAsync, casted_new_stack, |
| 17069 | is_async_call_builtin, result_loc, frame_type)->base; |
| 17029 | 17070 | } |
| 17030 | 17071 | } |
| 17031 | 17072 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| ... | ... | @@ -17417,25 +17458,21 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 17417 | 17458 | return &store_ptr->base; |
| 17418 | 17459 | } |
| 17419 | 17460 | |
| 17420 | | static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 17421 | | ZigFn *fn_entry) |
| 17461 | static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstruction *source_instr, |
| 17462 | IrInstruction *new_stack, bool is_async_call_builtin, ZigFn *fn_entry) |
| 17422 | 17463 | { |
| 17423 | | if (call_instruction->new_stack == nullptr) |
| 17464 | if (new_stack == nullptr) |
| 17424 | 17465 | return nullptr; |
| 17425 | 17466 | |
| 17426 | | if (!call_instruction->is_async_call_builtin && |
| 17467 | if (!is_async_call_builtin && |
| 17427 | 17468 | arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr) |
| 17428 | 17469 | { |
| 17429 | | ir_add_error(ira, &call_instruction->base, |
| 17470 | ir_add_error(ira, source_instr, |
| 17430 | 17471 | buf_sprintf("target arch '%s' does not support @newStackCall", |
| 17431 | 17472 | target_arch_name(ira->codegen->zig_target->arch))); |
| 17432 | 17473 | } |
| 17433 | 17474 | |
| 17434 | | IrInstruction *new_stack = call_instruction->new_stack->child; |
| 17435 | | if (type_is_invalid(new_stack->value->type)) |
| 17436 | | return ira->codegen->invalid_instruction; |
| 17437 | | |
| 17438 | | if (call_instruction->is_async_call_builtin && |
| 17475 | if (is_async_call_builtin && |
| 17439 | 17476 | fn_entry != nullptr && new_stack->value->type->id == ZigTypeIdPointer && |
| 17440 | 17477 | new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) |
| 17441 | 17478 | { |
| ... | ... | @@ -17451,9 +17488,11 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCall |
| 17451 | 17488 | } |
| 17452 | 17489 | } |
| 17453 | 17490 | |
| 17454 | | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 17491 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_instr, |
| 17455 | 17492 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 17456 | | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 17493 | IrInstruction *first_arg_ptr, CallModifier modifier, |
| 17494 | IrInstruction *new_stack, bool is_async_call_builtin, |
| 17495 | IrInstruction **args_ptr, size_t args_len, IrInstruction *ret_ptr, ResultLoc *call_result_loc) |
| 17457 | 17496 | { |
| 17458 | 17497 | Error err; |
| 17459 | 17498 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| ... | ... | @@ -17469,16 +17508,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17469 | 17508 | } |
| 17470 | 17509 | size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; |
| 17471 | 17510 | |
| 17472 | | size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; |
| 17473 | | for (size_t i = 0; i < call_instruction->arg_count; i += 1) { |
| 17474 | | ZigValue *arg_tuple_value = call_instruction->args[i]->child->value; |
| 17511 | size_t call_param_count = args_len + first_arg_1_or_0; |
| 17512 | for (size_t i = 0; i < args_len; i += 1) { |
| 17513 | ZigValue *arg_tuple_value = args_ptr[i]->value; |
| 17475 | 17514 | if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { |
| 17476 | 17515 | call_param_count -= 1; |
| 17477 | 17516 | call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - |
| 17478 | 17517 | arg_tuple_value->data.x_arg_tuple.start_index; |
| 17479 | 17518 | } |
| 17480 | 17519 | } |
| 17481 | | AstNode *source_node = call_instruction->base.source_node; |
| 17520 | AstNode *source_node = source_instr->source_node; |
| 17482 | 17521 | |
| 17483 | 17522 | AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; |
| 17484 | 17523 | |
| ... | ... | @@ -17511,14 +17550,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17511 | 17550 | return ira->codegen->invalid_instruction; |
| 17512 | 17551 | } |
| 17513 | 17552 | |
| 17514 | | if (comptime_fn_call) { |
| 17553 | if (modifier == CallModifierCompileTime) { |
| 17515 | 17554 | // No special handling is needed for compile time evaluation of generic functions. |
| 17516 | 17555 | if (!fn_entry || fn_entry->body_node == nullptr) { |
| 17517 | 17556 | ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); |
| 17518 | 17557 | return ira->codegen->invalid_instruction; |
| 17519 | 17558 | } |
| 17520 | 17559 | |
| 17521 | | if (!ir_emit_backward_branch(ira, &call_instruction->base)) |
| 17560 | if (!ir_emit_backward_branch(ira, source_instr)) |
| 17522 | 17561 | return ira->codegen->invalid_instruction; |
| 17523 | 17562 | |
| 17524 | 17563 | // Fork a scope of the function with known values for the parameters. |
| ... | ... | @@ -17550,16 +17589,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17550 | 17589 | } |
| 17551 | 17590 | |
| 17552 | 17591 | if (fn_proto_node->data.fn_proto.is_var_args) { |
| 17553 | | ir_add_error(ira, &call_instruction->base, |
| 17592 | ir_add_error(ira, source_instr, |
| 17554 | 17593 | buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); |
| 17555 | 17594 | return ira->codegen->invalid_instruction; |
| 17556 | 17595 | } |
| 17557 | 17596 | |
| 17558 | 17597 | |
| 17559 | | for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { |
| 17560 | | IrInstruction *old_arg = call_instruction->args[call_i]->child; |
| 17561 | | if (type_is_invalid(old_arg->value->type)) |
| 17562 | | return ira->codegen->invalid_instruction; |
| 17598 | for (size_t call_i = 0; call_i < args_len; call_i += 1) { |
| 17599 | IrInstruction *old_arg = args_ptr[call_i]; |
| 17563 | 17600 | |
| 17564 | 17601 | if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) |
| 17565 | 17602 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -17593,7 +17630,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17593 | 17630 | AstNode *body_node = fn_entry->body_node; |
| 17594 | 17631 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 17595 | 17632 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 17596 | | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, |
| 17633 | nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, |
| 17597 | 17634 | UndefOk); |
| 17598 | 17635 | |
| 17599 | 17636 | if (inferred_err_set_type != nullptr) { |
| ... | ... | @@ -17623,24 +17660,21 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17623 | 17660 | } |
| 17624 | 17661 | } |
| 17625 | 17662 | |
| 17626 | | IrInstruction *new_instruction = ir_const_move(ira, &call_instruction->base, result); |
| 17663 | IrInstruction *new_instruction = ir_const_move(ira, source_instr, result); |
| 17627 | 17664 | return ir_finish_anal(ira, new_instruction); |
| 17628 | 17665 | } |
| 17629 | 17666 | |
| 17630 | 17667 | if (fn_type->data.fn.is_generic) { |
| 17631 | 17668 | if (!fn_entry) { |
| 17632 | | ir_add_error(ira, call_instruction->fn_ref, |
| 17669 | ir_add_error(ira, fn_ref, |
| 17633 | 17670 | buf_sprintf("calling a generic function requires compile-time known function value")); |
| 17634 | 17671 | return ira->codegen->invalid_instruction; |
| 17635 | 17672 | } |
| 17636 | 17673 | |
| 17637 | 17674 | // Count the arguments of the function type id we are creating |
| 17638 | 17675 | size_t new_fn_arg_count = first_arg_1_or_0; |
| 17639 | | for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { |
| 17640 | | IrInstruction *arg = call_instruction->args[call_i]->child; |
| 17641 | | if (type_is_invalid(arg->value->type)) |
| 17642 | | return ira->codegen->invalid_instruction; |
| 17643 | | |
| 17676 | for (size_t call_i = 0; call_i < args_len; call_i += 1) { |
| 17677 | IrInstruction *arg = args_ptr[call_i]; |
| 17644 | 17678 | if (arg->value->type->id == ZigTypeIdArgTuple) { |
| 17645 | 17679 | new_fn_arg_count += arg->value->data.x_arg_tuple.end_index - arg->value->data.x_arg_tuple.start_index; |
| 17646 | 17680 | } else { |
| ... | ... | @@ -17702,10 +17736,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17702 | 17736 | |
| 17703 | 17737 | ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 17704 | 17738 | assert(parent_fn_entry); |
| 17705 | | for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { |
| 17706 | | IrInstruction *arg = call_instruction->args[call_i]->child; |
| 17707 | | if (type_is_invalid(arg->value->type)) |
| 17708 | | return ira->codegen->invalid_instruction; |
| 17739 | for (size_t call_i = 0; call_i < args_len; call_i += 1) { |
| 17740 | IrInstruction *arg = args_ptr[call_i]; |
| 17709 | 17741 | |
| 17710 | 17742 | if (arg->value->type->id == ZigTypeIdArgTuple) { |
| 17711 | 17743 | for (size_t arg_tuple_i = arg->value->data.x_arg_tuple.start_index; |
| ... | ... | @@ -17804,8 +17836,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17804 | 17836 | switch (type_requires_comptime(ira->codegen, specified_return_type)) { |
| 17805 | 17837 | case ReqCompTimeYes: |
| 17806 | 17838 | // Throw out our work and call the function as if it were comptime. |
| 17807 | | return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, |
| 17808 | | true, FnInlineAuto); |
| 17839 | return ir_analyze_fn_call(ira, source_instr, fn_entry, fn_type, fn_ref, first_arg_ptr, |
| 17840 | CallModifierCompileTime, new_stack, is_async_call_builtin, args_ptr, args_len, |
| 17841 | ret_ptr, call_result_loc); |
| 17809 | 17842 | case ReqCompTimeInvalid: |
| 17810 | 17843 | return ira->codegen->invalid_instruction; |
| 17811 | 17844 | case ReqCompTimeNo: |
| ... | ... | @@ -17823,9 +17856,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17823 | 17856 | if (type_is_invalid(impl_fn->type_entry)) |
| 17824 | 17857 | return ira->codegen->invalid_instruction; |
| 17825 | 17858 | |
| 17826 | | impl_fn->ir_executable->source_node = call_instruction->base.source_node; |
| 17859 | impl_fn->ir_executable->source_node = source_instr->source_node; |
| 17827 | 17860 | impl_fn->ir_executable->parent_exec = ira->new_irb.exec; |
| 17828 | | impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; |
| 17861 | impl_fn->analyzed_executable.source_node = source_instr->source_node; |
| 17829 | 17862 | impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; |
| 17830 | 17863 | impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; |
| 17831 | 17864 | impl_fn->analyzed_executable.is_generic_instantiation = true; |
| ... | ... | @@ -17839,32 +17872,35 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17839 | 17872 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 17840 | 17873 | } |
| 17841 | 17874 | |
| 17842 | | IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, impl_fn); |
| 17875 | IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, |
| 17876 | is_async_call_builtin, impl_fn); |
| 17843 | 17877 | if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) |
| 17844 | 17878 | return ira->codegen->invalid_instruction; |
| 17845 | 17879 | |
| 17846 | 17880 | size_t impl_param_count = impl_fn_type_id->param_count; |
| 17847 | | if (call_instruction->modifier == CallModifierAsync) { |
| 17848 | | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 17849 | | nullptr, casted_args, impl_param_count, casted_new_stack); |
| 17881 | if (modifier == CallModifierAsync) { |
| 17882 | IrInstruction *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, |
| 17883 | nullptr, casted_args, impl_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, |
| 17884 | call_result_loc); |
| 17850 | 17885 | return ir_finish_anal(ira, result); |
| 17851 | 17886 | } |
| 17852 | 17887 | |
| 17853 | 17888 | IrInstruction *result_loc; |
| 17854 | 17889 | if (handle_is_ptr(impl_fn_type_id->return_type)) { |
| 17855 | | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 17890 | result_loc = ir_resolve_result(ira, source_instr, call_result_loc, |
| 17856 | 17891 | impl_fn_type_id->return_type, nullptr, true, true, false); |
| 17857 | 17892 | if (result_loc != nullptr) { |
| 17858 | 17893 | if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { |
| 17859 | 17894 | return result_loc; |
| 17860 | 17895 | } |
| 17861 | 17896 | if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { |
| 17862 | | ir_reset_result(call_instruction->result_loc); |
| 17897 | ir_reset_result(call_result_loc); |
| 17863 | 17898 | result_loc = nullptr; |
| 17864 | 17899 | } |
| 17865 | 17900 | } |
| 17866 | | } else if (call_instruction->is_async_call_builtin) { |
| 17867 | | result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type); |
| 17901 | } else if (is_async_call_builtin) { |
| 17902 | result_loc = get_async_call_result_loc(ira, source_instr, impl_fn_type_id->return_type, |
| 17903 | is_async_call_builtin, args_ptr, args_len, ret_ptr); |
| 17868 | 17904 | if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) |
| 17869 | 17905 | return ira->codegen->invalid_instruction; |
| 17870 | 17906 | } else { |
| ... | ... | @@ -17873,18 +17909,17 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17873 | 17909 | |
| 17874 | 17910 | if (impl_fn_type_id->cc == CallingConventionAsync && |
| 17875 | 17911 | parent_fn_entry->inferred_async_node == nullptr && |
| 17876 | | call_instruction->modifier != CallModifierNoAsync) |
| 17912 | modifier != CallModifierNoAsync) |
| 17877 | 17913 | { |
| 17878 | 17914 | parent_fn_entry->inferred_async_node = fn_ref->source_node; |
| 17879 | 17915 | parent_fn_entry->inferred_async_fn = impl_fn; |
| 17880 | 17916 | } |
| 17881 | 17917 | |
| 17882 | | IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 17883 | | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 17884 | | call_instruction->modifier, casted_new_stack, call_instruction->is_async_call_builtin, result_loc, |
| 17885 | | impl_fn_type_id->return_type); |
| 17918 | IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, source_instr, |
| 17919 | impl_fn, nullptr, impl_param_count, casted_args, modifier, casted_new_stack, |
| 17920 | is_async_call_builtin, result_loc, impl_fn_type_id->return_type); |
| 17886 | 17921 | |
| 17887 | | if (get_scope_typeof(call_instruction->base.scope) == nullptr) { |
| 17922 | if (get_scope_typeof(source_instr->scope) == nullptr) { |
| 17888 | 17923 | parent_fn_entry->call_list.append(new_call_instruction); |
| 17889 | 17924 | } |
| 17890 | 17925 | |
| ... | ... | @@ -17926,8 +17961,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17926 | 17961 | casted_args[next_arg_index] = casted_arg; |
| 17927 | 17962 | next_arg_index += 1; |
| 17928 | 17963 | } |
| 17929 | | for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { |
| 17930 | | IrInstruction *old_arg = call_instruction->args[call_i]->child; |
| 17964 | for (size_t call_i = 0; call_i < args_len; call_i += 1) { |
| 17965 | IrInstruction *old_arg = args_ptr[call_i]; |
| 17931 | 17966 | if (type_is_invalid(old_arg->value->type)) |
| 17932 | 17967 | return ira->codegen->invalid_instruction; |
| 17933 | 17968 | |
| ... | ... | @@ -17988,25 +18023,26 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17988 | 18023 | if (type_is_invalid(return_type)) |
| 17989 | 18024 | return ira->codegen->invalid_instruction; |
| 17990 | 18025 | |
| 17991 | | if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { |
| 17992 | | ir_add_error(ira, &call_instruction->base, |
| 18026 | if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && modifier == CallModifierNeverInline) { |
| 18027 | ir_add_error(ira, source_instr, |
| 17993 | 18028 | buf_sprintf("no-inline call of inline function")); |
| 17994 | 18029 | return ira->codegen->invalid_instruction; |
| 17995 | 18030 | } |
| 17996 | 18031 | |
| 17997 | | IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, fn_entry); |
| 18032 | IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, |
| 18033 | is_async_call_builtin, fn_entry); |
| 17998 | 18034 | if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) |
| 17999 | 18035 | return ira->codegen->invalid_instruction; |
| 18000 | 18036 | |
| 18001 | | if (call_instruction->modifier == CallModifierAsync) { |
| 18002 | | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 18003 | | casted_args, call_param_count, casted_new_stack); |
| 18037 | if (modifier == CallModifierAsync) { |
| 18038 | IrInstruction *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, |
| 18039 | casted_args, call_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); |
| 18004 | 18040 | return ir_finish_anal(ira, result); |
| 18005 | 18041 | } |
| 18006 | 18042 | |
| 18007 | 18043 | if (fn_type_id->cc == CallingConventionAsync && |
| 18008 | 18044 | parent_fn_entry->inferred_async_node == nullptr && |
| 18009 | | call_instruction->modifier != CallModifierNoAsync) |
| 18045 | modifier != CallModifierNoAsync) |
| 18010 | 18046 | { |
| 18011 | 18047 | parent_fn_entry->inferred_async_node = fn_ref->source_node; |
| 18012 | 18048 | parent_fn_entry->inferred_async_fn = fn_entry; |
| ... | ... | @@ -18014,41 +18050,163 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 18014 | 18050 | |
| 18015 | 18051 | IrInstruction *result_loc; |
| 18016 | 18052 | if (handle_is_ptr(return_type)) { |
| 18017 | | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 18053 | result_loc = ir_resolve_result(ira, source_instr, call_result_loc, |
| 18018 | 18054 | return_type, nullptr, true, true, false); |
| 18019 | 18055 | if (result_loc != nullptr) { |
| 18020 | 18056 | if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { |
| 18021 | 18057 | return result_loc; |
| 18022 | 18058 | } |
| 18023 | 18059 | if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { |
| 18024 | | ir_reset_result(call_instruction->result_loc); |
| 18060 | ir_reset_result(call_result_loc); |
| 18025 | 18061 | result_loc = nullptr; |
| 18026 | 18062 | } |
| 18027 | 18063 | } |
| 18028 | | } else if (call_instruction->is_async_call_builtin) { |
| 18029 | | result_loc = get_async_call_result_loc(ira, call_instruction, return_type); |
| 18064 | } else if (is_async_call_builtin) { |
| 18065 | result_loc = get_async_call_result_loc(ira, source_instr, return_type, is_async_call_builtin, |
| 18066 | args_ptr, args_len, ret_ptr); |
| 18030 | 18067 | if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) |
| 18031 | 18068 | return ira->codegen->invalid_instruction; |
| 18032 | 18069 | } else { |
| 18033 | 18070 | result_loc = nullptr; |
| 18034 | 18071 | } |
| 18035 | 18072 | |
| 18036 | | IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 18037 | | call_param_count, casted_args, fn_inline, call_instruction->modifier, casted_new_stack, |
| 18038 | | call_instruction->is_async_call_builtin, result_loc, return_type); |
| 18039 | | if (get_scope_typeof(call_instruction->base.scope) == nullptr) { |
| 18073 | IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, |
| 18074 | call_param_count, casted_args, modifier, casted_new_stack, |
| 18075 | is_async_call_builtin, result_loc, return_type); |
| 18076 | if (get_scope_typeof(source_instr->scope) == nullptr) { |
| 18040 | 18077 | parent_fn_entry->call_list.append(new_call_instruction); |
| 18041 | 18078 | } |
| 18042 | 18079 | return ir_finish_anal(ira, &new_call_instruction->base); |
| 18043 | 18080 | } |
| 18044 | 18081 | |
| 18082 | static IrInstruction *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 18083 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 18084 | IrInstruction *first_arg_ptr, CallModifier modifier) |
| 18085 | { |
| 18086 | IrInstruction *new_stack = nullptr; |
| 18087 | if (call_instruction->new_stack) { |
| 18088 | new_stack = call_instruction->new_stack->child; |
| 18089 | if (type_is_invalid(new_stack->value->type)) |
| 18090 | return ira->codegen->invalid_instruction; |
| 18091 | } |
| 18092 | IrInstruction **args_ptr = allocate<IrInstruction *>(call_instruction->arg_count, "IrInstruction *"); |
| 18093 | for (size_t i = 0; i < call_instruction->arg_count; i += 1) { |
| 18094 | args_ptr[i] = call_instruction->args[i]->child; |
| 18095 | if (type_is_invalid(args_ptr[i]->value->type)) |
| 18096 | return ira->codegen->invalid_instruction; |
| 18097 | } |
| 18098 | IrInstruction *ret_ptr = nullptr; |
| 18099 | if (call_instruction->ret_ptr != nullptr) { |
| 18100 | ret_ptr = call_instruction->ret_ptr->child; |
| 18101 | if (type_is_invalid(ret_ptr->value->type)) |
| 18102 | return ira->codegen->invalid_instruction; |
| 18103 | } |
| 18104 | IrInstruction *result = ir_analyze_fn_call(ira, &call_instruction->base, fn_entry, fn_type, fn_ref, |
| 18105 | first_arg_ptr, modifier, new_stack, call_instruction->is_async_call_builtin, |
| 18106 | args_ptr, call_instruction->arg_count, ret_ptr, call_instruction->result_loc); |
| 18107 | deallocate(args_ptr, call_instruction->arg_count, "IrInstruction *"); |
| 18108 | return result; |
| 18109 | } |
| 18110 | |
| 18111 | static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstructionCallExtra *instruction) { |
| 18112 | IrInstruction *options = instruction->options->child; |
| 18113 | if (type_is_invalid(options->value->type)) |
| 18114 | return ira->codegen->invalid_instruction; |
| 18115 | |
| 18116 | IrInstruction *fn_ref = instruction->fn_ref->child; |
| 18117 | if (type_is_invalid(fn_ref->value->type)) |
| 18118 | return ira->codegen->invalid_instruction; |
| 18119 | ZigFn *fn = ir_resolve_fn(ira, fn_ref); |
| 18120 | ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; |
| 18121 | |
| 18122 | IrInstruction *args = instruction->args->child; |
| 18123 | ZigType *args_type = args->value->type; |
| 18124 | if (type_is_invalid(args_type)) |
| 18125 | return ira->codegen->invalid_instruction; |
| 18126 | |
| 18127 | if (args_type->id != ZigTypeIdStruct) { |
| 18128 | ir_add_error(ira, args, |
| 18129 | buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); |
| 18130 | return ira->codegen->invalid_instruction; |
| 18131 | } |
| 18132 | |
| 18133 | IrInstruction **args_ptr = nullptr; |
| 18134 | size_t args_len = 0; |
| 18135 | |
| 18136 | if (is_tuple(args_type)) { |
| 18137 | args_len = args_type->data.structure.src_field_count; |
| 18138 | args_ptr = allocate<IrInstruction *>(args_len, "IrInstruction *"); |
| 18139 | for (size_t i = 0; i < args_len; i += 1) { |
| 18140 | TypeStructField *arg_field = args_type->data.structure.fields[i]; |
| 18141 | args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base, args, arg_field); |
| 18142 | if (type_is_invalid(args_ptr[i]->value->type)) |
| 18143 | return ira->codegen->invalid_instruction; |
| 18144 | } |
| 18145 | } else { |
| 18146 | ir_add_error(ira, args, buf_sprintf("TODO: struct args")); |
| 18147 | return ira->codegen->invalid_instruction; |
| 18148 | } |
| 18149 | |
| 18150 | TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); |
| 18151 | ir_assert(modifier_field != nullptr, &instruction->base); |
| 18152 | IrInstruction *modifier_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, modifier_field); |
| 18153 | ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); |
| 18154 | if (modifier_val == nullptr) |
| 18155 | return ira->codegen->invalid_instruction; |
| 18156 | CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); |
| 18157 | if (modifier == CallModifierAsync) { |
| 18158 | ir_add_error(ira, args, buf_sprintf("TODO: @call with async modifier")); |
| 18159 | return ira->codegen->invalid_instruction; |
| 18160 | } |
| 18161 | if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { |
| 18162 | switch (modifier) { |
| 18163 | case CallModifierBuiltin: |
| 18164 | zig_unreachable(); |
| 18165 | case CallModifierAsync: |
| 18166 | ir_add_error(ira, args, buf_sprintf("TODO: comptime @call with async modifier")); |
| 18167 | return ira->codegen->invalid_instruction; |
| 18168 | case CallModifierCompileTime: |
| 18169 | case CallModifierNone: |
| 18170 | case CallModifierAlwaysInline: |
| 18171 | case CallModifierAlwaysTail: |
| 18172 | case CallModifierNoAsync: |
| 18173 | modifier = CallModifierCompileTime; |
| 18174 | break; |
| 18175 | case CallModifierNeverInline: |
| 18176 | ir_add_error(ira, args, |
| 18177 | buf_sprintf("unable to perform 'never_inline' call at compile-time")); |
| 18178 | return ira->codegen->invalid_instruction; |
| 18179 | case CallModifierNeverTail: |
| 18180 | ir_add_error(ira, args, |
| 18181 | buf_sprintf("unable to perform 'never_tail' call at compile-time")); |
| 18182 | return ira->codegen->invalid_instruction; |
| 18183 | } |
| 18184 | } |
| 18185 | |
| 18186 | TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); |
| 18187 | ir_assert(stack_field != nullptr, &instruction->base); |
| 18188 | IrInstruction *stack = ir_analyze_struct_value_field_value(ira, &instruction->base, options, stack_field); |
| 18189 | IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, &instruction->base, stack); |
| 18190 | bool stack_is_non_null; |
| 18191 | if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) |
| 18192 | return ira->codegen->invalid_instruction; |
| 18193 | if (!stack_is_non_null) |
| 18194 | stack = nullptr; |
| 18195 | |
| 18196 | IrInstruction *result = ir_analyze_fn_call(ira, &instruction->base, fn, fn_type, fn_ref, nullptr, |
| 18197 | modifier, stack, false, args_ptr, args_len, nullptr, instruction->result_loc); |
| 18198 | deallocate(args_ptr, args_len, "IrInstruction *"); |
| 18199 | return result; |
| 18200 | } |
| 18201 | |
| 18045 | 18202 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 18046 | 18203 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 18047 | 18204 | if (type_is_invalid(fn_ref->value->type)) |
| 18048 | 18205 | return ira->codegen->invalid_instruction; |
| 18049 | 18206 | |
| 18050 | | bool is_comptime = call_instruction->is_comptime || |
| 18207 | bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) || |
| 18051 | 18208 | ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); |
| 18209 | CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; |
| 18052 | 18210 | |
| 18053 | 18211 | if (is_comptime || instr_is_comptime(fn_ref)) { |
| 18054 | 18212 | if (fn_ref->value->type->id == ZigTypeIdMetaType) { |
| ... | ... | @@ -18063,14 +18221,16 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 18063 | 18221 | } else if (fn_ref->value->type->id == ZigTypeIdFn) { |
| 18064 | 18222 | ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); |
| 18065 | 18223 | ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; |
| 18066 | | return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_type, |
| 18067 | | fn_ref, nullptr, is_comptime, call_instruction->fn_inline); |
| 18224 | CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; |
| 18225 | return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, |
| 18226 | fn_ref, nullptr, modifier); |
| 18068 | 18227 | } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { |
| 18069 | 18228 | assert(fn_ref->value->special == ConstValSpecialStatic); |
| 18070 | 18229 | ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; |
| 18071 | 18230 | IrInstruction *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; |
| 18072 | | return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, |
| 18073 | | fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); |
| 18231 | CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; |
| 18232 | return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, |
| 18233 | fn_ref, first_arg_ptr, modifier); |
| 18074 | 18234 | } else { |
| 18075 | 18235 | ir_add_error_node(ira, fn_ref->source_node, |
| 18076 | 18236 | buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); |
| ... | ... | @@ -18079,8 +18239,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 18079 | 18239 | } |
| 18080 | 18240 | |
| 18081 | 18241 | if (fn_ref->value->type->id == ZigTypeIdFn) { |
| 18082 | | return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value->type, |
| 18083 | | fn_ref, nullptr, false, call_instruction->fn_inline); |
| 18242 | return ir_analyze_fn_call_src(ira, call_instruction, nullptr, fn_ref->value->type, |
| 18243 | fn_ref, nullptr, modifier); |
| 18084 | 18244 | } else { |
| 18085 | 18245 | ir_add_error_node(ira, fn_ref->source_node, |
| 18086 | 18246 | buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); |
| ... | ... | @@ -21794,9 +21954,7 @@ static void ensure_field_index(ZigType *type, const char *field_name, size_t ind |
| 21794 | 21954 | |
| 21795 | 21955 | static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { |
| 21796 | 21956 | Error err; |
| 21797 | | ZigValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); |
| 21798 | | assert(type_info_var->type->id == ZigTypeIdMetaType); |
| 21799 | | ZigType *type_info_type = type_info_var->data.x_type; |
| 21957 | ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo"); |
| 21800 | 21958 | assert(type_info_type->id == ZigTypeIdUnion); |
| 21801 | 21959 | if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { |
| 21802 | 21960 | zig_unreachable(); |
| ... | ... | @@ -23026,9 +23184,7 @@ static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, |
| 23026 | 23184 | if (type_is_invalid(type_entry)) |
| 23027 | 23185 | return ira->codegen->invalid_instruction; |
| 23028 | 23186 | |
| 23029 | | ZigValue *var_value = get_builtin_value(ira->codegen, "TypeId"); |
| 23030 | | assert(var_value->type->id == ZigTypeIdMetaType); |
| 23031 | | ZigType *result_type = var_value->data.x_type; |
| 23187 | ZigType *result_type = get_builtin_type(ira->codegen, "TypeId"); |
| 23032 | 23188 | |
| 23033 | 23189 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); |
| 23034 | 23190 | bigint_init_unsigned(&result->value->data.x_enum_tag, type_id_index(type_entry)); |
| ... | ... | @@ -27779,6 +27935,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 27779 | 27935 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 27780 | 27936 | case IrInstructionIdCallSrc: |
| 27781 | 27937 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 27938 | case IrInstructionIdCallExtra: |
| 27939 | return ir_analyze_instruction_call_extra(ira, (IrInstructionCallExtra *)instruction); |
| 27782 | 27940 | case IrInstructionIdBr: |
| 27783 | 27941 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 27784 | 27942 | case IrInstructionIdCondBr: |
| ... | ... | @@ -28176,6 +28334,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 28176 | 28334 | case IrInstructionIdDeclVarGen: |
| 28177 | 28335 | case IrInstructionIdStorePtr: |
| 28178 | 28336 | case IrInstructionIdVectorStoreElem: |
| 28337 | case IrInstructionIdCallExtra: |
| 28179 | 28338 | case IrInstructionIdCallSrc: |
| 28180 | 28339 | case IrInstructionIdCallGen: |
| 28181 | 28340 | case IrInstructionIdReturn: |