InternPool: avoid as many slices pointing to string_bytes as possible
These are frequently invalidated whenever a string is interned, so avoid creating pointers to `string_bytes` wherever possible. This is an attempt to fix random CI failures.
This commit is contained in:
committed by
Andrew Kelley
parent
54460e39ac
commit
d37ebfcf23
@@ -156,6 +156,35 @@ pub const NullTerminatedString = enum(u32) {
|
||||
_ = ctx;
|
||||
return @enumToInt(a) < @enumToInt(b);
|
||||
}
|
||||
|
||||
pub fn toUnsigned(self: NullTerminatedString, ip: *const InternPool) ?u32 {
|
||||
const s = ip.stringToSlice(self);
|
||||
if (s.len > 1 and s[0] == '0') return null;
|
||||
if (std.mem.indexOfScalar(u8, s, '_')) |_| return null;
|
||||
return std.fmt.parseUnsigned(u32, s, 10) catch null;
|
||||
}
|
||||
|
||||
const FormatData = struct {
|
||||
string: NullTerminatedString,
|
||||
ip: *const InternPool,
|
||||
};
|
||||
fn format(
|
||||
data: FormatData,
|
||||
comptime specifier: []const u8,
|
||||
_: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
const s = data.ip.stringToSlice(data.string);
|
||||
if (comptime std.mem.eql(u8, specifier, "")) {
|
||||
try writer.writeAll(s);
|
||||
} else if (comptime std.mem.eql(u8, specifier, "i")) {
|
||||
try writer.print("{}", .{std.zig.fmtId(s)});
|
||||
} else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'");
|
||||
}
|
||||
|
||||
pub fn fmt(self: NullTerminatedString, ip: *const InternPool) std.fmt.Formatter(format) {
|
||||
return .{ .data = .{ .string = self, .ip = ip } };
|
||||
}
|
||||
};
|
||||
|
||||
/// An index into `string_bytes` which might be `none`.
|
||||
@@ -5252,10 +5281,9 @@ pub fn getOrPutString(
|
||||
gpa: Allocator,
|
||||
s: []const u8,
|
||||
) Allocator.Error!NullTerminatedString {
|
||||
const string_bytes = &ip.string_bytes;
|
||||
try string_bytes.ensureUnusedCapacity(gpa, s.len + 1);
|
||||
string_bytes.appendSliceAssumeCapacity(s);
|
||||
string_bytes.appendAssumeCapacity(0);
|
||||
try ip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1);
|
||||
ip.string_bytes.appendSliceAssumeCapacity(s);
|
||||
ip.string_bytes.appendAssumeCapacity(0);
|
||||
return ip.getOrPutTrailingString(gpa, s.len + 1);
|
||||
}
|
||||
|
||||
@@ -5265,10 +5293,12 @@ pub fn getOrPutStringFmt(
|
||||
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);
|
||||
// ensure that references to string_bytes in args do not get invalidated
|
||||
const len = std.fmt.count(format, args) + 1;
|
||||
try ip.string_bytes.ensureUnusedCapacity(gpa, len);
|
||||
ip.string_bytes.writer(undefined).print(format, args) catch unreachable;
|
||||
ip.string_bytes.appendAssumeCapacity(0);
|
||||
return ip.getOrPutTrailingString(gpa, len);
|
||||
}
|
||||
|
||||
pub fn getOrPutStringOpt(
|
||||
|
||||
122
src/Module.zig
122
src/Module.zig
@@ -270,11 +270,7 @@ pub const GlobalEmitH = struct {
|
||||
pub const ErrorInt = u32;
|
||||
|
||||
pub const Export = struct {
|
||||
name: InternPool.NullTerminatedString,
|
||||
linkage: std.builtin.GlobalLinkage,
|
||||
section: InternPool.OptionalNullTerminatedString,
|
||||
visibility: std.builtin.SymbolVisibility,
|
||||
|
||||
opts: Options,
|
||||
src: LazySrcLoc,
|
||||
/// The Decl that performs the export. Note that this is *not* the Decl being exported.
|
||||
owner_decl: Decl.Index,
|
||||
@@ -292,6 +288,13 @@ pub const Export = struct {
|
||||
complete,
|
||||
},
|
||||
|
||||
pub const Options = struct {
|
||||
name: InternPool.NullTerminatedString,
|
||||
linkage: std.builtin.GlobalLinkage = .Strong,
|
||||
section: InternPool.OptionalNullTerminatedString = .none,
|
||||
visibility: std.builtin.SymbolVisibility = .default,
|
||||
};
|
||||
|
||||
pub fn getSrcLoc(exp: Export, mod: *Module) SrcLoc {
|
||||
const src_decl = mod.declPtr(exp.src_decl);
|
||||
return .{
|
||||
@@ -691,16 +694,15 @@ pub const Decl = struct {
|
||||
}
|
||||
|
||||
pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
|
||||
const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
|
||||
if (decl.name_fully_qualified) {
|
||||
return writer.writeAll(unqualified_name);
|
||||
try writer.print("{}", .{decl.name.fmt(&mod.intern_pool)});
|
||||
} else {
|
||||
try mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, decl.name, writer);
|
||||
}
|
||||
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, unqualified_name, writer);
|
||||
}
|
||||
|
||||
pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
|
||||
const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
|
||||
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);
|
||||
return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, decl.name, writer);
|
||||
}
|
||||
|
||||
pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {
|
||||
@@ -712,8 +714,7 @@ pub const Decl = struct {
|
||||
var ns: Namespace.Index = decl.src_namespace;
|
||||
while (true) {
|
||||
const namespace = mod.namespacePtr(ns);
|
||||
const ns_decl_index = namespace.getDeclIndex(mod);
|
||||
const ns_decl = mod.declPtr(ns_decl_index);
|
||||
const ns_decl = mod.declPtr(namespace.getDeclIndex(mod));
|
||||
count += ip.stringToSlice(ns_decl.name).len + 1;
|
||||
ns = namespace.parent.unwrap() orelse {
|
||||
count += namespace.file_scope.sub_file_path.len;
|
||||
@@ -1722,44 +1723,34 @@ pub const Namespace = struct {
|
||||
pub fn renderFullyQualifiedName(
|
||||
ns: Namespace,
|
||||
mod: *Module,
|
||||
name: []const u8,
|
||||
name: InternPool.NullTerminatedString,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
if (ns.parent.unwrap()) |parent| {
|
||||
const decl_index = ns.getDeclIndex(mod);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = mod.intern_pool.stringToSlice(decl.name);
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl_name, writer);
|
||||
const decl = mod.declPtr(ns.getDeclIndex(mod));
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl.name, writer);
|
||||
} else {
|
||||
try ns.file_scope.renderFullyQualifiedName(writer);
|
||||
}
|
||||
if (name.len != 0) {
|
||||
try writer.writeAll(".");
|
||||
try writer.writeAll(name);
|
||||
}
|
||||
if (name != .empty) try writer.print(".{}", .{name.fmt(&mod.intern_pool)});
|
||||
}
|
||||
|
||||
/// This renders e.g. "std/fs.zig:Dir.OpenOptions"
|
||||
pub fn renderFullyQualifiedDebugName(
|
||||
ns: Namespace,
|
||||
mod: *Module,
|
||||
name: []const u8,
|
||||
name: InternPool.NullTerminatedString,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
var separator_char: u8 = '.';
|
||||
if (ns.parent.unwrap()) |parent| {
|
||||
const decl_index = ns.getDeclIndex(mod);
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = mod.intern_pool.stringToSlice(decl.name);
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl_name, writer);
|
||||
} else {
|
||||
const separator_char: u8 = if (ns.parent.unwrap()) |parent| sep: {
|
||||
const decl = mod.declPtr(ns.getDeclIndex(mod));
|
||||
try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl.name, writer);
|
||||
break :sep '.';
|
||||
} else sep: {
|
||||
try ns.file_scope.renderFullyQualifiedDebugName(writer);
|
||||
separator_char = ':';
|
||||
}
|
||||
if (name.len != 0) {
|
||||
try writer.writeByte(separator_char);
|
||||
try writer.writeAll(name);
|
||||
}
|
||||
break :sep ':';
|
||||
};
|
||||
if (name != .empty) try writer.print("{c}{}", .{ separator_char, name.fmt(&mod.intern_pool) });
|
||||
}
|
||||
|
||||
pub fn getDeclIndex(ns: Namespace, mod: *Module) Decl.Index {
|
||||
@@ -4185,10 +4176,10 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void
|
||||
defer liveness.deinit(gpa);
|
||||
|
||||
if (dump_air) {
|
||||
const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
|
||||
std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});
|
||||
const fqn = try decl.getFullyQualifiedName(mod);
|
||||
std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(&mod.intern_pool)});
|
||||
@import("print_air.zig").dump(mod, air, liveness);
|
||||
std.debug.print("# End Function AIR: {s}\n\n", .{fqn});
|
||||
std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(&mod.intern_pool)});
|
||||
}
|
||||
|
||||
if (std.debug.runtime_safety) {
|
||||
@@ -4620,10 +4611,7 @@ 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 = mod.intern_pool.stringToSlice(decl.name),
|
||||
};
|
||||
try sema.analyzeExport(&block_scope, export_src, options, decl_index);
|
||||
try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
|
||||
}
|
||||
return type_changed or is_inline != prev_is_inline;
|
||||
}
|
||||
@@ -4720,10 +4708,7 @@ 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 = mod.intern_pool.stringToSlice(decl.name),
|
||||
};
|
||||
try sema.analyzeExport(&block_scope, export_src, options, decl_index);
|
||||
try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
|
||||
}
|
||||
|
||||
return type_changed;
|
||||
@@ -5222,12 +5207,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
.parent_decl_node = decl.src_node,
|
||||
.lazy = .{ .token_offset = 1 },
|
||||
};
|
||||
const msg = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"duplicate test name: {s}",
|
||||
.{ip.stringToSlice(decl_name)},
|
||||
);
|
||||
const msg = try ErrorMsg.create(gpa, src_loc, "duplicate test name: {}", .{
|
||||
decl_name.fmt(&mod.intern_pool),
|
||||
});
|
||||
errdefer msg.destroy(gpa);
|
||||
try mod.failed_decls.putNoClobber(gpa, decl_index, msg);
|
||||
const other_src_loc = SrcLoc{
|
||||
@@ -5417,16 +5399,16 @@ 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.name);
|
||||
elf.deleteDeclExport(decl_index, exp.opts.name);
|
||||
}
|
||||
if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {
|
||||
try macho.deleteDeclExport(decl_index, exp.name);
|
||||
try macho.deleteDeclExport(decl_index, exp.opts.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.name);
|
||||
coff.deleteDeclExport(decl_index, exp.opts.name);
|
||||
}
|
||||
if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
|
||||
failed_kv.value.destroy(mod.gpa);
|
||||
@@ -5810,12 +5792,9 @@ 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 ip = &mod.intern_pool;
|
||||
// This protects the getOrPutStringFmt from reallocating src decl name while reading it.
|
||||
try ip.string_bytes.ensureUnusedCapacity(mod.gpa, ip.stringToSlice(src_decl.name).len + 20);
|
||||
const name = ip.getOrPutStringFmt(mod.gpa, "{s}__anon_{d}", .{
|
||||
ip.stringToSlice(src_decl.name), @enumToInt(new_decl_index),
|
||||
}) catch unreachable;
|
||||
const name = try mod.intern_pool.getOrPutStringFmt(mod.gpa, "{}__anon_{d}", .{
|
||||
src_decl.name.fmt(&mod.intern_pool), @enumToInt(new_decl_index),
|
||||
});
|
||||
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);
|
||||
return new_decl_index;
|
||||
}
|
||||
@@ -6301,13 +6280,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.name);
|
||||
const gop = try symbol_exports.getOrPut(gpa, new_export.opts.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}", .{
|
||||
mod.intern_pool.stringToSlice(new_export.name),
|
||||
const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {}", .{
|
||||
new_export.opts.name.fmt(&mod.intern_pool),
|
||||
});
|
||||
errdefer msg.destroy(gpa);
|
||||
const other_export = gop.value_ptr.*;
|
||||
@@ -6752,18 +6731,9 @@ pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Alloca
|
||||
} })).toType();
|
||||
}
|
||||
|
||||
pub fn singleErrorSetType(mod: *Module, name: []const u8) Allocator.Error!Type {
|
||||
const gpa = mod.gpa;
|
||||
const ip = &mod.intern_pool;
|
||||
return singleErrorSetTypeNts(mod, try ip.getOrPutString(gpa, name));
|
||||
}
|
||||
|
||||
pub fn singleErrorSetTypeNts(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type {
|
||||
const gpa = mod.gpa;
|
||||
const ip = &mod.intern_pool;
|
||||
const names = [1]InternPool.NullTerminatedString{name};
|
||||
const i = try ip.get(gpa, .{ .error_set_type = .{ .names = &names } });
|
||||
return i.toType();
|
||||
pub fn singleErrorSetType(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type {
|
||||
const names: *const [1]InternPool.NullTerminatedString = &name;
|
||||
return (try mod.intern_pool.get(mod.gpa, .{ .error_set_type = .{ .names = names } })).toType();
|
||||
}
|
||||
|
||||
/// Sorts `names` in place.
|
||||
|
||||
802
src/Sema.zig
802
src/Sema.zig
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,7 @@ pub fn print(
|
||||
) (@TypeOf(writer).Error || Allocator.Error)!void {
|
||||
var val = tv.val;
|
||||
var ty = tv.ty;
|
||||
const ip = &mod.intern_pool;
|
||||
while (true) switch (val.ip_index) {
|
||||
.none => switch (val.tag()) {
|
||||
.aggregate => return printAggregate(ty, val, writer, level, mod),
|
||||
@@ -87,7 +88,7 @@ pub fn print(
|
||||
try writer.writeAll(".{ ");
|
||||
|
||||
try print(.{
|
||||
.ty = mod.unionPtr(mod.intern_pool.indexToKey(ty.toIntern()).union_type.index).tag_ty,
|
||||
.ty = mod.unionPtr(ip.indexToKey(ty.toIntern()).union_type.index).tag_ty,
|
||||
.val = union_val.tag,
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(" = ");
|
||||
@@ -174,7 +175,7 @@ pub fn print(
|
||||
ty = ty.optionalChild(mod);
|
||||
},
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
else => switch (ip.indexToKey(val.toIntern())) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
@@ -200,11 +201,11 @@ pub fn print(
|
||||
else => return writer.writeAll(@tagName(simple_value)),
|
||||
},
|
||||
.variable => return writer.writeAll("(variable)"),
|
||||
.extern_func => |extern_func| return writer.print("(extern function '{s}')", .{
|
||||
mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name),
|
||||
.extern_func => |extern_func| return writer.print("(extern function '{}')", .{
|
||||
mod.declPtr(extern_func.decl).name.fmt(ip),
|
||||
}),
|
||||
.func => |func| return writer.print("(function '{s}')", .{
|
||||
mod.intern_pool.stringToSlice(mod.declPtr(mod.funcPtr(func.index).owner_decl).name),
|
||||
.func => |func| return writer.print("(function '{}')", .{
|
||||
mod.declPtr(mod.funcPtr(func.index).owner_decl).name.fmt(ip),
|
||||
}),
|
||||
.int => |int| switch (int.storage) {
|
||||
inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
|
||||
@@ -215,29 +216,28 @@ pub fn print(
|
||||
lazy_ty.toType().abiSize(mod),
|
||||
}),
|
||||
},
|
||||
.err => |err| return writer.print("error.{s}", .{
|
||||
mod.intern_pool.stringToSlice(err.name),
|
||||
.err => |err| return writer.print("error.{}", .{
|
||||
err.name.fmt(ip),
|
||||
}),
|
||||
.error_union => |error_union| switch (error_union.val) {
|
||||
.err_name => |err_name| return writer.print("error.{s}", .{
|
||||
mod.intern_pool.stringToSlice(err_name),
|
||||
.err_name => |err_name| return writer.print("error.{}", .{
|
||||
err_name.fmt(ip),
|
||||
}),
|
||||
.payload => |payload| {
|
||||
val = payload.toValue();
|
||||
ty = ty.errorUnionPayload(mod);
|
||||
},
|
||||
},
|
||||
.enum_literal => |enum_literal| return writer.print(".{s}", .{
|
||||
mod.intern_pool.stringToSlice(enum_literal),
|
||||
.enum_literal => |enum_literal| return writer.print(".{}", .{
|
||||
enum_literal.fmt(ip),
|
||||
}),
|
||||
.enum_tag => |enum_tag| {
|
||||
if (level == 0) {
|
||||
return writer.writeAll("(enum)");
|
||||
}
|
||||
const enum_type = mod.intern_pool.indexToKey(ty.toIntern()).enum_type;
|
||||
if (enum_type.tagValueIndex(&mod.intern_pool, val.toIntern())) |tag_index| {
|
||||
const tag_name = mod.intern_pool.stringToSlice(enum_type.names[tag_index]);
|
||||
try writer.print(".{}", .{std.zig.fmtId(tag_name)});
|
||||
const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
|
||||
if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
|
||||
try writer.print(".{i}", .{enum_type.names[tag_index].fmt(ip)});
|
||||
return;
|
||||
}
|
||||
try writer.writeAll("@intToEnum(");
|
||||
@@ -247,7 +247,7 @@ pub fn print(
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(", ");
|
||||
try print(.{
|
||||
.ty = mod.intern_pool.typeOf(enum_tag.int).toType(),
|
||||
.ty = ip.typeOf(enum_tag.int).toType(),
|
||||
.val = enum_tag.int.toValue(),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
@@ -259,13 +259,13 @@ pub fn print(
|
||||
},
|
||||
.ptr => |ptr| {
|
||||
if (ptr.addr == .int) {
|
||||
const i = mod.intern_pool.indexToKey(ptr.addr.int).int;
|
||||
const i = ip.indexToKey(ptr.addr.int).int;
|
||||
switch (i.storage) {
|
||||
inline else => |addr| return writer.print("{x:0>8}", .{addr}),
|
||||
}
|
||||
}
|
||||
|
||||
const ptr_ty = mod.intern_pool.indexToKey(ty.toIntern()).ptr_type;
|
||||
const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type;
|
||||
if (ptr_ty.flags.size == .Slice) {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
@@ -301,7 +301,7 @@ pub fn print(
|
||||
switch (ptr.addr) {
|
||||
.decl => |decl_index| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (level == 0) return writer.print("(decl '{s}')", .{mod.intern_pool.stringToSlice(decl.name)});
|
||||
if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)});
|
||||
return print(.{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
@@ -309,7 +309,7 @@ pub fn print(
|
||||
},
|
||||
.mut_decl => |mut_decl| {
|
||||
const decl = mod.declPtr(mut_decl.decl);
|
||||
if (level == 0) return writer.print("(mut decl '{s}')", .{mod.intern_pool.stringToSlice(decl.name)});
|
||||
if (level == 0) return writer.print("(mut decl '{}')", .{decl.name.fmt(ip)});
|
||||
return print(.{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
@@ -317,7 +317,7 @@ pub fn print(
|
||||
},
|
||||
.comptime_field => |field_val_ip| {
|
||||
return print(.{
|
||||
.ty = mod.intern_pool.typeOf(field_val_ip).toType(),
|
||||
.ty = ip.typeOf(field_val_ip).toType(),
|
||||
.val = field_val_ip.toValue(),
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
@@ -325,27 +325,27 @@ pub fn print(
|
||||
.eu_payload => |eu_ip| {
|
||||
try writer.writeAll("(payload of ");
|
||||
try print(.{
|
||||
.ty = mod.intern_pool.typeOf(eu_ip).toType(),
|
||||
.ty = ip.typeOf(eu_ip).toType(),
|
||||
.val = eu_ip.toValue(),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
},
|
||||
.opt_payload => |opt_ip| {
|
||||
try print(.{
|
||||
.ty = mod.intern_pool.typeOf(opt_ip).toType(),
|
||||
.ty = ip.typeOf(opt_ip).toType(),
|
||||
.val = opt_ip.toValue(),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(".?");
|
||||
},
|
||||
.elem => |elem| {
|
||||
try print(.{
|
||||
.ty = mod.intern_pool.typeOf(elem.base).toType(),
|
||||
.ty = ip.typeOf(elem.base).toType(),
|
||||
.val = elem.base.toValue(),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.print("[{}]", .{elem.index});
|
||||
},
|
||||
.field => |field| {
|
||||
const container_ty = mod.intern_pool.typeOf(field.base).toType();
|
||||
const container_ty = ip.typeOf(field.base).toType();
|
||||
try print(.{
|
||||
.ty = container_ty,
|
||||
.val = field.base.toValue(),
|
||||
@@ -356,14 +356,12 @@ pub fn print(
|
||||
if (container_ty.isTuple(mod)) {
|
||||
try writer.print("[{d}]", .{field.index});
|
||||
}
|
||||
const field_name_ip = container_ty.structFieldName(@intCast(usize, field.index), mod);
|
||||
const field_name = mod.intern_pool.stringToSlice(field_name_ip);
|
||||
try writer.print(".{}", .{std.zig.fmtId(field_name)});
|
||||
const field_name = container_ty.structFieldName(@intCast(usize, field.index), mod);
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
},
|
||||
.Union => {
|
||||
const field_name_ip = container_ty.unionFields(mod).keys()[@intCast(usize, field.index)];
|
||||
const field_name = mod.intern_pool.stringToSlice(field_name_ip);
|
||||
try writer.print(".{}", .{std.zig.fmtId(field_name)});
|
||||
const field_name = container_ty.unionFields(mod).keys()[@intCast(usize, field.index)];
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
},
|
||||
.Pointer => {
|
||||
std.debug.assert(container_ty.isSlice(mod));
|
||||
@@ -440,9 +438,7 @@ fn printAggregate(
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
if (field_name.unwrap()) |name_ip| try writer.print(".{s} = ", .{
|
||||
mod.intern_pool.stringToSlice(name_ip),
|
||||
});
|
||||
if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(&mod.intern_pool)});
|
||||
try print(.{
|
||||
.ty = ty.structFieldType(i, mod),
|
||||
.val = try val.fieldValue(mod, i),
|
||||
|
||||
@@ -1850,9 +1850,9 @@ pub const DeclGen = struct {
|
||||
try mod.markDeclAlive(decl);
|
||||
|
||||
if (mod.decl_exports.get(decl_index)) |exports| {
|
||||
try writer.writeAll(mod.intern_pool.stringToSlice(exports.items[export_index].name));
|
||||
try writer.print("{}", .{exports.items[export_index].opts.name.fmt(&mod.intern_pool)});
|
||||
} else if (decl.isExtern(mod)) {
|
||||
try writer.writeAll(mod.intern_pool.stringToSlice(decl.name));
|
||||
try writer.print("{}", .{decl.name.fmt(&mod.intern_pool)});
|
||||
} 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.
|
||||
@@ -2481,8 +2481,8 @@ fn genExports(o: *Object) !void {
|
||||
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(ip.stringToSlice(exports.items[0].name), null),
|
||||
fmtStringLiteral(ip.stringToSlice(@"export".name), null),
|
||||
fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
|
||||
fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,11 +687,9 @@ pub const Object = struct {
|
||||
for (export_list.items) |exp| {
|
||||
// Detect if the LLVM global has already been created as an extern. In such
|
||||
// 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 = mod.intern_pool.stringToSlice(exp.name);
|
||||
const exp_name = mod.intern_pool.stringToSlice(exp.opts.name);
|
||||
|
||||
const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
|
||||
const other_global = object.getLlvmGlobal(exp_name.ptr) orelse continue;
|
||||
if (other_global == llvm_global) continue;
|
||||
|
||||
other_global.replaceAllUsesWith(llvm_global);
|
||||
@@ -1320,7 +1318,7 @@ pub const Object = struct {
|
||||
}
|
||||
}
|
||||
} else if (exports.len != 0) {
|
||||
const exp_name = mod.intern_pool.stringToSlice(exports[0].name);
|
||||
const exp_name = mod.intern_pool.stringToSlice(exports[0].opts.name);
|
||||
llvm_global.setValueName2(exp_name.ptr, exp_name.len);
|
||||
llvm_global.setUnnamedAddr(.False);
|
||||
if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
|
||||
@@ -1335,18 +1333,18 @@ pub const Object = struct {
|
||||
di_global.replaceLinkageName(linkage_name);
|
||||
}
|
||||
}
|
||||
switch (exports[0].linkage) {
|
||||
switch (exports[0].opts.linkage) {
|
||||
.Internal => unreachable,
|
||||
.Strong => llvm_global.setLinkage(.External),
|
||||
.Weak => llvm_global.setLinkage(.WeakODR),
|
||||
.LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
|
||||
}
|
||||
switch (exports[0].visibility) {
|
||||
switch (exports[0].opts.visibility) {
|
||||
.default => llvm_global.setVisibility(.Default),
|
||||
.hidden => llvm_global.setVisibility(.Hidden),
|
||||
.protected => llvm_global.setVisibility(.Protected),
|
||||
}
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exports[0].section)) |section| {
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exports[0].opts.section)) |section| {
|
||||
llvm_global.setSection(section);
|
||||
}
|
||||
if (decl.val.getVariable(mod)) |variable| {
|
||||
@@ -1362,7 +1360,7 @@ pub const Object = struct {
|
||||
// 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 = mod.intern_pool.stringToSlice(exp.name);
|
||||
const exp_name_z = mod.intern_pool.stringToSlice(exp.opts.name);
|
||||
|
||||
if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
|
||||
alias.setAliasee(llvm_global);
|
||||
@@ -2539,10 +2537,10 @@ pub const DeclGen = struct {
|
||||
|
||||
const fn_type = try dg.lowerType(zig_fn_type);
|
||||
|
||||
const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
|
||||
const fqn = try decl.getFullyQualifiedName(mod);
|
||||
|
||||
const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
|
||||
const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace);
|
||||
const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace);
|
||||
gop.value_ptr.* = llvm_fn;
|
||||
|
||||
const is_extern = decl.isExtern(mod);
|
||||
@@ -2693,7 +2691,7 @@ pub const DeclGen = struct {
|
||||
|
||||
const mod = dg.module;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
|
||||
const fqn = try decl.getFullyQualifiedName(mod);
|
||||
|
||||
const target = mod.getTarget();
|
||||
|
||||
@@ -2702,7 +2700,7 @@ pub const DeclGen = struct {
|
||||
|
||||
const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace(
|
||||
llvm_type,
|
||||
fqn,
|
||||
mod.intern_pool.stringToSlice(fqn),
|
||||
llvm_actual_addrspace,
|
||||
);
|
||||
gop.value_ptr.* = llvm_global;
|
||||
@@ -5942,6 +5940,8 @@ pub const FuncGen = struct {
|
||||
.base_line = self.base_line,
|
||||
});
|
||||
|
||||
const fqn = try decl.getFullyQualifiedName(mod);
|
||||
|
||||
const is_internal_linkage = !mod.decl_exports.contains(decl_index);
|
||||
const fn_ty = try mod.funcType(.{
|
||||
.param_types = &.{},
|
||||
@@ -5959,11 +5959,10 @@ pub const FuncGen = struct {
|
||||
.addrspace_is_generic = false,
|
||||
});
|
||||
const fn_di_ty = try self.dg.object.lowerDebugType(fn_ty, .full);
|
||||
const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
|
||||
const subprogram = dib.createFunction(
|
||||
di_file.toScope(),
|
||||
mod.intern_pool.stringToSlice(decl.name),
|
||||
fqn,
|
||||
mod.intern_pool.stringToSlice(fqn),
|
||||
di_file,
|
||||
line_number,
|
||||
fn_di_ty,
|
||||
@@ -8661,8 +8660,8 @@ pub const FuncGen = struct {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
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 fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
|
||||
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)});
|
||||
|
||||
const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
|
||||
|
||||
@@ -8733,8 +8732,8 @@ pub const FuncGen = struct {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
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 fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
|
||||
const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
|
||||
|
||||
const slice_ty = Type.slice_const_u8_sentinel_0;
|
||||
const llvm_ret_ty = try self.dg.lowerType(slice_ty);
|
||||
|
||||
@@ -294,7 +294,7 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
|
||||
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".name, {});
|
||||
try export_names.put(gpa, @"export".opts.name, {});
|
||||
|
||||
while (f.remaining_decls.popOrNull()) |kv| {
|
||||
const decl_index = kv.key;
|
||||
|
||||
@@ -1430,20 +1430,20 @@ pub fn updateDeclExports(
|
||||
else => std.builtin.CallingConvention.C,
|
||||
};
|
||||
const decl_cc = exported_decl.ty.fnCallingConvention(mod);
|
||||
if (decl_cc == .C and ip.stringEqlSlice(exp.name, "main") and
|
||||
if (decl_cc == .C and ip.stringEqlSlice(exp.opts.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 (ip.stringEqlSlice(exp.name, "WinMain")) {
|
||||
if (ip.stringEqlSlice(exp.opts.name, "WinMain")) {
|
||||
mod.stage1_flags.have_winmain = true;
|
||||
} else if (ip.stringEqlSlice(exp.name, "wWinMain")) {
|
||||
} else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) {
|
||||
mod.stage1_flags.have_wwinmain = true;
|
||||
} else if (ip.stringEqlSlice(exp.name, "WinMainCRTStartup")) {
|
||||
} else if (ip.stringEqlSlice(exp.opts.name, "WinMainCRTStartup")) {
|
||||
mod.stage1_flags.have_winmain_crt_startup = true;
|
||||
} else if (ip.stringEqlSlice(exp.name, "wWinMainCRTStartup")) {
|
||||
} else if (ip.stringEqlSlice(exp.opts.name, "wWinMainCRTStartup")) {
|
||||
mod.stage1_flags.have_wwinmain_crt_startup = true;
|
||||
} else if (ip.stringEqlSlice(exp.name, "DllMainCRTStartup")) {
|
||||
} else if (ip.stringEqlSlice(exp.opts.name, "DllMainCRTStartup")) {
|
||||
mod.stage1_flags.have_dllmain_crt_startup = true;
|
||||
}
|
||||
}
|
||||
@@ -1461,10 +1461,9 @@ pub fn updateDeclExports(
|
||||
const decl_metadata = self.decls.getPtr(decl_index).?;
|
||||
|
||||
for (exports) |exp| {
|
||||
const exp_name = mod.intern_pool.stringToSlice(exp.name);
|
||||
log.debug("adding new export '{s}'", .{exp_name});
|
||||
log.debug("adding new export '{}'", .{exp.opts.name.fmt(&mod.intern_pool)});
|
||||
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text")) {
|
||||
try mod.failed_exports.putNoClobber(
|
||||
gpa,
|
||||
@@ -1480,7 +1479,7 @@ pub fn updateDeclExports(
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.linkage == .LinkOnce) {
|
||||
if (exp.opts.linkage == .LinkOnce) {
|
||||
try mod.failed_exports.putNoClobber(
|
||||
gpa,
|
||||
exp,
|
||||
@@ -1494,19 +1493,19 @@ pub fn updateDeclExports(
|
||||
continue;
|
||||
}
|
||||
|
||||
const sym_index = decl_metadata.getExport(self, exp_name) orelse blk: {
|
||||
const sym_index = decl_metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.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_name);
|
||||
try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.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.linkage) {
|
||||
switch (exp.opts.linkage) {
|
||||
.Strong => {
|
||||
sym.storage_class = .EXTERNAL;
|
||||
},
|
||||
|
||||
@@ -2879,9 +2879,9 @@ pub fn updateDeclExports(
|
||||
try self.global_symbols.ensureUnusedCapacity(gpa, exports.len);
|
||||
|
||||
for (exports) |exp| {
|
||||
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")) {
|
||||
const exp_name = mod.intern_pool.stringToSlice(exp.opts.name);
|
||||
if (exp.opts.section.unwrap()) |section_name| {
|
||||
if (!mod.intern_pool.stringEqlSlice(section_name, ".text")) {
|
||||
try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
|
||||
mod.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
@@ -2890,7 +2890,7 @@ pub fn updateDeclExports(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const stb_bits: u8 = switch (exp.linkage) {
|
||||
const stb_bits: u8 = switch (exp.opts.linkage) {
|
||||
.Internal => elf.STB_LOCAL,
|
||||
.Strong => blk: {
|
||||
const entry_name = self.base.options.entry orelse "_start";
|
||||
|
||||
@@ -2401,15 +2401,15 @@ pub fn updateDeclExports(
|
||||
const decl_metadata = self.decls.getPtr(decl_index).?;
|
||||
|
||||
for (exports) |exp| {
|
||||
const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{
|
||||
mod.intern_pool.stringToSlice(exp.name),
|
||||
const exp_name = try std.fmt.allocPrint(gpa, "_{}", .{
|
||||
exp.opts.name.fmt(&mod.intern_pool),
|
||||
});
|
||||
defer gpa.free(exp_name);
|
||||
|
||||
log.debug("adding new export '{s}'", .{exp_name});
|
||||
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
|
||||
if (!mem.eql(u8, section_name, "__text")) {
|
||||
if (exp.opts.section.unwrap()) |section_name| {
|
||||
if (!mod.intern_pool.stringEqlSlice(section_name, "__text")) {
|
||||
try mod.failed_exports.putNoClobber(
|
||||
mod.gpa,
|
||||
exp,
|
||||
@@ -2424,7 +2424,7 @@ pub fn updateDeclExports(
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.linkage == .LinkOnce) {
|
||||
if (exp.opts.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.linkage) {
|
||||
switch (exp.opts.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.
|
||||
|
||||
@@ -725,10 +725,10 @@ fn addDeclExports(
|
||||
const decl_block = self.getDeclBlock(metadata.index);
|
||||
|
||||
for (exports) |exp| {
|
||||
const exp_name = mod.intern_pool.stringToSlice(exp.name);
|
||||
const exp_name = mod.intern_pool.stringToSlice(exp.opts.name);
|
||||
// plan9 does not support custom sections
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {
|
||||
if (exp.opts.section.unwrap()) |section_name| {
|
||||
if (!mod.intern_pool.stringEqlSlice(section_name, ".text") and !mod.intern_pool.stringEqlSlice(section_name, ".data")) {
|
||||
try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
|
||||
self.base.allocator,
|
||||
mod.declPtr(decl_index).srcLoc(mod),
|
||||
@@ -972,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, ip.stringToSlice(e.name))) |exp_i| {
|
||||
for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| {
|
||||
try self.writeSym(writer, self.syms.items[exp_i]);
|
||||
};
|
||||
}
|
||||
@@ -998,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, ip.stringToSlice(e.name))) |exp_i| {
|
||||
for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| {
|
||||
const s = self.syms.items[exp_i];
|
||||
if (mem.eql(u8, s.name, "_start"))
|
||||
self.entry_val = s.value;
|
||||
|
||||
@@ -147,7 +147,7 @@ pub fn updateDeclExports(
|
||||
const spv_decl_index = entry.value_ptr.*;
|
||||
|
||||
for (exports) |exp| {
|
||||
try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.name));
|
||||
try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.opts.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1706,7 +1706,7 @@ pub fn updateDeclExports(
|
||||
const gpa = mod.gpa;
|
||||
|
||||
for (exports) |exp| {
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section| {
|
||||
if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section| {
|
||||
try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(mod),
|
||||
@@ -1716,12 +1716,12 @@ pub fn updateDeclExports(
|
||||
continue;
|
||||
}
|
||||
|
||||
const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.name));
|
||||
const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.opts.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.linkage == .Internal or exp.linkage == .Weak;
|
||||
const exp_is_weak = exp.opts.linkage == .Internal or exp.opts.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.
|
||||
@@ -1729,11 +1729,11 @@ pub fn updateDeclExports(
|
||||
try mod.failed_exports.put(gpa, exp, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(mod),
|
||||
\\LinkError: symbol '{s}' defined multiple times
|
||||
\\LinkError: symbol '{}' defined multiple times
|
||||
\\ first definition in '{s}'
|
||||
\\ next definition in '{s}'
|
||||
,
|
||||
.{ mod.intern_pool.stringToSlice(exp.name), wasm.name, wasm.name },
|
||||
.{ exp.opts.name.fmt(&mod.intern_pool), wasm.name, wasm.name },
|
||||
));
|
||||
continue;
|
||||
} else if (exp_is_weak) {
|
||||
@@ -1750,7 +1750,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.linkage) {
|
||||
switch (exp.opts.linkage) {
|
||||
.Internal => {
|
||||
symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
|
||||
},
|
||||
@@ -1769,7 +1769,7 @@ pub fn updateDeclExports(
|
||||
},
|
||||
}
|
||||
// Ensure the symbol will be exported using the given name
|
||||
if (!mod.intern_pool.stringEqlSlice(exp.name, sym_loc.getName(wasm))) {
|
||||
if (!mod.intern_pool.stringEqlSlice(exp.opts.name, sym_loc.getName(wasm))) {
|
||||
try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -685,9 +685,8 @@ 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}", .{ip.stringToSlice(owner_decl.name)});
|
||||
try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)});
|
||||
}
|
||||
|
||||
fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
|
||||
@@ -284,7 +284,7 @@ pub const Type = struct {
|
||||
try writer.writeAll("error{");
|
||||
for (names, 0..) |name, i| {
|
||||
if (i != 0) try writer.writeByte(',');
|
||||
try writer.writeAll(mod.intern_pool.stringToSlice(name));
|
||||
try writer.print("{}", .{name.fmt(&mod.intern_pool)});
|
||||
}
|
||||
try writer.writeAll("}");
|
||||
},
|
||||
@@ -341,7 +341,7 @@ pub const Type = struct {
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
} else if (struct_type.namespace.unwrap()) |namespace_index| {
|
||||
const namespace = mod.namespacePtr(namespace_index);
|
||||
try namespace.renderFullyQualifiedName(mod, "", writer);
|
||||
try namespace.renderFullyQualifiedName(mod, .empty, writer);
|
||||
} else {
|
||||
try writer.writeAll("@TypeOf(.{})");
|
||||
}
|
||||
@@ -357,9 +357,7 @@ pub const Type = struct {
|
||||
try writer.writeAll("comptime ");
|
||||
}
|
||||
if (anon_struct.names.len != 0) {
|
||||
const name = mod.intern_pool.stringToSlice(anon_struct.names[i]);
|
||||
try writer.writeAll(name);
|
||||
try writer.writeAll(": ");
|
||||
try writer.print("{}: ", .{anon_struct.names[i].fmt(&mod.intern_pool)});
|
||||
}
|
||||
|
||||
try print(field_ty.toType(), writer, mod);
|
||||
|
||||
@@ -525,23 +525,6 @@ pub const Value = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn tagName(val: Value, mod: *Module) []const u8 {
|
||||
const ip = &mod.intern_pool;
|
||||
const enum_tag = switch (ip.indexToKey(val.toIntern())) {
|
||||
.un => |un| ip.indexToKey(un.tag).enum_tag,
|
||||
.enum_tag => |x| x,
|
||||
.enum_literal => |name| return ip.stringToSlice(name),
|
||||
else => unreachable,
|
||||
};
|
||||
const enum_type = ip.indexToKey(enum_tag.ty).enum_type;
|
||||
const field_index = field_index: {
|
||||
const field_index = enum_type.tagValueIndex(ip, val.toIntern()).?;
|
||||
break :field_index @intCast(u32, field_index);
|
||||
};
|
||||
const field_name = enum_type.names[field_index];
|
||||
return ip.stringToSlice(field_name);
|
||||
}
|
||||
|
||||
/// Asserts the value is an integer.
|
||||
pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {
|
||||
return val.toBigIntAdvanced(space, mod, null) catch unreachable;
|
||||
@@ -2092,33 +2075,23 @@ pub const Value = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Valid only for error (union) types. Asserts the value is not undefined and not
|
||||
/// 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(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 {
|
||||
/// Valid only for error (union) types. Asserts the value is not undefined and not unreachable.
|
||||
pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTerminatedString {
|
||||
return switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.err => |err| err.name,
|
||||
.err => |err| err.name.toOptional(),
|
||||
.error_union => |error_union| switch (error_union.val) {
|
||||
.err_name => |err_name| err_name,
|
||||
.payload => .empty,
|
||||
.err_name => |err_name| err_name.toOptional(),
|
||||
.payload => .none,
|
||||
},
|
||||
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).?),
|
||||
};
|
||||
return if (getErrorName(val, mod).unwrap()) |err_name|
|
||||
@intCast(Module.ErrorInt, mod.global_error_set.getIndex(err_name).?)
|
||||
else
|
||||
0;
|
||||
}
|
||||
|
||||
/// Assumes the type is an error union. Returns true if and only if the value is
|
||||
|
||||
Reference in New Issue
Block a user