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(...@@ -18805,6 +18805,7 @@ fn zirReify(
18805 const target = mod.getTarget();18805 const target = mod.getTarget();
18806 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;18806 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
18807 if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);18807 if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
18808 const ip = &mod.intern_pool;
18808 switch (@intToEnum(std.builtin.TypeId, tag_index)) {18809 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
18809 .Type => return Air.Inst.Ref.type_type,18810 .Type => return Air.Inst.Ref.type_type,
18810 .Void => return Air.Inst.Ref.void_type,18811 .Void => return Air.Inst.Ref.void_type,
...@@ -18817,10 +18818,12 @@ fn zirReify(...@@ -18817,10 +18818,12 @@ fn zirReify(
18817 .AnyFrame => return sema.failWithUseOfAsync(block, src),18818 .AnyFrame => return sema.failWithUseOfAsync(block, src),
18818 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,18819 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
18819 .Int => {18820 .Int => {
18820 const struct_val = union_val.val.castTag(.aggregate).?.data;18821 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18821 // TODO use reflection instead of magic numbers here18822 const signedness_index = fields.getIndex("signedness").?;
18822 const signedness_val = struct_val[0];18823 const bits_index = fields.getIndex("bits").?;
18823 const bits_val = struct_val[1];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
18825 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);18828 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
18826 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));18829 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
...@@ -18828,10 +18831,12 @@ fn zirReify(...@@ -18828,10 +18831,12 @@ fn zirReify(
18828 return sema.addType(ty);18831 return sema.addType(ty);
18829 },18832 },
18830 .Vector => {18833 .Vector => {
18831 const struct_val = union_val.val.castTag(.aggregate).?.data;18834 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18832 // TODO use reflection instead of magic numbers here18835 const len_index = fields.getIndex("len").?;
18833 const len_val = struct_val[0];18836 const child_index = fields.getIndex("child").?;
18834 const child_val = struct_val[1];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
18836 const len = @intCast(u32, len_val.toUnsignedInt(mod));18841 const len = @intCast(u32, len_val.toUnsignedInt(mod));
18837 const child_ty = child_val.toType();18842 const child_ty = child_val.toType();
...@@ -18845,10 +18850,10 @@ fn zirReify(...@@ -18845,10 +18850,10 @@ fn zirReify(
18845 return sema.addType(ty);18850 return sema.addType(ty);
18846 },18851 },
18847 .Float => {18852 .Float => {
18848 const struct_val = union_val.val.castTag(.aggregate).?.data;18853 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18849 // TODO use reflection instead of magic numbers here18854 const bits_index = fields.getIndex("bits").?;
18850 // bits: comptime_int,18855
18851 const bits_val = struct_val[0];18856 const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
1885218857
18853 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));18858 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
18854 const ty = switch (bits) {18859 const ty = switch (bits) {
...@@ -18862,16 +18867,24 @@ fn zirReify(...@@ -18862,16 +18867,24 @@ fn zirReify(
18862 return sema.addType(ty);18867 return sema.addType(ty);
18863 },18868 },
18864 .Pointer => {18869 .Pointer => {
18865 const struct_val = union_val.val.castTag(.aggregate).?.data;18870 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18866 // TODO use reflection instead of magic numbers here18871 const size_index = fields.getIndex("size").?;
18867 const size_val = struct_val[0];18872 const is_const_index = fields.getIndex("is_const").?;
18868 const is_const_val = struct_val[1];18873 const is_volatile_index = fields.getIndex("is_volatile").?;
18869 const is_volatile_val = struct_val[2];18874 const alignment_index = fields.getIndex("alignment").?;
18870 const alignment_val = struct_val[3];18875 const address_space_index = fields.getIndex("address_space").?;
18871 const address_space_val = struct_val[4];18876 const child_index = fields.getIndex("child").?;
18872 const child_val = struct_val[5];18877 const is_allowzero_index = fields.getIndex("is_allowzero").?;
18873 const is_allowzero_val = struct_val[6];18878 const sentinel_index = fields.getIndex("sentinel").?;
18874 const sentinel_val = struct_val[7];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
18876 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {18889 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
18877 return sema.fail(block, src, "alignment must fit in 'u32'", .{});18890 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
...@@ -18954,14 +18967,14 @@ fn zirReify(...@@ -18954,14 +18967,14 @@ fn zirReify(
18954 return sema.addType(ty);18967 return sema.addType(ty);
18955 },18968 },
18956 .Array => {18969 .Array => {
18957 const struct_val = union_val.val.castTag(.aggregate).?.data;18970 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18958 // TODO use reflection instead of magic numbers here18971 const len_index = fields.getIndex("len").?;
18959 // len: comptime_int,18972 const child_index = fields.getIndex("child").?;
18960 const len_val = struct_val[0];18973 const sentinel_index = fields.getIndex("sentinel").?;
18961 // child: type,18974
18962 const child_val = struct_val[1];18975 const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
18963 // sentinel: ?*const anyopaque,18976 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
18964 const sentinel_val = struct_val[2];18977 const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
1896518978
18966 const len = len_val.toUnsignedInt(mod);18979 const len = len_val.toUnsignedInt(mod);
18967 const child_ty = child_val.toType();18980 const child_ty = child_val.toType();
...@@ -18977,10 +18990,10 @@ fn zirReify(...@@ -18977,10 +18990,10 @@ fn zirReify(
18977 return sema.addType(ty);18990 return sema.addType(ty);
18978 },18991 },
18979 .Optional => {18992 .Optional => {
18980 const struct_val = union_val.val.castTag(.aggregate).?.data;18993 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18981 // TODO use reflection instead of magic numbers here18994 const child_index = fields.getIndex("child").?;
18982 // child: type,18995
18983 const child_val = struct_val[0];18996 const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
1898418997
18985 const child_ty = child_val.toType();18998 const child_ty = child_val.toType();
1898618999
...@@ -18988,12 +19001,12 @@ fn zirReify(...@@ -18988,12 +19001,12 @@ fn zirReify(
18988 return sema.addType(ty);19001 return sema.addType(ty);
18989 },19002 },
18990 .ErrorUnion => {19003 .ErrorUnion => {
18991 const struct_val = union_val.val.castTag(.aggregate).?.data;19004 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
18992 // TODO use reflection instead of magic numbers here19005 const error_set_index = fields.getIndex("error_set").?;
18993 // error_set: type,19006 const payload_index = fields.getIndex("payload").?;
18994 const error_set_val = struct_val[0];19007
18995 // payload: type,19008 const error_set_val = try union_val.val.fieldValue(fields.values()[error_set_index].ty, mod, error_set_index);
18996 const payload_val = struct_val[1];19009 const payload_val = try union_val.val.fieldValue(fields.values()[payload_index].ty, mod, payload_index);
1899719010
18998 const error_set_ty = error_set_val.toType();19011 const error_set_ty = error_set_val.toType();
18999 const payload_ty = payload_val.toType();19012 const payload_ty = payload_val.toType();
...@@ -19031,19 +19044,18 @@ fn zirReify(...@@ -19031,19 +19044,18 @@ fn zirReify(
19031 return sema.addType(ty);19044 return sema.addType(ty);
19032 },19045 },
19033 .Struct => {19046 .Struct => {
19034 // TODO use reflection instead of magic numbers here19047 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19035 const struct_val = union_val.val.castTag(.aggregate).?.data;19048 const layout_index = fields.getIndex("layout").?;
19036 // layout: containerlayout,19049 const backing_integer_index = fields.getIndex("backing_integer").?;
19037 const layout_val = struct_val[0];19050 const fields_index = fields.getIndex("fields").?;
19038 // backing_int: ?type,19051 const decls_index = fields.getIndex("decls").?;
19039 const backing_int_val = struct_val[1];19052 const is_tuple_index = fields.getIndex("is_tuple").?;
19040 // fields: []const enumfield,19053
19041 const fields_val = struct_val[2];19054 const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
19042 // decls: []const declaration,19055 const backing_integer_val = try union_val.val.fieldValue(fields.values()[backing_integer_index].ty, mod, backing_integer_index);
19043 const decls_val = struct_val[3];19056 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19044 // is_tuple: bool,19057 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
19045 const is_tuple_val = struct_val[4];19058 const is_tuple_val = try union_val.val.fieldValue(fields.values()[is_tuple_index].ty, mod, is_tuple_index);
19046 assert(struct_val.len == 5);
1904719059
19048 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);19060 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1904919061
...@@ -19052,23 +19064,23 @@ fn zirReify(...@@ -19052,23 +19064,23 @@ fn zirReify(
19052 return sema.fail(block, src, "reified structs must have no decls", .{});19064 return sema.fail(block, src, "reified structs must have no decls", .{});
19053 }19065 }
1905419066
19055 if (layout != .Packed and !backing_int_val.isNull(mod)) {19067 if (layout != .Packed and !backing_integer_val.isNull(mod)) {
19056 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});19068 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
19057 }19069 }
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));
19060 },19072 },
19061 .Enum => {19073 .Enum => {
19062 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;19074 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19063 // TODO use reflection instead of magic numbers here19075 const tag_type_index = fields.getIndex("tag_type").?;
19064 // tag_type: type,19076 const fields_index = fields.getIndex("fields").?;
19065 const tag_type_val = struct_val[0];19077 const decls_index = fields.getIndex("decls").?;
19066 // fields: []const EnumField,19078 const is_exhaustive_index = fields.getIndex("is_exhaustive").?;
19067 const fields_val = struct_val[1];19079
19068 // decls: []const Declaration,19080 const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
19069 const decls_val = struct_val[2];19081 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19070 // is_exhaustive: bool,19082 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
19071 const is_exhaustive_val = struct_val[3];19083 const is_exhaustive_val = try union_val.val.fieldValue(fields.values()[is_exhaustive_index].ty, mod, is_exhaustive_index);
1907219084
19073 // Decls19085 // Decls
19074 if (decls_val.sliceLen(mod) > 0) {19086 if (decls_val.sliceLen(mod) > 0) {
...@@ -19160,9 +19172,10 @@ fn zirReify(...@@ -19160,9 +19172,10 @@ fn zirReify(
19160 return sema.analyzeDeclVal(block, src, new_decl_index);19172 return sema.analyzeDeclVal(block, src, new_decl_index);
19161 },19173 },
19162 .Opaque => {19174 .Opaque => {
19163 const struct_val = union_val.val.castTag(.aggregate).?.data;19175 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19164 // decls: []const Declaration,19176 const decls_index = fields.getIndex("decls").?;
19165 const decls_val = struct_val[0];19177
19178 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
1916619179
19167 // Decls19180 // Decls
19168 if (decls_val.sliceLen(mod) > 0) {19181 if (decls_val.sliceLen(mod) > 0) {
...@@ -19205,16 +19218,16 @@ fn zirReify(...@@ -19205,16 +19218,16 @@ fn zirReify(
19205 return sema.analyzeDeclVal(block, src, new_decl_index);19218 return sema.analyzeDeclVal(block, src, new_decl_index);
19206 },19219 },
19207 .Union => {19220 .Union => {
19208 // TODO use reflection instead of magic numbers here19221 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19209 const struct_val = union_val.val.castTag(.aggregate).?.data;19222 const layout_index = fields.getIndex("layout").?;
19210 // layout: containerlayout,19223 const tag_type_index = fields.getIndex("tag_type").?;
19211 const layout_val = struct_val[0];19224 const fields_index = fields.getIndex("fields").?;
19212 // tag_type: ?type,19225 const decls_index = fields.getIndex("decls").?;
19213 const tag_type_val = struct_val[1];19226
19214 // fields: []const enumfield,19227 const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
19215 const fields_val = struct_val[2];19228 const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
19216 // decls: []const declaration,19229 const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
19217 const decls_val = struct_val[3];19230 const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
1921819231
19219 // Decls19232 // Decls
19220 if (decls_val.sliceLen(mod) > 0) {19233 if (decls_val.sliceLen(mod) > 0) {
...@@ -19411,25 +19424,28 @@ fn zirReify(...@@ -19411,25 +19424,28 @@ fn zirReify(
19411 return sema.analyzeDeclVal(block, src, new_decl_index);19424 return sema.analyzeDeclVal(block, src, new_decl_index);
19412 },19425 },
19413 .Fn => {19426 .Fn => {
19414 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;19427 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
19415 // TODO use reflection instead of magic numbers here19428 const calling_convention_index = fields.getIndex("calling_convention").?;
19416 // calling_convention: CallingConvention,19429 const alignment_index = fields.getIndex("alignment").?;
19417 const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);19430 const is_generic_index = fields.getIndex("is_generic").?;
19418 // alignment: comptime_int,19431 const is_var_args_index = fields.getIndex("is_var_args").?;
19419 const alignment_val = struct_val[1];19432 const return_type_index = fields.getIndex("return_type").?;
19420 // is_generic: bool,19433 const params_index = fields.getIndex("params").?;
19421 const is_generic = struct_val[2].toBool(mod);19434
19422 // is_var_args: bool,19435 const calling_convention_val = try union_val.val.fieldValue(fields.values()[calling_convention_index].ty, mod, calling_convention_index);
19423 const is_var_args = struct_val[3].toBool(mod);19436 const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
19424 // return_type: ?type,19437 const is_generic_val = try union_val.val.fieldValue(fields.values()[is_generic_index].ty, mod, is_generic_index);
19425 const return_type_val = struct_val[4];19438 const is_var_args_val = try union_val.val.fieldValue(fields.values()[is_var_args_index].ty, mod, is_var_args_index);
19426 // args: []const Param,19439 const return_type_val = try union_val.val.fieldValue(fields.values()[return_type_index].ty, mod, return_type_index);
19427 const args_val = struct_val[5];19440 const params_val = try union_val.val.fieldValue(fields.values()[params_index].ty, mod, params_index);
1942819441
19442 const is_generic = is_generic_val.toBool(mod);
19429 if (is_generic) {19443 if (is_generic) {
19430 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});19444 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
19431 }19445 }
1943219446
19447 const is_var_args = is_var_args_val.toBool(mod);
19448 const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val);
19433 if (is_var_args and cc != .C) {19449 if (is_var_args and cc != .C) {
19434 return sema.fail(block, src, "varargs functions must have C calling convention", .{});19450 return sema.fail(block, src, "varargs functions must have C calling convention", .{});
19435 }19451 }
...@@ -19448,7 +19464,7 @@ fn zirReify(...@@ -19448,7 +19464,7 @@ fn zirReify(
19448 const return_type = return_type_val.optionalValue(mod) orelse19464 const return_type = return_type_val.optionalValue(mod) orelse
19449 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});19465 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;
19452 const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));19468 const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));
1945319469
19454 const param_types = try sema.arena.alloc(InternPool.Index, args_len);19470 const param_types = try sema.arena.alloc(InternPool.Index, args_len);
src/type.zig+7-2
...@@ -3148,8 +3148,13 @@ pub const Type = struct {...@@ -3148,8 +3148,13 @@ pub const Type = struct {
3148 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {3148 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
3149 const ip = &mod.intern_pool;3149 const ip = &mod.intern_pool;
3150 const enum_type = ip.indexToKey(ty.ip_index).enum_type;3150 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
3151 assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);3151 const int_tag = switch (ip.indexToKey(enum_tag.ip_index)) {
3152 return enum_type.tagValueIndex(ip, 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);
3153 }3158 }
31543159
3155 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {3160 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {