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