| ... | @@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi | ... | @@ -2766,9 +2766,13 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi |
| 2766 | return &instruction->base; | 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 | IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); | 2774 | IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); |
| 2771 | instruction->values = values; | 2775 | instruction->value.list = values; |
| 2772 | instruction->value_count = value_count; | 2776 | instruction->value_count = value_count; |
| 2773 | | 2777 | |
| 2774 | for (size_t i = 0; i < value_count; i++) | 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,6 +2781,15 @@ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *sour |
| 2777 | return &instruction->base; | 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 | static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { | 2793 | static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { |
| 2781 | IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); | 2794 | IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); |
| 2782 | instruction->is_cold = is_cold; | 2795 | instruction->is_cold = is_cold; |
| ... | @@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN | ... | @@ -6045,9 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN |
| 6045 | if (fn_ref == irb->codegen->invalid_inst_src) | 6058 | if (fn_ref == irb->codegen->invalid_inst_src) |
| 6046 | return fn_ref; | 6059 | return fn_ref; |
| 6047 | | 6060 | |
| 6048 | IrInstSrc **typeof_args = heap::c_allocator.allocate<IrInstSrc*>(1); | 6061 | IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref); |
| 6049 | typeof_args[0] = fn_ref; | | |
| 6050 | IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, typeof_args, 1); | | |
| 6051 | | 6062 | |
| 6052 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); | 6063 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); |
| 6053 | for (size_t i = 0; i < args_len; i += 1) { | 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,22 +6121,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 6110 | | 6121 | |
| 6111 | size_t arg_count = node->data.fn_call_expr.params.length; | 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 | add_node_error(irb->codegen, node, | 6127 | add_node_error(irb->codegen, node, |
| 6115 | buf_sprintf("expected at least 1 argument, found 0")); | 6128 | buf_sprintf("expected at least 1 argument, found 0")); |
| 6116 | return irb->codegen->invalid_inst_src; | 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); | 6136 | type_of = ir_build_typeof_1(irb, scope, node, arg0_value); |
| 6120 | for (size_t i = 0; i < arg_count; i += 1) { | 6137 | } else { |
| 6121 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); | 6138 | IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); |
| 6122 | IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); | 6139 | for (size_t i = 0; i < arg_count; i += 1) { |
| 6123 | if (arg == irb->codegen->invalid_inst_src) | 6140 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); |
| 6124 | return irb->codegen->invalid_inst_src; | 6141 | IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); |
| 6125 | args[i] = arg; | 6142 | if (arg == irb->codegen->invalid_inst_src) |
| 6126 | } | 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 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); | 6149 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 6130 | } | 6150 | } |
| 6131 | case BuiltinFnIdSetCold: | 6151 | case BuiltinFnIdSetCold: |
| ... | @@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf | ... | @@ -21684,11 +21704,11 @@ static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf |
| 21684 | | 21704 | |
| 21685 | // Fast path for the common case of TypeOf with a single argument | 21705 | // Fast path for the common case of TypeOf with a single argument |
| 21686 | if (value_count < 2) { | 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 | } else { | 21708 | } else { |
| 21689 | IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count); | 21709 | IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count); |
| 21690 | for (size_t i = 0; i < value_count; i += 1) { | 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 | if (type_is_invalid(value->value->type)) | 21712 | if (type_is_invalid(value->value->type)) |
| 21693 | return ira->codegen->invalid_inst_gen; | 21713 | return ira->codegen->invalid_inst_gen; |
| 21694 | args[i] = value; | 21714 | args[i] = value; |