authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-19 23:16:36-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:53-07:00
logc4735941148eb32eee16307ba13876ae21606fba
tree19d2bb586c02ba132c85965fbbf1dc2cdf3ddc15
parentf8b6eb63d53bba303a200a5c2493c5d5bddd1f66

Sema: port reify struct access to use InternPool


2 files changed, 117 insertions(+), 96 deletions(-)

src/Sema.zig+110-94
......@@ -18805,6 +18805,7 @@ fn zirReify(
1880518805 const target = mod.getTarget();
1880618806 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
1880718807 if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
18808 const ip = &mod.intern_pool;
1880818809 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1880918810 .Type => return Air.Inst.Ref.type_type,
1881018811 .Void => return Air.Inst.Ref.void_type,
......@@ -18817,10 +18818,12 @@ fn zirReify(
1881718818 .AnyFrame => return sema.failWithUseOfAsync(block, src),
1881818819 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
1881918820 .Int => {
18820 const struct_val = union_val.val.castTag(.aggregate).?.data;
18821 // TODO use reflection instead of magic numbers here
18822 const signedness_val = struct_val[0];
18823 const bits_val = struct_val[1];
18821 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18822 const signedness_index = fields.getIndex("signedness").?;
18823 const bits_index = fields.getIndex("bits").?;
18824
18825 const signedness_val = try union_val.val.fieldValue(fields.values()[signedness_index].ty, mod, signedness_index);
18826 const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
1882418827
1882518828 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
1882618829 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
......@@ -18828,10 +18831,12 @@ fn zirReify(
1882818831 return sema.addType(ty);
1882918832 },
1883018833 .Vector => {
18831 const struct_val = union_val.val.castTag(.aggregate).?.data;
18832 // TODO use reflection instead of magic numbers here
18833 const len_val = struct_val[0];
18834 const child_val = struct_val[1];
18834 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18835 const len_index = fields.getIndex("len").?;
18836 const child_index = fields.getIndex("child").?;
18837
18838 const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
18839 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
1883518840
1883618841 const len = @intCast(u32, len_val.toUnsignedInt(mod));
1883718842 const child_ty = child_val.toType();
......@@ -18845,10 +18850,10 @@ fn zirReify(
1884518850 return sema.addType(ty);
1884618851 },
1884718852 .Float => {
18848 const struct_val = union_val.val.castTag(.aggregate).?.data;
18849 // TODO use reflection instead of magic numbers here
18850 // bits: comptime_int,
18851 const bits_val = struct_val[0];
18853 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18854 const bits_index = fields.getIndex("bits").?;
18855
18856 const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
1885218857
1885318858 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
1885418859 const ty = switch (bits) {
......@@ -18862,16 +18867,24 @@ fn zirReify(
1886218867 return sema.addType(ty);
1886318868 },
1886418869 .Pointer => {
18865 const struct_val = union_val.val.castTag(.aggregate).?.data;
18866 // TODO use reflection instead of magic numbers here
18867 const size_val = struct_val[0];
18868 const is_const_val = struct_val[1];
18869 const is_volatile_val = struct_val[2];
18870 const alignment_val = struct_val[3];
18871 const address_space_val = struct_val[4];
18872 const child_val = struct_val[5];
18873 const is_allowzero_val = struct_val[6];
18874 const sentinel_val = struct_val[7];
18870 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18871 const size_index = fields.getIndex("size").?;
18872 const is_const_index = fields.getIndex("is_const").?;
18873 const is_volatile_index = fields.getIndex("is_volatile").?;
18874 const alignment_index = fields.getIndex("alignment").?;
18875 const address_space_index = fields.getIndex("address_space").?;
18876 const child_index = fields.getIndex("child").?;
18877 const is_allowzero_index = fields.getIndex("is_allowzero").?;
18878 const sentinel_index = fields.getIndex("sentinel").?;
18879
18880 const size_val = try union_val.val.fieldValue(fields.values()[size_index].ty, mod, size_index);
18881 const is_const_val = try union_val.val.fieldValue(fields.values()[is_const_index].ty, mod, is_const_index);
18882 const is_volatile_val = try union_val.val.fieldValue(fields.values()[is_volatile_index].ty, mod, is_volatile_index);
18883 const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
18884 const address_space_val = try union_val.val.fieldValue(fields.values()[address_space_index].ty, mod, address_space_index);
18885 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
18886 const is_allowzero_val = try union_val.val.fieldValue(fields.values()[is_allowzero_index].ty, mod, is_allowzero_index);
18887 const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
1887518888
1887618889 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1887718890 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
......@@ -18954,14 +18967,14 @@ fn zirReify(
1895418967 return sema.addType(ty);
1895518968 },
1895618969 .Array => {
18957 const struct_val = union_val.val.castTag(.aggregate).?.data;
18958 // TODO use reflection instead of magic numbers here
18959 // len: comptime_int,
18960 const len_val = struct_val[0];
18961 // child: type,
18962 const child_val = struct_val[1];
18963 // sentinel: ?*const anyopaque,
18964 const sentinel_val = struct_val[2];
18970 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18971 const len_index = fields.getIndex("len").?;
18972 const child_index = fields.getIndex("child").?;
18973 const sentinel_index = fields.getIndex("sentinel").?;
18974
18975 const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
18976 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
18977 const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
1896518978
1896618979 const len = len_val.toUnsignedInt(mod);
1896718980 const child_ty = child_val.toType();
......@@ -18977,10 +18990,10 @@ fn zirReify(
1897718990 return sema.addType(ty);
1897818991 },
1897918992 .Optional => {
18980 const struct_val = union_val.val.castTag(.aggregate).?.data;
18981 // TODO use reflection instead of magic numbers here
18982 // child: type,
18983 const child_val = struct_val[0];
18993 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18994 const child_index = fields.getIndex("child").?;
18995
18996 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
1898418997
1898518998 const child_ty = child_val.toType();
1898618999
......@@ -18988,12 +19001,12 @@ fn zirReify(
1898819001 return sema.addType(ty);
1898919002 },
1899019003 .ErrorUnion => {
18991 const struct_val = union_val.val.castTag(.aggregate).?.data;
18992 // TODO use reflection instead of magic numbers here
18993 // error_set: type,
18994 const error_set_val = struct_val[0];
18995 // payload: type,
18996 const payload_val = struct_val[1];
19004 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19005 const error_set_index = fields.getIndex("error_set").?;
19006 const payload_index = fields.getIndex("payload").?;
19007
19008 const error_set_val = try union_val.val.fieldValue(fields.values()[error_set_index].ty, mod, error_set_index);
19009 const payload_val = try union_val.val.fieldValue(fields.values()[payload_index].ty, mod, payload_index);
1899719010
1899819011 const error_set_ty = error_set_val.toType();
1899919012 const payload_ty = payload_val.toType();
......@@ -19031,19 +19044,18 @@ fn zirReify(
1903119044 return sema.addType(ty);
1903219045 },
1903319046 .Struct => {
19034 // TODO use reflection instead of magic numbers here
19035 const struct_val = union_val.val.castTag(.aggregate).?.data;
19036 // layout: containerlayout,
19037 const layout_val = struct_val[0];
19038 // backing_int: ?type,
19039 const backing_int_val = struct_val[1];
19040 // fields: []const enumfield,
19041 const fields_val = struct_val[2];
19042 // decls: []const declaration,
19043 const decls_val = struct_val[3];
19044 // is_tuple: bool,
19045 const is_tuple_val = struct_val[4];
19046 assert(struct_val.len == 5);
19047 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19048 const layout_index = fields.getIndex("layout").?;
19049 const backing_integer_index = fields.getIndex("backing_integer").?;
19050 const fields_index = fields.getIndex("fields").?;
19051 const decls_index = fields.getIndex("decls").?;
19052 const is_tuple_index = fields.getIndex("is_tuple").?;
19053
19054 const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
19055 const backing_integer_val = try union_val.val.fieldValue(fields.values()[backing_integer_index].ty, mod, backing_integer_index);
19056 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19057 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
19058 const is_tuple_val = try union_val.val.fieldValue(fields.values()[is_tuple_index].ty, mod, is_tuple_index);
1904719059
1904819060 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1904919061
......@@ -19052,23 +19064,23 @@ fn zirReify(
1905219064 return sema.fail(block, src, "reified structs must have no decls", .{});
1905319065 }
1905419066
19055 if (layout != .Packed and !backing_int_val.isNull(mod)) {
19067 if (layout != .Packed and !backing_integer_val.isNull(mod)) {
1905619068 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
1905719069 }
1905819070
19059 return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
19071 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
1906019072 },
1906119073 .Enum => {
19062 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
19063 // TODO use reflection instead of magic numbers here
19064 // tag_type: type,
19065 const tag_type_val = struct_val[0];
19066 // fields: []const EnumField,
19067 const fields_val = struct_val[1];
19068 // decls: []const Declaration,
19069 const decls_val = struct_val[2];
19070 // is_exhaustive: bool,
19071 const is_exhaustive_val = struct_val[3];
19074 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19075 const tag_type_index = fields.getIndex("tag_type").?;
19076 const fields_index = fields.getIndex("fields").?;
19077 const decls_index = fields.getIndex("decls").?;
19078 const is_exhaustive_index = fields.getIndex("is_exhaustive").?;
19079
19080 const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
19081 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19082 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
19083 const is_exhaustive_val = try union_val.val.fieldValue(fields.values()[is_exhaustive_index].ty, mod, is_exhaustive_index);
1907219084
1907319085 // Decls
1907419086 if (decls_val.sliceLen(mod) > 0) {
......@@ -19160,9 +19172,10 @@ fn zirReify(
1916019172 return sema.analyzeDeclVal(block, src, new_decl_index);
1916119173 },
1916219174 .Opaque => {
19163 const struct_val = union_val.val.castTag(.aggregate).?.data;
19164 // decls: []const Declaration,
19165 const decls_val = struct_val[0];
19175 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19176 const decls_index = fields.getIndex("decls").?;
19177
19178 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
1916619179
1916719180 // Decls
1916819181 if (decls_val.sliceLen(mod) > 0) {
......@@ -19205,16 +19218,16 @@ fn zirReify(
1920519218 return sema.analyzeDeclVal(block, src, new_decl_index);
1920619219 },
1920719220 .Union => {
19208 // TODO use reflection instead of magic numbers here
19209 const struct_val = union_val.val.castTag(.aggregate).?.data;
19210 // layout: containerlayout,
19211 const layout_val = struct_val[0];
19212 // tag_type: ?type,
19213 const tag_type_val = struct_val[1];
19214 // fields: []const enumfield,
19215 const fields_val = struct_val[2];
19216 // decls: []const declaration,
19217 const decls_val = struct_val[3];
19221 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19222 const layout_index = fields.getIndex("layout").?;
19223 const tag_type_index = fields.getIndex("tag_type").?;
19224 const fields_index = fields.getIndex("fields").?;
19225 const decls_index = fields.getIndex("decls").?;
19226
19227 const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
19228 const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
19229 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19230 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
1921819231
1921919232 // Decls
1922019233 if (decls_val.sliceLen(mod) > 0) {
......@@ -19411,25 +19424,28 @@ fn zirReify(
1941119424 return sema.analyzeDeclVal(block, src, new_decl_index);
1941219425 },
1941319426 .Fn => {
19414 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
19415 // TODO use reflection instead of magic numbers here
19416 // calling_convention: CallingConvention,
19417 const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);
19418 // alignment: comptime_int,
19419 const alignment_val = struct_val[1];
19420 // is_generic: bool,
19421 const is_generic = struct_val[2].toBool(mod);
19422 // is_var_args: bool,
19423 const is_var_args = struct_val[3].toBool(mod);
19424 // return_type: ?type,
19425 const return_type_val = struct_val[4];
19426 // args: []const Param,
19427 const args_val = struct_val[5];
19428
19427 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19428 const calling_convention_index = fields.getIndex("calling_convention").?;
19429 const alignment_index = fields.getIndex("alignment").?;
19430 const is_generic_index = fields.getIndex("is_generic").?;
19431 const is_var_args_index = fields.getIndex("is_var_args").?;
19432 const return_type_index = fields.getIndex("return_type").?;
19433 const params_index = fields.getIndex("params").?;
19434
19435 const calling_convention_val = try union_val.val.fieldValue(fields.values()[calling_convention_index].ty, mod, calling_convention_index);
19436 const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
19437 const is_generic_val = try union_val.val.fieldValue(fields.values()[is_generic_index].ty, mod, is_generic_index);
19438 const is_var_args_val = try union_val.val.fieldValue(fields.values()[is_var_args_index].ty, mod, is_var_args_index);
19439 const return_type_val = try union_val.val.fieldValue(fields.values()[return_type_index].ty, mod, return_type_index);
19440 const params_val = try union_val.val.fieldValue(fields.values()[params_index].ty, mod, params_index);
19441
19442 const is_generic = is_generic_val.toBool(mod);
1942919443 if (is_generic) {
1943019444 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
1943119445 }
1943219446
19447 const is_var_args = is_var_args_val.toBool(mod);
19448 const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val);
1943319449 if (is_var_args and cc != .C) {
1943419450 return sema.fail(block, src, "varargs functions must have C calling convention", .{});
1943519451 }
......@@ -19448,7 +19464,7 @@ fn zirReify(
1944819464 const return_type = return_type_val.optionalValue(mod) orelse
1944919465 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
1945019466
19451 const args_slice_val = args_val.castTag(.slice).?.data;
19467 const args_slice_val = params_val.castTag(.slice).?.data;
1945219468 const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));
1945319469
1945419470 const param_types = try sema.arena.alloc(InternPool.Index, args_len);
src/type.zig+7-2
......@@ -3148,8 +3148,13 @@ pub const Type = struct {
31483148 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
31493149 const ip = &mod.intern_pool;
31503150 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
3151 assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
3152 return enum_type.tagValueIndex(ip, enum_tag.ip_index);
3151 const int_tag = switch (ip.indexToKey(enum_tag.ip_index)) {
3152 .int => enum_tag.ip_index,
3153 .enum_tag => |info| info.int,
3154 else => unreachable,
3155 };
3156 assert(ip.typeOf(int_tag) == enum_type.tag_ty);
3157 return enum_type.tagValueIndex(ip, int_tag);
31533158 }
31543159
31553160 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {