Commit 69b7b91092
Changed files (26)
src/arch/aarch64/CodeGen.zig
@@ -4350,7 +4350,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.data = .{ .reg = .x30 },
});
} else if (func_value.getExternFunc(mod)) |extern_func| {
- const decl_name = mem.sliceTo(mod.declPtr(extern_func.decl).name, 0);
+ const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
src/arch/sparc64/CodeGen.zig
@@ -276,8 +276,6 @@ pub fn generate(
assert(fn_owner_decl.has_tv);
const fn_type = fn_owner_decl.ty;
- log.debug("fn {s}", .{fn_owner_decl.name});
-
var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
defer {
assert(branch_stack.items.len == 1);
src/arch/wasm/CodeGen.zig
@@ -2208,7 +2208,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
const atom = func.bin_file.getAtomPtr(atom_index);
const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
try func.bin_file.addOrUpdateImport(
- mem.sliceTo(ext_decl.name, 0),
+ mod.intern_pool.stringToSlice(ext_decl.name),
atom.getSymbolIndex().?,
mod.intern_pool.stringToSliceUnwrap(ext_decl.getOwnedExternFunc(mod).?.lib_name),
type_index,
@@ -3180,9 +3180,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
}
},
.err => |err| {
- const name = mod.intern_pool.stringToSlice(err.name);
- const kv = try mod.getErrorValue(name);
- return WValue{ .imm32 = kv.value };
+ const int = try mod.getErrorValue(err.name);
+ return WValue{ .imm32 = int };
},
.error_union => |error_union| {
const err_tv: TypedValue = switch (error_union.val) {
@@ -3320,18 +3319,15 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
.enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod),
.int => |int| intStorageAsI32(int.storage, mod),
.ptr => |ptr| intIndexAsI32(&mod.intern_pool, ptr.addr.int, mod),
- .err => |err| @bitCast(i32, mod.global_error_set.get(mod.intern_pool.stringToSlice(err.name)).?),
+ .err => |err| @bitCast(i32, @intCast(Module.ErrorInt, mod.global_error_set.getIndex(err.name).?)),
else => unreachable,
},
}
- switch (ty.zigTypeTag(mod)) {
- .ErrorSet => {
- const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError(mod).?) catch unreachable; // passed invalid `Value` to function
- return @bitCast(i32, kv.value);
- },
+ return switch (ty.zigTypeTag(mod)) {
+ .ErrorSet => @bitCast(i32, val.getErrorInt(mod)),
else => unreachable, // Programmer called this function for an illegal type
- }
+ };
}
fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Module) i32 {
@@ -6874,8 +6870,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- const fqn = try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod);
- defer mod.gpa.free(fqn);
+ const fqn = mod.intern_pool.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.
@@ -7037,9 +7032,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
var lowest: ?u32 = null;
var highest: ?u32 = null;
- for (names) |name_ip| {
- const name = mod.intern_pool.stringToSlice(name_ip);
- const err_int = mod.global_error_set.get(name).?;
+ for (names) |name| {
+ const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
if (lowest) |*l| {
if (err_int < l.*) {
l.* = err_int;
src/arch/x86_64/CodeGen.zig
@@ -8132,7 +8132,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}));
} else unreachable;
} else if (func_value.getExternFunc(mod)) |extern_func| {
- const decl_name = mem.sliceTo(mod.declPtr(extern_func.decl).name, 0);
+ const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
if (self.bin_file.cast(link.File.Coff)) |coff_file| {
const atom_index = try self.owner.getSymbolIndex(self);
src/codegen/c/type.zig
@@ -1953,11 +1953,11 @@ pub const CType = extern union {
.name = try if (ty.isSimpleTuple(mod))
std.fmt.allocPrintZ(arena, "f{}", .{field_i})
else
- arena.dupeZ(u8, switch (zig_ty_tag) {
+ arena.dupeZ(u8, mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.structFieldName(field_i, mod),
.Union => ty.unionFields(mod).keys()[field_i],
else => unreachable,
- }),
+ })),
.type = store.set.typeToIndex(field_ty, mod, switch (kind) {
.forward, .forward_parameter => .forward,
.complete, .parameter, .payload => .complete,
@@ -2102,12 +2102,13 @@ pub const CType = extern union {
}) or !mem.eql(
u8,
if (ty.isSimpleTuple(mod))
- std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
- else switch (zig_ty_tag) {
- .Struct => ty.structFieldName(field_i, mod),
- .Union => ty.unionFields(mod).keys()[field_i],
- else => unreachable,
- },
+ std.fmt.bufPrintZ(&name_buf, "f{}", .{field_i}) catch unreachable
+ else
+ mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
+ .Struct => ty.structFieldName(field_i, mod),
+ .Union => ty.unionFields(mod).keys()[field_i],
+ else => unreachable,
+ }),
mem.span(c_field.name),
) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
c_field.alignas.@"align") return false;
@@ -2225,11 +2226,12 @@ pub const CType = extern union {
});
hasher.update(if (ty.isSimpleTuple(mod))
std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
- else switch (zig_ty_tag) {
- .Struct => ty.structFieldName(field_i, mod),
- .Union => ty.unionFields(mod).keys()[field_i],
- else => unreachable,
- });
+ else
+ mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
+ .Struct => ty.structFieldName(field_i, mod),
+ .Union => ty.unionFields(mod).keys()[field_i],
+ else => unreachable,
+ }));
autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
}
},
src/codegen/c.zig
@@ -452,6 +452,7 @@ pub const Function = struct {
var promoted = f.object.dg.ctypes.promote(gpa);
defer f.object.dg.ctypes.demote(promoted);
const arena = promoted.arena.allocator();
+ const mod = f.object.dg.module;
gop.value_ptr.* = .{
.fn_name = switch (key) {
@@ -460,7 +461,7 @@ pub const Function = struct {
.never_inline,
=> |owner_decl| try std.fmt.allocPrint(arena, "zig_{s}_{}__{d}", .{
@tagName(key),
- fmtIdent(mem.span(f.object.dg.module.declPtr(owner_decl).name)),
+ fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
@enumToInt(owner_decl),
}),
},
@@ -1465,7 +1466,7 @@ pub const DeclGen = struct {
try writer.writeAll(" .payload = {");
}
if (field_ty.hasRuntimeBits(mod)) {
- try writer.print(" .{ } = ", .{fmtIdent(field_name)});
+ try writer.print(" .{ } = ", .{fmtIdent(mod.intern_pool.stringToSlice(field_name))});
try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
try writer.writeByte(' ');
} else for (ty.unionFields(mod).values()) |field| {
@@ -1849,9 +1850,9 @@ pub const DeclGen = struct {
try mod.markDeclAlive(decl);
if (mod.decl_exports.get(decl_index)) |exports| {
- try writer.writeAll(exports.items[export_index].options.name);
+ try writer.writeAll(mod.intern_pool.stringToSlice(exports.items[export_index].name));
} else if (decl.isExtern(mod)) {
- try writer.writeAll(mem.span(decl.name));
+ try writer.writeAll(mod.intern_pool.stringToSlice(decl.name));
} else {
// MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
// expand to 3x the length of its input, but let's cut it off at a much shorter limit.
@@ -1987,7 +1988,7 @@ fn renderTypeName(
try w.print("{s} {s}{}__{d}", .{
@tagName(tag)["fwd_".len..],
attributes,
- fmtIdent(mem.span(mod.declPtr(owner_decl).name)),
+ fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
@enumToInt(owner_decl),
});
},
@@ -2406,11 +2407,12 @@ pub fn genErrDecls(o: *Object) !void {
try writer.writeAll("enum {\n");
o.indent_writer.pushIndent();
var max_name_len: usize = 0;
- for (mod.error_name_list.items[1..], 1..) |name, value| {
- max_name_len = std.math.max(name.len, max_name_len);
+ for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
+ const name = mod.intern_pool.stringToSlice(name_nts);
+ max_name_len = @max(name.len, max_name_len);
const err_val = try mod.intern(.{ .err = .{
.ty = .anyerror_type,
- .name = mod.intern_pool.getString(name).unwrap().?,
+ .name = name_nts,
} });
try o.dg.renderValue(writer, Type.anyerror, err_val.toValue(), .Other);
try writer.print(" = {d}u,\n", .{value});
@@ -2424,7 +2426,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.error_name_list.items) |name| {
+ for (mod.global_error_set.keys()) |name_nts| {
+ const name = mod.intern_pool.stringToSlice(name_nts);
@memcpy(name_buf[name_prefix.len..][0..name.len], name);
const identifier = name_buf[0 .. name_prefix.len + name.len];
@@ -2446,14 +2449,15 @@ pub fn genErrDecls(o: *Object) !void {
}
const name_array_ty = try mod.arrayType(.{
- .len = mod.error_name_list.items.len,
+ .len = mod.global_error_set.count(),
.child = .slice_const_u8_sentinel_0_type,
});
try writer.writeAll("static ");
try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete);
try writer.writeAll(" = {");
- for (mod.error_name_list.items, 0..) |name, value| {
+ for (mod.global_error_set.keys(), 0..) |name_nts, value| {
+ const name = mod.intern_pool.stringToSlice(name_nts);
if (value != 0) try writer.writeByte(',');
const len_val = try mod.intValue(Type.usize, name.len);
@@ -2469,14 +2473,16 @@ fn genExports(o: *Object) !void {
const tracy = trace(@src());
defer tracy.end();
+ const mod = o.dg.module;
+ const ip = &mod.intern_pool;
const fwd_decl_writer = o.dg.fwd_decl.writer();
- if (o.dg.module.decl_exports.get(o.dg.decl_index.unwrap().?)) |exports| {
+ if (mod.decl_exports.get(o.dg.decl_index.unwrap().?)) |exports| {
for (exports.items[1..], 1..) |@"export", i| {
try fwd_decl_writer.writeAll("zig_export(");
try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });
try fwd_decl_writer.print(", {s}, {s});\n", .{
- fmtStringLiteral(exports.items[0].options.name, null),
- fmtStringLiteral(@"export".options.name, null),
+ fmtStringLiteral(ip.stringToSlice(exports.items[0].name), null),
+ fmtStringLiteral(ip.stringToSlice(@"export".name), null),
});
}
}
@@ -2680,9 +2686,10 @@ pub fn genDecl(o: *Object) !void {
if (!is_global) try w.writeAll("static ");
if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
- if (decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section});
+ if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
+ try w.print("zig_linksection(\"{s}\", ", .{s});
try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete);
- if (decl.@"linksection" != null) try w.writeAll(", read, write)");
+ if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
try w.writeAll(" = ");
try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
try w.writeByte(';');
@@ -2697,9 +2704,10 @@ pub fn genDecl(o: *Object) !void {
const w = o.writer();
if (!is_global) try w.writeAll("static ");
- if (decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section});
+ if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
+ try w.print("zig_linksection(\"{s}\", ", .{s});
try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.@"align", .complete);
- if (decl.@"linksection" != null) try w.writeAll(", read)");
+ if (decl.@"linksection" != .none) try w.writeAll(", read)");
try w.writeAll(" = ");
try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
try w.writeAll(";\n");
@@ -4229,7 +4237,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const writer = f.object.writer();
const function = mod.funcPtr(ty_fn.func);
- try writer.print("/* dbg func:{s} */\n", .{mod.declPtr(function.owner_decl).name});
+ try writer.print("/* dbg func:{s} */\n", .{
+ mod.intern_pool.stringToSlice(mod.declPtr(function.owner_decl).name),
+ });
return .none;
}
@@ -5176,6 +5186,7 @@ fn fieldLocation(
byte_offset: u32,
end: void,
} {
+ const ip = &mod.intern_pool;
return switch (container_ty.zigTypeTag(mod)) {
.Struct => switch (container_ty.containerLayout(mod)) {
.Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index| {
@@ -5186,7 +5197,7 @@ fn fieldLocation(
break .{ .field = if (container_ty.isSimpleTuple(mod))
.{ .field = next_field_index }
else
- .{ .identifier = container_ty.structFieldName(next_field_index, mod) } };
+ .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
} else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
.Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)
.{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
@@ -5204,9 +5215,9 @@ fn fieldLocation(
.begin;
const field_name = container_ty.unionFields(mod).keys()[field_index];
return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|
- .{ .payload_identifier = field_name }
+ .{ .payload_identifier = ip.stringToSlice(field_name) }
else
- .{ .identifier = field_name } };
+ .{ .identifier = ip.stringToSlice(field_name) } };
},
.Packed => .begin,
},
@@ -5347,6 +5358,7 @@ fn fieldPtr(
fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
+ const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
@@ -5369,7 +5381,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
.Auto, .Extern => if (struct_ty.isSimpleTuple(mod))
.{ .field = extra.field_index }
else
- .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
+ .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
.Packed => {
const struct_obj = mod.typeToStruct(struct_ty).?;
const int_info = struct_ty.intInfo(mod);
@@ -5431,7 +5443,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
.{ .field = extra.field_index }
else
- .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
+ .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
.union_type => |union_type| field_name: {
const union_obj = mod.unionPtr(union_type.index);
@@ -5462,9 +5474,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
} else {
const name = union_obj.fields.keys()[extra.field_index];
break :field_name if (union_type.hasTag()) .{
- .payload_identifier = name,
+ .payload_identifier = ip.stringToSlice(name),
} else .{
- .identifier = name,
+ .identifier = ip.stringToSlice(name),
};
}
},
@@ -6723,6 +6735,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
+ const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const inst_ty = f.typeOfIndex(inst);
const len = @intCast(usize, inst_ty.arrayLen(mod));
@@ -6773,7 +6786,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod))
.{ .field = field_i }
else
- .{ .identifier = inst_ty.structFieldName(field_i, mod) });
+ .{ .identifier = ip.stringToSlice(inst_ty.structFieldName(field_i, mod)) });
try a.assign(f, writer);
try f.writeCValue(writer, element, .Other);
try a.end(f, writer);
@@ -6851,6 +6864,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
+ const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
@@ -6886,8 +6900,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
try a.end(f, writer);
}
- break :field .{ .payload_identifier = field_name };
- } else .{ .identifier = field_name };
+ break :field .{ .payload_identifier = ip.stringToSlice(field_name) };
+ } else .{ .identifier = ip.stringToSlice(field_name) };
const a = try Assignment.start(f, writer, payload_ty);
try f.writeCValueMember(writer, local, field);
src/codegen/llvm.zig
@@ -585,13 +585,13 @@ pub const Object = struct {
const slice_ty = Type.slice_const_u8_sentinel_0;
const slice_alignment = slice_ty.abiAlignment(mod);
- const error_name_list = mod.error_name_list.items;
+ const error_name_list = mod.global_error_set.keys();
const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);
defer mod.gpa.free(llvm_errors);
llvm_errors[0] = llvm_slice_ty.getUndef();
- for (llvm_errors[1..], 0..) |*llvm_error, i| {
- const name = error_name_list[1..][i];
+ for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {
+ const name = mod.intern_pool.stringToSlice(name_nts);
const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");
str_global.setInitializer(str_init);
@@ -671,7 +671,7 @@ pub const Object = struct {
const llvm_global = entry.value_ptr.*;
// Same logic as below but for externs instead of exports.
const decl = mod.declPtr(decl_index);
- const other_global = object.getLlvmGlobal(decl.name) orelse continue;
+ const other_global = object.getLlvmGlobal(mod.intern_pool.stringToSlice(decl.name)) orelse continue;
if (other_global == llvm_global) continue;
llvm_global.replaceAllUsesWith(other_global);
@@ -689,8 +689,7 @@ pub const Object = struct {
// case, we need to replace all uses of it with this exported global.
// TODO update std.builtin.ExportOptions to have the name be a
// null-terminated slice.
- const exp_name_z = try mod.gpa.dupeZ(u8, exp.options.name);
- defer mod.gpa.free(exp_name_z);
+ const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
if (other_global == llvm_global) continue;
@@ -923,9 +922,8 @@ pub const Object = struct {
dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
}
- if (decl.@"linksection") |section| {
+ if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
llvm_func.setSection(section);
- }
// Remove all the basic blocks of a function in order to start over, generating
// LLVM IR from an empty function body.
@@ -1173,7 +1171,7 @@ pub const Object = struct {
0;
const subprogram = dib.createFunction(
di_file.?.toScope(),
- decl.name,
+ mod.intern_pool.stringToSlice(decl.name),
llvm_func.getValueName(),
di_file.?,
line_number,
@@ -1273,22 +1271,26 @@ pub const Object = struct {
if (decl.isExtern(mod)) {
var free_decl_name = false;
const decl_name = decl_name: {
+ const decl_name = mod.intern_pool.stringToSlice(decl.name);
+
if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {
if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
if (!std.mem.eql(u8, lib_name, "c")) {
free_decl_name = true;
- break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{ decl.name, lib_name });
+ break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{
+ decl_name, lib_name,
+ });
}
}
}
- break :decl_name std.mem.span(decl.name);
+
+ break :decl_name decl_name;
};
defer if (free_decl_name) gpa.free(decl_name);
llvm_global.setValueName(decl_name);
if (self.getLlvmGlobal(decl_name)) |other_global| {
if (other_global != llvm_global) {
- log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
try self.extern_collisions.put(gpa, decl_index, {});
}
}
@@ -1298,11 +1300,11 @@ pub const Object = struct {
if (self.di_map.get(decl)) |di_node| {
if (try decl.isFunction(mod)) {
const di_func = @ptrCast(*llvm.DISubprogram, di_node);
- const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
+ const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
di_func.replaceLinkageName(linkage_name);
} else {
const di_global = @ptrCast(*llvm.DIGlobalVariable, di_node);
- const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
+ const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
di_global.replaceLinkageName(linkage_name);
}
}
@@ -1317,7 +1319,7 @@ pub const Object = struct {
}
}
} else if (exports.len != 0) {
- const exp_name = exports[0].options.name;
+ const exp_name = mod.intern_pool.stringToSlice(exports[0].name);
llvm_global.setValueName2(exp_name.ptr, exp_name.len);
llvm_global.setUnnamedAddr(.False);
if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
@@ -1332,21 +1334,19 @@ pub const Object = struct {
di_global.replaceLinkageName(linkage_name);
}
}
- switch (exports[0].options.linkage) {
+ switch (exports[0].linkage) {
.Internal => unreachable,
.Strong => llvm_global.setLinkage(.External),
.Weak => llvm_global.setLinkage(.WeakODR),
.LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
}
- switch (exports[0].options.visibility) {
+ switch (exports[0].visibility) {
.default => llvm_global.setVisibility(.Default),
.hidden => llvm_global.setVisibility(.Hidden),
.protected => llvm_global.setVisibility(.Protected),
}
- if (exports[0].options.section) |section| {
- const section_z = try gpa.dupeZ(u8, section);
- defer gpa.free(section_z);
- llvm_global.setSection(section_z);
+ if (mod.intern_pool.stringToSliceUnwrap(exports[0].section)) |section| {
+ llvm_global.setSection(section);
}
if (decl.val.getVariable(mod)) |variable| {
if (variable.is_threadlocal) {
@@ -1356,13 +1356,12 @@ pub const Object = struct {
// If a Decl is exported more than one time (which is rare),
// we add aliases for all but the first export.
- // TODO LLVM C API does not support deleting aliases. We need to
- // patch it to support this or figure out how to wrap the C++ API ourselves.
+ // TODO LLVM C API does not support deleting aliases.
+ // The planned solution to this is https://github.com/ziglang/zig/issues/13265
// Until then we iterate over existing aliases and make them point
// to the correct decl, or otherwise add a new alias. Old aliases are leaked.
for (exports[1..]) |exp| {
- const exp_name_z = try gpa.dupeZ(u8, exp.options.name);
- defer gpa.free(exp_name_z);
+ const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
alias.setAliasee(llvm_global);
@@ -1376,8 +1375,7 @@ pub const Object = struct {
}
}
} else {
- const fqn = try decl.getFullyQualifiedName(mod);
- defer gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
llvm_global.setValueName2(fqn.ptr, fqn.len);
llvm_global.setLinkage(.Internal);
if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
@@ -2092,8 +2090,7 @@ pub const Object = struct {
const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
offset = field_offset + field_size;
- const field_name = try gpa.dupeZ(u8, fields.keys()[field_and_index.index]);
- defer gpa.free(field_name);
+ const field_name = mod.intern_pool.stringToSlice(fields.keys()[field_and_index.index]);
try di_fields.append(gpa, dib.createMemberType(
fwd_decl.toScope(),
@@ -2200,12 +2197,9 @@ pub const Object = struct {
const field_size = field.ty.abiSize(mod);
const field_align = field.normalAlignment(mod);
- const field_name_copy = try gpa.dupeZ(u8, field_name);
- defer gpa.free(field_name_copy);
-
di_fields.appendAssumeCapacity(dib.createMemberType(
fwd_decl.toScope(),
- field_name_copy,
+ mod.intern_pool.stringToSlice(field_name),
null, // file
0, // line
field_size * 8, // size in bits
@@ -2327,7 +2321,7 @@ pub const Object = struct {
if (fn_info.return_type.toType().isError(mod) and
o.module.comp.bin_file.options.error_return_tracing)
{
- const ptr_ty = try mod.singleMutPtrType(o.getStackTraceType());
+ const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
}
@@ -2384,7 +2378,7 @@ pub const Object = struct {
const fields: [0]*llvm.DIType = .{};
return o.di_builder.?.createStructType(
try o.namespaceToDebugScope(decl.src_namespace),
- decl.name, // TODO use fully qualified name
+ mod.intern_pool.stringToSlice(decl.name), // TODO use fully qualified name
try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),
decl.src_line + 1,
0, // size in bits
@@ -2399,18 +2393,18 @@ pub const Object = struct {
);
}
- fn getStackTraceType(o: *Object) Type {
+ fn getStackTraceType(o: *Object) Allocator.Error!Type {
const mod = o.module;
const std_pkg = mod.main_pkg.table.get("std").?;
const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
- const builtin_str: []const u8 = "builtin";
+ const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");
const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
const builtin_decl = std_namespace.decls
.getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;
- const stack_trace_str: []const u8 = "StackTrace";
+ const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace");
// buffer is only used for int_type, `builtin` is a struct.
const builtin_ty = mod.declPtr(builtin_decl).val.toType();
const builtin_namespace = builtin_ty.getNamespace(mod).?;
@@ -2452,16 +2446,13 @@ pub const DeclGen = struct {
const decl_index = dg.decl_index;
assert(decl.has_tv);
- log.debug("gen: {s} type: {}, value: {}", .{
- decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
- });
if (decl.val.getExternFunc(mod)) |extern_func| {
_ = try dg.resolveLlvmFunction(extern_func.decl);
} else {
const target = mod.getTarget();
var global = try dg.resolveGlobalDecl(decl_index);
global.setAlignment(decl.getAlignment(mod));
- if (decl.@"linksection") |section| global.setSection(section);
+ if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s);
assert(decl.has_tv);
const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
break :init_val variable.init;
@@ -2495,7 +2486,8 @@ pub const DeclGen = struct {
new_global.setLinkage(global.getLinkage());
new_global.setUnnamedAddr(global.getUnnamedAddress());
new_global.setAlignment(global.getAlignment());
- if (decl.@"linksection") |section| new_global.setSection(section);
+ if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
+ new_global.setSection(s);
new_global.setInitializer(llvm_init);
// TODO: How should this work then the address space of a global changed?
global.replaceAllUsesWith(new_global);
@@ -2513,7 +2505,7 @@ pub const DeclGen = struct {
const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
const di_global = dib.createGlobalVariableExpression(
di_file.toScope(),
- decl.name,
+ mod.intern_pool.stringToSlice(decl.name),
global.getValueName(),
di_file,
line_number,
@@ -2544,8 +2536,7 @@ pub const DeclGen = struct {
const fn_type = try dg.lowerType(zig_fn_type);
- const fqn = try decl.getFullyQualifiedName(mod);
- defer dg.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace);
@@ -2557,7 +2548,7 @@ pub const DeclGen = struct {
llvm_fn.setUnnamedAddr(.True);
} else {
if (target.isWasm()) {
- dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));
+ dg.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name));
if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
if (!std.mem.eql(u8, lib_name, "c")) {
dg.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
@@ -2699,8 +2690,7 @@ pub const DeclGen = struct {
const mod = dg.module;
const decl = mod.declPtr(decl_index);
- const fqn = try decl.getFullyQualifiedName(mod);
- defer dg.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const target = mod.getTarget();
@@ -2716,7 +2706,7 @@ pub const DeclGen = struct {
// This is needed for declarations created by `@extern`.
if (decl.isExtern(mod)) {
- llvm_global.setValueName(decl.name);
+ llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name));
llvm_global.setUnnamedAddr(.False);
llvm_global.setLinkage(.External);
if (decl.val.getVariable(mod)) |variable| {
@@ -2811,8 +2801,7 @@ pub const DeclGen = struct {
if (gop.found_existing) return gop.value_ptr.*;
const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;
- const name = try mod.opaqueFullyQualifiedName(opaque_type);
- defer gpa.free(name);
+ const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type));
const llvm_struct_ty = dg.context.structCreateNamed(name);
gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
@@ -2963,8 +2952,7 @@ pub const DeclGen = struct {
return int_llvm_ty;
}
- const name = try struct_obj.getFullyQualifiedName(mod);
- defer gpa.free(name);
+ const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
const llvm_struct_ty = dg.context.structCreateNamed(name);
gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
@@ -3040,8 +3028,7 @@ pub const DeclGen = struct {
return enum_tag_llvm_ty;
}
- const name = try union_obj.getFullyQualifiedName(mod);
- defer gpa.free(name);
+ const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod));
const llvm_union_ty = dg.context.structCreateNamed(name);
gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
@@ -3119,7 +3106,7 @@ pub const DeclGen = struct {
if (fn_info.return_type.toType().isError(mod) and
mod.comp.bin_file.options.error_return_tracing)
{
- const ptr_ty = try mod.singleMutPtrType(dg.object.getStackTraceType());
+ const ptr_ty = try mod.singleMutPtrType(try dg.object.getStackTraceType());
try llvm_params.append(try dg.lowerType(ptr_ty));
}
@@ -3266,9 +3253,8 @@ pub const DeclGen = struct {
},
.err => |err| {
const llvm_ty = try dg.lowerType(Type.anyerror);
- const name = mod.intern_pool.stringToSlice(err.name);
- const kv = try mod.getErrorValue(name);
- return llvm_ty.constInt(kv.value, .False);
+ const int = try mod.getErrorValue(err.name);
+ return llvm_ty.constInt(int, .False);
},
.error_union => |error_union| {
const err_tv: TypedValue = switch (error_union.val) {
@@ -5960,8 +5946,7 @@ pub const FuncGen = struct {
.base_line = self.base_line,
});
- const fqn = try decl.getFullyQualifiedName(mod);
- defer self.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const is_internal_linkage = !mod.decl_exports.contains(decl_index);
const fn_ty = try mod.funcType(.{
@@ -5981,7 +5966,7 @@ pub const FuncGen = struct {
});
const subprogram = dib.createFunction(
di_file.toScope(),
- decl.name,
+ mod.intern_pool.stringToSlice(decl.name),
fqn,
di_file,
line_number,
@@ -8629,9 +8614,8 @@ pub const FuncGen = struct {
const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
- for (names) |name_ip| {
- const name = mod.intern_pool.stringToSlice(name_ip);
- const err_int = mod.global_error_set.get(name).?;
+ for (names) |name| {
+ const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
const this_tag_int_value = try self.dg.lowerValue(.{
.ty = Type.err_int,
.val = try mod.intValue(Type.err_int, err_int),
@@ -8681,8 +8665,7 @@ pub const FuncGen = struct {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
- defer self.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
@@ -8754,8 +8737,7 @@ pub const FuncGen = struct {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
- defer self.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
const slice_ty = Type.slice_const_u8_sentinel_0;
src/codegen/spirv.zig
@@ -593,7 +593,6 @@ pub const DeclGen = struct {
.extern_func => unreachable, // TODO
else => {
const result_id = dg.spv.allocId();
- log.debug("addDeclRef: id = {}, index = {}, name = {s}", .{ result_id.id, @enumToInt(spv_decl_index), decl.name });
try self.decl_deps.put(spv_decl_index, {});
@@ -664,9 +663,8 @@ pub const DeclGen = struct {
=> unreachable, // non-runtime values
.int => try self.addInt(ty, val),
.err => |err| {
- const name = mod.intern_pool.stringToSlice(err.name);
- const kv = try mod.getErrorValue(name);
- try self.addConstInt(u16, @intCast(u16, kv.value));
+ const int = try mod.getErrorValue(err.name);
+ try self.addConstInt(u16, @intCast(u16, int));
},
.error_union => |error_union| {
const payload_ty = ty.errorUnionPayload(mod);
@@ -1288,8 +1286,7 @@ pub const DeclGen = struct {
member_index += 1;
}
- const name = try struct_obj.getFullyQualifiedName(self.module);
- defer self.module.gpa.free(name);
+ const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
return try self.spv.resolve(.{ .struct_type = .{
.name = try self.spv.resolveString(name),
@@ -1500,7 +1497,6 @@ pub const DeclGen = struct {
const spv_decl_index = try self.resolveDecl(self.decl_index);
const decl_id = self.spv.declPtr(spv_decl_index).result_id;
- log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });
if (decl.val.getFunction(mod)) |_| {
assert(decl.ty.zigTypeTag(mod) == .Fn);
@@ -1542,8 +1538,7 @@ pub const DeclGen = struct {
try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
try self.spv.addFunction(spv_decl_index, self.func);
- const fqn = try decl.getFullyQualifiedName(self.module);
- defer self.module.gpa.free(fqn);
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(self.module));
try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{
.target = decl_id,
src/link/C.zig
@@ -6,6 +6,7 @@ const fs = std.fs;
const C = @This();
const Module = @import("../Module.zig");
+const InternPool = @import("../InternPool.zig");
const Compilation = @import("../Compilation.zig");
const codegen = @import("../codegen/c.zig");
const link = @import("../link.zig");
@@ -289,11 +290,11 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
}
{
- var export_names = std.StringHashMapUnmanaged(void){};
+ var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
defer export_names.deinit(gpa);
try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len));
for (module.decl_exports.values()) |exports| for (exports.items) |@"export"|
- try export_names.put(gpa, @"export".options.name, {});
+ try export_names.put(gpa, @"export".name, {});
while (f.remaining_decls.popOrNull()) |kv| {
const decl_index = kv.key;
@@ -553,7 +554,7 @@ fn flushDecl(
self: *C,
f: *Flush,
decl_index: Module.Decl.Index,
- export_names: std.StringHashMapUnmanaged(void),
+ export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
) FlushDeclError!void {
const gpa = self.base.allocator;
const mod = self.base.options.module.?;
@@ -571,7 +572,7 @@ fn flushDecl(
try self.flushLazyFns(f, decl_block.lazy_fns);
try f.all_buffers.ensureUnusedCapacity(gpa, 1);
- if (!(decl.isExtern(mod) and export_names.contains(mem.span(decl.name))))
+ if (!(decl.isExtern(mod) and export_names.contains(decl.name)))
f.appendBufAssumeCapacity(decl_block.fwd_decl.items);
}
src/link/Coff.zig
@@ -1097,8 +1097,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
const atom_index = try self.createAtom();
const sym_name = blk: {
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const index = unnamed_consts.items.len;
break :blk try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
@@ -1324,12 +1323,10 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
}
fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void {
- const gpa = self.base.allocator;
const mod = self.base.options.module.?;
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
const required_alignment = decl.getAlignment(mod);
@@ -1420,6 +1417,8 @@ pub fn updateDeclExports(
@panic("Attempted to compile for object format that was disabled by build configuration");
}
+ const ip = &mod.intern_pool;
+
if (build_options.have_llvm) {
// Even in the case of LLVM, we need to notice certain exported symbols in order to
// detect the default subsystem.
@@ -1431,20 +1430,20 @@ pub fn updateDeclExports(
else => std.builtin.CallingConvention.C,
};
const decl_cc = exported_decl.ty.fnCallingConvention(mod);
- if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and
+ if (decl_cc == .C and ip.stringEqlSlice(exp.name, "main") and
self.base.options.link_libc)
{
mod.stage1_flags.have_c_main = true;
} else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
- if (mem.eql(u8, exp.options.name, "WinMain")) {
+ if (ip.stringEqlSlice(exp.name, "WinMain")) {
mod.stage1_flags.have_winmain = true;
- } else if (mem.eql(u8, exp.options.name, "wWinMain")) {
+ } else if (ip.stringEqlSlice(exp.name, "wWinMain")) {
mod.stage1_flags.have_wwinmain = true;
- } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {
+ } else if (ip.stringEqlSlice(exp.name, "WinMainCRTStartup")) {
mod.stage1_flags.have_winmain_crt_startup = true;
- } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
+ } else if (ip.stringEqlSlice(exp.name, "wWinMainCRTStartup")) {
mod.stage1_flags.have_wwinmain_crt_startup = true;
- } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) {
+ } else if (ip.stringEqlSlice(exp.name, "DllMainCRTStartup")) {
mod.stage1_flags.have_dllmain_crt_startup = true;
}
}
@@ -1453,9 +1452,6 @@ pub fn updateDeclExports(
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
}
- const tracy = trace(@src());
- defer tracy.end();
-
const gpa = self.base.allocator;
const decl = mod.declPtr(decl_index);
@@ -1465,12 +1461,13 @@ pub fn updateDeclExports(
const decl_metadata = self.decls.getPtr(decl_index).?;
for (exports) |exp| {
- log.debug("adding new export '{s}'", .{exp.options.name});
+ const exp_name = mod.intern_pool.stringToSlice(exp.name);
+ log.debug("adding new export '{s}'", .{exp_name});
- if (exp.options.section) |section_name| {
+ if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
if (!mem.eql(u8, section_name, ".text")) {
try mod.failed_exports.putNoClobber(
- mod.gpa,
+ gpa,
exp,
try Module.ErrorMsg.create(
gpa,
@@ -1483,9 +1480,9 @@ pub fn updateDeclExports(
}
}
- if (exp.options.linkage == .LinkOnce) {
+ if (exp.linkage == .LinkOnce) {
try mod.failed_exports.putNoClobber(
- mod.gpa,
+ gpa,
exp,
try Module.ErrorMsg.create(
gpa,
@@ -1497,19 +1494,19 @@ pub fn updateDeclExports(
continue;
}
- const sym_index = decl_metadata.getExport(self, exp.options.name) orelse blk: {
+ const sym_index = decl_metadata.getExport(self, exp_name) orelse blk: {
const sym_index = try self.allocateSymbol();
try decl_metadata.exports.append(gpa, sym_index);
break :blk sym_index;
};
const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
const sym = self.getSymbolPtr(sym_loc);
- try self.setSymbolName(sym, exp.options.name);
+ try self.setSymbolName(sym, exp_name);
sym.value = decl_sym.value;
sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1);
sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL };
- switch (exp.options.linkage) {
+ switch (exp.linkage) {
.Strong => {
sym.storage_class = .EXTERNAL;
},
@@ -1522,9 +1519,15 @@ pub fn updateDeclExports(
}
}
-pub fn deleteDeclExport(self: *Coff, decl_index: Module.Decl.Index, name: []const u8) void {
+pub fn deleteDeclExport(
+ self: *Coff,
+ decl_index: Module.Decl.Index,
+ name_ip: InternPool.NullTerminatedString,
+) void {
if (self.llvm_object) |_| return;
const metadata = self.decls.getPtr(decl_index) orelse return;
+ const mod = self.base.options.module.?;
+ const name = mod.intern_pool.stringToSlice(name_ip);
const sym_index = metadata.getExportPtr(self, name) orelse return;
const gpa = self.base.allocator;
@@ -2540,6 +2543,7 @@ const ImportTable = @import("Coff/ImportTable.zig");
const Liveness = @import("../Liveness.zig");
const LlvmObject = @import("../codegen/llvm.zig").Object;
const Module = @import("../Module.zig");
+const InternPool = @import("../InternPool.zig");
const Object = @import("Coff/Object.zig");
const Relocation = @import("Coff/Relocation.zig");
const TableSection = @import("table_section.zig").TableSection;
src/link/Dwarf.zig
@@ -358,8 +358,9 @@ pub const DeclState = struct {
struct_obj.fields.keys(),
struct_obj.fields.values(),
0..,
- ) |field_name, field, field_index| {
+ ) |field_name_ip, field, field_index| {
if (!field.ty.hasRuntimeBits(mod)) continue;
+ const field_name = mod.intern_pool.stringToSlice(field_name_ip);
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
@@ -469,7 +470,8 @@ pub const DeclState = struct {
// DW.AT.member
try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
- try dbg_info_buffer.writer().print("{s}\x00", .{field_name});
+ try dbg_info_buffer.appendSlice(mod.intern_pool.stringToSlice(field_name));
+ try dbg_info_buffer.append(0);
// DW.AT.type, DW.FORM.ref4
const index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
@@ -949,8 +951,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
defer tracy.end();
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer self.allocator.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
log.debug("initDeclState {s}{*}", .{ decl_name, decl });
@@ -1273,7 +1274,6 @@ pub fn commitDeclState(
}
}
- log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});
try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));
while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
@@ -1345,7 +1345,6 @@ pub fn commitDeclState(
}
}
- log.debug("writeDeclDebugInfo for '{s}", .{decl.name});
try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
}
@@ -2523,15 +2522,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
// TODO: don't create a zig type for this, just make the dwarf info
// without touching the zig type system.
- const names = try arena.alloc(InternPool.NullTerminatedString, module.global_error_set.count());
- {
- var it = module.global_error_set.keyIterator();
- var i: usize = 0;
- while (it.next()) |key| : (i += 1) {
- names[i] = module.intern_pool.getString(key.*).unwrap().?;
- }
- }
-
+ const names = try arena.dupe(InternPool.NullTerminatedString, module.global_error_set.keys());
std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);
const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
@@ -2682,8 +2673,8 @@ fn addDbgInfoErrorSet(
const error_names = ty.errorSetNames(mod);
for (error_names) |error_name_ip| {
+ const int = try mod.getErrorValue(error_name_ip);
const error_name = mod.intern_pool.stringToSlice(error_name_ip);
- const kv = mod.getErrorValue(error_name) catch unreachable;
// DW.AT.enumerator
try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
@@ -2691,7 +2682,7 @@ fn addDbgInfoErrorSet(
dbg_info_buffer.appendSliceAssumeCapacity(error_name);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.const_value, DW.FORM.data8
- mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), kv.value, target_endian);
+ mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), int, target_endian);
}
// DW.AT.enumeration_type delimit children
src/link/Elf.zig
@@ -28,6 +28,7 @@ const File = link.File;
const Liveness = @import("../Liveness.zig");
const LlvmObject = @import("../codegen/llvm.zig").Object;
const Module = @import("../Module.zig");
+const InternPool = @import("../InternPool.zig");
const Package = @import("../Package.zig");
const StringTable = @import("strtab.zig").StringTable;
const TableSection = @import("table_section.zig").TableSection;
@@ -2480,8 +2481,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
const mod = self.base.options.module.?;
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer self.base.allocator.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
const required_alignment = decl.getAlignment(mod);
@@ -2802,8 +2802,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
const decl = mod.declPtr(decl_index);
const name_str_index = blk: {
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const index = unnamed_consts.items.len;
const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
defer gpa.free(name);
@@ -2880,7 +2879,8 @@ pub fn updateDeclExports(
try self.global_symbols.ensureUnusedCapacity(gpa, exports.len);
for (exports) |exp| {
- if (exp.options.section) |section_name| {
+ const exp_name = mod.intern_pool.stringToSlice(exp.name);
+ if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
if (!mem.eql(u8, section_name, ".text")) {
try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
mod.failed_exports.putAssumeCapacityNoClobber(
@@ -2890,11 +2890,11 @@ pub fn updateDeclExports(
continue;
}
}
- const stb_bits: u8 = switch (exp.options.linkage) {
+ const stb_bits: u8 = switch (exp.linkage) {
.Internal => elf.STB_LOCAL,
.Strong => blk: {
const entry_name = self.base.options.entry orelse "_start";
- if (mem.eql(u8, exp.options.name, entry_name)) {
+ if (mem.eql(u8, exp_name, entry_name)) {
self.entry_addr = decl_sym.st_value;
}
break :blk elf.STB_GLOBAL;
@@ -2910,10 +2910,10 @@ pub fn updateDeclExports(
},
};
const stt_bits: u8 = @truncate(u4, decl_sym.st_info);
- if (decl_metadata.getExport(self, exp.options.name)) |i| {
+ if (decl_metadata.getExport(self, exp_name)) |i| {
const sym = &self.global_symbols.items[i];
sym.* = .{
- .st_name = try self.shstrtab.insert(gpa, exp.options.name),
+ .st_name = try self.shstrtab.insert(gpa, exp_name),
.st_info = (stb_bits << 4) | stt_bits,
.st_other = 0,
.st_shndx = shdr_index,
@@ -2927,7 +2927,7 @@ pub fn updateDeclExports(
};
try decl_metadata.exports.append(gpa, @intCast(u32, i));
self.global_symbols.items[i] = .{
- .st_name = try self.shstrtab.insert(gpa, exp.options.name),
+ .st_name = try self.shstrtab.insert(gpa, exp_name),
.st_info = (stb_bits << 4) | stt_bits,
.st_other = 0,
.st_shndx = shdr_index,
@@ -2944,8 +2944,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
defer tracy.end();
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer self.base.allocator.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
@@ -2955,11 +2954,15 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
}
}
-pub fn deleteDeclExport(self: *Elf, decl_index: Module.Decl.Index, name: []const u8) void {
+pub fn deleteDeclExport(
+ self: *Elf,
+ decl_index: Module.Decl.Index,
+ name: InternPool.NullTerminatedString,
+) void {
if (self.llvm_object) |_| return;
const metadata = self.decls.getPtr(decl_index) orelse return;
- const sym_index = metadata.getExportPtr(self, name) orelse return;
- log.debug("deleting export '{s}'", .{name});
+ const mod = self.base.options.module.?;
+ const sym_index = metadata.getExportPtr(self, mod.intern_pool.stringToSlice(name)) orelse return;
self.global_symbol_free_list.append(self.base.allocator, sym_index.*) catch {};
self.global_symbols.items[sym_index.*].st_info = 0;
sym_index.* = 0;
src/link/MachO.zig
@@ -40,6 +40,7 @@ const Liveness = @import("../Liveness.zig");
const LlvmObject = @import("../codegen/llvm.zig").Object;
const Md5 = std.crypto.hash.Md5;
const Module = @import("../Module.zig");
+const InternPool = @import("../InternPool.zig");
const Relocation = @import("MachO/Relocation.zig");
const StringTable = @import("strtab.zig").StringTable;
const TableSection = @import("table_section.zig").TableSection;
@@ -1921,8 +1922,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
const unnamed_consts = gop.value_ptr;
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const name_str_index = blk: {
const index = unnamed_consts.items.len;
@@ -2206,8 +2206,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
const required_alignment = decl.getAlignment(mod);
- const decl_name = try decl.getFullyQualifiedName(module);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(module));
const init_sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name});
defer gpa.free(init_sym_name);
@@ -2306,8 +2305,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
const required_alignment = decl.getAlignment(mod);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer gpa.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const decl_metadata = self.decls.get(decl_index).?;
const atom_index = decl_metadata.atom;
@@ -2403,12 +2401,14 @@ pub fn updateDeclExports(
const decl_metadata = self.decls.getPtr(decl_index).?;
for (exports) |exp| {
- const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{exp.options.name});
+ const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{
+ mod.intern_pool.stringToSlice(exp.name),
+ });
defer gpa.free(exp_name);
log.debug("adding new export '{s}'", .{exp_name});
- if (exp.options.section) |section_name| {
+ if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
if (!mem.eql(u8, section_name, "__text")) {
try mod.failed_exports.putNoClobber(
mod.gpa,
@@ -2424,7 +2424,7 @@ pub fn updateDeclExports(
}
}
- if (exp.options.linkage == .LinkOnce) {
+ if (exp.linkage == .LinkOnce) {
try mod.failed_exports.putNoClobber(
mod.gpa,
exp,
@@ -2453,7 +2453,7 @@ pub fn updateDeclExports(
.n_value = decl_sym.n_value,
};
- switch (exp.options.linkage) {
+ switch (exp.linkage) {
.Internal => {
// Symbol should be hidden, or in MachO lingo, private extern.
// We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
@@ -2488,12 +2488,17 @@ pub fn updateDeclExports(
}
}
-pub fn deleteDeclExport(self: *MachO, decl_index: Module.Decl.Index, name: []const u8) Allocator.Error!void {
+pub fn deleteDeclExport(
+ self: *MachO,
+ decl_index: Module.Decl.Index,
+ name: InternPool.NullTerminatedString,
+) Allocator.Error!void {
if (self.llvm_object) |_| return;
const metadata = self.decls.getPtr(decl_index) orelse return;
const gpa = self.base.allocator;
- const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
+ const mod = self.base.options.module.?;
+ const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{mod.intern_pool.stringToSlice(name)});
defer gpa.free(exp_name);
const sym_index = metadata.getExportPtr(self, exp_name) orelse return;
src/link/Plan9.zig
@@ -287,7 +287,6 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air:
self.freeUnnamedConsts(decl_index);
_ = try self.seeDecl(decl_index);
- log.debug("codegen decl {*} ({s})", .{ decl, decl.name });
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
defer code_buffer.deinit();
@@ -345,8 +344,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
}
const unnamed_consts = gop.value_ptr;
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer self.base.allocator.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
const index = unnamed_consts.items.len;
// name is freed when the unnamed const is freed
@@ -403,8 +401,6 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
_ = try self.seeDecl(decl_index);
- log.debug("codegen decl {*} ({s}) ({d})", .{ decl, decl.name, decl_index });
-
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
defer code_buffer.deinit();
const decl_val = if (decl.val.getVariable(mod)) |variable| variable.init.toValue() else decl.val;
@@ -435,7 +431,6 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
const mod = self.base.options.module.?;
const decl = mod.declPtr(decl_index);
const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
- log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });
const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
@@ -446,7 +441,7 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
const sym: aout.Sym = .{
.value = undefined, // the value of stuff gets filled in in flushModule
.type = decl_block.type,
- .name = mem.span(decl.name),
+ .name = mod.intern_pool.stringToSlice(decl.name),
};
if (decl_block.sym_index) |s| {
@@ -567,10 +562,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
var it = fentry.value_ptr.functions.iterator();
while (it.next()) |entry| {
const decl_index = entry.key_ptr.*;
- const decl = mod.declPtr(decl_index);
const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
const out = entry.value_ptr.*;
- log.debug("write text decl {*} ({s}), lines {d} to {d}", .{ decl, decl.name, out.start_line + 1, out.end_line });
{
// connect the previous decl to the next
const delta_line = @intCast(i32, out.start_line) - @intCast(i32, linecount);
@@ -616,10 +609,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
var it = self.data_decl_table.iterator();
while (it.next()) |entry| {
const decl_index = entry.key_ptr.*;
- const decl = mod.declPtr(decl_index);
const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
const code = entry.value_ptr.*;
- log.debug("write data decl {*} ({s})", .{ decl, decl.name });
foff += code.len;
iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
@@ -695,15 +686,12 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
const source_decl = mod.declPtr(source_decl_index);
for (kv.value_ptr.items) |reloc| {
const target_decl_index = reloc.target;
- const target_decl = mod.declPtr(target_decl_index);
const target_decl_block = self.getDeclBlock(self.decls.get(target_decl_index).?.index);
const target_decl_offset = target_decl_block.offset.?;
const offset = reloc.offset;
const addend = reloc.addend;
- log.debug("relocating the address of '{s}' + {d} into '{s}' + {d}", .{ target_decl.name, addend, source_decl.name, offset });
-
const code = blk: {
const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
if (is_fn) {
@@ -737,8 +725,9 @@ fn addDeclExports(
const decl_block = self.getDeclBlock(metadata.index);
for (exports) |exp| {
+ const exp_name = mod.intern_pool.stringToSlice(exp.name);
// plan9 does not support custom sections
- if (exp.options.section) |section_name| {
+ if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {
try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
self.base.allocator,
@@ -752,10 +741,10 @@ fn addDeclExports(
const sym = .{
.value = decl_block.offset.?,
.type = decl_block.type.toGlobal(),
- .name = exp.options.name,
+ .name = exp_name,
};
- if (metadata.getExport(self, exp.options.name)) |i| {
+ if (metadata.getExport(self, exp_name)) |i| {
self.syms.items[i] = sym;
} else {
try self.syms.append(self.base.allocator, sym);
@@ -956,7 +945,10 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
try w.writeAll(sym.name);
try w.writeByte(0);
}
+
pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
+ const mod = self.base.options.module.?;
+ const ip = &mod.intern_pool;
const writer = buf.writer();
// write the f symbols
{
@@ -980,7 +972,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
const sym = self.syms.items[decl_block.sym_index.?];
try self.writeSym(writer, sym);
if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
- for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| {
+ for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| {
try self.writeSym(writer, self.syms.items[exp_i]);
};
}
@@ -1006,7 +998,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
const sym = self.syms.items[decl_block.sym_index.?];
try self.writeSym(writer, sym);
if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
- for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| {
+ for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| {
const s = self.syms.items[exp_i];
if (mem.eql(u8, s.name, "_start"))
self.entry_val = s.value;
src/link/SpirV.zig
@@ -147,7 +147,7 @@ pub fn updateDeclExports(
const spv_decl_index = entry.value_ptr.*;
for (exports) |exp| {
- try self.spv.declareEntryPoint(spv_decl_index, exp.options.name);
+ try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.name));
}
}
@@ -190,7 +190,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
var error_info = std.ArrayList(u8).init(self.spv.arena);
try error_info.appendSlice("zig_errors");
const module = self.base.options.module.?;
- for (module.error_name_list.items) |name| {
+ for (module.global_error_set.keys()) |name_nts| {
+ const name = module.intern_pool.stringToSlice(name_nts);
// Errors can contain pretty much any character - to encode them in a string we must escape
// them somehow. Easiest here is to use some established scheme, one which also preseves the
// name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
src/link/Wasm.zig
@@ -1416,7 +1416,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
if (decl.isExtern(mod)) {
const variable = decl.getOwnedVariable(mod).?;
- const name = mem.sliceTo(decl.name, 0);
+ const name = mod.intern_pool.stringToSlice(decl.name);
const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
return wasm.addOrUpdateImport(name, atom.sym_index, lib_name, null);
}
@@ -1453,8 +1453,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.I
defer tracy.end();
const decl = mod.declPtr(decl_index);
- const decl_name = try decl.getFullyQualifiedName(mod);
- defer wasm.base.allocator.free(decl_name);
+ const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
try dw.updateDeclLineNumber(mod, decl_index);
@@ -1467,8 +1466,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8
const atom_index = wasm.decls.get(decl_index).?;
const atom = wasm.getAtomPtr(atom_index);
const symbol = &wasm.symbols.items[atom.sym_index];
- const full_name = try decl.getFullyQualifiedName(mod);
- defer wasm.base.allocator.free(full_name);
+ const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);
try atom.code.appendSlice(wasm.base.allocator, code);
try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
@@ -1535,9 +1533,10 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
const parent_atom = wasm.getAtomPtr(parent_atom_index);
const local_index = parent_atom.locals.items.len;
try parent_atom.locals.append(wasm.base.allocator, atom_index);
- const fqdn = try decl.getFullyQualifiedName(mod);
- defer wasm.base.allocator.free(fqdn);
- const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
+ const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{
+ fqn, local_index,
+ });
defer wasm.base.allocator.free(name);
var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);
defer value_bytes.deinit();
@@ -1690,11 +1689,12 @@ pub fn updateDeclExports(
const decl = mod.declPtr(decl_index);
const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
const atom = wasm.getAtom(atom_index);
+ const gpa = mod.gpa;
for (exports) |exp| {
- if (exp.options.section) |section| {
- try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
- mod.gpa,
+ if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section| {
+ try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
+ gpa,
decl.srcLoc(mod),
"Unimplemented: ExportOptions.section '{s}'",
.{section},
@@ -1702,24 +1702,24 @@ pub fn updateDeclExports(
continue;
}
- const export_name = try wasm.string_table.put(wasm.base.allocator, exp.options.name);
+ const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.name));
if (wasm.globals.getPtr(export_name)) |existing_loc| {
if (existing_loc.index == atom.sym_index) continue;
const existing_sym: Symbol = existing_loc.getSymbol(wasm).*;
- const exp_is_weak = exp.options.linkage == .Internal or exp.options.linkage == .Weak;
+ const exp_is_weak = exp.linkage == .Internal or exp.linkage == .Weak;
// When both the to-be-exported symbol and the already existing symbol
// are strong symbols, we have a linker error.
// In the other case we replace one with the other.
if (!exp_is_weak and !existing_sym.isWeak()) {
- try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
- mod.gpa,
+ try mod.failed_exports.put(gpa, exp, try Module.ErrorMsg.create(
+ gpa,
decl.srcLoc(mod),
\\LinkError: symbol '{s}' defined multiple times
\\ first definition in '{s}'
\\ next definition in '{s}'
,
- .{ exp.options.name, wasm.name, wasm.name },
+ .{ mod.intern_pool.stringToSlice(exp.name), wasm.name, wasm.name },
));
continue;
} else if (exp_is_weak) {
@@ -1736,7 +1736,7 @@ pub fn updateDeclExports(
const exported_atom = wasm.getAtom(exported_atom_index);
const sym_loc = exported_atom.symbolLoc();
const symbol = sym_loc.getSymbol(wasm);
- switch (exp.options.linkage) {
+ switch (exp.linkage) {
.Internal => {
symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
},
@@ -1745,8 +1745,8 @@ pub fn updateDeclExports(
},
.Strong => {}, // symbols are strong by default
.LinkOnce => {
- try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
- mod.gpa,
+ try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
+ gpa,
decl.srcLoc(mod),
"Unimplemented: LinkOnce",
.{},
@@ -1755,7 +1755,7 @@ pub fn updateDeclExports(
},
}
// Ensure the symbol will be exported using the given name
- if (!mem.eql(u8, exp.options.name, sym_loc.getName(wasm))) {
+ if (!mod.intern_pool.stringEqlSlice(exp.name, sym_loc.getName(wasm))) {
try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);
}
@@ -1769,7 +1769,7 @@ pub fn updateDeclExports(
// if the symbol was previously undefined, remove it as an import
_ = wasm.imports.remove(sym_loc);
- _ = wasm.undefs.swapRemove(exp.options.name);
+ _ = wasm.undefs.swapRemove(mod.intern_pool.stringToSlice(exp.name));
}
}
@@ -2987,7 +2987,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
// Addend for each relocation to the table
var addend: u32 = 0;
const mod = wasm.base.options.module.?;
- for (mod.error_name_list.items) |error_name| {
+ for (mod.global_error_set.keys()) |error_name_nts| {
+ const error_name = mod.intern_pool.stringToSlice(error_name_nts);
const len = @intCast(u32, error_name.len + 1); // names are 0-termianted
const slice_ty = Type.slice_const_u8_sentinel_0;
src/codegen.zig
@@ -142,11 +142,12 @@ pub fn generateLazySymbol(
if (lazy_sym.ty.isAnyError(mod)) {
alignment.* = 4;
- const err_names = mod.error_name_list.items;
+ const err_names = mod.global_error_set.keys();
mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
var offset = code.items.len;
try code.resize((1 + err_names.len + 1) * 4);
- for (err_names) |err_name| {
+ for (err_names) |err_name_nts| {
+ const err_name = mod.intern_pool.stringToSlice(err_name_nts);
mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
offset += 4;
try code.ensureUnusedCapacity(err_name.len + 1);
@@ -251,15 +252,13 @@ pub fn generateSymbol(
val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
},
.err => |err| {
- const name = mod.intern_pool.stringToSlice(err.name);
- const kv = try mod.getErrorValue(name);
- try code.writer().writeInt(u16, @intCast(u16, kv.value), endian);
+ const int = try mod.getErrorValue(err.name);
+ try code.writer().writeInt(u16, @intCast(u16, int), endian);
},
.error_union => |error_union| {
const payload_ty = typed_value.ty.errorUnionPayload(mod);
-
const err_val = switch (error_union.val) {
- .err_name => |err_name| @intCast(u16, (try mod.getErrorValue(mod.intern_pool.stringToSlice(err_name))).value),
+ .err_name => |err_name| @intCast(u16, try mod.getErrorValue(err_name)),
.payload => @as(u16, 0),
};
@@ -974,11 +973,8 @@ pub fn genTypedValue(
}, owner_decl_index);
},
.ErrorSet => {
- const err_name = mod.intern_pool.stringToSlice(
- mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name,
- );
- const global_error_set = mod.global_error_set;
- const error_index = global_error_set.get(err_name).?;
+ const err_name = mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
+ const error_index = mod.global_error_set.getIndex(err_name).?;
return GenResult.mcv(.{ .immediate = error_index });
},
.ErrorUnion => {
src/Compilation.zig
@@ -1317,7 +1317,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.global_zir_cache = global_zir_cache,
.local_zir_cache = local_zir_cache,
.emit_h = emit_h,
- .error_name_list = .{},
+ .tmp_hack_arena = std.heap.ArenaAllocator.init(gpa),
};
try module.init();
@@ -2627,7 +2627,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
var it = module.failed_files.iterator();
while (it.next()) |entry| {
if (entry.value_ptr.*) |msg| {
- try addModuleErrorMsg(&bundle, msg.*);
+ try addModuleErrorMsg(module, &bundle, msg.*);
} else {
// Must be ZIR errors. Note that this may include AST errors.
// addZirErrorMessages asserts that the tree is loaded.
@@ -2640,7 +2640,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
var it = module.failed_embed_files.iterator();
while (it.next()) |entry| {
const msg = entry.value_ptr.*;
- try addModuleErrorMsg(&bundle, msg.*);
+ try addModuleErrorMsg(module, &bundle, msg.*);
}
}
{
@@ -2650,7 +2650,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
// Skip errors for Decls within files that had a parse failure.
// We'll try again once parsing succeeds.
if (module.declFileScope(decl_index).okToReportErrors()) {
- try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
+ try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {
try bundle.addRootErrorMessage(.{
.msg = try bundle.addString(std.mem.span(c_error.msg)),
@@ -2675,12 +2675,12 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
// Skip errors for Decls within files that had a parse failure.
// We'll try again once parsing succeeds.
if (module.declFileScope(decl_index).okToReportErrors()) {
- try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
+ try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
}
}
}
for (module.failed_exports.values()) |value| {
- try addModuleErrorMsg(&bundle, value.*);
+ try addModuleErrorMsg(module, &bundle, value.*);
}
}
@@ -2728,7 +2728,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
};
}
- try addModuleErrorMsg(&bundle, err_msg);
+ try addModuleErrorMsg(module, &bundle, err_msg);
}
}
@@ -2784,8 +2784,9 @@ pub const ErrorNoteHashContext = struct {
}
};
-pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg) !void {
+pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg) !void {
const gpa = eb.gpa;
+ const ip = &mod.intern_pool;
const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| {
const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa);
defer gpa.free(file_path);
@@ -2811,7 +2812,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
.src_loc = .none,
});
break;
- } else if (module_reference.decl == null) {
+ } else if (module_reference.decl == .none) {
try ref_traces.append(gpa, .{
.decl_name = 0,
.src_loc = .none,
@@ -2824,7 +2825,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa);
defer gpa.free(rt_file_path);
try ref_traces.append(gpa, .{
- .decl_name = try eb.addString(std.mem.sliceTo(module_reference.decl.?, 0)),
+ .decl_name = try eb.addString(ip.stringToSliceUnwrap(module_reference.decl).?),
.src_loc = try eb.addSourceLocation(.{
.src_path = try eb.addString(rt_file_path),
.span_start = span.start,
src/InternPool.zig
@@ -124,6 +124,8 @@ pub const String = enum(u32) {
/// An index into `string_bytes`.
pub const NullTerminatedString = enum(u32) {
+ /// This is distinct from `none` - it is a valid index that represents empty string.
+ empty = 0,
_,
pub fn toString(self: NullTerminatedString) String {
@@ -157,6 +159,8 @@ pub const NullTerminatedString = enum(u32) {
/// An index into `string_bytes` which might be `none`.
pub const OptionalNullTerminatedString = enum(u32) {
+ /// This is distinct from `none` - it is a valid index that represents empty string.
+ empty = 0,
none = std.math.maxInt(u32),
_,
@@ -2447,6 +2451,9 @@ pub const MemoizedCall = struct {
pub fn init(ip: *InternPool, gpa: Allocator) !void {
assert(ip.items.len == 0);
+ // Reserve string index 0 for an empty string.
+ assert((try ip.getOrPutString(gpa, "")) == .empty);
+
// So that we can use `catch unreachable` below.
try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
@@ -5222,6 +5229,28 @@ pub fn getOrPutString(
return ip.getOrPutTrailingString(gpa, s.len + 1);
}
+pub fn getOrPutStringFmt(
+ ip: *InternPool,
+ gpa: Allocator,
+ comptime format: []const u8,
+ args: anytype,
+) Allocator.Error!NullTerminatedString {
+ const start = ip.string_bytes.items.len;
+ try ip.string_bytes.writer(gpa).print(format, args);
+ try ip.string_bytes.append(gpa, 0);
+ return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
+}
+
+pub fn getOrPutStringOpt(
+ ip: *InternPool,
+ gpa: Allocator,
+ optional_string: ?[]const u8,
+) Allocator.Error!OptionalNullTerminatedString {
+ const s = optional_string orelse return .none;
+ const interned = try getOrPutString(ip, gpa, s);
+ return interned.toOptional();
+}
+
/// Uses the last len bytes of ip.string_bytes as the key.
pub fn getOrPutTrailingString(
ip: *InternPool,
@@ -5273,6 +5302,10 @@ pub fn stringToSliceUnwrap(ip: *const InternPool, s: OptionalNullTerminatedStrin
return ip.stringToSlice(s.unwrap() orelse return null);
}
+pub fn stringEqlSlice(ip: *const InternPool, a: NullTerminatedString, b: []const u8) bool {
+ return std.mem.eql(u8, stringToSlice(ip, a), b);
+}
+
pub fn typeOf(ip: *const InternPool, index: Index) Index {
// This optimization of static keys is required so that typeOf can be called
// on static keys that haven't been added yet during static key initialization.
src/link.zig
@@ -502,8 +502,6 @@ pub const File = struct {
/// of the final binary.
pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: Module.Decl.Index) UpdateDeclError!u32 {
if (build_options.only_c) @compileError("unreachable");
- const decl = base.options.module.?.declPtr(decl_index);
- log.debug("lowerUnnamedConst {*} ({s})", .{ decl, decl.name });
switch (base.tag) {
// zig fmt: off
.coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),
@@ -543,7 +541,6 @@ pub const File = struct {
/// May be called before or after updateDeclExports for any given Decl.
pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
const decl = module.declPtr(decl_index);
- log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmt(module) });
assert(decl.has_tv);
if (build_options.only_c) {
assert(base.tag == .c);
@@ -566,10 +563,6 @@ pub const File = struct {
/// May be called before or after updateDeclExports for any given Decl.
pub fn updateFunc(base: *File, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
const func = module.funcPtr(func_index);
- const owner_decl = module.declPtr(func.owner_decl);
- log.debug("updateFunc {*} ({s}), type={}", .{
- owner_decl, owner_decl.name, owner_decl.ty.fmt(module),
- });
if (build_options.only_c) {
assert(base.tag == .c);
return @fieldParentPtr(C, "base", base).updateFunc(module, func, air, liveness);
@@ -590,9 +583,6 @@ pub const File = struct {
pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
const decl = module.declPtr(decl_index);
- log.debug("updateDeclLineNumber {*} ({s}), line={}", .{
- decl, decl.name, decl.src_line + 1,
- });
assert(decl.has_tv);
if (build_options.only_c) {
assert(base.tag == .c);
@@ -868,7 +858,6 @@ pub const File = struct {
exports: []const *Module.Export,
) UpdateDeclExportsError!void {
const decl = module.declPtr(decl_index);
- log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
assert(decl.has_tv);
if (build_options.only_c) {
assert(base.tag == .c);
src/Module.zig
@@ -88,6 +88,14 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
/// Stores all Type and Value objects; periodically garbage collected.
intern_pool: InternPool = .{},
+/// To be eliminated in a future commit by moving more data into InternPool.
+/// Current uses that must be eliminated:
+/// * Struct comptime_args
+/// * Struct optimized_order
+/// * Union fields
+/// This memory lives until the Module is destroyed.
+tmp_hack_arena: std.heap.ArenaAllocator,
+
/// This is currently only used for string literals.
memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.Index) = .{},
@@ -125,13 +133,8 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},
/// contains Decls that need to be deleted if they end up having no references to them.
deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
-/// Error tags and their values, tag names are duped with mod.gpa.
-/// Corresponds with `error_name_list`.
-global_error_set: std.StringHashMapUnmanaged(ErrorInt) = .{},
-
-/// ErrorInt -> []const u8 for fast lookups for @intToError at comptime
-/// Corresponds with `global_error_set`.
-error_name_list: ArrayListUnmanaged([]const u8),
+/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
+global_error_set: GlobalErrorSet = .{},
/// Incrementing integer used to compare against the corresponding Decl
/// field to determine whether a Decl's status applies to an ongoing update, or a
@@ -182,6 +185,8 @@ reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct {
src: LazySrcLoc,
}) = .{},
+pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
+
pub const CImportError = struct {
offset: u32,
line: u32,
@@ -248,7 +253,11 @@ pub const GlobalEmitH = struct {
pub const ErrorInt = u32;
pub const Export = struct {
- options: std.builtin.ExportOptions,
+ name: InternPool.NullTerminatedString,
+ linkage: std.builtin.GlobalLinkage,
+ section: InternPool.OptionalNullTerminatedString,
+ visibility: std.builtin.SymbolVisibility,
+
src: LazySrcLoc,
/// The Decl that performs the export. Note that this is *not* the Decl being exported.
owner_decl: Decl.Index,
@@ -392,8 +401,7 @@ const ValueArena = struct {
};
pub const Decl = struct {
- /// Allocated with Module's allocator; outlives the ZIR code.
- name: [*:0]const u8,
+ name: InternPool.NullTerminatedString,
/// The most recent Type of the Decl after a successful semantic analysis.
/// Populated when `has_tv`.
ty: Type,
@@ -401,15 +409,11 @@ pub const Decl = struct {
/// Populated when `has_tv`.
val: Value,
/// Populated when `has_tv`.
- /// Points to memory inside value_arena.
- @"linksection": ?[*:0]const u8,
+ @"linksection": InternPool.OptionalNullTerminatedString,
/// Populated when `has_tv`.
@"align": u32,
/// Populated when `has_tv`.
@"addrspace": std.builtin.AddressSpace,
- /// The memory for ty, val, align, linksection, and captures.
- /// If this is `null` then there is no memory management needed.
- value_arena: ?*ValueArena = null,
/// The direct parent namespace of the Decl.
/// Reference to externally owned memory.
/// In the case of the Decl corresponding to a file, this is
@@ -564,13 +568,7 @@ pub const Decl = struct {
function_body,
};
- pub fn clearName(decl: *Decl, gpa: Allocator) void {
- gpa.free(mem.sliceTo(decl.name, 0));
- decl.name = undefined;
- }
-
pub fn clearValues(decl: *Decl, mod: *Module) void {
- const gpa = mod.gpa;
if (decl.getOwnedFunctionIndex(mod).unwrap()) |func| {
_ = mod.align_stack_fns.remove(func);
if (mod.funcPtr(func).comptime_args != null) {
@@ -579,19 +577,6 @@ pub const Decl = struct {
mod.destroyFunc(func);
}
_ = mod.memoized_decls.remove(decl.val.ip_index);
- if (decl.value_arena) |value_arena| {
- value_arena.deinit(gpa);
- decl.value_arena = null;
- decl.has_tv = false;
- decl.owns_tv = false;
- }
- }
-
- pub fn finalizeNewArena(decl: *Decl, arena: *std.heap.ArenaAllocator) !void {
- assert(decl.value_arena == null);
- const value_arena = try arena.allocator().create(ValueArena);
- value_arena.* = .{ .state = arena.state };
- decl.value_arena = value_arena;
}
/// This name is relative to the containing namespace of the decl.
@@ -692,7 +677,7 @@ pub const Decl = struct {
}
pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
- const unqualified_name = mem.sliceTo(decl.name, 0);
+ const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
if (decl.name_fully_qualified) {
return writer.writeAll(unqualified_name);
}
@@ -700,24 +685,27 @@ pub const Decl = struct {
}
pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
- const unqualified_name = mem.sliceTo(decl.name, 0);
+ const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);
}
- pub fn getFullyQualifiedName(decl: Decl, mod: *Module) ![:0]u8 {
- var buffer = std.ArrayList(u8).init(mod.gpa);
- defer buffer.deinit();
- try decl.renderFullyQualifiedName(mod, buffer.writer());
+ pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {
+ const gpa = mod.gpa;
+ const ip = &mod.intern_pool;
+ const start = ip.string_bytes.items.len;
+ try decl.renderFullyQualifiedName(mod, ip.string_bytes.writer(gpa));
// Sanitize the name for nvptx which is more restrictive.
+ // TODO This should be handled by the backend, not the frontend. Have a
+ // look at how the C backend does it for inspiration.
if (mod.comp.bin_file.options.target.cpu.arch.isNvptx()) {
- for (buffer.items) |*byte| switch (byte.*) {
+ for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
'{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
else => {},
};
}
- return buffer.toOwnedSliceSentinel(0);
+ return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
}
pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
@@ -804,11 +792,11 @@ pub const Decl = struct {
pub fn dump(decl: *Decl) void {
const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);
- std.debug.print("{s}:{d}:{d} name={s} status={s}", .{
+ std.debug.print("{s}:{d}:{d} name={d} status={s}", .{
decl.scope.sub_file_path,
loc.line + 1,
loc.column + 1,
- mem.sliceTo(decl.name, 0),
+ @enumToInt(decl.name),
@tagName(decl.analysis),
});
if (decl.has_tv) {
@@ -922,15 +910,15 @@ pub const Struct = struct {
}
};
- pub const Fields = std.StringArrayHashMapUnmanaged(Field);
+ pub const Fields = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Field);
/// The `Type` and `Value` memory is owned by the arena of the Struct's owner_decl.
pub const Field = struct {
/// Uses `noreturn` to indicate `anytype`.
/// undefined until `status` is >= `have_field_types`.
ty: Type,
- /// Uses `unreachable_value` to indicate no default.
- default_val: Value,
+ /// Uses `none` to indicate no default.
+ default_val: InternPool.Index,
/// Zero means to use the ABI alignment of the type.
abi_align: u32,
/// undefined until `status` is `have_layout`.
@@ -982,7 +970,7 @@ pub const Struct = struct {
/// runtime version of the struct.
pub const omitted_field = std.math.maxInt(u32);
- pub fn getFullyQualifiedName(s: *Struct, mod: *Module) ![:0]u8 {
+ pub fn getFullyQualifiedName(s: *Struct, mod: *Module) !InternPool.NullTerminatedString {
return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
}
@@ -1141,9 +1129,9 @@ pub const Union = struct {
}
};
- pub const Fields = std.StringArrayHashMapUnmanaged(Field);
+ pub const Fields = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Field);
- pub fn getFullyQualifiedName(s: *Union, mod: *Module) ![:0]u8 {
+ pub fn getFullyQualifiedName(s: *Union, mod: *Module) !InternPool.NullTerminatedString {
return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
}
@@ -1569,15 +1557,15 @@ pub const Fn = struct {
pub const DeclAdapter = struct {
mod: *Module,
- pub fn hash(self: @This(), s: []const u8) u32 {
+ pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
_ = self;
- return @truncate(u32, std.hash.Wyhash.hash(0, s));
+ return std.hash.uint32(@enumToInt(s));
}
- pub fn eql(self: @This(), a: []const u8, b_decl_index: Decl.Index, b_index: usize) bool {
+ pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {
_ = b_index;
const b_decl = self.mod.declPtr(b_decl_index);
- return mem.eql(u8, a, mem.sliceTo(b_decl.name, 0));
+ return a == b_decl.name;
}
};
@@ -1628,16 +1616,14 @@ pub const Namespace = struct {
pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
const decl = ctx.module.declPtr(decl_index);
- return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceTo(decl.name, 0)));
+ return std.hash.uint32(@enumToInt(decl.name));
}
pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
_ = b_index;
const a_decl = ctx.module.declPtr(a_decl_index);
const b_decl = ctx.module.declPtr(b_decl_index);
- const a_name = mem.sliceTo(a_decl.name, 0);
- const b_name = mem.sliceTo(b_decl.name, 0);
- return mem.eql(u8, a_name, b_name);
+ return a_decl.name == b_decl.name;
}
};
@@ -1649,8 +1635,6 @@ pub const Namespace = struct {
pub fn destroyDecls(ns: *Namespace, mod: *Module) void {
const gpa = mod.gpa;
- log.debug("destroyDecls {*}", .{ns});
-
var decls = ns.decls;
ns.decls = .{};
@@ -1676,8 +1660,6 @@ pub const Namespace = struct {
) !void {
const gpa = mod.gpa;
- log.debug("deleteAllDecls {*}", .{ns});
-
var decls = ns.decls;
ns.decls = .{};
@@ -1712,7 +1694,8 @@ pub const Namespace = struct {
if (ns.parent.unwrap()) |parent| {
const decl_index = ns.getDeclIndex(mod);
const decl = mod.declPtr(decl_index);
- try mod.namespacePtr(parent).renderFullyQualifiedName(mod, mem.sliceTo(decl.name, 0), writer);
+ const decl_name = mod.intern_pool.stringToSlice(decl.name);
+ try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl_name, writer);
} else {
try ns.file_scope.renderFullyQualifiedName(writer);
}
@@ -1733,7 +1716,8 @@ pub const Namespace = struct {
if (ns.parent.unwrap()) |parent| {
const decl_index = ns.getDeclIndex(mod);
const decl = mod.declPtr(decl_index);
- try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, mem.sliceTo(decl.name, 0), writer);
+ const decl_name = mod.intern_pool.stringToSlice(decl.name);
+ try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl_name, writer);
} else {
try ns.file_scope.renderFullyQualifiedDebugName(writer);
separator_char = ':';
@@ -1927,11 +1911,11 @@ pub const File = struct {
};
}
- pub fn fullyQualifiedNameZ(file: File, gpa: Allocator) ![:0]u8 {
- var buf = std.ArrayList(u8).init(gpa);
- defer buf.deinit();
- try file.renderFullyQualifiedName(buf.writer());
- return buf.toOwnedSliceSentinel(0);
+ pub fn fullyQualifiedName(file: File, mod: *Module) !InternPool.NullTerminatedString {
+ const ip = &mod.intern_pool;
+ const start = ip.string_bytes.items.len;
+ try file.renderFullyQualifiedName(ip.string_bytes.writer(mod.gpa));
+ return ip.getOrPutTrailingString(mod.gpa, ip.string_bytes.items.len - start);
}
/// Returns the full path to this file relative to its package.
@@ -2055,7 +2039,7 @@ pub const ErrorMsg = struct {
reference_trace: []Trace = &.{},
pub const Trace = struct {
- decl: ?[*:0]const u8,
+ decl: InternPool.OptionalNullTerminatedString,
src_loc: SrcLoc,
hidden: u32 = 0,
};
@@ -3180,8 +3164,8 @@ pub const CompileError = error{
pub fn init(mod: *Module) !void {
const gpa = mod.gpa;
- try mod.error_name_list.append(gpa, "(no error)");
try mod.intern_pool.init(gpa);
+ try mod.global_error_set.put(gpa, .empty, {});
}
pub fn deinit(mod: *Module) void {
@@ -3282,15 +3266,8 @@ pub fn deinit(mod: *Module) void {
}
mod.export_owners.deinit(gpa);
- {
- var it = mod.global_error_set.keyIterator();
- while (it.next()) |key| {
- gpa.free(key.*);
- }
- mod.global_error_set.deinit(gpa);
- }
+ mod.global_error_set.deinit(gpa);
- mod.error_name_list.deinit(gpa);
mod.test_functions.deinit(gpa);
mod.align_stack_fns.deinit(gpa);
mod.monomorphed_funcs.deinit(gpa);
@@ -3305,13 +3282,13 @@ pub fn deinit(mod: *Module) void {
mod.memoized_decls.deinit(gpa);
mod.intern_pool.deinit(gpa);
+ mod.tmp_hack_arena.deinit();
}
pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
const gpa = mod.gpa;
{
const decl = mod.declPtr(decl_index);
- log.debug("destroy {*} ({s})", .{ decl, decl.name });
_ = mod.test_functions.swapRemove(decl_index);
if (decl.deletion_flag) {
assert(mod.deletion_set.swapRemove(decl_index));
@@ -3329,7 +3306,6 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
decl.clearValues(mod);
decl.dependants.deinit(gpa);
decl.dependencies.deinit(gpa);
- decl.clearName(gpa);
decl.* = undefined;
}
mod.decls_free_list.append(gpa, decl_index) catch {
@@ -3391,11 +3367,7 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
}
fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
- for (export_list.items) |exp| {
- gpa.free(exp.options.name);
- if (exp.options.section) |s| gpa.free(s);
- gpa.destroy(exp);
- }
+ for (export_list.items) |exp| gpa.destroy(exp);
export_list.deinit(gpa);
}
@@ -3814,9 +3786,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
if (decl.zir_decl_index != 0) {
const old_zir_decl_index = decl.zir_decl_index;
const new_zir_decl_index = extra_map.get(old_zir_decl_index) orelse {
- log.debug("updateZirRefs {s}: delete {*} ({s})", .{
- file.sub_file_path, decl, decl.name,
- });
try file.deleted_decls.append(gpa, decl_index);
continue;
};
@@ -3824,14 +3793,7 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
decl.zir_decl_index = new_zir_decl_index;
const new_hash = decl.contentsHashZir(new_zir);
if (!std.zig.srcHashEql(old_hash, new_hash)) {
- log.debug("updateZirRefs {s}: outdated {*} ({s}) {d} => {d}", .{
- file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
- });
try file.outdated_decls.append(gpa, decl_index);
- } else {
- log.debug("updateZirRefs {s}: unchanged {*} ({s}) {d} => {d}", .{
- file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
- });
}
}
@@ -4031,8 +3993,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
.complete => return,
.outdated => blk: {
- log.debug("re-analyzing {*} ({s})", .{ decl, decl.name });
-
// The exports this Decl performs will be re-discovered, so we remove them here
// prior to re-analysis.
try mod.deleteDeclExports(decl_index);
@@ -4047,9 +4007,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
const dep = mod.declPtr(dep_index);
dep.removeDependant(decl_index);
if (dep.dependants.count() == 0 and !dep.deletion_flag) {
- log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
- decl, decl.name, dep, dep.name,
- });
try mod.markDeclForDeletion(dep_index);
}
}
@@ -4061,7 +4018,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
.unreferenced => false,
};
- var decl_prog_node = mod.sema_prog_node.start(mem.sliceTo(decl.name, 0), 0);
+ var decl_prog_node = mod.sema_prog_node.start(mod.intern_pool.stringToSlice(decl.name), 0);
decl_prog_node.activate();
defer decl_prog_node.end();
@@ -4190,14 +4147,11 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void
if (no_bin_file and !dump_air and !dump_llvm_ir) return;
- log.debug("analyze liveness of {s}", .{decl.name});
var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);
defer liveness.deinit(gpa);
if (dump_air) {
- const fqn = try decl.getFullyQualifiedName(mod);
- defer mod.gpa.free(fqn);
-
+ const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});
@import("print_air.zig").dump(mod, air, liveness);
std.debug.print("# End Function AIR: {s}\n\n", .{fqn});
@@ -4354,9 +4308,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
if (file.root_decl != .none) return;
const gpa = mod.gpa;
- var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
- errdefer new_decl_arena.deinit();
- const new_decl_arena_allocator = new_decl_arena.allocator();
// Because these three things each reference each other, `undefined`
// placeholders are used before being set after the struct type gains an
@@ -4394,7 +4345,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
new_namespace.ty = struct_ty.toType();
file.root_decl = new_decl_index.toOptional();
- new_decl.name = try file.fullyQualifiedNameZ(gpa);
+ new_decl.name = try file.fullyQualifiedName(mod);
new_decl.src_line = 0;
new_decl.is_pub = true;
new_decl.is_exported = false;
@@ -4403,7 +4354,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
new_decl.ty = Type.type;
new_decl.val = struct_ty.toValue();
new_decl.@"align" = 0;
- new_decl.@"linksection" = null;
+ new_decl.@"linksection" = .none;
new_decl.has_tv = true;
new_decl.owns_tv = true;
new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive.
@@ -4431,7 +4382,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
.mod = mod,
.gpa = gpa,
.arena = sema_arena_allocator,
- .perm_arena = new_decl_arena_allocator,
.code = file.zir,
.owner_decl = new_decl,
.owner_decl_index = new_decl_index,
@@ -4484,8 +4434,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
} else {
new_decl.analysis = .file_failure;
}
-
- try new_decl.finalizeNewArena(&new_decl_arena);
}
/// Returns `true` if the Decl type changed.
@@ -4507,28 +4455,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.analysis = .in_progress;
- // We need the memory for the Type to go into the arena for the Decl
- var decl_arena = std.heap.ArenaAllocator.init(gpa);
- const decl_arena_allocator = decl_arena.allocator();
- const decl_value_arena = blk: {
- errdefer decl_arena.deinit();
- const s = try decl_arena_allocator.create(ValueArena);
- s.* = .{ .state = undefined };
- break :blk s;
- };
- defer {
- if (decl.value_arena) |value_arena| {
- assert(value_arena.state_acquired == null);
- decl_value_arena.prev = value_arena;
- }
-
- decl_value_arena.state = decl_arena.state;
- decl.value_arena = decl_value_arena;
- }
-
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
- const analysis_arena_allocator = analysis_arena.allocator();
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
defer comptime_mutable_decls.deinit();
@@ -4536,8 +4464,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
var sema: Sema = .{
.mod = mod,
.gpa = gpa,
- .arena = analysis_arena_allocator,
- .perm_arena = decl_arena_allocator,
+ .arena = analysis_arena.allocator(),
.code = zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -4551,7 +4478,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
defer sema.deinit();
if (mod.declIsRoot(decl_index)) {
- log.debug("semaDecl root {*} ({s})", .{ decl, decl.name });
const main_struct_inst = Zir.main_struct_inst;
const struct_index = decl.getOwnedStructIndex(mod).unwrap().?;
const struct_obj = mod.structPtr(struct_index);
@@ -4563,7 +4489,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.generation = mod.generation;
return false;
}
- log.debug("semaDecl {*} ({s})", .{ decl, decl.name });
var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);
defer wip_captures.deinit();
@@ -4619,7 +4544,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.ty = InternPool.Index.type_type.toType();
decl.val = ty.toValue();
decl.@"align" = 0;
- decl.@"linksection" = null;
+ decl.@"linksection" = .none;
decl.has_tv = true;
decl.owns_tv = false;
decl.analysis = .complete;
@@ -4646,7 +4571,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.clearValues(mod);
decl.ty = decl_tv.ty;
- decl.val = try decl_tv.val.copy(decl_arena_allocator);
+ decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
// linksection, align, and addrspace were already set by Sema
decl.has_tv = true;
decl.owns_tv = owns_tv;
@@ -4660,7 +4585,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
return sema.fail(&block_scope, export_src, "export of inline function", .{});
}
// The scope needs to have the decl in it.
- const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
+ const options: std.builtin.ExportOptions = .{
+ .name = mod.intern_pool.stringToSlice(decl.name),
+ };
try sema.analyzeExport(&block_scope, export_src, options, decl_index);
}
return type_changed or is_inline != prev_is_inline;
@@ -4693,14 +4620,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
.func => {},
else => {
- log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
queue_linker_work = true;
},
},
}
decl.ty = decl_tv.ty;
- decl.val = try decl_tv.val.copy(decl_arena_allocator);
+ decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
decl.@"align" = blk: {
const align_ref = decl.zirAlignRef(mod);
if (align_ref == .none) break :blk 0;
@@ -4708,14 +4634,15 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
};
decl.@"linksection" = blk: {
const linksection_ref = decl.zirLinksectionRef(mod);
- if (linksection_ref == .none) break :blk null;
+ if (linksection_ref == .none) break :blk .none;
const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime-known");
if (mem.indexOfScalar(u8, bytes, 0) != null) {
return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
} else if (bytes.len == 0) {
return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
}
- break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
+ const section = try mod.intern_pool.getOrPutString(gpa, bytes);
+ break :blk section.toOptional();
};
decl.@"addrspace" = blk: {
const addrspace_ctx: Sema.AddressSpaceContext = switch (mod.intern_pool.indexToKey(decl_tv.val.toIntern())) {
@@ -4743,7 +4670,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
(queue_linker_work and try sema.typeHasRuntimeBits(decl.ty));
if (has_runtime_bits) {
- log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
// Needed for codegen_decl which will call updateDecl and then the
// codegen backend wants full access to the Decl Type.
@@ -4759,7 +4685,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
if (decl.is_exported) {
const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
// The scope needs to have the decl in it.
- const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
+ const options: std.builtin.ExportOptions = .{
+ .name = mod.intern_pool.stringToSlice(decl.name),
+ };
try sema.analyzeExport(&block_scope, export_src, options, decl_index);
}
@@ -4785,10 +4713,6 @@ pub fn declareDeclDependencyType(mod: *Module, depender_index: Decl.Index, depen
}
}
- log.debug("{*} ({s}) depends on {*} ({s})", .{
- depender, depender.name, dependee, dependee.name,
- });
-
if (dependee.deletion_flag) {
dependee.deletion_flag = false;
assert(mod.deletion_set.swapRemove(dependee_index));
@@ -5138,6 +5062,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
const namespace = mod.namespacePtr(namespace_index);
const gpa = mod.gpa;
const zir = namespace.file_scope.zir;
+ const ip = &mod.intern_pool;
// zig fmt: off
const is_pub = (flags & 0b0001) != 0;
@@ -5157,31 +5082,31 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
// Every Decl needs a name.
var is_named_test = false;
var kind: Decl.Kind = .named;
- const decl_name: [:0]const u8 = switch (decl_name_index) {
+ const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) {
0 => name: {
if (export_bit) {
const i = iter.usingnamespace_index;
iter.usingnamespace_index += 1;
kind = .@"usingnamespace";
- break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i});
+ break :name try ip.getOrPutStringFmt(gpa, "usingnamespace_{d}", .{i});
} else {
const i = iter.comptime_index;
iter.comptime_index += 1;
kind = .@"comptime";
- break :name try std.fmt.allocPrintZ(gpa, "comptime_{d}", .{i});
+ break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});
}
},
1 => name: {
const i = iter.unnamed_test_index;
iter.unnamed_test_index += 1;
kind = .@"test";
- break :name try std.fmt.allocPrintZ(gpa, "test_{d}", .{i});
+ break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});
},
2 => name: {
is_named_test = true;
const test_name = zir.nullTerminatedString(decl_doccomment_index);
kind = .@"test";
- break :name try std.fmt.allocPrintZ(gpa, "decltest.{s}", .{test_name});
+ break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name});
},
else => name: {
const raw_name = zir.nullTerminatedString(decl_name_index);
@@ -5189,14 +5114,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
is_named_test = true;
const test_name = zir.nullTerminatedString(decl_name_index + 1);
kind = .@"test";
- break :name try std.fmt.allocPrintZ(gpa, "test.{s}", .{test_name});
+ break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name});
} else {
- break :name try gpa.dupeZ(u8, raw_name);
+ break :name try ip.getOrPutString(gpa, raw_name);
}
},
};
- var must_free_decl_name = true;
- defer if (must_free_decl_name) gpa.free(decl_name);
const is_exported = export_bit and decl_name_index != 0;
if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
@@ -5204,7 +5127,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
// We create a Decl for it regardless of analysis status.
const gop = try namespace.decls.getOrPutContextAdapted(
gpa,
- @as([]const u8, mem.sliceTo(decl_name, 0)),
+ decl_name,
DeclAdapter{ .mod = mod },
Namespace.DeclContext{ .module = mod },
);
@@ -5214,11 +5137,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
const new_decl = mod.declPtr(new_decl_index);
new_decl.kind = kind;
new_decl.name = decl_name;
- must_free_decl_name = false;
if (kind == .@"usingnamespace") {
namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);
}
- log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
new_decl.src_line = line;
gop.key_ptr.* = new_decl_index;
// Exported decls, comptime decls, usingnamespace decls, and
@@ -5239,7 +5160,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
if (!comp.bin_file.options.is_test) break :blk false;
if (decl_pkg != mod.main_pkg) break :blk false;
if (comp.test_filter) |test_filter| {
- if (mem.indexOf(u8, decl_name, test_filter) == null) {
+ if (mem.indexOf(u8, ip.stringToSlice(decl_name), test_filter) == null) {
break :blk false;
}
}
@@ -5270,7 +5191,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
gpa,
src_loc,
"duplicate test name: {s}",
- .{decl_name},
+ .{ip.stringToSlice(decl_name)},
);
errdefer msg.destroy(gpa);
try mod.failed_decls.putNoClobber(gpa, decl_index, msg);
@@ -5281,7 +5202,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
};
try mod.errNoteNonLazy(other_src_loc, msg, "other test here", .{});
}
- log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
// Update the AST node of the decl; even if its contents are unchanged, it may
// have been re-ordered.
decl.src_node = decl_node;
@@ -5315,7 +5235,6 @@ pub fn clearDecl(
defer tracy.end();
const decl = mod.declPtr(decl_index);
- log.debug("clearing {*} ({s})", .{ decl, decl.name });
const gpa = mod.gpa;
try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());
@@ -5330,9 +5249,6 @@ pub fn clearDecl(
const dep = mod.declPtr(dep_index);
dep.removeDependant(decl_index);
if (dep.dependants.count() == 0 and !dep.deletion_flag) {
- log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
- decl, decl.name, dep, dep.name,
- });
// We don't recursively perform a deletion here, because during the update,
// another reference to it may turn up.
dep.deletion_flag = true;
@@ -5387,7 +5303,6 @@ pub fn clearDecl(
/// This function is exclusively called for anonymous decls.
pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
const decl = mod.declPtr(decl_index);
- log.debug("deleteUnusedDecl {d} ({s})", .{ decl_index, decl.name });
assert(!mod.declIsRoot(decl_index));
assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
@@ -5415,7 +5330,6 @@ fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void {
/// If other decls depend on this decl, they must be aborted first.
pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
const decl = mod.declPtr(decl_index);
- log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });
assert(!mod.declIsRoot(decl_index));
assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
@@ -5468,21 +5382,20 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
}
}
if (mod.comp.bin_file.cast(link.File.Elf)) |elf| {
- elf.deleteDeclExport(decl_index, exp.options.name);
+ elf.deleteDeclExport(decl_index, exp.name);
}
if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {
- try macho.deleteDeclExport(decl_index, exp.options.name);
+ try macho.deleteDeclExport(decl_index, exp.name);
}
if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| {
wasm.deleteDeclExport(decl_index);
}
if (mod.comp.bin_file.cast(link.File.Coff)) |coff| {
- coff.deleteDeclExport(decl_index, exp.options.name);
+ coff.deleteDeclExport(decl_index, exp.name);
}
if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
failed_kv.value.destroy(mod.gpa);
}
- mod.gpa.free(exp.options.name);
mod.gpa.destroy(exp);
}
export_owners.deinit(mod.gpa);
@@ -5497,11 +5410,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
const decl_index = func.owner_decl;
const decl = mod.declPtr(decl_index);
- // Use the Decl's arena for captured values.
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
-
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
defer comptime_mutable_decls.deinit();
@@ -5512,7 +5420,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
.mod = mod,
.gpa = gpa,
.arena = arena,
- .perm_arena = decl_arena_allocator,
.code = decl.getFileScope(mod).zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -5616,7 +5523,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
}
func.state = .in_progress;
- log.debug("set {s} to in_progress", .{decl.name});
const last_arg_index = inner_block.instructions.items.len;
@@ -5677,7 +5583,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = main_block_index;
func.state = .success;
- log.debug("set {s} to success", .{decl.name});
// Finally we must resolve the return type and parameter types so that backends
// have full access to type information.
@@ -5724,7 +5629,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
const decl = mod.declPtr(decl_index);
- log.debug("mark outdated {*} ({s})", .{ decl, decl.name });
try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });
if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
kv.value.destroy(mod.gpa);
@@ -5821,7 +5725,7 @@ pub fn allocateNewDecl(
.ty = undefined,
.val = undefined,
.@"align" = undefined,
- .@"linksection" = undefined,
+ .@"linksection" = .none,
.@"addrspace" = .generic,
.analysis = .unreferenced,
.deletion_flag = false,
@@ -5839,25 +5743,20 @@ pub fn allocateNewDecl(
return decl_and_index.decl_index;
}
-/// Get error value for error tag `name`.
-pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged(ErrorInt).KV {
+pub fn getErrorValue(
+ mod: *Module,
+ name: InternPool.NullTerminatedString,
+) Allocator.Error!ErrorInt {
const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
- if (gop.found_existing) {
- return std.StringHashMapUnmanaged(ErrorInt).KV{
- .key = gop.key_ptr.*,
- .value = gop.value_ptr.*,
- };
- }
+ return @intCast(ErrorInt, gop.index);
+}
- errdefer assert(mod.global_error_set.remove(name));
- try mod.error_name_list.ensureUnusedCapacity(mod.gpa, 1);
- gop.key_ptr.* = try mod.gpa.dupe(u8, name);
- gop.value_ptr.* = @intCast(ErrorInt, mod.error_name_list.items.len);
- mod.error_name_list.appendAssumeCapacity(gop.key_ptr.*);
- return std.StringHashMapUnmanaged(ErrorInt).KV{
- .key = gop.key_ptr.*,
- .value = gop.value_ptr.*,
- };
+pub fn getErrorValueFromSlice(
+ mod: *Module,
+ name: []const u8,
+) Allocator.Error!ErrorInt {
+ const interned_name = try mod.intern_pool.getOrPutString(mod.gpa, name);
+ return getErrorValue(mod, interned_name);
}
pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {
@@ -5874,24 +5773,23 @@ pub fn createAnonymousDeclFromDecl(
) !Decl.Index {
const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
errdefer mod.destroyDecl(new_decl_index);
- const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{
- src_decl.name, @enumToInt(new_decl_index),
+ const ip = &mod.intern_pool;
+ const name = try ip.getOrPutStringFmt(mod.gpa, "{s}__anon_{d}", .{
+ ip.stringToSlice(src_decl.name), @enumToInt(new_decl_index),
});
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);
return new_decl_index;
}
-/// Takes ownership of `name` even if it returns an error.
pub fn initNewAnonDecl(
mod: *Module,
new_decl_index: Decl.Index,
src_line: u32,
namespace: Namespace.Index,
typed_value: TypedValue,
- name: [:0]u8,
+ name: InternPool.NullTerminatedString,
) Allocator.Error!void {
assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));
- errdefer mod.gpa.free(name);
const new_decl = mod.declPtr(new_decl_index);
@@ -5900,7 +5798,7 @@ pub fn initNewAnonDecl(
new_decl.ty = typed_value.ty;
new_decl.val = typed_value.val;
new_decl.@"align" = 0;
- new_decl.@"linksection" = null;
+ new_decl.@"linksection" = .none;
new_decl.has_tv = true;
new_decl.analysis = .complete;
new_decl.generation = mod.generation;
@@ -6330,12 +6228,11 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
// deletion set at this time.
for (file.deleted_decls.items) |decl_index| {
const decl = mod.declPtr(decl_index);
- log.debug("deleted from source: {*} ({s})", .{ decl, decl.name });
// Remove from the namespace it resides in, preserving declaration order.
assert(decl.zir_decl_index != 0);
_ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted(
- @as([]const u8, mem.sliceTo(decl.name, 0)),
+ decl.name,
DeclAdapter{ .mod = mod },
);
@@ -6357,7 +6254,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
pub fn processExports(mod: *Module) !void {
const gpa = mod.gpa;
// Map symbol names to `Export` for name collision detection.
- var symbol_exports: std.StringArrayHashMapUnmanaged(*Export) = .{};
+ var symbol_exports: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, *Export) = .{};
defer symbol_exports.deinit(gpa);
var it = mod.decl_exports.iterator();
@@ -6365,13 +6262,13 @@ pub fn processExports(mod: *Module) !void {
const exported_decl = entry.key_ptr.*;
const exports = entry.value_ptr.items;
for (exports) |new_export| {
- const gop = try symbol_exports.getOrPut(gpa, new_export.options.name);
+ const gop = try symbol_exports.getOrPut(gpa, new_export.name);
if (gop.found_existing) {
new_export.status = .failed_retryable;
try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
const src_loc = new_export.getSrcLoc(mod);
const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{
- new_export.options.name,
+ mod.intern_pool.stringToSlice(new_export.name),
});
errdefer msg.destroy(gpa);
const other_export = gop.value_ptr.*;
@@ -6408,8 +6305,9 @@ pub fn populateTestFunctions(
const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);
+ const test_functions_str = try mod.intern_pool.getOrPutString(gpa, "test_functions");
const decl_index = builtin_namespace.decls.getKeyAdapted(
- @as([]const u8, "test_functions"),
+ test_functions_str,
DeclAdapter{ .mod = mod },
).?;
{
@@ -6443,7 +6341,7 @@ pub fn populateTestFunctions(
for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {
const test_decl = mod.declPtr(test_decl_index);
- const test_decl_name = mem.span(test_decl.name);
+ const test_decl_name = mod.intern_pool.stringToSlice(test_decl.name);
const test_name_decl_index = n: {
const test_name_decl_ty = try mod.arrayType(.{
.len = test_decl_name.len,
@@ -7156,7 +7054,7 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc
return mod.declPtr(opaque_type.decl).srcLoc(mod);
}
-pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) ![:0]u8 {
+pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) !InternPool.NullTerminatedString {
return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);
}
src/print_air.zig
@@ -685,8 +685,9 @@ const Writer = struct {
fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;
const func_index = ty_fn.func;
+ const ip = &w.module.intern_pool;
const owner_decl = w.module.declPtr(w.module.funcPtr(func_index).owner_decl);
- try s.print("{s}", .{owner_decl.name});
+ try s.print("{s}", .{ip.stringToSlice(owner_decl.name)});
}
fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/Sema.zig
@@ -11,9 +11,6 @@ gpa: Allocator,
/// Points to the temporary arena allocator of the Sema.
/// This arena will be cleared when the sema is destroyed.
arena: Allocator,
-/// Points to the arena allocator for the owner_decl.
-/// This arena will persist until the decl is invalidated.
-perm_arena: Allocator,
code: Zir,
air_instructions: std.MultiArrayList(Air.Inst) = .{},
air_extra: std.ArrayListUnmanaged(u32) = .{},
@@ -740,7 +737,6 @@ pub const Block = struct {
// TODO: migrate Decl alignment to use `InternPool.Alignment`
new_decl.@"align" = @intCast(u32, alignment);
errdefer sema.mod.abortAnonDecl(new_decl_index);
- try new_decl.finalizeNewArena(&wad.new_decl_arena);
wad.finished = true;
try sema.mod.finalizeAnonDecl(new_decl_index);
return new_decl_index;
@@ -1825,6 +1821,20 @@ pub fn resolveConstString(
return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
}
+pub fn resolveConstStringIntern(
+ sema: *Sema,
+ block: *Block,
+ src: LazySrcLoc,
+ zir_ref: Zir.Inst.Ref,
+ reason: []const u8,
+) !InternPool.NullTerminatedString {
+ const air_inst = try sema.resolveInst(zir_ref);
+ const wanted_type = Type.slice_const_u8;
+ const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
+ const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
+ return val.toIpString(wanted_type, sema.mod);
+}
+
pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
const air_inst = try sema.resolveInst(zir_ref);
assert(air_inst != .var_args_param_type);
@@ -1847,11 +1857,13 @@ fn analyzeAsType(
pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
if (!mod.backendSupportsFeature(.error_return_trace)) return;
assert(!block.is_comptime);
var err_trace_block = block.makeSubBlock();
- defer err_trace_block.instructions.deinit(sema.gpa);
+ defer err_trace_block.instructions.deinit(gpa);
const src: LazySrcLoc = .unneeded;
@@ -1866,17 +1878,19 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
// st.instruction_addresses = &addrs;
- const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, "instruction_addresses", src, true);
+ const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses");
+ const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, instruction_addresses_field_name, src, true);
try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);
// st.index = 0;
- const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, "index", src, true);
+ const index_field_name = try ip.getOrPutString(gpa, "index");
+ const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, index_field_name, src, true);
try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);
// @errorReturnTrace() = &st;
_ = try err_trace_block.addUnOp(.set_err_return_trace, st_ptr);
- try block.instructions.insertSlice(sema.gpa, last_arg_index, err_trace_block.instructions.items);
+ try block.instructions.insertSlice(gpa, last_arg_index, err_trace_block.instructions.items);
}
/// May return Value Tags: `variable`, `undef`.
@@ -2179,7 +2193,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
return sema.failWithOwnedErrorMsg(msg);
}
-fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
+fn failWithInvalidFieldAccess(
+ sema: *Sema,
+ block: *Block,
+ src: LazySrcLoc,
+ object_ty: Type,
+ field_name: InternPool.NullTerminatedString,
+) CompileError {
const mod = sema.mod;
const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty;
@@ -2207,15 +2227,16 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
}
-fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: []const u8) bool {
+fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool {
+ const ip = &mod.intern_pool;
switch (ty.zigTypeTag(mod)) {
- .Array => return mem.eql(u8, field_name, "len"),
+ .Array => return ip.stringEqlSlice(field_name, "len"),
.Pointer => {
const ptr_info = ty.ptrInfo(mod);
if (ptr_info.size == .Slice) {
- return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len");
+ return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");
} else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
- return mem.eql(u8, field_name, "len");
+ return ip.stringEqlSlice(field_name, "len");
} else return false;
},
.Type, .Struct, .Union => return true,
@@ -2308,19 +2329,19 @@ pub fn fail(
fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
@setCold(true);
const gpa = sema.gpa;
+ const mod = sema.mod;
- if (crash_report.is_enabled and sema.mod.comp.debug_compile_errors) {
+ if (crash_report.is_enabled and mod.comp.debug_compile_errors) {
if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation;
var wip_errors: std.zig.ErrorBundle.Wip = undefined;
wip_errors.init(gpa) catch unreachable;
- Compilation.addModuleErrorMsg(&wip_errors, err_msg.*) catch unreachable;
+ Compilation.addModuleErrorMsg(mod, &wip_errors, err_msg.*) catch unreachable;
std.debug.print("compile error during Sema:\n", .{});
var error_bundle = wip_errors.toOwnedBundle("") catch unreachable;
error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
crash_report.compilerPanic("unexpected compile error occurred", null, null);
}
- const mod = sema.mod;
ref: {
errdefer err_msg.destroy(gpa);
if (err_msg.src_loc.lazy == .unneeded) {
@@ -2330,9 +2351,9 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
try mod.failed_files.ensureUnusedCapacity(gpa, 1);
const max_references = blk: {
- if (sema.mod.comp.reference_trace) |num| break :blk num;
+ if (mod.comp.reference_trace) |num| break :blk num;
// Do not add multiple traces without explicit request.
- if (sema.mod.failed_decls.count() != 0) break :ref;
+ if (mod.failed_decls.count() != 0) break :ref;
break :blk default_reference_trace_len;
};
@@ -2350,13 +2371,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
if (gop.found_existing) break;
if (cur_reference_trace < max_references) {
const decl = sema.mod.declPtr(ref.referencer);
- try reference_stack.append(.{ .decl = decl.name, .src_loc = ref.src.toSrcLoc(decl, mod) });
+ try reference_stack.append(.{
+ .decl = decl.name.toOptional(),
+ .src_loc = ref.src.toSrcLoc(decl, mod),
+ });
}
referenced_by = ref.referencer;
}
if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) {
try reference_stack.append(.{
- .decl = null,
+ .decl = .none,
.src_loc = undefined,
.hidden = 0,
});
@@ -2795,7 +2819,6 @@ fn zirStructDecl(
new_namespace.ty = struct_ty.toType();
try sema.analyzeStructDecl(new_decl, inst, struct_index);
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
@@ -2812,6 +2835,7 @@ fn createAnonymousDeclTypeNamed(
) !Decl.Index {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const namespace = block.namespace;
const src_scope = block.wip_capture_scope;
const src_decl = mod.declPtr(block.src_decl);
@@ -2827,16 +2851,19 @@ fn createAnonymousDeclTypeNamed(
// semantically analyzed.
// This name is also used as the key in the parent namespace so it cannot be
// renamed.
- const name = try std.fmt.allocPrintZ(gpa, "{s}__{s}_{d}", .{
- src_decl.name, anon_prefix, @enumToInt(new_decl_index),
- });
- errdefer gpa.free(name);
+
+ // This ensureUnusedCapacity protects against the src_decl slice from being
+ // reallocated during the call to `getOrPutStringFmt`.
+ try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(src_decl.name).len +
+ anon_prefix.len + 20);
+ const name = ip.getOrPutStringFmt(gpa, "{s}__{s}_{d}", .{
+ ip.stringToSlice(src_decl.name), anon_prefix, @enumToInt(new_decl_index),
+ }) catch unreachable;
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
return new_decl_index;
},
.parent => {
- const name = try gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
- errdefer gpa.free(name);
+ const name = mod.declPtr(block.src_decl).name;
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
return new_decl_index;
},
@@ -2846,7 +2873,7 @@ fn createAnonymousDeclTypeNamed(
var buf = std.ArrayList(u8).init(gpa);
defer buf.deinit();
- try buf.appendSlice(mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
+ try buf.appendSlice(ip.stringToSlice(mod.declPtr(block.src_decl).name));
try buf.appendSlice("(");
var arg_i: usize = 0;
@@ -2871,8 +2898,7 @@ fn createAnonymousDeclTypeNamed(
};
try buf.appendSlice(")");
- const name = try buf.toOwnedSliceSentinel(0);
- errdefer gpa.free(name);
+ const name = try ip.getOrPutString(gpa, buf.items);
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
return new_decl_index;
},
@@ -2885,10 +2911,17 @@ fn createAnonymousDeclTypeNamed(
.dbg_var_ptr, .dbg_var_val => {
if (zir_data[i].str_op.operand != ref) continue;
- const name = try std.fmt.allocPrintZ(gpa, "{s}.{s}", .{
- src_decl.name, zir_data[i].str_op.getStr(sema.code),
- });
- errdefer gpa.free(name);
+ // This ensureUnusedCapacity protects against the src_decl
+ // slice from being reallocated during the call to
+ // `getOrPutStringFmt`.
+ const zir_str = zir_data[i].str_op.getStr(sema.code);
+ try ip.string_bytes.ensureUnusedCapacity(
+ gpa,
+ ip.stringToSlice(src_decl.name).len + zir_str.len + 10,
+ );
+ const name = ip.getOrPutStringFmt(gpa, "{s}.{s}", .{
+ ip.stringToSlice(src_decl.name), zir_str,
+ }) catch unreachable;
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
return new_decl_index;
@@ -3249,7 +3282,6 @@ fn zirUnionDecl(
_ = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
@@ -3315,7 +3347,6 @@ fn zirOpaqueDecl(
extra_index = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
@@ -3344,8 +3375,8 @@ fn zirErrorSetDecl(
while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
const str_index = sema.code.extra[extra_index];
const name = sema.code.nullTerminatedString(str_index);
- const kv = try mod.getErrorValue(name);
- const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
+ const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
+ _ = try mod.getErrorValue(name_ip);
const result = names.getOrPutAssumeCapacity(name_ip);
assert(!result.found_existing); // verified in AstGen
}
@@ -3512,7 +3543,8 @@ fn indexablePtrLen(
const is_pointer_to = object_ty.isSinglePointer(mod);
const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
try checkIndexable(sema, block, src, indexable_ty);
- return sema.fieldVal(block, src, object, "len", src);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len");
+ return sema.fieldVal(block, src, object, field_name, src);
}
fn indexablePtrLenOrNone(
@@ -3525,7 +3557,8 @@ fn indexablePtrLenOrNone(
const operand_ty = sema.typeOf(operand);
try checkMemOperand(sema, block, src, operand_ty);
if (operand_ty.ptrSize(mod) == .Many) return .none;
- return sema.fieldVal(block, src, operand, "len", src);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len");
+ return sema.fieldVal(block, src, operand, field_name, src);
}
fn zirAllocExtended(
@@ -4079,6 +4112,7 @@ fn zirFieldBasePtr(
fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
const args = sema.code.refSlice(extra.end, extra.data.operands_len);
@@ -4122,7 +4156,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
if (!object_ty.indexableHasLen(mod)) continue;
- break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);
+ break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, "len"), arg_src);
};
const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
if (len == .none) {
@@ -4308,6 +4342,7 @@ fn validateUnionInit(
union_ptr: Air.Inst.Ref,
) CompileError!void {
const mod = sema.mod;
+ const gpa = sema.gpa;
if (instrs.len != 1) {
const msg = msg: {
@@ -4317,7 +4352,7 @@ fn validateUnionInit(
"cannot initialize multiple union fields at once; unions can only have one active field",
.{},
);
- errdefer msg.destroy(sema.gpa);
+ errdefer msg.destroy(gpa);
for (instrs[1..]) |inst| {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
@@ -4341,7 +4376,7 @@ fn validateUnionInit(
const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;
const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
- const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start);
+ const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_ptr_extra.field_name_start));
// Validate the field access but ignore the index since we want the tag enum field index.
_ = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
const air_tags = sema.air_instructions.items(.tag);
@@ -4444,6 +4479,7 @@ fn validateStructInit(
) CompileError!void {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
// Maps field index to field_ptr index of where it was already initialized.
const found_fields = try gpa.alloc(Zir.Inst.Index, struct_ty.structFieldCount(mod));
@@ -4457,7 +4493,10 @@ fn validateStructInit(
const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
struct_ptr_zir_ref = field_ptr_extra.lhs;
- const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start);
+ const field_name = try ip.getOrPutString(
+ gpa,
+ sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
+ );
const field_index = if (struct_ty.isTuple(mod))
try sema.tupleFieldIndex(block, struct_ty, field_name, field_src)
else
@@ -4504,7 +4543,7 @@ fn validateStructInit(
}
const field_name = struct_ty.structFieldName(i, mod);
const template = "missing struct field: {s}";
- const args = .{field_name};
+ const args = .{ip.stringToSlice(field_name)};
if (root_msg) |msg| {
try sema.errNote(block, init_src, msg, template, args);
} else {
@@ -4525,8 +4564,7 @@ fn validateStructInit(
if (root_msg) |msg| {
if (mod.typeToStruct(struct_ty)) |struct_obj| {
- const fqn = try struct_obj.getFullyQualifiedName(mod);
- defer gpa.free(fqn);
+ const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
try mod.errNoteNonLazy(
struct_obj.srcLoc(mod),
msg,
@@ -4649,7 +4687,7 @@ fn validateStructInit(
}
const field_name = struct_ty.structFieldName(i, mod);
const template = "missing struct field: {s}";
- const args = .{field_name};
+ const args = .{ip.stringToSlice(field_name)};
if (root_msg) |msg| {
try sema.errNote(block, init_src, msg, template, args);
} else {
@@ -4662,10 +4700,9 @@ fn validateStructInit(
if (root_msg) |msg| {
if (mod.typeToStruct(struct_ty)) |struct_obj| {
- const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
- defer gpa.free(fqn);
+ const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
try sema.mod.errNoteNonLazy(
- struct_obj.srcLoc(sema.mod),
+ struct_obj.srcLoc(mod),
msg,
"struct '{s}' declared here",
.{fqn},
@@ -4949,7 +4986,7 @@ fn failWithBadMemberAccess(
block: *Block,
agg_ty: Type,
field_src: LazySrcLoc,
- field_name: []const u8,
+ field_name_nts: InternPool.NullTerminatedString,
) CompileError {
const mod = sema.mod;
const kw_name = switch (agg_ty.zigTypeTag(mod)) {
@@ -4959,6 +4996,7 @@ fn failWithBadMemberAccess(
.Enum => "enum",
else => unreachable,
};
+ const field_name = mod.intern_pool.stringToSlice(field_name_nts);
if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (sema.mod.declIsRoot(some)) {
return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{
agg_ty.fmt(sema.mod), field_name,
@@ -4980,22 +5018,23 @@ fn failWithBadStructFieldAccess(
block: *Block,
struct_obj: *Module.Struct,
field_src: LazySrcLoc,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
) CompileError {
+ const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
- const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
- defer gpa.free(fqn);
+ const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
const msg = msg: {
const msg = try sema.errMsg(
block,
field_src,
"no field named '{s}' in struct '{s}'",
- .{ field_name, fqn },
+ .{ ip.stringToSlice(field_name), fqn },
);
errdefer msg.destroy(gpa);
- try sema.mod.errNoteNonLazy(struct_obj.srcLoc(sema.mod), msg, "struct declared here", .{});
+ try mod.errNoteNonLazy(struct_obj.srcLoc(mod), msg, "struct declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
@@ -5006,22 +5045,23 @@ fn failWithBadUnionFieldAccess(
block: *Block,
union_obj: *Module.Union,
field_src: LazySrcLoc,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
) CompileError {
+ const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
- const fqn = try union_obj.getFullyQualifiedName(sema.mod);
- defer gpa.free(fqn);
+ const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
const msg = msg: {
const msg = try sema.errMsg(
block,
field_src,
"no field named '{s}' in union '{s}'",
- .{ field_name, fqn },
+ .{ ip.stringToSlice(field_name), fqn },
);
errdefer msg.destroy(gpa);
- try sema.mod.errNoteNonLazy(union_obj.srcLoc(sema.mod), msg, "union declared here", .{});
+ try mod.errNoteNonLazy(union_obj.srcLoc(mod), msg, "union declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
@@ -5772,7 +5812,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const src = inst_data.src();
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const decl_name = sema.code.nullTerminatedString(extra.decl_name);
+ const decl_name = try mod.intern_pool.getOrPutString(mod.gpa, sema.code.nullTerminatedString(extra.decl_name));
const decl_index = if (extra.namespace != .none) index_blk: {
const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
const container_namespace = container_ty.getNamespaceIndex(mod).unwrap().?;
@@ -5875,19 +5915,14 @@ pub fn analyzeExport(
const new_export = try gpa.create(Export);
errdefer gpa.destroy(new_export);
- const symbol_name = try gpa.dupe(u8, borrowed_options.name);
- errdefer gpa.free(symbol_name);
-
- const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
- errdefer if (section) |s| gpa.free(s);
+ const symbol_name = try mod.intern_pool.getOrPutString(gpa, borrowed_options.name);
+ const section = try mod.intern_pool.getOrPutStringOpt(gpa, borrowed_options.section);
new_export.* = .{
- .options = .{
- .name = symbol_name,
- .linkage = borrowed_options.linkage,
- .section = section,
- .visibility = borrowed_options.visibility,
- },
+ .name = symbol_name,
+ .linkage = borrowed_options.linkage,
+ .section = section,
+ .visibility = borrowed_options.visibility,
.src = src,
.owner_decl = sema.owner_decl_index,
.src_decl = block.src_decl,
@@ -6121,23 +6156,25 @@ fn addDbgVar(
}
fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
const src = inst_data.src();
- const decl_name = inst_data.get(sema.code);
+ const decl_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
const decl_index = try sema.lookupIdentifier(block, src, decl_name);
try sema.addReferencedBy(block, src, decl_index);
return sema.analyzeDeclRef(decl_index);
}
fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
const src = inst_data.src();
- const decl_name = inst_data.get(sema.code);
+ const decl_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
const decl = try sema.lookupIdentifier(block, src, decl_name);
return sema.analyzeDeclVal(block, src, decl);
}
-fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !Decl.Index {
+fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !Decl.Index {
const mod = sema.mod;
var namespace = block.namespace;
while (true) {
@@ -6156,7 +6193,7 @@ fn lookupInNamespace(
block: *Block,
src: LazySrcLoc,
namespace_index: Namespace.Index,
- ident_name: []const u8,
+ ident_name: InternPool.NullTerminatedString,
observe_usingnamespace: bool,
) CompileError!?Decl.Index {
const mod = sema.mod;
@@ -6249,9 +6286,6 @@ fn lookupInNamespace(
return decl_index;
}
- log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{
- sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name,
- });
// TODO This dependency is too strong. Really, it should only be a dependency
// on the non-existence of `ident_name` in the namespace. We can lessen the number of
// outdated declarations by making this dependency more sophisticated.
@@ -6276,10 +6310,12 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
}
pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
+ const mod = sema.mod;
+ const gpa = sema.gpa;
const src = sema.src;
- if (!sema.mod.backendSupportsFeature(.error_return_trace)) return .none;
- if (!sema.mod.comp.bin_file.options.error_return_tracing) return .none;
+ if (!mod.backendSupportsFeature(.error_return_trace)) return .none;
+ if (!mod.comp.bin_file.options.error_return_tracing) return .none;
if (block.is_comptime)
return .none;
@@ -6292,7 +6328,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
else => |e| return e,
};
- const field_index = sema.structFieldIndex(block, stack_trace_ty, "index", src) catch |err| switch (err) {
+ const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
+ const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, src) catch |err| switch (err) {
error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
else => |e| return e,
};
@@ -6316,6 +6353,7 @@ fn popErrorReturnTrace(
saved_error_trace_index: Air.Inst.Ref,
) CompileError!void {
const mod = sema.mod;
+ const gpa = sema.gpa;
var is_non_error: ?bool = null;
var is_non_error_inst: Air.Inst.Ref = undefined;
if (operand != .none) {
@@ -6332,13 +6370,14 @@ fn popErrorReturnTrace(
const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
- const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true);
+ const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
+ const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
} else if (is_non_error == null) {
// The result might be an error. If it is, we leave the error trace alone. If it isn't, we need
// to pop any error trace that may have been propagated from our arguments.
- try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).Struct.fields.len);
+ try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len);
const cond_block_inst = try block.addInstAsIndex(.{
.tag = .block,
.data = .{
@@ -6350,28 +6389,29 @@ fn popErrorReturnTrace(
});
var then_block = block.makeSubBlock();
- defer then_block.instructions.deinit(sema.gpa);
+ defer then_block.instructions.deinit(gpa);
// If non-error, then pop the error return trace by restoring the index.
const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
- const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, "index", src, stack_trace_ty, true);
+ const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
+ const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
_ = try then_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);
// Otherwise, do nothing
var else_block = block.makeSubBlock();
- defer else_block.instructions.deinit(sema.gpa);
+ defer else_block.instructions.deinit(gpa);
_ = try else_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);
- try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.CondBr).Struct.fields.len +
+ try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
then_block.instructions.items.len + else_block.instructions.items.len +
@typeInfo(Air.Block).Struct.fields.len + 1); // +1 for the sole .cond_br instruction in the .block
const cond_br_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
- try sema.air_instructions.append(sema.gpa, .{ .tag = .cond_br, .data = .{ .pl_op = .{
+ try sema.air_instructions.append(gpa, .{ .tag = .cond_br, .data = .{ .pl_op = .{
.operand = is_non_error_inst,
.payload = sema.addExtraAssumeCapacity(Air.CondBr{
.then_body_len = @intCast(u32, then_block.instructions.items.len),
@@ -6414,7 +6454,7 @@ fn zirCall(
.direct => .{ .direct = try sema.resolveInst(extra.data.callee) },
.field => blk: {
const object_ptr = try sema.resolveInst(extra.data.obj_ptr);
- const field_name = sema.code.nullTerminatedString(extra.data.field_name_start);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.data.field_name_start));
const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
break :blk try sema.fieldCallBind(block, callee_src, object_ptr, field_name, field_name_src);
},
@@ -6509,7 +6549,8 @@ fn zirCall(
if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError(mod))) {
const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
- const field_index = try sema.structFieldIndex(block, stack_trace_ty, "index", call_src);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index");
+ const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
// Insert a save instruction before the arg resolution + call instructions we just generated
const save_inst = try block.insertInst(block_index, .{
@@ -7436,9 +7477,10 @@ fn instantiateGenericCall(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime-known");
- const module_fn = mod.funcPtr(switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
+ const module_fn = mod.funcPtr(switch (ip.indexToKey(func_val.toIntern())) {
.func => |function| function.index,
.ptr => |ptr| mod.declPtr(ptr.addr.decl).val.getFunctionIndex(mod).unwrap().?,
else => unreachable,
@@ -7567,9 +7609,12 @@ fn instantiateGenericCall(
const new_decl_index = try mod.allocateNewDecl(namespace_index, fn_owner_decl.src_node, src_decl.src_scope);
const new_decl = mod.declPtr(new_decl_index);
// TODO better names for generic function instantiations
- const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{
- fn_owner_decl.name, @enumToInt(new_decl_index),
- });
+ // The ensureUnusedCapacity here protects against fn_owner_decl.name slice being
+ // reallocated during getOrPutStringFmt.
+ try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(fn_owner_decl.name).len + 20);
+ const decl_name = ip.getOrPutStringFmt(gpa, "{s}__anon_{d}", .{
+ ip.stringToSlice(fn_owner_decl.name), @enumToInt(new_decl_index),
+ }) catch unreachable;
new_decl.name = decl_name;
new_decl.src_line = fn_owner_decl.src_line;
new_decl.is_pub = fn_owner_decl.is_pub;
@@ -7590,12 +7635,8 @@ fn instantiateGenericCall(
assert(new_decl.dependencies.keys().len == 0);
try mod.declareDeclDependencyType(new_decl_index, module_fn.owner_decl, .function_body);
- var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
- const new_decl_arena_allocator = new_decl_arena.allocator();
-
const new_func = sema.resolveGenericInstantiationType(
block,
- new_decl_arena_allocator,
fn_zir,
new_decl,
new_decl_index,
@@ -7608,7 +7649,6 @@ fn instantiateGenericCall(
bound_arg_src,
) catch |err| switch (err) {
error.GenericPoison, error.ComptimeReturn => {
- new_decl_arena.deinit();
// Resolving the new function type below will possibly declare more decl dependencies
// and so we remove them all here in case of error.
for (new_decl.dependencies.keys()) |dep_index| {
@@ -7623,10 +7663,6 @@ fn instantiateGenericCall(
},
else => {
assert(mod.monomorphed_funcs.removeContext(new_module_func_index, .{ .mod = mod }));
- {
- errdefer new_decl_arena.deinit();
- try new_decl.finalizeNewArena(&new_decl_arena);
- }
// TODO look up the compile error that happened here and attach a note to it
// pointing here, at the generic instantiation callsite.
if (sema.owner_func) |owner_func| {
@@ -7637,9 +7673,7 @@ fn instantiateGenericCall(
return err;
},
};
- errdefer new_decl_arena.deinit();
- try new_decl.finalizeNewArena(&new_decl_arena);
break :callee new_func;
} else gop.key_ptr.*;
const callee = mod.funcPtr(callee_index);
@@ -7729,7 +7763,6 @@ fn instantiateGenericCall(
fn resolveGenericInstantiationType(
sema: *Sema,
block: *Block,
- new_decl_arena_allocator: Allocator,
fn_zir: Zir,
new_decl: *Decl,
new_decl_index: Decl.Index,
@@ -7755,7 +7788,6 @@ fn resolveGenericInstantiationType(
.mod = mod,
.gpa = gpa,
.arena = sema.arena,
- .perm_arena = new_decl_arena_allocator,
.code = fn_zir,
.owner_decl = new_decl,
.owner_decl_index = new_decl_index,
@@ -7764,7 +7796,8 @@ fn resolveGenericInstantiationType(
.fn_ret_ty = Type.void,
.owner_func = null,
.owner_func_index = .none,
- .comptime_args = try new_decl_arena_allocator.alloc(TypedValue, uncasted_args.len),
+ // TODO: fully migrate functions into InternPool
+ .comptime_args = try mod.tmp_hack_arena.allocator().alloc(TypedValue, uncasted_args.len),
.comptime_args_fn_inst = module_fn.zir_body_inst,
.preallocated_new_func = new_module_func.toOptional(),
.is_generic_instantiation = true,
@@ -7931,10 +7964,6 @@ fn resolveGenericInstantiationType(
new_decl.owns_tv = true;
new_decl.analysis = .complete;
- log.debug("generic function '{s}' instantiated with type {}", .{
- new_decl.name, new_decl.ty.fmtDebug(),
- });
-
// Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
// will be populated, ensuring it will have `analyzeBody` called with the ZIR
// parameters mapped appropriately.
@@ -8134,13 +8163,13 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
_ = block;
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
- const name = inst_data.get(sema.code);
+ const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
+ _ = try mod.getErrorValue(name);
// Create an error set type with only this error value, and return the value.
- const kv = try sema.mod.getErrorValue(name);
- const error_set_type = try mod.singleErrorSetType(kv.key);
+ const error_set_type = try mod.singleErrorSetTypeNts(name);
return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
.ty = error_set_type.toIntern(),
- .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),
+ .name = name,
} })).toValue());
}
@@ -8162,7 +8191,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
const err_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
return sema.addConstant(Type.err_int, try mod.intValue(
Type.err_int,
- (try mod.getErrorValue(mod.intern_pool.stringToSlice(err_name))).value,
+ try mod.getErrorValue(err_name),
));
}
@@ -8173,8 +8202,8 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
switch (names.len) {
0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
1 => {
- const name = mod.intern_pool.stringToSlice(names[0]);
- return sema.addIntUnsigned(Type.err_int, mod.global_error_set.get(name).?);
+ const int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(names[0]).?);
+ return sema.addIntUnsigned(Type.err_int, int);
},
else => {},
}
@@ -8197,11 +8226,11 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));
- if (int > sema.mod.global_error_set.count() or int == 0)
+ if (int > mod.global_error_set.count() or int == 0)
return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
return sema.addConstant(Type.anyerror, (try mod.intern(.{ .err = .{
.ty = .anyerror_type,
- .name = mod.intern_pool.getString(sema.mod.error_name_list.items[int]).unwrap().?,
+ .name = mod.global_error_set.keys()[int],
} })).toValue());
}
try sema.requireRuntimeBlock(block, src, operand_src);
@@ -8917,7 +8946,7 @@ fn handleExternLibName(
const FuncLinkSection = union(enum) {
generic,
default,
- explicit: []const u8,
+ explicit: InternPool.NullTerminatedString,
};
fn funcCommon(
@@ -9186,9 +9215,9 @@ fn funcCommon(
};
sema.owner_decl.@"linksection" = switch (section) {
- .generic => undefined,
- .default => null,
- .explicit => |section_name| try sema.perm_arena.dupeZ(u8, section_name),
+ .generic => .none,
+ .default => .none,
+ .explicit => |section_name| section_name.toOptional(),
};
sema.owner_decl.@"align" = alignment orelse 0;
sema.owner_decl.@"addrspace" = address_space orelse .generic;
@@ -9572,11 +9601,12 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const tracy = trace(@src());
defer tracy.end();
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
- const field_name = sema.code.nullTerminatedString(extra.field_name_start);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
const object = try sema.resolveInst(extra.lhs);
return sema.fieldVal(block, src, object, field_name, field_name_src);
}
@@ -9585,11 +9615,12 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index, initializing: b
const tracy = trace(@src());
defer tracy.end();
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
- const field_name = sema.code.nullTerminatedString(extra.field_name_start);
+ const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
const object_ptr = try sema.resolveInst(extra.lhs);
return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, initializing);
}
@@ -9603,7 +9634,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
const object = try sema.resolveInst(extra.lhs);
- const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, "field name must be comptime-known");
return sema.fieldVal(block, src, object, field_name, field_name_src);
}
@@ -9616,7 +9647,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
const object_ptr = try sema.resolveInst(extra.lhs);
- const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, "field name must be comptime-known");
return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
}
@@ -10434,6 +10465,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
const src_node_offset = inst_data.src_node;
@@ -10605,7 +10637,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
i,
msg,
"unhandled enumeration value: '{s}'",
- .{field_name},
+ .{ip.stringToSlice(field_name)},
);
}
try mod.errNoteNonLazy(
@@ -10689,7 +10721,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
for (operand_ty.errorSetNames(mod)) |error_name_ip| {
- const error_name = mod.intern_pool.stringToSlice(error_name_ip);
+ const error_name = ip.stringToSlice(error_name_ip);
if (!seen_errors.contains(error_name) and special_prong != .@"else") {
const msg = maybe_msg orelse blk: {
maybe_msg = try sema.errMsg(
@@ -10758,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
var names: Module.Fn.InferredErrorSet.NameMap = .{};
try names.ensureUnusedCapacity(sema.arena, error_names.len);
for (error_names) |error_name_ip| {
- const error_name = mod.intern_pool.stringToSlice(error_name_ip);
+ const error_name = ip.stringToSlice(error_name_ip);
if (seen_errors.contains(error_name)) continue;
names.putAssumeCapacityNoClobber(error_name_ip, {});
@@ -12062,7 +12094,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
- const field_name = try sema.resolveConstString(block, name_src, extra.rhs, "field name must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, "field name must be comptime-known");
const ty = try sema.resolveTypeFields(unresolved_ty);
const ip = &mod.intern_pool;
@@ -12070,19 +12102,17 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
switch (ip.indexToKey(ty.toIntern())) {
.ptr_type => |ptr_type| switch (ptr_type.flags.size) {
.Slice => {
- if (mem.eql(u8, field_name, "ptr")) break :hf true;
- if (mem.eql(u8, field_name, "len")) break :hf true;
+ if (ip.stringEqlSlice(field_name, "ptr")) break :hf true;
+ if (ip.stringEqlSlice(field_name, "len")) break :hf true;
break :hf false;
},
else => {},
},
.anon_struct_type => |anon_struct| {
if (anon_struct.names.len != 0) {
- // If the string is not interned, then the field certainly is not present.
- const name_interned = ip.getString(field_name).unwrap() orelse break :hf false;
- break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, name_interned) != null;
+ break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null;
} else {
- const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch break :hf false;
+ const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch break :hf false;
break :hf field_index < ty.structFieldCount(mod);
}
},
@@ -12097,11 +12127,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
break :hf union_obj.fields.contains(field_name);
},
.enum_type => |enum_type| {
- // If the string is not interned, then the field certainly is not present.
- const name_interned = ip.getString(field_name).unwrap() orelse break :hf false;
- break :hf enum_type.nameIndex(ip, name_interned) != null;
+ break :hf enum_type.nameIndex(ip, field_name) != null;
},
- .array_type => break :hf mem.eql(u8, field_name, "len"),
+ .array_type => break :hf ip.stringEqlSlice(field_name, "len"),
else => {},
}
return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
@@ -12123,7 +12151,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
- const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "decl name must be comptime-known");
+ const decl_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, "decl name must be comptime-known");
try sema.checkNamespaceType(block, lhs_src, container_type);
@@ -12218,14 +12246,12 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
- const err_name = inst_data.get(sema.code);
-
- // Return the error code from the function.
- const kv = try mod.getErrorValue(err_name);
- const error_set_type = try mod.singleErrorSetType(kv.key);
+ const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
+ _ = try mod.getErrorValue(name);
+ const error_set_type = try mod.singleErrorSetTypeNts(name);
return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
.ty = error_set_type.toIntern(),
- .name = mod.intern_pool.getString(kv.key).unwrap().?,
+ .name = name,
} })).toValue());
}
@@ -15730,12 +15756,7 @@ fn zirThis(
return sema.analyzeDeclVal(block, src, this_decl_index);
}
-fn zirClosureCapture(
- sema: *Sema,
- block: *Block,
- inst: Zir.Inst.Index,
-) CompileError!void {
- // TODO: Compile error when closed over values are modified
+fn zirClosureCapture(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
// Closures are not necessarily constant values. For example, the
// code might do something like this:
@@ -15754,13 +15775,8 @@ fn zirClosureCapture(
try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, capture);
}
-fn zirClosureGet(
- sema: *Sema,
- block: *Block,
- inst: Zir.Inst.Index,
-) CompileError!Air.Inst.Ref {
+fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
- // TODO CLOSURE: Test this with inline functions
const inst_data = sema.code.instructions.items(.data)[inst].inst_node;
var scope: *CaptureScope = mod.declPtr(block.src_decl).src_scope.?;
// Note: The target closure must be in this scope list.
@@ -15896,7 +15912,7 @@ fn zirBuiltinSrc(
const func_name_val = blk: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
- const name = mem.span(fn_owner_decl.name);
+ const name = mod.intern_pool.stringToSlice(fn_owner_decl.name);
const new_decl_ty = try mod.arrayType(.{
.len = name.len,
.child = .u8_type,
@@ -15965,6 +15981,7 @@ fn zirBuiltinSrc(
fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const ty = try sema.resolveType(block, src, inst_data.operand);
@@ -15995,7 +16012,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Fn",
+ try ip.getOrPutString(gpa, "Fn"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
try sema.ensureDeclAnalyzed(fn_info_decl_index);
@@ -16006,7 +16023,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
fn_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Param",
+ try ip.getOrPutString(gpa, "Param"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
try sema.ensureDeclAnalyzed(param_info_decl_index);
@@ -16018,8 +16035,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const info = mod.typeToFunc(ty).?;
const param_ty = info.param_types[i];
const is_generic = param_ty == .generic_poison_type;
- const param_ty_val = try mod.intern_pool.get(gpa, .{ .opt = .{
- .ty = try mod.intern_pool.get(gpa, .{ .opt_type = .type_type }),
+ const param_ty_val = try ip.get(gpa, .{ .opt = .{
+ .ty = try ip.get(gpa, .{ .opt_type = .type_type }),
.val = if (is_generic) .none else param_ty,
} });
@@ -16070,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const info = mod.typeToFunc(ty).?;
const ret_ty_opt = try mod.intern(.{ .opt = .{
- .ty = try mod.intern_pool.get(gpa, .{ .opt_type = .type_type }),
+ .ty = try ip.get(gpa, .{ .opt_type = .type_type }),
.val = if (info.return_type == .generic_poison_type) .none else info.return_type,
} });
@@ -16104,7 +16121,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Int",
+ try ip.getOrPutString(gpa, "Int"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, int_info_decl_index);
try sema.ensureDeclAnalyzed(int_info_decl_index);
@@ -16133,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Float",
+ try ip.getOrPutString(gpa, "Float"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, float_info_decl_index);
try sema.ensureDeclAnalyzed(float_info_decl_index);
@@ -16166,7 +16183,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
(try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
- "Pointer",
+ try ip.getOrPutString(gpa, "Pointer"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
try sema.ensureDeclAnalyzed(decl_index);
@@ -16178,7 +16195,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
pointer_ty.getNamespaceIndex(mod).unwrap().?,
- "Size",
+ try ip.getOrPutString(gpa, "Size"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
try sema.ensureDeclAnalyzed(decl_index);
@@ -16219,7 +16236,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Array",
+ try ip.getOrPutString(gpa, "Array"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, array_field_ty_decl_index);
try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
@@ -16251,7 +16268,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Vector",
+ try ip.getOrPutString(gpa, "Vector"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, vector_field_ty_decl_index);
try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
@@ -16281,7 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Optional",
+ try ip.getOrPutString(gpa, "Optional"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, optional_field_ty_decl_index);
try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
@@ -16312,7 +16329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Error",
+ try ip.getOrPutString(gpa, "Error"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
@@ -16332,7 +16349,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const names = ty.errorSetNames(mod);
const vals = try sema.arena.alloc(InternPool.Index, names.len);
for (vals, names) |*field_val, name_ip| {
- const name = mod.intern_pool.stringToSlice(name_ip);
+ const name = ip.stringToSlice(name_ip);
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
@@ -16415,7 +16432,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "ErrorUnion",
+ try ip.getOrPutString(gpa, "ErrorUnion"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, error_union_field_ty_decl_index);
try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);
@@ -16440,7 +16457,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
},
.Enum => {
// TODO: look into memoizing this result.
- const enum_type = mod.intern_pool.indexToKey(ty.toIntern()).enum_type;
+ const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
const is_exhaustive = Value.makeBool(enum_type.tag_mode != .nonexhaustive);
@@ -16452,7 +16469,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "EnumField",
+ try ip.getOrPutString(gpa, "EnumField"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
@@ -16462,8 +16479,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_type.names.len);
for (enum_field_vals, 0..) |*field_val, i| {
- const name_ip = mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[i];
- const name = mod.intern_pool.stringToSlice(name_ip);
+ const name_ip = ip.indexToKey(ty.toIntern()).enum_type.names[i];
+ const name = ip.stringToSlice(name_ip);
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
@@ -16532,7 +16549,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Enum",
+ try ip.getOrPutString(gpa, "Enum"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, type_enum_ty_decl_index);
try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
@@ -16570,7 +16587,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Union",
+ try ip.getOrPutString(gpa, "Union"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, type_union_ty_decl_index);
try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
@@ -16583,7 +16600,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "UnionField",
+ try ip.getOrPutString(gpa, "UnionField"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
@@ -16601,7 +16618,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
for (union_field_vals, 0..) |*field_val, i| {
const field = union_fields.values()[i];
- const name = union_fields.keys()[i];
+ const name = ip.stringToSlice(union_fields.keys()[i]);
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
@@ -16682,7 +16699,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
(try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
- "ContainerLayout",
+ try ip.getOrPutString(gpa, "ContainerLayout"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
try sema.ensureDeclAnalyzed(decl_index);
@@ -16721,7 +16738,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Struct",
+ try ip.getOrPutString(gpa, "Struct"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, type_struct_ty_decl_index);
try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
@@ -16734,7 +16751,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "StructField",
+ try ip.getOrPutString(gpa, "StructField"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
@@ -16749,11 +16766,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
var struct_field_vals: []InternPool.Index = &.{};
defer gpa.free(struct_field_vals);
fv: {
- const struct_type = switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
+ const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) {
.anon_struct_type => |tuple| {
struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
for (struct_field_vals, 0..) |*struct_field_val, i| {
- const anon_struct_type = mod.intern_pool.indexToKey(struct_ty.toIntern()).anon_struct_type;
+ const anon_struct_type = ip.indexToKey(struct_ty.toIntern()).anon_struct_type;
const field_ty = anon_struct_type.types[i];
const field_val = anon_struct_type.values[i];
const name_val = v: {
@@ -16761,7 +16778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
defer anon_decl.deinit();
const bytes = if (tuple.names.len != 0)
// https://github.com/ziglang/zig/issues/15709
- @as([]const u8, mod.intern_pool.stringToSlice(tuple.names[i]))
+ @as([]const u8, ip.stringToSlice(tuple.names[i]))
else
try std.fmt.allocPrint(sema.arena, "{d}", .{i});
const new_decl_ty = try mod.arrayType(.{
@@ -16815,7 +16832,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
struct_field_vals,
struct_obj.fields.keys(),
struct_obj.fields.values(),
- ) |*field_val, name, field| {
+ ) |*field_val, name_nts, field| {
+ const name = ip.stringToSlice(name_nts);
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
@@ -16838,10 +16856,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
} });
};
- const opt_default_val = if (field.default_val.toIntern() == .unreachable_value)
+ const opt_default_val = if (field.default_val == .none)
null
else
- field.default_val;
+ field.default_val.toValue();
const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);
const alignment = field.alignment(mod, layout);
@@ -16908,7 +16926,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
(try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
- "ContainerLayout",
+ try ip.getOrPutString(gpa, "ContainerLayout"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
try sema.ensureDeclAnalyzed(decl_index);
@@ -16945,7 +16963,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Opaque",
+ try ip.getOrPutString(gpa, "Opaque"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, type_opaque_ty_decl_index);
try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
@@ -16982,6 +17000,8 @@ fn typeInfoDecls(
opt_namespace: Module.Namespace.OptionalIndex,
) CompileError!InternPool.Index {
const mod = sema.mod;
+ const gpa = sema.gpa;
+
var decls_anon_decl = try block.startAnonDecl();
defer decls_anon_decl.deinit();
@@ -16990,7 +17010,7 @@ fn typeInfoDecls(
block,
src,
type_info_ty.getNamespaceIndex(mod).unwrap().?,
- "Declaration",
+ try mod.intern_pool.getOrPutString(gpa, "Declaration"),
)).?;
try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
@@ -16999,10 +17019,10 @@ fn typeInfoDecls(
};
try sema.queueFullTypeResolution(declaration_ty);
- var decl_vals = std.ArrayList(InternPool.Index).init(sema.gpa);
+ var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
defer decl_vals.deinit();
- var seen_namespaces = std.AutoHashMap(*Namespace, void).init(sema.gpa);
+ var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
defer seen_namespaces.deinit();
if (opt_namespace.unwrap()) |namespace_index| {
@@ -17061,7 +17081,7 @@ fn typeInfoNamespaceDecls(
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
- const name = mem.span(decl.name);
+ const name = mod.intern_pool.stringToSlice(decl.name);
const new_decl_ty = try mod.arrayType(.{
.len = name.len,
.child = .u8_type,
@@ -17696,15 +17716,14 @@ fn zirRetErrValue(
) CompileError!Zir.Inst.Index {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
- const err_name = inst_data.get(sema.code);
+ const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
+ _ = try mod.getErrorValue(err_name);
const src = inst_data.src();
-
// Return the error code from the function.
- const kv = try mod.getErrorValue(err_name);
- const error_set_type = try mod.singleErrorSetType(err_name);
+ const error_set_type = try mod.singleErrorSetTypeNts(err_name);
const result_inst = try sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
.ty = error_set_type.toIntern(),
- .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),
+ .name = err_name,
} })).toValue());
return sema.analyzeRet(block, result_inst, src);
}
@@ -18177,7 +18196,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
- const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "name of field being initialized must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, "name of field being initialized must be comptime-known");
const init = try sema.resolveInst(extra.init);
return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
}
@@ -18189,7 +18208,7 @@ fn unionInit(
init_src: LazySrcLoc,
union_ty: Type,
union_ty_src: LazySrcLoc,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
@@ -18257,7 +18276,7 @@ fn zirStructInit(
const field_type_data = zir_datas[item.data.field_type].pl_node;
const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
- const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
+ const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_type_extra.name_start));
const field_index = if (resolved_ty.isTuple(mod))
try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src)
else
@@ -18298,7 +18317,7 @@ fn zirStructInit(
const field_type_data = zir_datas[item.data.field_type].pl_node;
const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
- const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
+ const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_type_extra.name_start));
const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
@@ -18347,12 +18366,12 @@ fn finishStructInit(
is_ref: bool,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
- const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
var root_msg: ?*Module.ErrorMsg = null;
errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
- switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
+ switch (ip.indexToKey(struct_ty.toIntern())) {
.anon_struct_type => |anon_struct| {
for (anon_struct.types, anon_struct.values, 0..) |field_ty, default_val, i| {
if (field_inits[i] != .none) continue;
@@ -18366,9 +18385,9 @@ fn finishStructInit(
root_msg = try sema.errMsg(block, init_src, template, .{i});
}
} else {
- const field_name = mod.intern_pool.stringToSlice(anon_struct.names[i]);
+ const field_name = anon_struct.names[i];
const template = "missing struct field: {s}";
- const args = .{field_name};
+ const args = .{ip.stringToSlice(field_name)};
if (root_msg) |msg| {
try sema.errNote(block, init_src, msg, template, args);
} else {
@@ -18385,17 +18404,17 @@ fn finishStructInit(
for (struct_obj.fields.values(), 0..) |field, i| {
if (field_inits[i] != .none) continue;
- if (field.default_val.toIntern() == .unreachable_value) {
+ if (field.default_val == .none) {
const field_name = struct_obj.fields.keys()[i];
const template = "missing struct field: {s}";
- const args = .{field_name};
+ const args = .{ip.stringToSlice(field_name)};
if (root_msg) |msg| {
try sema.errNote(block, init_src, msg, template, args);
} else {
root_msg = try sema.errMsg(block, init_src, template, args);
}
} else {
- field_inits[i] = try sema.addConstant(field.ty, field.default_val);
+ field_inits[i] = try sema.addConstant(field.ty, field.default_val.toValue());
}
}
},
@@ -18404,10 +18423,9 @@ fn finishStructInit(
if (root_msg) |msg| {
if (mod.typeToStruct(struct_ty)) |struct_obj| {
- const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
- defer gpa.free(fqn);
- try sema.mod.errNoteNonLazy(
- struct_obj.srcLoc(sema.mod),
+ const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
+ try mod.errNoteNonLazy(
+ struct_obj.srcLoc(mod),
msg,
"struct '{s}' declared here",
.{fqn},
@@ -18826,11 +18844,13 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
const ty_src = inst_data.src();
const field_src = inst_data.src();
const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
- const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "field name must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, "field name must be comptime-known");
return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
}
fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+ const mod = sema.mod;
+ const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
const ty_src = inst_data.src();
@@ -18843,7 +18863,8 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
error.GenericPoison => return Air.Inst.Ref.generic_poison_type,
else => |e| return e,
};
- const field_name = sema.code.nullTerminatedString(extra.name_start);
+ const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
+ const field_name = try ip.getOrPutString(sema.gpa, zir_field_name);
return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
}
@@ -18851,7 +18872,7 @@ fn fieldType(
sema: *Sema,
block: *Block,
aggregate_ty: Type,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_src: LazySrcLoc,
ty_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
@@ -19050,13 +19071,14 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
const mod = sema.mod;
+ const ip = &mod.intern_pool;
try sema.resolveTypeLayout(operand_ty);
const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
.EnumLiteral => {
const val = try sema.resolveConstValue(block, .unneeded, operand, "");
- const tag_name = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
- const bytes = mod.intern_pool.stringToSlice(tag_name);
+ const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
+ const bytes = ip.stringToSlice(tag_name);
return sema.addStrLit(block, bytes);
},
.Enum => operand_ty,
@@ -19089,7 +19111,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const enum_decl = mod.declPtr(enum_decl_index);
const msg = msg: {
const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{s}'", .{
- val.fmtValue(enum_ty, sema.mod), enum_decl.name,
+ val.fmtValue(enum_ty, sema.mod), ip.stringToSlice(enum_decl.name),
});
errdefer msg.destroy(sema.gpa);
try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
@@ -19098,7 +19120,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
return sema.failWithOwnedErrorMsg(msg);
};
const field_name = enum_ty.enumFieldName(field_index, mod);
- return sema.addStrLit(block, field_name);
+ return sema.addStrLit(block, ip.stringToSlice(field_name));
}
try sema.requireRuntimeBlock(block, src, operand_src);
if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {
@@ -19119,6 +19141,7 @@ fn zirReify(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
@@ -19127,11 +19150,10 @@ fn zirReify(
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");
- const union_val = mod.intern_pool.indexToKey(val.toIntern()).un;
+ const union_val = ip.indexToKey(val.toIntern()).un;
const target = mod.getTarget();
if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;
- const ip = &mod.intern_pool;
switch (@intToEnum(std.builtin.TypeId, tag_index)) {
.Type => return Air.Inst.Ref.type_type,
.Void => return Air.Inst.Ref.void_type,
@@ -19145,8 +19167,14 @@ fn zirReify(
.EnumLiteral => return Air.Inst.Ref.enum_literal_type,
.Int => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const signedness_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("signedness").?);
- const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
+ const signedness_val = try union_val.val.toValue().fieldValue(
+ mod,
+ fields.getIndex(try ip.getOrPutString(gpa, "signedness")).?,
+ );
+ const bits_val = try union_val.val.toValue().fieldValue(
+ mod,
+ fields.getIndex(try ip.getOrPutString(gpa, "bits")).?,
+ );
const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
@@ -19155,8 +19183,12 @@ fn zirReify(
},
.Vector => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
- const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
+ const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "len"),
+ ).?);
+ const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "child"),
+ ).?);
const len = @intCast(u32, len_val.toUnsignedInt(mod));
const child_ty = child_val.toType();
@@ -19171,7 +19203,9 @@ fn zirReify(
},
.Float => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
+ const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "bits"),
+ ).?);
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
const ty = switch (bits) {
@@ -19186,14 +19220,30 @@ fn zirReify(
},
.Pointer => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("size").?);
- const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_const").?);
- const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_volatile").?);
- const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
- const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("address_space").?);
- const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
- const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_allowzero").?);
- const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
+ const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "size"),
+ ).?);
+ const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_const"),
+ ).?);
+ const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_volatile"),
+ ).?);
+ const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "alignment"),
+ ).?);
+ const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "address_space"),
+ ).?);
+ const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "child"),
+ ).?);
+ const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_allowzero"),
+ ).?);
+ const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "sentinel"),
+ ).?);
if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
@@ -19279,9 +19329,15 @@ fn zirReify(
},
.Array => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
- const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
- const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
+ const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "len"),
+ ).?);
+ const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "child"),
+ ).?);
+ const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "sentinel"),
+ ).?);
const len = len_val.toUnsignedInt(mod);
const child_ty = child_val.toType();
@@ -19298,7 +19354,9 @@ fn zirReify(
},
.Optional => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
+ const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "child"),
+ ).?);
const child_ty = child_val.toType();
@@ -19307,8 +19365,12 @@ fn zirReify(
},
.ErrorUnion => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("error_set").?);
- const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("payload").?);
+ const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "error_set"),
+ ).?);
+ const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "payload"),
+ ).?);
const error_set_ty = error_set_val.toType();
const payload_ty = payload_val.toType();
@@ -19330,14 +19392,17 @@ fn zirReify(
for (0..len) |i| {
const elem_val = try payload_val.elemValue(mod, i);
const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
- const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
+ const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "name"),
+ ).?);
- const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
- const kv = try mod.getErrorValue(name_str);
- const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
- const gop = names.getOrPutAssumeCapacity(name_ip);
+ const name = try name_val.toIpString(Type.slice_const_u8, mod);
+ _ = try mod.getErrorValue(name);
+ const gop = names.getOrPutAssumeCapacity(name);
if (gop.found_existing) {
- return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
+ return sema.fail(block, src, "duplicate error '{s}'", .{
+ ip.stringToSlice(name),
+ });
}
}
@@ -19346,11 +19411,21 @@ fn zirReify(
},
.Struct => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
- const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("backing_integer").?);
- const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
- const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
- const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_tuple").?);
+ const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "layout"),
+ ).?);
+ const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "backing_integer"),
+ ).?);
+ const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "fields"),
+ ).?);
+ const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "decls"),
+ ).?);
+ const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_tuple"),
+ ).?);
const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
@@ -19367,10 +19442,18 @@ fn zirReify(
},
.Enum => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
- const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
- const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
- const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_exhaustive").?);
+ const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "tag_type"),
+ ).?);
+ const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "fields"),
+ ).?);
+ const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "decls"),
+ ).?);
+ const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_exhaustive"),
+ ).?);
// Decls
if (decls_val.sliceLen(mod) > 0) {
@@ -19396,7 +19479,7 @@ fn zirReify(
// Define our empty enum decl
const fields_len = @intCast(u32, try sema.usizeCast(block, src, fields_val.sliceLen(mod)));
- const incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{
+ const incomplete_enum = try ip.getIncompleteEnum(gpa, .{
.decl = new_decl_index,
.namespace = .none,
.fields_len = fields_len,
@@ -19407,35 +19490,36 @@ fn zirReify(
.explicit,
.tag_ty = int_tag_ty.toIntern(),
});
- errdefer mod.intern_pool.remove(incomplete_enum.index);
+ errdefer ip.remove(incomplete_enum.index);
new_decl.val = incomplete_enum.index.toValue();
for (0..fields_len) |field_i| {
const elem_val = try fields_val.elemValue(mod, field_i);
const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
- const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
- const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("value").?);
+ const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "name"),
+ ).?);
+ const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "value"),
+ ).?);
- const field_name = try name_val.toAllocatedBytes(
- Type.slice_const_u8,
- sema.arena,
- mod,
- );
- const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
+ const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
if (!try sema.intFitsInType(value_val, int_tag_ty, null)) {
// TODO: better source location
return sema.fail(block, src, "field '{s}' with enumeration value '{}' is too large for backing int type '{}'", .{
- field_name,
+ ip.stringToSlice(field_name),
value_val.fmtValue(Type.comptime_int, mod),
int_tag_ty.fmt(mod),
});
}
- if (try incomplete_enum.addFieldName(&mod.intern_pool, gpa, field_name_ip)) |other_index| {
+ if (try incomplete_enum.addFieldName(ip, gpa, field_name)) |other_index| {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{field_name});
+ const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{
+ ip.stringToSlice(field_name),
+ });
errdefer msg.destroy(gpa);
_ = other_index; // TODO: this note is incorrect
try sema.errNote(block, src, msg, "other field here", .{});
@@ -19444,7 +19528,7 @@ fn zirReify(
return sema.failWithOwnedErrorMsg(msg);
}
- if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, (try mod.getCoerced(value_val, int_tag_ty)).toIntern())) |other| {
+ if (try incomplete_enum.addFieldValue(ip, gpa, (try mod.getCoerced(value_val, int_tag_ty)).toIntern())) |other| {
const msg = msg: {
const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
errdefer msg.destroy(gpa);
@@ -19462,7 +19546,9 @@ fn zirReify(
},
.Opaque => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
+ const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "decls"),
+ ).?);
// Decls
if (decls_val.sliceLen(mod) > 0) {
@@ -19496,22 +19582,29 @@ fn zirReify(
.decl = new_decl_index,
.namespace = new_namespace_index,
} });
- errdefer mod.intern_pool.remove(opaque_ty);
+ errdefer ip.remove(opaque_ty);
new_decl.val = opaque_ty.toValue();
new_namespace.ty = opaque_ty.toType();
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
},
.Union => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
- const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
- const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
- const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
+ const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "layout"),
+ ).?);
+ const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "tag_type"),
+ ).?);
+ const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "fields"),
+ ).?);
+ const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "decls"),
+ ).?);
// Decls
if (decls_val.sliceLen(mod) > 0) {
@@ -19555,7 +19648,7 @@ fn zirReify(
const union_obj = mod.unionPtr(union_index);
errdefer mod.destroyUnion(union_index);
- const union_ty = try mod.intern_pool.get(gpa, .{ .union_type = .{
+ const union_ty = try ip.get(gpa, .{ .union_type = .{
.index = union_index,
.runtime_tag = if (!tag_type_val.isNull(mod))
.tagged
@@ -19566,7 +19659,7 @@ fn zirReify(
.ReleaseFast, .ReleaseSmall => .none,
},
} });
- errdefer mod.intern_pool.remove(union_ty);
+ errdefer ip.remove(union_ty);
new_decl.val = union_ty.toValue();
new_namespace.ty = union_ty.toType();
@@ -19579,7 +19672,7 @@ fn zirReify(
if (tag_type_val.optionalValue(mod)) |payload_val| {
union_obj.tag_ty = payload_val.toType();
- const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
+ const enum_type = switch (ip.indexToKey(union_obj.tag_ty.toIntern())) {
.enum_type => |x| x,
else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
};
@@ -19597,26 +19690,26 @@ fn zirReify(
for (0..fields_len) |i| {
const elem_val = try fields_val.elemValue(mod, i);
const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
- const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
- const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
- const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
-
- const field_name = try name_val.toAllocatedBytes(
- Type.slice_const_u8,
- new_decl_arena_allocator,
- mod,
- );
-
- const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
+ const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "name"),
+ ).?);
+ const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "type"),
+ ).?);
+ const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "alignment"),
+ ).?);
+
+ const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
if (enum_field_names.len != 0) {
- enum_field_names[i] = field_name_ip;
+ enum_field_names[i] = field_name;
}
if (explicit_enum_info) |tag_info| {
- const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
+ const enum_index = tag_info.nameIndex(ip, field_name) orelse {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });
+ const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod) });
errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
break :msg msg;
@@ -19632,7 +19725,7 @@ fn zirReify(
const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
if (gop.found_existing) {
// TODO: better source location
- return sema.fail(block, src, "duplicate union field {s}", .{field_name});
+ return sema.fail(block, src, "duplicate union field {s}", .{ip.stringToSlice(field_name)});
}
const field_ty = type_val.toType();
@@ -19688,7 +19781,7 @@ fn zirReify(
for (tag_info.names, 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{
- mod.intern_pool.stringToSlice(field_name),
+ ip.stringToSlice(field_name),
});
}
try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
@@ -19700,19 +19793,30 @@ fn zirReify(
union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, enum_field_names, null);
}
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
},
.Fn => {
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
- const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("calling_convention").?);
- const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
- const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_generic").?);
- const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_var_args").?);
- const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?);
- const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?);
+ const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "calling_convention"),
+ ).?);
+ const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "alignment"),
+ ).?);
+ const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_generic"),
+ ).?);
+ const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "is_var_args"),
+ ).?);
+ const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "return_type"),
+ ).?);
+ const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
+ try ip.getOrPutString(gpa, "params"),
+ ).?);
const is_generic = is_generic_val.toBool();
if (is_generic) {
@@ -19746,9 +19850,15 @@ fn zirReify(
for (param_types, 0..) |*param_type, i| {
const elem_val = try params_val.elemValue(mod, i);
const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
- const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_generic").?);
- const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_noalias").?);
- const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
+ const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "is_generic"),
+ ).?);
+ const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "is_noalias"),
+ ).?);
+ const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "type"),
+ ).?);
if (param_is_generic_val.toBool()) {
return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
@@ -19801,6 +19911,7 @@ fn reifyStruct(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
errdefer new_decl_arena.deinit();
@@ -19839,11 +19950,11 @@ fn reifyStruct(
const struct_obj = mod.structPtr(struct_index);
errdefer mod.destroyStruct(struct_index);
- const struct_ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{
+ const struct_ty = try ip.get(gpa, .{ .struct_type = .{
.index = struct_index.toOptional(),
.namespace = new_namespace_index.toOptional(),
} });
- errdefer mod.intern_pool.remove(struct_ty);
+ errdefer ip.remove(struct_ty);
new_decl.val = struct_ty.toValue();
new_namespace.ty = struct_ty.toType();
@@ -19854,12 +19965,22 @@ fn reifyStruct(
var i: usize = 0;
while (i < fields_len) : (i += 1) {
const elem_val = try fields_val.elemValue(mod, i);
- const elem_fields = mod.intern_pool.typeOf(elem_val.toIntern()).toType().structFields(mod);
- const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
- const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
- const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("default_value").?);
- const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_comptime").?);
- const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
+ const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
+ const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "name"),
+ ).?);
+ const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "type"),
+ ).?);
+ const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "default_value"),
+ ).?);
+ const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "is_comptime"),
+ ).?);
+ const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
+ try ip.getOrPutString(gpa, "alignment"),
+ ).?);
if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
@@ -19874,19 +19995,15 @@ fn reifyStruct(
return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
}
- const field_name = try name_val.toAllocatedBytes(
- Type.slice_const_u8,
- new_decl_arena_allocator,
- mod,
- );
+ const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
if (is_tuple) {
- const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch {
+ const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch {
return sema.fail(
block,
src,
"tuple cannot have non-numeric field '{s}'",
- .{field_name},
+ .{ip.stringToSlice(field_name)},
);
};
@@ -19902,16 +20019,16 @@ fn reifyStruct(
const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
if (gop.found_existing) {
// TODO: better source location
- return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
+ return sema.fail(block, src, "duplicate struct field {s}", .{ip.stringToSlice(field_name)});
}
const field_ty = type_val.toType();
const default_val = if (default_value_val.optionalValue(mod)) |opt_val|
- try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
- return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")
+ (try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
+ return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")).toIntern()
else
- Value.@"unreachable";
- if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {
+ .none;
+ if (is_comptime_val.toBool() and default_val == .none) {
return sema.fail(block, src, "comptime field without default initialization value", .{});
}
@@ -20000,7 +20117,6 @@ fn reifyStruct(
struct_obj.status = .have_layout;
}
- try new_decl.finalizeNewArena(&new_decl_arena);
const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
try mod.finalizeAnonDecl(new_decl_index);
return decl_val;
@@ -20871,7 +20987,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const ty = try sema.resolveType(block, lhs_src, extra.lhs);
- const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, "name of field must be comptime-known");
const mod = sema.mod;
try sema.resolveTypeLayout(ty);
@@ -20889,7 +21005,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
}
const field_index = if (ty.isTuple(mod)) blk: {
- if (mem.eql(u8, field_name, "len")) {
+ if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
return sema.fail(block, src, "no offset available for 'len' field of tuple", .{});
}
break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src);
@@ -21351,6 +21467,8 @@ fn resolveExportOptions(
zir_ref: Zir.Inst.Ref,
) CompileError!std.builtin.ExportOptions {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const export_options_ty = try sema.getBuiltinType("ExportOptions");
const air_ref = try sema.resolveInst(zir_ref);
const options = try sema.coerce(block, export_options_ty, air_ref, src);
@@ -21360,16 +21478,16 @@ fn resolveExportOptions(
const section_src = sema.maybeOptionsSrc(block, src, "section");
const visibility_src = sema.maybeOptionsSrc(block, src, "visibility");
- const name_operand = try sema.fieldVal(block, src, options, "name", name_src);
+ const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");
const name_ty = Type.slice_const_u8;
const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod);
- const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
+ const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src);
const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");
const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
- const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
+ const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "section"), section_src);
const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
const section_ty = Type.slice_const_u8;
const section = if (section_opt_val.optionalValue(mod)) |section_val|
@@ -21377,7 +21495,7 @@ fn resolveExportOptions(
else
null;
- const visibility_operand = try sema.fieldVal(block, src, options, "visibility", visibility_src);
+ const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "visibility"), visibility_src);
const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");
const visibility = mod.toEnum(std.builtin.SymbolVisibility, visibility_val);
@@ -22217,10 +22335,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
const parent_ty = try sema.resolveType(block, ty_src, extra.parent_type);
- const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");
+ const field_name = try sema.resolveConstStringIntern(block, name_src, extra.field_name, "field name must be comptime-known");
const field_ptr = try sema.resolveInst(extra.field_ptr);
const field_ptr_ty = sema.typeOf(field_ptr);
const mod = sema.mod;
+ const ip = &mod.intern_pool;
if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {
return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});
@@ -22230,7 +22349,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const field_index = switch (parent_ty.zigTypeTag(mod)) {
.Struct => blk: {
if (parent_ty.isTuple(mod)) {
- if (mem.eql(u8, field_name, "len")) {
+ if (ip.stringEqlSlice(field_name, "len")) {
return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});
}
break :blk try sema.tupleFieldIndex(block, parent_ty, field_name, name_src);
@@ -22276,7 +22395,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
- const field = switch (mod.intern_pool.indexToKey(field_ptr_val.toIntern())) {
+ const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
.ptr => |ptr| switch (ptr.addr) {
.field => |field| field,
else => null,
@@ -22291,7 +22410,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
src,
"field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
.{
- field_name,
+ ip.stringToSlice(field_name),
field_index,
field.index,
parent_ty.fmt(sema.mod),
@@ -22807,6 +22926,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = inst_data.src();
@@ -22824,7 +22945,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const dest_elem_ty = dest_ptr_ty.elemType2(mod);
const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
- const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);
+ const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len"), dest_src);
const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
break :rs dest_src;
const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;
@@ -23068,11 +23189,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
if (val.isGenericPoison()) {
break :blk FuncLinkSection{ .generic = {} };
}
- break :blk FuncLinkSection{ .explicit = try val.toAllocatedBytes(ty, sema.arena, sema.mod) };
+ break :blk FuncLinkSection{ .explicit = try val.toIpString(ty, mod) };
} else if (extra.data.bits.has_section_ref) blk: {
const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const section_name = sema.resolveConstString(block, section_src, section_ref, "linksection must be comptime-known") catch |err| switch (err) {
+ const section_name = sema.resolveConstStringIntern(block, section_src, section_ref, "linksection must be comptime-known") catch |err| switch (err) {
error.GenericPoison => {
break :blk FuncLinkSection{ .generic = {} };
},
@@ -23272,6 +23393,8 @@ fn resolvePrefetchOptions(
zir_ref: Zir.Inst.Ref,
) CompileError!std.builtin.PrefetchOptions {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const options_ty = try sema.getBuiltinType("PrefetchOptions");
const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
@@ -23279,13 +23402,13 @@ fn resolvePrefetchOptions(
const locality_src = sema.maybeOptionsSrc(block, src, "locality");
const cache_src = sema.maybeOptionsSrc(block, src, "cache");
- const rw = try sema.fieldVal(block, src, options, "rw", rw_src);
+ const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "rw"), rw_src);
const rw_val = try sema.resolveConstValue(block, rw_src, rw, "prefetch read/write must be comptime-known");
- const locality = try sema.fieldVal(block, src, options, "locality", locality_src);
+ const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "locality"), locality_src);
const locality_val = try sema.resolveConstValue(block, locality_src, locality, "prefetch locality must be comptime-known");
- const cache = try sema.fieldVal(block, src, options, "cache", cache_src);
+ const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "cache"), cache_src);
const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");
return std.builtin.PrefetchOptions{
@@ -23336,6 +23459,8 @@ fn resolveExternOptions(
zir_ref: Zir.Inst.Ref,
) CompileError!std.builtin.ExternOptions {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const options_inst = try sema.resolveInst(zir_ref);
const extern_options_ty = try sema.getBuiltinType("ExternOptions");
const options = try sema.coerce(block, extern_options_ty, options_inst, src);
@@ -23345,18 +23470,18 @@ fn resolveExternOptions(
const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");
const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local");
- const name_ref = try sema.fieldVal(block, src, options, "name", name_src);
+ const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
const name_val = try sema.resolveConstValue(block, name_src, name_ref, "name of the extern symbol must be comptime-known");
const name = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
- const library_name_inst = try sema.fieldVal(block, src, options, "library_name", library_src);
+ const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name"), library_src);
const library_name_val = try sema.resolveConstValue(block, library_src, library_name_inst, "library in which extern symbol is must be comptime-known");
- const linkage_ref = try sema.fieldVal(block, src, options, "linkage", linkage_src);
+ const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src);
const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");
const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
- const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
+ const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "is_thread_local"), thread_local_src);
const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");
const library_name = if (library_name_val.optionalValue(mod)) |payload| blk: {
@@ -23425,7 +23550,7 @@ fn zirBuiltinExtern(
const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);
errdefer mod.destroyDecl(new_decl_index);
const new_decl = mod.declPtr(new_decl_index);
- new_decl.name = try sema.gpa.dupeZ(u8, options.name);
+ new_decl.name = try mod.intern_pool.getOrPutString(sema.gpa, options.name);
{
const new_var = try mod.intern(.{ .variable = .{
@@ -23444,7 +23569,7 @@ fn zirBuiltinExtern(
new_decl.ty = ty;
new_decl.val = new_var.toValue();
new_decl.@"align" = 0;
- new_decl.@"linksection" = null;
+ new_decl.@"linksection" = .none;
new_decl.has_tv = true;
new_decl.analysis = .complete;
new_decl.generation = mod.generation;
@@ -24265,12 +24390,13 @@ fn safetyPanic(
panic_id: PanicId,
) CompileError!void {
const mod = sema.mod;
+ const gpa = sema.gpa;
const panic_messages_ty = try sema.getBuiltinType("panic_messages");
const msg_decl_index = (try sema.namespaceLookup(
block,
sema.src,
panic_messages_ty.getNamespaceIndex(mod).unwrap().?,
- @tagName(panic_id),
+ try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id)),
)).?;
const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);
@@ -24302,14 +24428,13 @@ fn fieldVal(
block: *Block,
src: LazySrcLoc,
object: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
// When editing this function, note that there is corresponding logic to be edited
// in `fieldPtr`. This function takes a value and returns a value.
const mod = sema.mod;
- const gpa = sema.gpa;
const ip = &mod.intern_pool;
const object_src = src; // TODO better source location
const object_ty = sema.typeOf(object);
@@ -24326,12 +24451,12 @@ fn fieldVal(
switch (inner_ty.zigTypeTag(mod)) {
.Array => {
- if (mem.eql(u8, field_name, "len")) {
+ if (ip.stringEqlSlice(field_name, "len")) {
return sema.addConstant(
Type.usize,
try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
);
- } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {
+ } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
const ptr_info = object_ty.ptrInfo(mod);
const result_ty = try Type.ptr(sema.arena, mod, .{
.pointee_type = ptr_info.pointee_type.childType(mod),
@@ -24352,20 +24477,20 @@ fn fieldVal(
block,
field_name_src,
"no member named '{s}' in '{}'",
- .{ field_name, object_ty.fmt(mod) },
+ .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
);
}
},
.Pointer => {
const ptr_info = inner_ty.ptrInfo(mod);
if (ptr_info.size == .Slice) {
- if (mem.eql(u8, field_name, "ptr")) {
+ if (ip.stringEqlSlice(field_name, "ptr")) {
const slice = if (is_pointer_to)
try sema.analyzeLoad(block, src, object, object_src)
else
object;
return sema.analyzeSlicePtr(block, object_src, slice, inner_ty);
- } else if (mem.eql(u8, field_name, "len")) {
+ } else if (ip.stringEqlSlice(field_name, "len")) {
const slice = if (is_pointer_to)
try sema.analyzeLoad(block, src, object, object_src)
else
@@ -24376,7 +24501,7 @@ fn fieldVal(
block,
field_name_src,
"no member named '{s}' in '{}'",
- .{ field_name, object_ty.fmt(mod) },
+ .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
);
}
}
@@ -24392,13 +24517,12 @@ fn fieldVal(
switch (try child_type.zigTypeTagOrPoison(mod)) {
.ErrorSet => {
- const name = try ip.getOrPutString(gpa, field_name);
switch (ip.indexToKey(child_type.toIntern())) {
.error_set_type => |error_set_type| blk: {
- if (error_set_type.nameIndex(ip, name) != null) break :blk;
+ if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
const msg = msg: {
const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{
- field_name, child_type.fmt(mod),
+ ip.stringToSlice(field_name), child_type.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, child_type);
@@ -24419,10 +24543,10 @@ fn fieldVal(
const error_set_type = if (!child_type.isAnyError(mod))
child_type
else
- try mod.singleErrorSetTypeNts(name);
+ try mod.singleErrorSetTypeNts(field_name);
return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
.ty = error_set_type.toIntern(),
- .name = name,
+ .name = field_name,
} })).toValue());
},
.Union => {
@@ -24499,7 +24623,7 @@ fn fieldPtr(
block: *Block,
src: LazySrcLoc,
object_ptr: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
initializing: bool,
) CompileError!Air.Inst.Ref {
@@ -24507,7 +24631,6 @@ fn fieldPtr(
// in `fieldVal`. This function takes a pointer and returns a pointer.
const mod = sema.mod;
- const gpa = sema.gpa;
const ip = &mod.intern_pool;
const object_ptr_src = src; // TODO better source location
const object_ptr_ty = sema.typeOf(object_ptr);
@@ -24528,7 +24651,7 @@ fn fieldPtr(
switch (inner_ty.zigTypeTag(mod)) {
.Array => {
- if (mem.eql(u8, field_name, "len")) {
+ if (ip.stringEqlSlice(field_name, "len")) {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
return sema.analyzeDeclRef(try anon_decl.finish(
@@ -24541,7 +24664,7 @@ fn fieldPtr(
block,
field_name_src,
"no member named '{s}' in '{}'",
- .{ field_name, object_ty.fmt(mod) },
+ .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
);
}
},
@@ -24553,7 +24676,7 @@ fn fieldPtr(
const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;
- if (mem.eql(u8, field_name, "ptr")) {
+ if (ip.stringEqlSlice(field_name, "ptr")) {
const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
const result_ty = try Type.ptr(sema.arena, mod, .{
@@ -24575,7 +24698,7 @@ fn fieldPtr(
try sema.requireRuntimeBlock(block, src, null);
return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
- } else if (mem.eql(u8, field_name, "len")) {
+ } else if (ip.stringEqlSlice(field_name, "len")) {
const result_ty = try Type.ptr(sema.arena, mod, .{
.pointee_type = Type.usize,
.mutable = attr_ptr_ty.ptrIsMutable(mod),
@@ -24600,7 +24723,7 @@ fn fieldPtr(
block,
field_name_src,
"no member named '{s}' in '{}'",
- .{ field_name, object_ty.fmt(mod) },
+ .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
);
}
},
@@ -24617,14 +24740,13 @@ fn fieldPtr(
switch (child_type.zigTypeTag(mod)) {
.ErrorSet => {
- const name = try ip.getOrPutString(gpa, field_name);
switch (ip.indexToKey(child_type.toIntern())) {
.error_set_type => |error_set_type| blk: {
- if (error_set_type.nameIndex(ip, name) != null) {
+ if (error_set_type.nameIndex(ip, field_name) != null) {
break :blk;
}
return sema.fail(block, src, "no error named '{s}' in '{}'", .{
- field_name, child_type.fmt(mod),
+ ip.stringToSlice(field_name), child_type.fmt(mod),
});
},
.inferred_error_set_type => {
@@ -24642,12 +24764,12 @@ fn fieldPtr(
const error_set_type = if (!child_type.isAnyError(mod))
child_type
else
- try mod.singleErrorSetTypeNts(name);
+ try mod.singleErrorSetTypeNts(field_name);
return sema.analyzeDeclRef(try anon_decl.finish(
error_set_type,
(try mod.intern(.{ .err = .{
.ty = error_set_type.toIntern(),
- .name = name,
+ .name = field_name,
} })).toValue(),
0, // default alignment
));
@@ -24736,13 +24858,14 @@ fn fieldCallBind(
block: *Block,
src: LazySrcLoc,
raw_ptr: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
) CompileError!ResolvedFieldCallee {
// When editing this function, note that there is corresponding logic to be edited
// in `fieldVal`. This function takes a pointer and returns a pointer.
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const raw_ptr_src = src; // TODO better source location
const raw_ptr_ty = sema.typeOf(raw_ptr);
const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))
@@ -24771,18 +24894,18 @@ fn fieldCallBind(
return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);
} else if (struct_ty.isTuple(mod)) {
- if (mem.eql(u8, field_name, "len")) {
+ if (ip.stringEqlSlice(field_name, "len")) {
return .{ .direct = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod)) };
}
- if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
+ if (std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10)) |field_index| {
if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;
return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);
} else |_| {}
} else {
const max = struct_ty.structFieldCount(mod);
- var i: u32 = 0;
- while (i < max) : (i += 1) {
- if (mem.eql(u8, struct_ty.structFieldName(i, mod), field_name)) {
+ for (0..max) |i_usize| {
+ const i = @intCast(u32, i_usize);
+ if (field_name == struct_ty.structFieldName(i, mod)) {
return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);
}
}
@@ -24876,12 +24999,12 @@ fn fieldCallBind(
};
const msg = msg: {
- const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ field_name, concrete_ty.fmt(mod) });
+ const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ ip.stringToSlice(field_name), concrete_ty.fmt(mod) });
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, concrete_ty);
if (found_decl) |decl_idx| {
const decl = mod.declPtr(decl_idx);
- try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{s}' is not a member function", .{field_name});
+ try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{s}' is not a member function", .{ip.stringToSlice(field_name)});
}
break :msg msg;
};
@@ -24933,7 +25056,7 @@ fn namespaceLookup(
block: *Block,
src: LazySrcLoc,
namespace: Namespace.Index,
- decl_name: []const u8,
+ decl_name: InternPool.NullTerminatedString,
) CompileError!?Decl.Index {
const mod = sema.mod;
const gpa = sema.gpa;
@@ -24942,7 +25065,7 @@ fn namespaceLookup(
if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {
const msg = msg: {
const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{
- decl_name,
+ mod.intern_pool.stringToSlice(decl_name),
});
errdefer msg.destroy(gpa);
try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{});
@@ -24960,7 +25083,7 @@ fn namespaceLookupRef(
block: *Block,
src: LazySrcLoc,
namespace: Namespace.Index,
- decl_name: []const u8,
+ decl_name: InternPool.NullTerminatedString,
) CompileError!?Air.Inst.Ref {
const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
try sema.addReferencedBy(block, src, decl);
@@ -24972,7 +25095,7 @@ fn namespaceLookupVal(
block: *Block,
src: LazySrcLoc,
namespace: Namespace.Index,
- decl_name: []const u8,
+ decl_name: InternPool.NullTerminatedString,
) CompileError!?Air.Inst.Ref {
const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
return try sema.analyzeDeclVal(block, src, decl);
@@ -24983,7 +25106,7 @@ fn structFieldPtr(
block: *Block,
src: LazySrcLoc,
struct_ptr: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
unresolved_struct_ty: Type,
initializing: bool,
@@ -24995,7 +25118,7 @@ fn structFieldPtr(
try sema.resolveStructLayout(struct_ty);
if (struct_ty.isTuple(mod)) {
- if (mem.eql(u8, field_name, "len")) {
+ if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
const len_inst = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod));
return sema.analyzeRef(block, src, len_inst);
}
@@ -25101,7 +25224,7 @@ fn structFieldPtrByIndex(
if (field.is_comptime) {
const val = try mod.intern(.{ .ptr = .{
.ty = ptr_field_ty.toIntern(),
- .addr = .{ .comptime_field = try field.default_val.intern(field.ty, mod) },
+ .addr = .{ .comptime_field = field.default_val },
} });
return sema.addConstant(ptr_field_ty, val.toValue());
}
@@ -25126,7 +25249,7 @@ fn structFieldVal(
block: *Block,
src: LazySrcLoc,
struct_byval: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
unresolved_struct_ty: Type,
) CompileError!Air.Inst.Ref {
@@ -25145,7 +25268,7 @@ fn structFieldVal(
const field = struct_obj.fields.values()[field_index];
if (field.is_comptime) {
- return sema.addConstant(field.ty, field.default_val);
+ return sema.addConstant(field.ty, field.default_val.toValue());
}
if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {
@@ -25176,12 +25299,12 @@ fn tupleFieldVal(
block: *Block,
src: LazySrcLoc,
tuple_byval: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
tuple_ty: Type,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
- if (mem.eql(u8, field_name, "len")) {
+ if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
return sema.addIntUnsigned(Type.usize, tuple_ty.structFieldCount(mod));
}
const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);
@@ -25193,11 +25316,12 @@ fn tupleFieldIndex(
sema: *Sema,
block: *Block,
tuple_ty: Type,
- field_name: []const u8,
+ field_name_ip: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
) CompileError!u32 {
const mod = sema.mod;
- assert(!mem.eql(u8, field_name, "len"));
+ const field_name = mod.intern_pool.stringToSlice(field_name_ip);
+ assert(!std.mem.eql(u8, field_name, "len"));
if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
if (field_index < tuple_ty.structFieldCount(mod)) return field_index;
return sema.fail(block, field_name_src, "index '{s}' out of bounds of tuple '{}'", .{
@@ -25253,13 +25377,14 @@ fn unionFieldPtr(
block: *Block,
src: LazySrcLoc,
union_ptr: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
unresolved_union_ty: Type,
initializing: bool,
) CompileError!Air.Inst.Ref {
const arena = sema.arena;
const mod = sema.mod;
+ const ip = &mod.intern_pool;
assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
@@ -25281,7 +25406,9 @@ fn unionFieldPtr(
const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
errdefer msg.destroy(sema.gpa);
- try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
+ try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
+ ip.stringToSlice(field_name),
+ });
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
};
@@ -25296,14 +25423,17 @@ fn unionFieldPtr(
if (union_val.isUndef(mod)) {
return sema.failWithUseOfUndef(block, src);
}
- const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
+ const un = ip.indexToKey(union_val.toIntern()).un;
const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
const tag_matches = un.tag == field_tag.toIntern();
if (!tag_matches) {
const msg = msg: {
const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
- const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
+ const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{
+ ip.stringToSlice(field_name),
+ ip.stringToSlice(active_field_name),
+ });
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
@@ -25345,11 +25475,12 @@ fn unionFieldVal(
block: *Block,
src: LazySrcLoc,
union_byval: Air.Inst.Ref,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_name_src: LazySrcLoc,
unresolved_union_ty: Type,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
@@ -25361,7 +25492,7 @@ fn unionFieldVal(
if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);
- const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
+ const un = ip.indexToKey(union_val.toIntern()).un;
const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
const tag_matches = un.tag == field_tag.toIntern();
switch (union_obj.layout) {
@@ -25372,7 +25503,9 @@ fn unionFieldVal(
const msg = msg: {
const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
- const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
+ const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{
+ ip.stringToSlice(field_name), ip.stringToSlice(active_field_name),
+ });
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
@@ -26470,14 +26603,13 @@ fn coerceExtra(
// enum literal to enum
const val = try sema.resolveConstValue(block, .unneeded, inst, "");
const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
- const bytes = mod.intern_pool.stringToSlice(string);
- const field_index = dest_ty.enumFieldIndex(bytes, mod) orelse {
+ const field_index = dest_ty.enumFieldIndex(string, mod) orelse {
const msg = msg: {
const msg = try sema.errMsg(
block,
inst_src,
"no field named '{s}' in enum '{}'",
- .{ bytes, dest_ty.fmt(mod) },
+ .{ mod.intern_pool.stringToSlice(string), dest_ty.fmt(mod) },
);
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, dest_ty);
@@ -27876,10 +28008,7 @@ fn storePtrVal(
error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(mod)}),
};
- const arena = mut_kit.beginArena(mod);
- defer mut_kit.finishArena(mod);
-
- reinterpret.val_ptr.* = (try (try Value.readFromMemory(mut_kit.ty, mod, buffer, arena)).intern(mut_kit.ty, mod)).toValue();
+ reinterpret.val_ptr.* = (try (try Value.readFromMemory(mut_kit.ty, mod, buffer, sema.arena)).intern(mut_kit.ty, mod)).toValue();
},
.bad_decl_ty, .bad_ptr_ty => {
// TODO show the decl declaration site in a note and explain whether the decl
@@ -27913,18 +28042,6 @@ const ComptimePtrMutationKit = struct {
bad_ptr_ty,
},
ty: Type,
- decl_arena: std.heap.ArenaAllocator = undefined,
-
- fn beginArena(self: *ComptimePtrMutationKit, mod: *Module) Allocator {
- const decl = mod.declPtr(self.mut_decl.decl);
- return decl.value_arena.?.acquire(mod.gpa, &self.decl_arena);
- }
-
- fn finishArena(self: *ComptimePtrMutationKit, mod: *Module) void {
- const decl = mod.declPtr(self.mut_decl.decl);
- decl.value_arena.?.release(&self.decl_arena);
- self.decl_arena = undefined;
- }
};
fn beginComptimePtrMutation(
@@ -27966,10 +28083,8 @@ fn beginComptimePtrMutation(
// An error union has been initialized to undefined at comptime and now we
// are for the first time setting the payload. We must change the
// representation of the error union from `undef` to `opt_payload`.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
- const payload = try arena.create(Value.Payload.SubValue);
+ const payload = try sema.arena.create(Value.Payload.SubValue);
payload.* = .{
.base = .{ .tag = .eu_payload },
.data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(),
@@ -28019,10 +28134,8 @@ fn beginComptimePtrMutation(
// An optional has been initialized to undefined at comptime and now we
// are for the first time setting the payload. We must change the
// representation of the optional from `undef` to `opt_payload`.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
- const payload = try arena.create(Value.Payload.SubValue);
+ const payload = try sema.arena.create(Value.Payload.SubValue);
payload.* = .{
.base = .{ .tag = .opt_payload },
.data = payload_val.toValue(),
@@ -28088,8 +28201,7 @@ fn beginComptimePtrMutation(
// If we wanted to avoid this, there would need to be special detection
// elsewhere to identify when writing a value to an array element that is stored
// using the `bytes` tag, and handle it without making a call to this function.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
+ const arena = sema.arena;
const bytes = val_ptr.castTag(.bytes).?.data;
const dest_len = parent.ty.arrayLenIncludingSentinel(mod);
@@ -28121,8 +28233,7 @@ fn beginComptimePtrMutation(
// need to be special detection elsewhere to identify when writing a value to an
// array element that is stored using the `repeated` tag, and handle it
// without making a call to this function.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
+ const arena = sema.arena;
const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena);
const array_len_including_sentinel =
@@ -28163,8 +28274,7 @@ fn beginComptimePtrMutation(
// An array has been initialized to undefined at comptime and now we
// are for the first time setting an element. We must change the representation
// of the array from `undef` to `array`.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
+ const arena = sema.arena;
const array_len_including_sentinel =
try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
@@ -28261,8 +28371,7 @@ fn beginComptimePtrMutation(
parent.mut_decl,
),
.repeated => {
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
+ const arena = sema.arena;
const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod));
@memset(elems, val_ptr.castTag(.repeated).?.data);
@@ -28325,8 +28434,7 @@ fn beginComptimePtrMutation(
// A struct or union has been initialized to undefined at comptime and now we
// are for the first time setting a field. We must change the representation
// of the struct/union from `undef` to `struct`/`union`.
- const arena = parent.beginArena(sema.mod);
- defer parent.finishArena(sema.mod);
+ const arena = sema.arena;
switch (parent.ty.zigTypeTag(mod)) {
.Struct => {
@@ -28436,11 +28544,7 @@ fn beginComptimePtrMutationInner(
const target = mod.getTarget();
const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;
- const decl = mod.declPtr(mut_decl.decl);
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const allocator = decl.value_arena.?.acquire(sema.gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
- decl_val.* = try decl_val.unintern(allocator, mod);
+ decl_val.* = try decl_val.unintern(sema.arena, mod);
if (coerce_ok) {
return ComptimePtrMutationKit{
@@ -28928,6 +29032,7 @@ fn coerceEnumToUnion(
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const inst_ty = sema.typeOf(inst);
const tag_ty = union_ty.unionTagType(mod) orelse {
@@ -28966,7 +29071,9 @@ fn coerceEnumToUnion(
errdefer msg.destroy(sema.gpa);
const field_name = union_obj.fields.keys()[field_index];
- try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
+ try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
+ ip.stringToSlice(field_name),
+ });
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
};
@@ -28976,11 +29083,14 @@ fn coerceEnumToUnion(
const msg = msg: {
const field_name = union_obj.fields.keys()[field_index];
const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{
- inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), field_ty.fmt(sema.mod), field_name,
+ inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),
+ field_ty.fmt(sema.mod), ip.stringToSlice(field_name),
});
errdefer msg.destroy(sema.gpa);
- try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
+ try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
+ ip.stringToSlice(field_name),
+ });
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
};
@@ -29049,7 +29159,10 @@ fn coerceEnumToUnion(
const field_name = field.key_ptr.*;
const field_ty = field.value_ptr.ty;
if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
- try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
+ try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{
+ ip.stringToSlice(field_name),
+ field_ty.fmt(sema.mod),
+ });
}
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
@@ -29068,11 +29181,11 @@ fn coerceAnonStructToUnion(
const mod = sema.mod;
const inst_ty = sema.typeOf(inst);
const field_info: union(enum) {
- name: []const u8,
+ name: InternPool.NullTerminatedString,
count: usize,
} = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)
- .{ .name = mod.intern_pool.stringToSlice(anon_struct_type.names[0]) }
+ .{ .name = anon_struct_type.names[0] }
else
.{ .count = anon_struct_type.names.len },
.struct_type => |struct_type| name: {
@@ -29335,6 +29448,7 @@ fn coerceTupleToStruct(
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const struct_ty = try sema.resolveTypeFields(dest_ty);
if (struct_ty.isTupleOrAnonStruct(mod)) {
@@ -29348,7 +29462,7 @@ fn coerceTupleToStruct(
const inst_ty = sema.typeOf(inst);
var runtime_src: ?LazySrcLoc = null;
- const field_count = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
+ const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
.struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
struct_obj.fields.count()
@@ -29360,11 +29474,11 @@ fn coerceTupleToStruct(
const field_i = @intCast(u32, field_index_usize);
const field_src = inst_src; // TODO better source location
// https://github.com/ziglang/zig/issues/15709
- const field_name: []const u8 = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
+ const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
- mod.intern_pool.stringToSlice(anon_struct_type.names[field_i])
+ anon_struct_type.names[field_i]
else
- try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),
+ try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
else => unreachable,
};
@@ -29378,7 +29492,7 @@ fn coerceTupleToStruct(
return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
};
- if (!init_val.eql(field.default_val, field.ty, sema.mod)) {
+ if (!init_val.eql(field.default_val.toValue(), field.ty, sema.mod)) {
return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
}
}
@@ -29401,9 +29515,9 @@ fn coerceTupleToStruct(
const field_name = fields.keys()[i];
const field = fields.values()[i];
const field_src = inst_src; // TODO better source location
- if (field.default_val.toIntern() == .unreachable_value) {
+ if (field.default_val == .none) {
const template = "missing struct field: {s}";
- const args = .{field_name};
+ const args = .{ip.stringToSlice(field_name)};
if (root_msg) |msg| {
try sema.errNote(block, field_src, msg, template, args);
} else {
@@ -29412,9 +29526,9 @@ fn coerceTupleToStruct(
continue;
}
if (runtime_src == null) {
- field_vals[i] = field.default_val.toIntern();
+ field_vals[i] = field.default_val;
} else {
- field_ref.* = try sema.addConstant(field.ty, field.default_val);
+ field_ref.* = try sema.addConstant(field.ty, field.default_val.toValue());
}
}
@@ -29433,7 +29547,7 @@ fn coerceTupleToStruct(
.ty = struct_ty.toIntern(),
.storage = .{ .elems = field_vals },
} });
- errdefer mod.intern_pool.remove(struct_val);
+ errdefer ip.remove(struct_val);
return sema.addConstant(struct_ty, struct_val.toValue());
}
@@ -29446,7 +29560,8 @@ fn coerceTupleToTuple(
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
const mod = sema.mod;
- const dest_field_count = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
.struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
struct_obj.fields.count()
@@ -29459,7 +29574,7 @@ fn coerceTupleToTuple(
@memset(field_refs, .none);
const inst_ty = sema.typeOf(inst);
- const src_field_count = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
+ const src_field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
.struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
struct_obj.fields.count()
@@ -29474,30 +29589,26 @@ fn coerceTupleToTuple(
const field_i = @intCast(u32, field_index_usize);
const field_src = inst_src; // TODO better source location
// https://github.com/ziglang/zig/issues/15709
- const field_name: []const u8 = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
+ const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
- mod.intern_pool.stringToSlice(anon_struct_type.names[field_i])
+ anon_struct_type.names[field_i]
else
- try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),
+ try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
else => unreachable,
};
- if (mem.eql(u8, field_name, "len")) {
+ if (ip.stringEqlSlice(field_name, "len"))
return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
- }
- const field_ty = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
+ const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,
else => unreachable,
};
- const default_val = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
+ const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize],
- .struct_type => |struct_type| switch (mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val.toIntern()) {
- .unreachable_value => .none,
- else => |default_val| default_val,
- },
+ .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val,
else => unreachable,
};
@@ -29531,12 +29642,9 @@ fn coerceTupleToTuple(
for (field_refs, 0..) |*field_ref, i| {
if (field_ref.* != .none) continue;
- const default_val = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
+ const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.values[i],
- .struct_type => |struct_type| switch (mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val.toIntern()) {
- .unreachable_value => .none,
- else => |default_val| default_val,
- },
+ .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val,
else => unreachable,
};
@@ -29552,7 +29660,7 @@ fn coerceTupleToTuple(
continue;
}
const template = "missing struct field: {s}";
- const args = .{tuple_ty.structFieldName(i, mod)};
+ const args = .{ip.stringToSlice(tuple_ty.structFieldName(i, mod))};
if (root_msg) |msg| {
try sema.errNote(block, field_src, msg, template, args);
} else {
@@ -29563,7 +29671,7 @@ fn coerceTupleToTuple(
if (runtime_src == null) {
field_vals[i] = default_val;
} else {
- const field_ty = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
+ const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| anon_struct_type.types[i].toType(),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].ty,
else => unreachable,
@@ -31803,15 +31911,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
}
if (struct_obj.layout == .Auto and mod.backendSupportsFeature(.field_reordering)) {
- const optimized_order = if (struct_obj.owner_decl == sema.owner_decl_index)
- try sema.perm_arena.alloc(u32, struct_obj.fields.count())
- else blk: {
- const decl = mod.declPtr(struct_obj.owner_decl);
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const decl_arena_allocator = decl.value_arena.?.acquire(sema.gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
- break :blk try decl_arena_allocator.alloc(u32, struct_obj.fields.count());
- };
+ const optimized_order = try mod.tmp_hack_arena.allocator().alloc(u32, struct_obj.fields.count());
for (struct_obj.fields.values(), 0..) |field, i| {
optimized_order[i] = if (try sema.typeHasRuntimeBits(field.ty))
@@ -31852,9 +31952,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
const decl_index = struct_obj.owner_decl;
const decl = mod.declPtr(decl_index);
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
@@ -31880,7 +31977,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
.mod = mod,
.gpa = gpa,
.arena = analysis_arena.allocator(),
- .perm_arena = decl_arena_allocator,
.code = zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -31936,7 +32032,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
.mod = mod,
.gpa = gpa,
.arena = undefined,
- .perm_arena = decl_arena_allocator,
.code = zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -32581,6 +32676,7 @@ fn resolveInferredErrorSetTy(
fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
const gpa = mod.gpa;
+ const ip = &mod.intern_pool;
const decl_index = struct_obj.owner_decl;
const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
@@ -32628,9 +32724,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
}
const decl = mod.declPtr(decl_index);
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
@@ -32642,7 +32735,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
.mod = mod,
.gpa = gpa,
.arena = analysis_arena.allocator(),
- .perm_arena = decl_arena_allocator,
.code = zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -32674,7 +32766,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
}
struct_obj.fields = .{};
- try struct_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
+ try struct_obj.fields.ensureTotalCapacity(mod.tmp_hack_arena.allocator(), fields_len);
const Field = struct {
type_body_len: u32 = 0,
@@ -32725,16 +32817,15 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
extra_index += 1;
// This string needs to outlive the ZIR code.
- const field_name = if (field_name_zir) |some|
- try decl_arena_allocator.dupe(u8, some)
- else
- try std.fmt.allocPrint(decl_arena_allocator, "{d}", .{field_i});
+ const field_name = try ip.getOrPutString(gpa, if (field_name_zir) |s| s else try std.fmt.allocPrint(sema.arena, "{d}", .{
+ field_i,
+ }));
const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
if (gop.found_existing) {
const msg = msg: {
const field_src = mod.fieldSrcLoc(struct_obj.owner_decl, .{ .index = field_i }).lazy;
- const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name});
+ const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{ip.stringToSlice(field_name)});
errdefer msg.destroy(gpa);
const prev_field_index = struct_obj.fields.getIndex(field_name).?;
@@ -32748,7 +32839,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
gop.value_ptr.* = .{
.ty = Type.noreturn,
.abi_align = 0,
- .default_val = Value.@"unreachable",
+ .default_val = .none,
.is_comptime = is_comptime,
.offset = undefined,
};
@@ -32917,7 +33008,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
}).lazy;
return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known");
};
- field.default_val = try default_val.copy(decl_arena_allocator);
+ field.default_val = try default_val.intern(field.ty, mod);
}
}
}
@@ -32935,6 +33026,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
defer tracy.end();
const gpa = mod.gpa;
+ const ip = &mod.intern_pool;
const decl_index = union_obj.owner_decl;
const zir = mod.namespacePtr(union_obj.namespace).file_scope.zir;
const extended = zir.instructions.items(.data)[union_obj.zir_index].extended;
@@ -32978,9 +33070,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
extra_index += body.len;
const decl = mod.declPtr(decl_index);
- var decl_arena: std.heap.ArenaAllocator = undefined;
- const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
- defer decl.value_arena.?.release(&decl_arena);
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
@@ -32992,7 +33081,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
.mod = mod,
.gpa = gpa,
.arena = analysis_arena.allocator(),
- .perm_arena = decl_arena_allocator,
.code = zir,
.owner_decl = decl,
.owner_decl_index = decl_index,
@@ -33033,7 +33121,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
try ct_decl.intern(mod);
}
- try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
+ try union_obj.fields.ensureTotalCapacity(mod.tmp_hack_arena.allocator(), fields_len);
var int_tag_ty: Type = undefined;
var enum_field_names: []InternPool.NullTerminatedString = &.{};
@@ -33070,7 +33158,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
} else {
// The provided type is the enum tag type.
union_obj.tag_ty = provided_ty;
- const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
+ const enum_type = switch (ip.indexToKey(union_obj.tag_ty.toIntern())) {
.enum_type => |x| x,
else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(mod)}),
};
@@ -33174,10 +33262,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
}
// This string needs to outlive the ZIR code.
- const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
- const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
+ const field_name = try ip.getOrPutString(gpa, field_name_zir);
if (enum_field_names.len != 0) {
- enum_field_names[field_i] = field_name_ip;
+ enum_field_names[field_i] = field_name;
}
const field_ty: Type = if (!has_type)
@@ -33205,7 +33292,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
if (gop.found_existing) {
const msg = msg: {
const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy;
- const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name});
+ const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{
+ ip.stringToSlice(field_name),
+ });
errdefer msg.destroy(gpa);
const prev_field_index = union_obj.fields.getIndex(field_name).?;
@@ -33218,14 +33307,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
}
if (explicit_enum_info) |tag_info| {
- const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
+ const enum_index = tag_info.nameIndex(ip, field_name) orelse {
const msg = msg: {
const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{
.index = field_i,
.range = .type,
}).lazy;
const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{
- field_name, union_obj.tag_ty.fmt(mod),
+ ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
@@ -33317,7 +33406,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
for (tag_info.names, 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{
- mod.intern_pool.stringToSlice(field_name),
+ ip.stringToSlice(field_name),
});
}
try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
@@ -33345,14 +33434,22 @@ fn generateUnionTagTypeNumbered(
union_obj: *Module.Union,
) !Type {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const src_decl = mod.declPtr(block.src_decl);
const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
errdefer mod.destroyDecl(new_decl_index);
const name = name: {
- const fqn = try union_obj.getFullyQualifiedName(mod);
- defer sema.gpa.free(fqn);
- break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
+ const prefix = "@typeInfo(";
+ const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
+ const suffix = ").Union.tag_type.?";
+ const start = ip.string_bytes.items.len;
+ try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len);
+ ip.string_bytes.appendSliceAssumeCapacity(prefix);
+ ip.string_bytes.appendSliceAssumeCapacity(fqn);
+ ip.string_bytes.appendSliceAssumeCapacity(suffix);
+ break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
};
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
.ty = Type.type,
@@ -33390,6 +33487,8 @@ fn generateUnionTagTypeSimple(
maybe_union_obj: ?*Module.Union,
) !Type {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const new_decl_index = new_decl_index: {
const union_obj = maybe_union_obj orelse {
@@ -33402,9 +33501,15 @@ fn generateUnionTagTypeSimple(
const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
errdefer mod.destroyDecl(new_decl_index);
const name = name: {
- const fqn = try union_obj.getFullyQualifiedName(mod);
- defer sema.gpa.free(fqn);
- break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
+ const prefix = "@typeInfo(";
+ const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
+ const suffix = ").Union.tag_type.?";
+ const start = ip.string_bytes.items.len;
+ try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len);
+ ip.string_bytes.appendSliceAssumeCapacity(prefix);
+ ip.string_bytes.appendSliceAssumeCapacity(fqn);
+ ip.string_bytes.appendSliceAssumeCapacity(suffix);
+ break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
};
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
.ty = Type.type,
@@ -33436,7 +33541,9 @@ fn generateUnionTagTypeSimple(
}
fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
- var wip_captures = try WipCaptureScope.init(sema.gpa, sema.owner_decl.src_scope);
+ const gpa = sema.gpa;
+
+ var wip_captures = try WipCaptureScope.init(gpa, sema.owner_decl.src_scope);
defer wip_captures.deinit();
var block: Block = .{
@@ -33450,19 +33557,20 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
.is_comptime = true,
};
defer {
- block.instructions.deinit(sema.gpa);
- block.params.deinit(sema.gpa);
+ block.instructions.deinit(gpa);
+ block.params.deinit(gpa);
}
const src = LazySrcLoc.nodeOffset(0);
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const std_pkg = mod.main_pkg.table.get("std").?;
const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
const opt_builtin_inst = (try sema.namespaceLookupRef(
&block,
src,
mod.declPtr(std_file.root_decl.unwrap().?).src_namespace,
- "builtin",
+ try ip.getOrPutString(gpa, "builtin"),
)) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
const builtin_inst = try sema.analyzeLoad(&block, src, opt_builtin_inst, src);
const builtin_ty = sema.analyzeAsType(&block, src, builtin_inst) catch |err| switch (err) {
@@ -33473,7 +33581,7 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
&block,
src,
builtin_ty.getNamespaceIndex(mod).unwrap().?,
- name,
+ try ip.getOrPutString(gpa, name),
)) orelse std.debug.panic("lib/std/builtin.zig is corrupt and missing '{s}'", .{name});
return sema.analyzeDeclVal(&block, src, opt_ty_decl);
}
@@ -33608,7 +33716,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
if (field.is_comptime) {
- field_val.* = try field.default_val.intern(field.ty, mod);
+ field_val.* = field.default_val;
continue;
}
if (field.ty.eql(resolved_ty, sema.mod)) {
@@ -34287,7 +34395,7 @@ fn unionFieldIndex(
sema: *Sema,
block: *Block,
unresolved_union_ty: Type,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_src: LazySrcLoc,
) !u32 {
const mod = sema.mod;
@@ -34302,7 +34410,7 @@ fn structFieldIndex(
sema: *Sema,
block: *Block,
unresolved_struct_ty: Type,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_src: LazySrcLoc,
) !u32 {
const mod = sema.mod;
@@ -34321,19 +34429,17 @@ fn anonStructFieldIndex(
sema: *Sema,
block: *Block,
struct_ty: Type,
- field_name: []const u8,
+ field_name: InternPool.NullTerminatedString,
field_src: LazySrcLoc,
) !u32 {
const mod = sema.mod;
switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| {
- if (mem.eql(u8, mod.intern_pool.stringToSlice(name), field_name)) {
- return @intCast(u32, i);
- }
+ if (name == field_name) return @intCast(u32, i);
},
.struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
for (struct_obj.fields.keys(), 0..) |name, i| {
- if (mem.eql(u8, name, field_name)) {
+ if (name == field_name) {
return @intCast(u32, i);
}
}
@@ -34341,7 +34447,7 @@ fn anonStructFieldIndex(
else => unreachable,
}
return sema.fail(block, field_src, "no field named '{s}' in anonymous struct '{}'", .{
- field_name, struct_ty.fmt(sema.mod),
+ mod.intern_pool.stringToSlice(field_name), struct_ty.fmt(sema.mod),
});
}
src/type.zig
@@ -2546,7 +2546,7 @@ pub const Type = struct {
defer mod.gpa.free(field_vals);
for (field_vals, s.fields.values()) |*field_val, field| {
if (field.is_comptime) {
- field_val.* = try field.default_val.intern(field.ty, mod);
+ field_val.* = field.default_val;
continue;
}
if (try field.ty.onePossibleValue(mod)) |field_opv| {
@@ -2977,18 +2977,14 @@ pub const Type = struct {
return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names.len;
}
- pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) [:0]const u8 {
- const ip = &mod.intern_pool;
- const field_name = ip.indexToKey(ty.toIntern()).enum_type.names[field_index];
- return ip.stringToSlice(field_name);
+ pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
+ return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[field_index];
}
- pub fn enumFieldIndex(ty: Type, field_name: []const u8, mod: *Module) ?u32 {
+ pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, mod: *Module) ?u32 {
const ip = &mod.intern_pool;
const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
- // If the string is not interned, then the field certainly is not present.
- const field_name_interned = ip.getString(field_name).unwrap() orelse return null;
- return enum_type.nameIndex(ip, field_name_interned);
+ return enum_type.nameIndex(ip, field_name);
}
/// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
@@ -3017,19 +3013,16 @@ pub const Type = struct {
}
}
- pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) []const u8 {
- switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
+ return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
assert(struct_obj.haveFieldTypes());
return struct_obj.fields.keys()[field_index];
},
- .anon_struct_type => |anon_struct| {
- const name = anon_struct.names[field_index];
- return mod.intern_pool.stringToSlice(name);
- },
+ .anon_struct_type => |anon_struct| anon_struct.names[field_index],
else => unreachable,
- }
+ };
}
pub fn structFieldCount(ty: Type, mod: *Module) usize {
@@ -3082,7 +3075,10 @@ pub const Type = struct {
switch (mod.intern_pool.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
- return struct_obj.fields.values()[index].default_val;
+ const val = struct_obj.fields.values()[index].default_val;
+ // TODO: avoid using `unreachable` to indicate this.
+ if (val == .none) return Value.@"unreachable";
+ return val.toValue();
},
.anon_struct_type => |anon_struct| {
const val = anon_struct.values[index];
@@ -3100,7 +3096,7 @@ pub const Type = struct {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
const field = struct_obj.fields.values()[index];
if (field.is_comptime) {
- return field.default_val;
+ return field.default_val.toValue();
} else {
return field.ty.onePossibleValue(mod);
}
src/TypedValue.zig
@@ -201,10 +201,10 @@ pub fn print(
},
.variable => return writer.writeAll("(variable)"),
.extern_func => |extern_func| return writer.print("(extern function '{s}')", .{
- mod.declPtr(extern_func.decl).name,
+ mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name),
}),
- .func => |func| return writer.print("(function '{s}')", .{
- mod.declPtr(mod.funcPtr(func.index).owner_decl).name,
+ .func => |func| return writer.print("(function '{d}')", .{
+ mod.intern_pool.stringToSlice(mod.declPtr(mod.funcPtr(func.index).owner_decl).name),
}),
.int => |int| switch (int.storage) {
inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
@@ -296,19 +296,20 @@ fn printAggregate(
}
if (ty.zigTypeTag(mod) == .Struct) {
try writer.writeAll(".{");
- const max_len = std.math.min(ty.structFieldCount(mod), max_aggregate_items);
+ const max_len = @min(ty.structFieldCount(mod), max_aggregate_items);
- var i: u32 = 0;
- while (i < max_len) : (i += 1) {
+ for (0..max_len) |i| {
if (i != 0) try writer.writeAll(", ");
- if (switch (mod.intern_pool.indexToKey(ty.toIntern())) {
- .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[i],
- .anon_struct_type => |anon_struct_type| if (anon_struct_type.isTuple())
- null
- else
- mod.intern_pool.stringToSlice(anon_struct_type.names[i]),
+
+ const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(),
+ .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(),
else => unreachable,
- }) |field_name| try writer.print(".{s} = ", .{field_name});
+ };
+
+ if (field_name.unwrap()) |name_ip| try writer.print(".{s} = ", .{
+ mod.intern_pool.stringToSlice(name_ip),
+ });
try print(.{
.ty = ty.structFieldType(i, mod),
.val = try val.fieldValue(mod, i),
src/value.zig
@@ -24,9 +24,6 @@ pub const Value = struct {
/// This union takes advantage of the fact that the first page of memory
/// is unmapped, giving us 4096 possible enum tags that have no payload.
legacy: extern union {
- /// If the tag value is less than Tag.no_payload_count, then no pointer
- /// dereference is needed.
- tag_if_small_enough: Tag,
ptr_otherwise: *Payload,
},
@@ -64,8 +61,6 @@ pub const Value = struct {
/// An instance of a union.
@"union",
- pub const no_payload_count = 0;
-
pub fn Type(comptime t: Tag) type {
return switch (t) {
.eu_payload,
@@ -96,16 +91,7 @@ pub const Value = struct {
}
};
- pub fn initTag(small_tag: Tag) Value {
- assert(@enumToInt(small_tag) < Tag.no_payload_count);
- return Value{
- .ip_index = .none,
- .legacy = .{ .tag_if_small_enough = small_tag },
- };
- }
-
pub fn initPayload(payload: *Payload) Value {
- assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
return Value{
.ip_index = .none,
.legacy = .{ .ptr_otherwise = payload },
@@ -114,11 +100,7 @@ pub const Value = struct {
pub fn tag(self: Value) Tag {
assert(self.ip_index == .none);
- if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
- return self.legacy.tag_if_small_enough;
- } else {
- return self.legacy.ptr_otherwise.tag;
- }
+ return self.legacy.ptr_otherwise.tag;
}
/// Prefer `castTag` to this.
@@ -129,12 +111,7 @@ pub const Value = struct {
if (@hasField(T, "base_tag")) {
return self.castTag(T.base_tag);
}
- if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
- return null;
- }
inline for (@typeInfo(Tag).Enum.fields) |field| {
- if (field.value < Tag.no_payload_count)
- continue;
const t = @intToEnum(Tag, field.value);
if (self.legacy.ptr_otherwise.tag == t) {
if (T == t.Type()) {
@@ -149,9 +126,6 @@ pub const Value = struct {
pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
if (self.ip_index != .none) return null;
- if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count)
- return null;
-
if (self.legacy.ptr_otherwise.tag == t)
return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
@@ -164,12 +138,7 @@ pub const Value = struct {
if (self.ip_index != .none) {
return Value{ .ip_index = self.ip_index, .legacy = undefined };
}
- if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
- return Value{
- .ip_index = .none,
- .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
- };
- } else switch (self.legacy.ptr_otherwise.tag) {
+ switch (self.legacy.ptr_otherwise.tag) {
.bytes => {
const bytes = self.castTag(.bytes).?.data;
const new_payload = try arena.create(Payload.Bytes);
@@ -312,6 +281,30 @@ pub const Value = struct {
} };
}
+ /// Asserts that the value is representable as an array of bytes.
+ /// Returns the value as a null-terminated string stored in the InternPool.
+ pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {
+ const ip = &mod.intern_pool;
+ return switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ .enum_literal => |enum_literal| enum_literal,
+ .ptr => |ptr| switch (ptr.len) {
+ .none => unreachable,
+ else => try arrayToIpString(val, ptr.len.toValue().toUnsignedInt(mod), mod),
+ },
+ .aggregate => |aggregate| switch (aggregate.storage) {
+ .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes),
+ .elems => try arrayToIpString(val, ty.arrayLen(mod), mod),
+ .repeated_elem => |elem| {
+ const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));
+ const len = @intCast(usize, ty.arrayLen(mod));
+ try ip.string_bytes.appendNTimes(mod.gpa, byte, len);
+ return ip.getOrPutTrailingString(mod.gpa, len);
+ },
+ },
+ else => unreachable,
+ };
+ }
+
/// Asserts that the value is representable as an array of bytes.
/// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
@@ -319,11 +312,11 @@ pub const Value = struct {
.enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),
.ptr => |ptr| switch (ptr.len) {
.none => unreachable,
- else => arrayToAllocatedBytes(val, ptr.len.toValue().toUnsignedInt(mod), allocator, mod),
+ else => try arrayToAllocatedBytes(val, ptr.len.toValue().toUnsignedInt(mod), allocator, mod),
},
.aggregate => |aggregate| switch (aggregate.storage) {
.bytes => |bytes| try allocator.dupe(u8, bytes),
- .elems => arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
+ .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
.repeated_elem => |elem| {
const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));
const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen(mod)));
@@ -344,6 +337,23 @@ pub const Value = struct {
return result;
}
+ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTerminatedString {
+ const gpa = mod.gpa;
+ const ip = &mod.intern_pool;
+ const len = @intCast(usize, len_u64);
+ try ip.string_bytes.ensureUnusedCapacity(gpa, len);
+ for (0..len) |i| {
+ // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
+ // assert just to be sure.
+ const prev = ip.string_bytes.items.len;
+ const elem_val = try val.elemValue(mod, i);
+ assert(ip.string_bytes.items.len == prev);
+ const byte = @intCast(u8, elem_val.toUnsignedInt(mod));
+ ip.string_bytes.appendAssumeCapacity(byte);
+ }
+ return ip.getOrPutTrailingString(gpa, len);
+ }
+
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
switch (val.tag()) {
@@ -498,7 +508,7 @@ pub const Value = struct {
// Assume it is already an integer and return it directly.
.simple_type, .int_type => val,
.enum_literal => |enum_literal| {
- const field_index = ty.enumFieldIndex(ip.stringToSlice(enum_literal), mod).?;
+ const field_index = ty.enumFieldIndex(enum_literal, mod).?;
return switch (ip.indexToKey(ty.toIntern())) {
// Assume it is already an integer and return it directly.
.simple_type, .int_type => val,
@@ -776,7 +786,7 @@ pub const Value = struct {
.error_union => |error_union| error_union.val.err_name,
else => unreachable,
};
- const int = mod.global_error_set.get(mod.intern_pool.stringToSlice(name)).?;
+ const int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);
},
.Union => switch (ty.containerLayout(mod)) {
@@ -1028,10 +1038,10 @@ pub const Value = struct {
// TODO revisit this when we have the concept of the error tag type
const Int = u16;
const int = std.mem.readInt(Int, buffer[0..@sizeOf(Int)], endian);
- const name = mod.error_name_list.items[@intCast(usize, int)];
+ const name = mod.global_error_set.keys()[@intCast(usize, int)];
return (try mod.intern(.{ .err = .{
.ty = ty.toIntern(),
- .name = mod.intern_pool.getString(name).unwrap().?,
+ .name = name,
} })).toValue();
},
.Pointer => {
@@ -2155,15 +2165,29 @@ pub const Value = struct {
/// unreachable. For error unions, prefer `errorUnionIsPayload` to find out whether
/// something is an error or not because it works without having to figure out the
/// string.
- pub fn getError(self: Value, mod: *const Module) ?[]const u8 {
- return mod.intern_pool.stringToSliceUnwrap(switch (mod.intern_pool.indexToKey(self.toIntern())) {
- .err => |err| err.name.toOptional(),
+ pub fn getError(val: Value, mod: *const Module) ?[]const u8 {
+ return switch (getErrorName(val, mod)) {
+ .empty => null,
+ else => |s| mod.intern_pool.stringToSlice(s),
+ };
+ }
+
+ pub fn getErrorName(val: Value, mod: *const Module) InternPool.NullTerminatedString {
+ return switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ .err => |err| err.name,
.error_union => |error_union| switch (error_union.val) {
- .err_name => |err_name| err_name.toOptional(),
- .payload => .none,
+ .err_name => |err_name| err_name,
+ .payload => .empty,
},
else => unreachable,
- });
+ };
+ }
+
+ pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt {
+ return switch (getErrorName(val, mod)) {
+ .empty => 0,
+ else => |s| @intCast(Module.ErrorInt, mod.global_error_set.getIndex(s).?),
+ };
}
/// Assumes the type is an error union. Returns true if and only if the value is
@@ -4225,7 +4249,7 @@ pub const Value = struct {
var fields: [tags.len]std.builtin.Type.StructField = undefined;
for (&fields, tags) |*field, t| field.* = .{
.name = t.name,
- .type = *if (t.value < Tag.no_payload_count) void else @field(Tag, t.name).Type(),
+ .type = *@field(Tag, t.name).Type(),
.default_value = null,
.is_comptime = false,
.alignment = 0,