| ... | ... | @@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi |
| 2766 | 2766 | return &instruction->base; |
| 2767 | 2767 | } |
| 2768 | 2768 | |
| 2769 | | static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc **values, size_t value_count) { |
| 2769 | static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 2770 | IrInstSrc **values, size_t value_count) |
| 2771 | { |
| 2772 | assert(value_count >= 2); |
| 2773 | |
| 2770 | 2774 | IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); |
| 2771 | | instruction->values = values; |
| 2775 | instruction->value.list = values; |
| 2772 | 2776 | instruction->value_count = value_count; |
| 2773 | 2777 | |
| 2774 | 2778 | for (size_t i = 0; i < value_count; i++) |
| ... | ... | @@ -2777,6 +2781,15 @@ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *sour |
| 2777 | 2781 | return &instruction->base; |
| 2778 | 2782 | } |
| 2779 | 2783 | |
| 2784 | static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { |
| 2785 | IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); |
| 2786 | instruction->value.scalar = value; |
| 2787 | |
| 2788 | ir_ref_instruction(value, irb->current_basic_block); |
| 2789 | |
| 2790 | return &instruction->base; |
| 2791 | } |
| 2792 | |
| 2780 | 2793 | static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { |
| 2781 | 2794 | IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); |
| 2782 | 2795 | instruction->is_cold = is_cold; |
| ... | ... | @@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN |
| 6045 | 6058 | if (fn_ref == irb->codegen->invalid_inst_src) |
| 6046 | 6059 | return fn_ref; |
| 6047 | 6060 | |
| 6048 | | IrInstSrc **typeof_args = heap::c_allocator.allocate<IrInstSrc*>(1); |
| 6049 | | typeof_args[0] = fn_ref; |
| 6050 | | IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, typeof_args, 1); |
| 6061 | IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref); |
| 6051 | 6062 | |
| 6052 | 6063 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); |
| 6053 | 6064 | for (size_t i = 0; i < args_len; i += 1) { |
| ... | ... | @@ -6110,22 +6121,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 6110 | 6121 | |
| 6111 | 6122 | size_t arg_count = node->data.fn_call_expr.params.length; |
| 6112 | 6123 | |
| 6113 | | if (arg_count < 1) { |
| 6124 | IrInstSrc *type_of; |
| 6125 | |
| 6126 | if (arg_count == 0) { |
| 6114 | 6127 | add_node_error(irb->codegen, node, |
| 6115 | 6128 | buf_sprintf("expected at least 1 argument, found 0")); |
| 6116 | 6129 | return irb->codegen->invalid_inst_src; |
| 6117 | | } |
| 6130 | } else if (arg_count == 1) { |
| 6131 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 6132 | IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope); |
| 6133 | if (arg0_value == irb->codegen->invalid_inst_src) |
| 6134 | return arg0_value; |
| 6118 | 6135 | |
| 6119 | | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); |
| 6120 | | for (size_t i = 0; i < arg_count; i += 1) { |
| 6121 | | AstNode *arg_node = node->data.fn_call_expr.params.at(i); |
| 6122 | | IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); |
| 6123 | | if (arg == irb->codegen->invalid_inst_src) |
| 6124 | | return irb->codegen->invalid_inst_src; |
| 6125 | | args[i] = arg; |
| 6126 | | } |
| 6136 | type_of = ir_build_typeof_1(irb, scope, node, arg0_value); |
| 6137 | } else { |
| 6138 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); |
| 6139 | for (size_t i = 0; i < arg_count; i += 1) { |
| 6140 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); |
| 6141 | IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); |
| 6142 | if (arg == irb->codegen->invalid_inst_src) |
| 6143 | return irb->codegen->invalid_inst_src; |
| 6144 | args[i] = arg; |
| 6145 | } |
| 6127 | 6146 | |
| 6128 | | IrInstSrc *type_of = ir_build_typeof(irb, scope, node, args, arg_count); |
| 6147 | type_of = ir_build_typeof_n(irb, scope, node, args, arg_count); |
| 6148 | } |
| 6129 | 6149 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 6130 | 6150 | } |
| 6131 | 6151 | case BuiltinFnIdSetCold: |
| ... | ... | @@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf |
| 21684 | 21704 | |
| 21685 | 21705 | // Fast path for the common case of TypeOf with a single argument |
| 21686 | 21706 | if (value_count < 2) { |
| 21687 | | type_entry = typeof_instruction->values[0]->child->value->type; |
| 21707 | type_entry = typeof_instruction->value.scalar->child->value->type; |
| 21688 | 21708 | } else { |
| 21689 | 21709 | IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count); |
| 21690 | 21710 | for (size_t i = 0; i < value_count; i += 1) { |
| 21691 | | IrInstGen *value = typeof_instruction->values[i]->child; |
| 21711 | IrInstGen *value = typeof_instruction->value.list[i]->child; |
| 21692 | 21712 | if (type_is_invalid(value->value->type)) |
| 21693 | 21713 | return ira->codegen->invalid_inst_gen; |
| 21694 | 21714 | args[i] = value; |