Commit 6f08e17229
Changed files (9)
src
arch
wasm
x86_64
link
test
src/arch/wasm/CodeGen.zig
@@ -7216,13 +7216,14 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
const mod = func.bin_file.base.comp.module.?;
+ const ip = &mod.intern_pool;
const enum_decl_index = enum_ty.getOwnerDecl(mod);
var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
+ const fqn = ip.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
// check if we already generated code for this.
@@ -7252,9 +7253,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
// TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.
// generate an if-else chain for each tag value as well as constant.
- for (enum_ty.enumFields(mod), 0..) |tag_name_ip, field_index_usize| {
- const field_index = @as(u32, @intCast(field_index_usize));
- const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
+ const tag_names = enum_ty.enumFields(mod);
+ for (0..tag_names.len) |tag_index| {
+ const tag_name = ip.stringToSlice(tag_names.get(ip)[tag_index]);
// for each tag name, create an unnamed const,
// and then get a pointer to its value.
const name_ty = try mod.arrayType(.{
@@ -7279,7 +7280,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
try writer.writeByte(std.wasm.opcode(.local_get));
try leb.writeULEB128(writer, @as(u32, 1));
- const tag_val = try mod.enumValueFieldIndex(enum_ty, field_index);
+ const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
const tag_value = try func.lowerConstant(tag_val, enum_ty);
switch (tag_value) {
@@ -7372,6 +7373,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.comp.module.?;
+ const ip = &mod.intern_pool;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
@@ -7384,8 +7386,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
var lowest: ?u32 = null;
var highest: ?u32 = null;
- for (names) |name| {
- const err_int = @as(Module.ErrorInt, @intCast(mod.global_error_set.getIndex(name).?));
+ for (0..names.len) |name_index| {
+ const err_int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[name_index]).?);
if (lowest) |*l| {
if (err_int < l.*) {
l.* = err_int;
src/arch/x86_64/CodeGen.zig
@@ -2187,6 +2187,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
const mod = self.bin_file.comp.module.?;
+ const ip = &mod.intern_pool;
switch (lazy_sym.ty.zigTypeTag(mod)) {
.Enum => {
const enum_ty = lazy_sym.ty;
@@ -2209,10 +2210,10 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty });
var data_off: i32 = 0;
- for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, index_usize| {
- const index: u32 = @intCast(index_usize);
- const tag_name = mod.intern_pool.stringToSlice(enum_ty.enumFields(mod)[index_usize]);
- const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
+ const tag_names = enum_ty.enumFields(mod);
+ for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {
+ const tag_name_len = ip.stringToSlice(tag_names.get(ip)[tag_index]).len;
+ const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
const skip_reloc = try self.asmJccReloc(.ne, undefined);
@@ -2228,14 +2229,14 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
.{ .reg = ret_reg },
8,
Type.usize,
- .{ .immediate = tag_name.len },
+ .{ .immediate = tag_name_len },
.{},
);
exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
self.performReloc(skip_reloc);
- data_off += @intCast(tag_name.len + 1);
+ data_off += @intCast(tag_name_len + 1);
}
try self.airTrap();
src/codegen/c.zig
@@ -2595,6 +2595,7 @@ pub fn genGlobalAsm(mod: *Module, writer: anytype) !void {
pub fn genErrDecls(o: *Object) !void {
const mod = o.dg.module;
+ const ip = &mod.intern_pool;
const writer = o.writer();
var max_name_len: usize = 0;
@@ -2603,7 +2604,7 @@ pub fn genErrDecls(o: *Object) !void {
try writer.writeAll("enum {\n");
o.indent_writer.pushIndent();
for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
- const name = mod.intern_pool.stringToSlice(name_nts);
+ const name = ip.stringToSlice(name_nts);
max_name_len = @max(name.len, max_name_len);
const err_val = try mod.intern(.{ .err = .{
.ty = .anyerror_type,
@@ -2621,8 +2622,8 @@ pub fn genErrDecls(o: *Object) !void {
defer o.dg.gpa.free(name_buf);
@memcpy(name_buf[0..name_prefix.len], name_prefix);
- for (mod.global_error_set.keys()) |name_nts| {
- const name = mod.intern_pool.stringToSlice(name_nts);
+ for (mod.global_error_set.keys()) |name_ip| {
+ const name = ip.stringToSlice(name_ip);
@memcpy(name_buf[name_prefix.len..][0..name.len], name);
const identifier = name_buf[0 .. name_prefix.len + name.len];
@@ -2652,7 +2653,7 @@ pub fn genErrDecls(o: *Object) !void {
try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, .none, .complete);
try writer.writeAll(" = {");
for (mod.global_error_set.keys(), 0..) |name_nts, value| {
- const name = mod.intern_pool.stringToSlice(name_nts);
+ const name = ip.stringToSlice(name_nts);
if (value != 0) try writer.writeByte(',');
const len_val = try mod.intValue(Type.usize, name.len);
@@ -2730,6 +2731,7 @@ fn genExports(o: *Object) !void {
pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
const mod = o.dg.module;
+ const ip = &mod.intern_pool;
const w = o.writer();
const key = lazy_fn.key_ptr.*;
const val = lazy_fn.value_ptr;
@@ -2747,23 +2749,23 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
try w.writeByte('(');
try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
try w.writeAll(") {\n switch (tag) {\n");
- for (enum_ty.enumFields(mod), 0..) |name_ip, index_usize| {
- const index = @as(u32, @intCast(index_usize));
- const name = mod.intern_pool.stringToSlice(name_ip);
- const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
+ const tag_names = enum_ty.enumFields(mod);
+ for (0..tag_names.len) |tag_index| {
+ const tag_name = ip.stringToSlice(tag_names.get(ip)[tag_index]);
+ const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
const int_val = try tag_val.intFromEnum(enum_ty, mod);
const name_ty = try mod.arrayType(.{
- .len = name.len,
+ .len = tag_name.len,
.child = .u8_type,
.sentinel = .zero_u8,
});
const name_val = try mod.intern(.{ .aggregate = .{
.ty = name_ty.toIntern(),
- .storage = .{ .bytes = name },
+ .storage = .{ .bytes = tag_name },
} });
- const len_val = try mod.intValue(Type.usize, name.len);
+ const len_val = try mod.intValue(Type.usize, tag_name.len);
try w.print(" case {}: {{\n static ", .{
try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),
src/codegen/llvm.zig
@@ -9574,6 +9574,7 @@ pub const FuncGen = struct {
fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
const o = self.dg.object;
const mod = o.module;
+ const ip = &mod.intern_pool;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try self.resolveInst(ty_op.operand);
const error_set_ty = ty_op.ty.toType();
@@ -9585,8 +9586,8 @@ pub const FuncGen = struct {
var wip_switch = try self.wip.@"switch"(operand, invalid_block, @intCast(names.len));
defer wip_switch.finish(&self.wip);
- for (names) |name| {
- const err_int = mod.global_error_set.getIndex(name).?;
+ for (0..names.len) |name_index| {
+ const err_int = mod.global_error_set.getIndex(names.get(ip)[name_index]).?;
const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
}
src/link/Dwarf.zig
@@ -2828,7 +2828,7 @@ fn addDbgInfoErrorSet(
target: std.Target,
dbg_info_buffer: *std.ArrayList(u8),
) !void {
- return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod), target, dbg_info_buffer);
+ return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod).get(&mod.intern_pool), target, dbg_info_buffer);
}
fn addDbgInfoErrorSetNames(
src/codegen.zig
@@ -119,6 +119,7 @@ pub fn generateLazySymbol(
const comp = bin_file.comp;
const zcu = comp.module.?;
+ const ip = &zcu.intern_pool;
const target = comp.root_mod.resolved_target.result;
const endian = target.cpu.arch.endian();
const gpa = comp.gpa;
@@ -151,8 +152,9 @@ pub fn generateLazySymbol(
return Result.ok;
} else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) {
alignment.* = .@"1";
- for (lazy_sym.ty.enumFields(zcu)) |tag_name_ip| {
- const tag_name = zcu.intern_pool.stringToSlice(tag_name_ip);
+ const tag_names = lazy_sym.ty.enumFields(zcu);
+ for (0..tag_names.len) |tag_index| {
+ const tag_name = zcu.intern_pool.stringToSlice(tag_names.get(ip)[tag_index]);
try code.ensureUnusedCapacity(tag_name.len + 1);
code.appendSliceAssumeCapacity(tag_name);
code.appendAssumeCapacity(0);
src/Sema.zig
@@ -12619,8 +12619,9 @@ fn analyzeSwitchRuntimeBlock(
operand_ty.fmt(mod),
});
}
- for (0..operand_ty.errorSetNames(mod).len) |i| {
- const error_name = operand_ty.errorSetNames(mod)[i];
+ const error_names = operand_ty.errorSetNames(mod);
+ for (0..error_names.len) |name_index| {
+ const error_name = error_names.get(ip)[name_index];
if (seen_errors.contains(error_name)) continue;
cases_len += 1;
@@ -22362,8 +22363,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
if (!operand_ty.isAnyError(mod) and operand_ty.errorSetIsEmpty(mod)) break :disjoint true;
if (dest_ty.isAnyError(mod)) break :disjoint false;
if (operand_ty.isAnyError(mod)) break :disjoint false;
- for (dest_ty.errorSetNames(mod)) |dest_err_name| {
- if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
+ const dest_err_names = dest_ty.errorSetNames(mod);
+ for (0..dest_err_names.len) |dest_err_index| {
+ if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
break :disjoint false;
}
@@ -22375,8 +22377,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
_ = try sema.resolveInferredErrorSetTy(block, src, dest_ty.toIntern());
_ = try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty.toIntern());
- for (dest_ty.errorSetNames(mod)) |dest_err_name| {
- if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
+ for (0..dest_err_names.len) |dest_err_index| {
+ if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
break :disjoint false;
}
@@ -38780,17 +38782,18 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
/// Asserts that lhs and rhs are both error sets and are resolved.
fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const arena = sema.arena;
const lhs_names = lhs.errorSetNames(mod);
const rhs_names = rhs.errorSetNames(mod);
var names: InferredErrorSet.NameMap = .{};
try names.ensureUnusedCapacity(arena, lhs_names.len);
- for (lhs_names) |name| {
- names.putAssumeCapacityNoClobber(name, {});
+ for (0..lhs_names.len) |lhs_index| {
+ names.putAssumeCapacityNoClobber(lhs_names.get(ip)[lhs_index], {});
}
- for (rhs_names) |name| {
- try names.put(arena, name, {});
+ for (0..rhs_names.len) |rhs_index| {
+ try names.put(arena, rhs_names.get(ip)[rhs_index], {});
}
return mod.errorSetFromUnsortedNames(names.keys());
src/type.zig
@@ -2908,22 +2908,21 @@ pub const Type = struct {
// Asserts that `ty` is an error set and not `anyerror`.
// Asserts that `ty` is resolved if it is an inferred error set.
- pub fn errorSetNames(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
+ pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice {
const ip = &mod.intern_pool;
return switch (ip.indexToKey(ty.toIntern())) {
- .error_set_type => |x| x.names.get(ip),
+ .error_set_type => |x| x.names,
.inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {
.none => unreachable, // unresolved inferred error set
.anyerror_type => unreachable,
- else => |t| ip.indexToKey(t).error_set_type.names.get(ip),
+ else => |t| ip.indexToKey(t).error_set_type.names,
},
else => unreachable,
};
}
- pub fn enumFields(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
- const ip = &mod.intern_pool;
- return ip.indexToKey(ty.toIntern()).enum_type.names.get(ip);
+ pub fn enumFields(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice {
+ return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names;
}
pub fn enumFieldCount(ty: Type, mod: *Module) usize {
test/cbe.zig
@@ -219,23 +219,22 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void {
, "");
}
- // https://github.com/ziglang/zig/issues/18954
- //{
- // var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
+ {
+ var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
- // case.addCompareOutput(
- // \\fn add(a: i32, b: i32) i32 {
- // \\ return a + b;
- // \\}
- // \\
- // \\pub export fn main() c_int {
- // \\ const x = add(1, 2);
- // \\ var y = add(3, 0);
- // \\ y -= x;
- // \\ return y;
- // \\}
- // , "");
- //}
+ case.addCompareOutput(
+ \\fn add(a: i32, b: i32) i32 {
+ \\ return a + b;
+ \\}
+ \\
+ \\pub export fn main() c_int {
+ \\ const x = add(1, 2);
+ \\ var y = add(3, 0);
+ \\ y -= x;
+ \\ return y;
+ \\}
+ , "");
+ }
{
var case = ctx.exeFromCompiledC("control flow", .{}, b);