authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-09 18:49:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-18 19:02:05-07:00
logcbbb5cc2ec8893869f729153cd07a76c5df8c83e
tree9af86caeb4a8d8d921bf30ed1934f5655c4085fe
parent6d72f971afdffbd7b098ab3d606a67f4075c6de3

InternPool: implement getFuncInstance

This handles the case without an inferred error set. Still TODO is the case with one. Also fixes branchQuota returning a pointer to the wrong field.

2 files changed, 111 insertions(+), 95 deletions(-)

src/InternPool.zig+105-92
......@@ -645,7 +645,7 @@ pub const Key = union(enum) {
645645
646646 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
647647 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {
648 return &ip.extra.items[func.zir_body_inst_extra_index];
648 return &ip.extra.items[func.branch_quota_extra_index];
649649 }
650650
651651 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
......@@ -4649,100 +4649,109 @@ pub const GetFuncInstanceKey = struct {
46494649 is_noinline: bool,
46504650 generic_owner: Index,
46514651 inferred_error_set: bool,
4652 comptime_args: []const Index,
4653 generation: u32,
46524654};
46534655
46544656pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) Allocator.Error!Index {
4655 _ = ip;
4656 _ = gpa;
4657 _ = arg;
4658 @panic("TODO");
4659 //const func_ty = try ip.getFuncType(gpa, .{
4660 // .param_types = arg.param_types,
4661 // .bare_return_type = arg.bare_return_type,
4662 // .comptime_bits = arg.comptime_bits,
4663 // .noalias_bits = arg.noalias_bits,
4664 // .alignment = arg.alignment,
4665 // .cc = arg.cc,
4666 // .is_var_args = arg.is_var_args,
4667 // .is_generic = arg.is_generic,
4668 // .is_noinline = arg.is_noinline,
4669 // .section_is_generic = arg.section_is_generic,
4670 // .addrspace_is_generic = arg.addrspace_is_generic,
4671 // .inferred_error_set = arg.inferred_error_set,
4672 //});
4673
4674 //const fn_owner_decl = ip.declPtr(arg.fn_owner_decl);
4675 //const decl_index = try ip.createDecl(gpa, .{
4676 // .name = undefined,
4677 // .src_namespace = fn_owner_decl.src_namespace,
4678 // .src_node = fn_owner_decl.src_node,
4679 // .src_line = fn_owner_decl.src_line,
4680 // .has_tv = true,
4681 // .owns_tv = true,
4682 // .ty = func_ty,
4683 // .val = undefined,
4684 // .alignment = .none,
4685 // .@"linksection" = fn_owner_decl.@"linksection",
4686 // .@"addrspace" = fn_owner_decl.@"addrspace",
4687 // .analysis = .complete,
4688 // .deletion_flag = false,
4689 // .zir_decl_index = fn_owner_decl.zir_decl_index,
4690 // .src_scope = fn_owner_decl.src_scope,
4691 // .generation = arg.generation,
4692 // .is_pub = fn_owner_decl.is_pub,
4693 // .is_exported = fn_owner_decl.is_exported,
4694 // .has_linksection_or_addrspace = fn_owner_decl.has_linksection_or_addrspace,
4695 // .has_align = fn_owner_decl.has_align,
4696 // .alive = true,
4697 // .kind = .anon,
4698 //});
4699 //// TODO: improve this name
4700 //const decl = ip.declPtr(decl_index);
4701 //decl.name = try ip.getOrPutStringFmt(gpa, "{}__anon_{d}", .{
4702 // fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
4703 //});
4704
4705 //const gop = try ip.map.getOrPutAdapted(gpa, Key{
4706 // .func = .{
4707 // .ty = func_ty,
4708 // .generic_owner = .none,
4709 // .owner_decl = decl_index,
4710 // // Only the above fields will be read for hashing/equality.
4711 // .analysis_extra_index = undefined,
4712 // .zir_body_inst_extra_index = undefined,
4713 // .branch_quota_extra_index = undefined,
4714 // .resolved_error_set_extra_index = undefined,
4715 // .zir_body_inst = undefined,
4716 // .lbrace_line = undefined,
4717 // .rbrace_line = undefined,
4718 // .lbrace_column = undefined,
4719 // .rbrace_column = undefined,
4720 // .comptime_args = undefined,
4721 // },
4722 //}, KeyAdapter{ .intern_pool = ip });
4723 //if (gop.found_existing) return @enumFromInt(gop.index);
4724 //try ip.items.append(gpa, .{
4725 // .tag = .func_decl,
4726 // .data = try ip.addExtra(gpa, .{
4727 // .analysis = .{
4728 // .state = if (arg.cc == .Inline) .inline_only else .none,
4729 // .is_cold = false,
4730 // .is_noinline = arg.is_noinline,
4731 // .calls_or_awaits_errorable_fn = false,
4732 // .stack_alignment = .none,
4733 // },
4734 // .owner_decl = arg.owner_decl,
4735 // .ty = func_ty,
4736 // .zir_body_inst = arg.zir_body_inst,
4737 // .lbrace_line = arg.lbrace_line,
4738 // .rbrace_line = arg.rbrace_line,
4739 // .lbrace_column = arg.lbrace_column,
4740 // .rbrace_column = arg.rbrace_column,
4741 // }),
4742 //});
4743 //const func_index: InternPool.Index = @enumFromInt(ip.items.len - 1);
4744 //decl.val = func_index.toValue();
4745 //return func_index;
4657 if (arg.inferred_error_set) @panic("TODO");
4658
4659 const func_ty = try ip.getFuncType(gpa, .{
4660 .param_types = arg.param_types,
4661 .return_type = arg.bare_return_type,
4662 .comptime_bits = 0,
4663 .noalias_bits = arg.noalias_bits,
4664 .alignment = arg.alignment,
4665 .cc = arg.cc,
4666 .is_var_args = false,
4667 .is_generic = false,
4668 .is_noinline = arg.is_noinline,
4669 .section_is_generic = false,
4670 .addrspace_is_generic = false,
4671 });
4672
4673 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(arg.generic_owner)));
4674
4675 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +
4676 arg.comptime_args.len);
4677 const prev_extra_len = ip.extra.items.len;
4678 errdefer ip.extra.items.len = prev_extra_len;
4679
4680 const func_instance_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{
4681 .analysis = .{
4682 .state = if (arg.cc == .Inline) .inline_only else .none,
4683 .is_cold = false,
4684 .is_noinline = arg.is_noinline,
4685 .calls_or_awaits_errorable_fn = false,
4686 .stack_alignment = .none,
4687 .inferred_error_set = false,
4688 },
4689 // This is populated after we create the Decl below. It is not read
4690 // by equality or hashing functions.
4691 .owner_decl = undefined,
4692 .ty = func_ty,
4693 .branch_quota = 0,
4694 .generic_owner = arg.generic_owner,
4695 });
4696 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));
4697
4698 const gop = try ip.map.getOrPutAdapted(gpa, Key{
4699 .func = extraFuncInstance(ip, func_instance_extra_index),
4700 }, KeyAdapter{ .intern_pool = ip });
4701 errdefer _ = ip.map.pop();
4702
4703 if (gop.found_existing) {
4704 ip.extra.items.len = prev_extra_len;
4705 return @enumFromInt(gop.index);
4706 }
4707
4708 try ip.items.ensureUnusedCapacity(gpa, 1);
4709 const func_index: Index = @enumFromInt(ip.items.len);
4710
4711 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(arg.generic_owner));
4712 const decl_index = try ip.createDecl(gpa, .{
4713 .name = undefined,
4714 .src_namespace = fn_owner_decl.src_namespace,
4715 .src_node = fn_owner_decl.src_node,
4716 .src_line = fn_owner_decl.src_line,
4717 .has_tv = true,
4718 .owns_tv = true,
4719 .ty = func_ty.toType(),
4720 .val = func_index.toValue(),
4721 .alignment = .none,
4722 .@"linksection" = fn_owner_decl.@"linksection",
4723 .@"addrspace" = fn_owner_decl.@"addrspace",
4724 .analysis = .complete,
4725 .deletion_flag = false,
4726 .zir_decl_index = fn_owner_decl.zir_decl_index,
4727 .src_scope = fn_owner_decl.src_scope,
4728 .generation = arg.generation,
4729 .is_pub = fn_owner_decl.is_pub,
4730 .is_exported = fn_owner_decl.is_exported,
4731 .has_linksection_or_addrspace = fn_owner_decl.has_linksection_or_addrspace,
4732 .has_align = fn_owner_decl.has_align,
4733 .alive = true,
4734 .kind = .anon,
4735 });
4736 errdefer ip.destroyDecl(gpa, decl_index);
4737
4738 // Populate the owner_decl field which was left undefined until now.
4739 ip.extra.items[
4740 func_instance_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?
4741 ] = @intFromEnum(decl_index);
4742
4743 // TODO: improve this name
4744 const decl = ip.declPtr(decl_index);
4745 decl.name = try ip.getOrPutStringFmt(gpa, "{}__anon_{d}", .{
4746 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
4747 });
4748
4749 ip.items.appendAssumeCapacity(.{
4750 .tag = .func_instance,
4751 .data = func_instance_extra_index,
4752 });
4753
4754 return func_index;
47464755}
47474756
47484757/// Provides API for completing an enum type after calling `getIncompleteEnum`.
......@@ -6754,6 +6763,10 @@ pub fn funcDeclInfo(ip: *const InternPool, i: InternPool.Index) Key.Func {
67546763 return extraFuncDecl(ip, datas[@intFromEnum(i)]);
67556764}
67566765
6766pub fn funcDeclOwner(ip: *const InternPool, i: InternPool.Index) Module.Decl.Index {
6767 return funcDeclInfo(ip, i).owner_decl;
6768}
6769
67576770pub fn funcTypeParamsLen(ip: *const InternPool, i: InternPool.Index) u32 {
67586771 const tags = ip.items.items(.tag);
67596772 const datas = ip.items.items(.data);
src/Sema.zig+6-3
......@@ -7527,8 +7527,6 @@ fn instantiateGenericCall(
75277527 const callee = mod.funcInfo(callee_index);
75287528 callee.branchQuota(ip).* = @max(callee.branchQuota(ip).*, sema.branch_quota);
75297529
7530 const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);
7531
75327530 // Make a runtime call to the new function, making sure to omit the comptime args.
75337531 const func_ty = callee.ty.toType();
75347532 const func_ty_info = mod.typeToFunc(func_ty).?;
......@@ -7573,7 +7571,7 @@ fn instantiateGenericCall(
75737571 const result = try block.addInst(.{
75747572 .tag = call_tag,
75757573 .data = .{ .pl_op = .{
7576 .operand = callee_inst,
7574 .operand = Air.internedToRef(callee_index),
75777575 .payload = sema.addExtraAssumeCapacity(Air.Call{
75787576 .args_len = runtime_args_len,
75797577 }),
......@@ -8775,6 +8773,9 @@ fn funcCommon(
87758773 assert(section != .generic);
87768774 assert(address_space != null);
87778775 assert(!var_args);
8776 if (inferred_error_set) {
8777 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
8778 }
87788779 const func_index = try ip.getFuncInstance(gpa, .{
87798780 .param_types = param_types,
87808781 .noalias_bits = noalias_bits,
......@@ -8784,6 +8785,8 @@ fn funcCommon(
87848785 .is_noinline = is_noinline,
87858786 .inferred_error_set = inferred_error_set,
87868787 .generic_owner = sema.generic_owner,
8788 .comptime_args = sema.comptime_args,
8789 .generation = mod.generation,
87878790 });
87888791 return finishFunc(
87898792 sema,