@@ -2766,11 +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 *value ) {
2769
+ static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc **values, size_t value_count ) {
2770
2770
IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2771
- instruction->value = value;
2771
+ instruction->values = values;
2772
+ instruction->value_count = value_count;
2772
2773
2773
- ir_ref_instruction(value, irb->current_basic_block);
2774
+ for (size_t i = 0; i < value_count; i++)
2775
+ ir_ref_instruction(values[i], irb->current_basic_block);
2774
2776
2775
2777
return &instruction->base;
2776
2778
}
@@ -6043,7 +6045,9 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN
6043
6045
if (fn_ref == irb->codegen->invalid_inst_src)
6044
6046
return fn_ref;
6045
6047
6046
- IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref);
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);
6047
6051
6048
6052
IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
6049
6053
for (size_t i = 0; i < args_len; i += 1) {
@@ -6104,12 +6108,24 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
6104
6108
{
6105
6109
Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope);
6106
6110
6107
- AstNode *arg_node = node->data.fn_call_expr.params.at(0);
6108
- IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
6109
- if (arg == irb->codegen->invalid_inst_src)
6110
- return arg;
6111
+ size_t arg_count = node->data.fn_call_expr.params.length;
6112
+
6113
+ if (arg_count < 1) {
6114
+ add_node_error(irb->codegen, node,
6115
+ buf_sprintf("expected at least 1 argument, found 0"));
6116
+ return irb->codegen->invalid_inst_src;
6117
+ }
6118
+
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
+ }
6111
6127
6112
- IrInstSrc *type_of = ir_build_typeof(irb, scope, node, arg );
6128
+ IrInstSrc *type_of = ir_build_typeof(irb, scope, node, args, arg_count );
6113
6129
return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
6114
6130
}
6115
6131
case BuiltinFnIdSetCold:
@@ -21662,10 +21678,31 @@ static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadP
21662
21678
}
21663
21679
21664
21680
static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) {
21665
- IrInstGen *expr_value = typeof_instruction->value->child;
21666
- ZigType *type_entry = expr_value->value->type;
21681
+ ZigType *type_entry;
21682
+
21683
+ const size_t value_count = typeof_instruction->value_count;
21684
+
21685
+ // Fast path for the common case of TypeOf with a single argument
21686
+ if (value_count < 2) {
21687
+ type_entry = typeof_instruction->values[0]->child->value->type;
21688
+ } else {
21689
+ IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count);
21690
+ for (size_t i = 0; i < value_count; i += 1) {
21691
+ IrInstGen *value = typeof_instruction->values[i]->child;
21692
+ if (type_is_invalid(value->value->type))
21693
+ return ira->codegen->invalid_inst_gen;
21694
+ args[i] = value;
21695
+ }
21696
+
21697
+ type_entry = ir_resolve_peer_types(ira, typeof_instruction->base.base.source_node,
21698
+ nullptr, args, value_count);
21699
+
21700
+ heap::c_allocator.deallocate(args, value_count);
21701
+ }
21702
+
21667
21703
if (type_is_invalid(type_entry))
21668
21704
return ira->codegen->invalid_inst_gen;
21705
+
21669
21706
return ir_const_type(ira, &typeof_instruction->base.base, type_entry);
21670
21707
}
21671
21708
0 commit comments