authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-09 16:51:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-18 19:02:05-07:00
log6d72f971afdffbd7b098ab3d606a67f4075c6de3
tree6180b246e4c1f00c18f3b14f02d20f56a218290c
parent8fd77395d66e2fe376959d59e0879decdfea6907

InternPool: implement getExternFunc


4 files changed, 205 insertions(+), 116 deletions(-)

src/Air.zig+1-1
......@@ -1436,7 +1436,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
14361436
14371437 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
14381438 const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1439 return ip.funcReturnType(callee_ty.toIntern()).toType();
1439 return ip.funcTypeReturnType(callee_ty.toIntern()).toType();
14401440 },
14411441
14421442 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
src/InternPool.zig+15-17
......@@ -4393,22 +4393,20 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat
43934393 return @enumFromInt(ip.items.len - 1);
43944394}
43954395
4396pub const GetExternFuncKey = struct {
4397 param_types: []const Index,
4398 noalias_bits: u32,
4399 return_type: Index,
4400 cc: std.builtin.CallingConvention,
4401 alignment: Alignment,
4402 is_var_args: bool,
4403 decl: Module.Decl.Index,
4404 lib_name: OptionalNullTerminatedString,
4405};
4406
4407pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: GetExternFuncKey) Allocator.Error!Index {
4408 _ = ip;
4409 _ = gpa;
4410 _ = key;
4411 @panic("TODO");
4396pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Allocator.Error!Index {
4397 const adapter: KeyAdapter = .{ .intern_pool = ip };
4398 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter);
4399 if (gop.found_existing) return @enumFromInt(gop.index);
4400 errdefer _ = ip.map.pop();
4401 const prev_extra_len = ip.extra.items.len;
4402 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));
4403 errdefer ip.extra.items.len = prev_extra_len;
4404 try ip.items.append(gpa, .{
4405 .tag = .extern_func,
4406 .data = extra_index,
4407 });
4408 errdefer ip.items.len -= 1;
4409 return @enumFromInt(ip.items.len - 1);
44124410}
44134411
44144412pub const GetFuncDeclKey = struct {
......@@ -6375,7 +6373,7 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
63756373 };
63766374}
63776375
6378pub fn funcReturnType(ip: *const InternPool, ty: Index) Index {
6376pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
63796377 const item = ip.items.get(@intFromEnum(ty));
63806378 const child_item = switch (item.tag) {
63816379 .type_pointer => ip.items.get(ip.extra.items[
src/Sema.zig+188-97
......@@ -8767,92 +8767,63 @@ fn funcCommon(
87678767
87688768 const param_types = block.params.items(.ty);
87698769
8770 const opt_func_index: InternPool.Index = i: {
8771 if (!is_source_decl) {
8772 assert(has_body);
8773 assert(!is_generic);
8774 assert(comptime_bits == 0);
8775 assert(cc != null);
8776 assert(section != .generic);
8777 assert(address_space != null);
8778 assert(!var_args);
8779 break :i try ip.getFuncInstance(gpa, .{
8780 .param_types = param_types,
8781 .noalias_bits = noalias_bits,
8782 .bare_return_type = bare_return_type.toIntern(),
8783 .cc = cc_resolved,
8784 .alignment = alignment.?,
8785 .is_noinline = is_noinline,
8786 .inferred_error_set = inferred_error_set,
8787 .generic_owner = sema.generic_owner,
8788 });
8789 }
8790
8791 // extern_func and func_decl functions take ownership of `sema.owner_decl`.
8792
8793 sema.owner_decl.@"linksection" = switch (section) {
8794 .generic => .none,
8795 .default => .none,
8796 .explicit => |section_name| section_name.toOptional(),
8797 };
8798 sema.owner_decl.alignment = alignment orelse .none;
8799 sema.owner_decl.@"addrspace" = address_space orelse .generic;
8800
8801 if (is_extern) {
8802 assert(comptime_bits == 0);
8803 assert(cc != null);
8804 assert(section != .generic);
8805 assert(address_space != null);
8806 assert(!is_generic);
8807 break :i try ip.getExternFunc(gpa, .{
8808 .param_types = param_types,
8809 .noalias_bits = noalias_bits,
8810 .return_type = bare_return_type.toIntern(),
8811 .cc = cc_resolved,
8812 .alignment = alignment.?,
8813 .is_var_args = var_args,
8814 .decl = sema.owner_decl_index,
8815 .lib_name = if (opt_lib_name) |lib_name| (try mod.intern_pool.getOrPutString(
8816 gpa,
8817 try sema.handleExternLibName(block, .{
8818 .node_offset_lib_name = src_node_offset,
8819 }, lib_name),
8820 )).toOptional() else .none,
8821 });
8822 }
8823
8824 if (!has_body) break :i .none;
8825
8826 if (inferred_error_set) {
8827 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
8828 break :i try ip.getFuncDeclIes(gpa, .{
8829 .owner_decl = sema.owner_decl_index,
8770 if (!is_source_decl) {
8771 assert(has_body);
8772 assert(!is_generic);
8773 assert(comptime_bits == 0);
8774 assert(cc != null);
8775 assert(section != .generic);
8776 assert(address_space != null);
8777 assert(!var_args);
8778 const func_index = try ip.getFuncInstance(gpa, .{
8779 .param_types = param_types,
8780 .noalias_bits = noalias_bits,
8781 .bare_return_type = bare_return_type.toIntern(),
8782 .cc = cc_resolved,
8783 .alignment = alignment.?,
8784 .is_noinline = is_noinline,
8785 .inferred_error_set = inferred_error_set,
8786 .generic_owner = sema.generic_owner,
8787 });
8788 return finishFunc(
8789 sema,
8790 block,
8791 func_index,
8792 .none,
8793 ret_poison,
8794 bare_return_type,
8795 ret_ty_src,
8796 cc_resolved,
8797 is_source_decl,
8798 ret_ty_requires_comptime,
8799 func_inst,
8800 cc_src,
8801 is_noinline,
8802 is_generic,
8803 final_is_generic,
8804 );
8805 }
88308806
8831 .param_types = param_types,
8832 .noalias_bits = noalias_bits,
8833 .comptime_bits = comptime_bits,
8834 .bare_return_type = bare_return_type.toIntern(),
8835 .cc = cc,
8836 .alignment = alignment,
8837 .section_is_generic = section == .generic,
8838 .addrspace_is_generic = address_space == null,
8839 .is_var_args = var_args,
8840 .is_generic = final_is_generic,
8841 .is_noinline = is_noinline,
8842
8843 .zir_body_inst = func_inst,
8844 .lbrace_line = src_locs.lbrace_line,
8845 .rbrace_line = src_locs.rbrace_line,
8846 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
8847 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
8848 });
8849 }
8807 // extern_func and func_decl functions take ownership of `sema.owner_decl`.
8808 sema.owner_decl.@"linksection" = switch (section) {
8809 .generic => .none,
8810 .default => .none,
8811 .explicit => |section_name| section_name.toOptional(),
8812 };
8813 sema.owner_decl.alignment = alignment orelse .none;
8814 sema.owner_decl.@"addrspace" = address_space orelse .generic;
8815
8816 if (inferred_error_set) {
8817 assert(!is_extern);
8818 assert(has_body);
8819 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
8820 const func_index = try ip.getFuncDeclIes(gpa, .{
8821 .owner_decl = sema.owner_decl_index,
88508822
8851 const func_ty = try ip.getFuncType(gpa, .{
88528823 .param_types = param_types,
88538824 .noalias_bits = noalias_bits,
88548825 .comptime_bits = comptime_bits,
8855 .return_type = bare_return_type.toIntern(),
8826 .bare_return_type = bare_return_type.toIntern(),
88568827 .cc = cc,
88578828 .alignment = alignment,
88588829 .section_is_generic = section == .generic,
......@@ -8860,9 +8831,83 @@ fn funcCommon(
88608831 .is_var_args = var_args,
88618832 .is_generic = final_is_generic,
88628833 .is_noinline = is_noinline,
8834
8835 .zir_body_inst = func_inst,
8836 .lbrace_line = src_locs.lbrace_line,
8837 .rbrace_line = src_locs.rbrace_line,
8838 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
8839 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
88638840 });
8841 return finishFunc(
8842 sema,
8843 block,
8844 func_index,
8845 .none,
8846 ret_poison,
8847 bare_return_type,
8848 ret_ty_src,
8849 cc_resolved,
8850 is_source_decl,
8851 ret_ty_requires_comptime,
8852 func_inst,
8853 cc_src,
8854 is_noinline,
8855 is_generic,
8856 final_is_generic,
8857 );
8858 }
88648859
8865 break :i try ip.getFuncDecl(gpa, .{
8860 const func_ty = try ip.getFuncType(gpa, .{
8861 .param_types = param_types,
8862 .noalias_bits = noalias_bits,
8863 .comptime_bits = comptime_bits,
8864 .return_type = bare_return_type.toIntern(),
8865 .cc = cc,
8866 .alignment = alignment,
8867 .section_is_generic = section == .generic,
8868 .addrspace_is_generic = address_space == null,
8869 .is_var_args = var_args,
8870 .is_generic = final_is_generic,
8871 .is_noinline = is_noinline,
8872 });
8873
8874 if (is_extern) {
8875 assert(comptime_bits == 0);
8876 assert(cc != null);
8877 assert(section != .generic);
8878 assert(address_space != null);
8879 assert(!is_generic);
8880 const func_index = try ip.getExternFunc(gpa, .{
8881 .ty = func_ty,
8882 .decl = sema.owner_decl_index,
8883 .lib_name = if (opt_lib_name) |lib_name| (try mod.intern_pool.getOrPutString(
8884 gpa,
8885 try sema.handleExternLibName(block, .{
8886 .node_offset_lib_name = src_node_offset,
8887 }, lib_name),
8888 )).toOptional() else .none,
8889 });
8890 return finishFunc(
8891 sema,
8892 block,
8893 func_index,
8894 func_ty,
8895 ret_poison,
8896 bare_return_type,
8897 ret_ty_src,
8898 cc_resolved,
8899 is_source_decl,
8900 ret_ty_requires_comptime,
8901 func_inst,
8902 cc_src,
8903 is_noinline,
8904 is_generic,
8905 final_is_generic,
8906 );
8907 }
8908
8909 if (has_body) {
8910 const func_index = try ip.getFuncDecl(gpa, .{
88668911 .owner_decl = sema.owner_decl_index,
88678912 .ty = func_ty,
88688913 .cc = cc,
......@@ -8873,12 +8918,70 @@ fn funcCommon(
88738918 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
88748919 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
88758920 });
8876 };
8921 return finishFunc(
8922 sema,
8923 block,
8924 func_index,
8925 func_ty,
8926 ret_poison,
8927 bare_return_type,
8928 ret_ty_src,
8929 cc_resolved,
8930 is_source_decl,
8931 ret_ty_requires_comptime,
8932 func_inst,
8933 cc_src,
8934 is_noinline,
8935 is_generic,
8936 final_is_generic,
8937 );
8938 }
8939
8940 return finishFunc(
8941 sema,
8942 block,
8943 .none,
8944 func_ty,
8945 ret_poison,
8946 bare_return_type,
8947 ret_ty_src,
8948 cc_resolved,
8949 is_source_decl,
8950 ret_ty_requires_comptime,
8951 func_inst,
8952 cc_src,
8953 is_noinline,
8954 is_generic,
8955 final_is_generic,
8956 );
8957}
8958
8959fn finishFunc(
8960 sema: *Sema,
8961 block: *Block,
8962 opt_func_index: InternPool.Index,
8963 func_ty: InternPool.Index,
8964 ret_poison: bool,
8965 bare_return_type: Type,
8966 ret_ty_src: LazySrcLoc,
8967 cc_resolved: std.builtin.CallingConvention,
8968 is_source_decl: bool,
8969 ret_ty_requires_comptime: bool,
8970 func_inst: Zir.Inst.Index,
8971 cc_src: LazySrcLoc,
8972 is_noinline: bool,
8973 is_generic: bool,
8974 final_is_generic: bool,
8975) CompileError!Air.Inst.Ref {
8976 const mod = sema.mod;
8977 const ip = &mod.intern_pool;
8978 const gpa = sema.gpa;
8979 const target = mod.getTarget();
88778980
88788981 const return_type: Type = if (opt_func_index == .none or ret_poison)
88798982 bare_return_type
88808983 else
8881 ip.funcReturnType(ip.typeOf(opt_func_index)).toType();
8984 ip.funcTypeReturnType(ip.typeOf(opt_func_index)).toType();
88828985
88838986 if (!return_type.isValidReturnType(mod)) {
88848987 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
......@@ -8998,19 +9101,7 @@ fn funcCommon(
89989101 _ = try sema.resolveTypeFields(unresolved_stack_trace_ty);
89999102 }
90009103
9001 return Air.internedToRef(if (opt_func_index == .none) try ip.getFuncType(gpa, .{
9002 .param_types = param_types,
9003 .noalias_bits = noalias_bits,
9004 .comptime_bits = comptime_bits,
9005 .return_type = return_type.toIntern(),
9006 .cc = cc,
9007 .alignment = alignment,
9008 .section_is_generic = section == .generic,
9009 .addrspace_is_generic = address_space == null,
9010 .is_var_args = var_args,
9011 .is_generic = final_is_generic,
9012 .is_noinline = is_noinline,
9013 }) else opt_func_index);
9104 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
90149105}
90159106
90169107fn zirParam(
src/type.zig+1-1
......@@ -2364,7 +2364,7 @@ pub const Type = struct {
23642364
23652365 /// Asserts the type is a function or a function pointer.
23662366 pub fn fnReturnType(ty: Type, mod: *Module) Type {
2367 return mod.intern_pool.funcReturnType(ty.toIntern()).toType();
2367 return mod.intern_pool.funcTypeReturnType(ty.toIntern()).toType();
23682368 }
23692369
23702370 /// Asserts the type is a function.