mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Merge pull request #20570 from jacobly0/fix-races
InternPool: fix more races blocking a separate codegen/linker thread
This commit is contained in:
commit
80d7e260d7
@ -1034,7 +1034,12 @@ pub const Inst = struct {
|
||||
ty: Type,
|
||||
arg: struct {
|
||||
ty: Ref,
|
||||
src_index: u32,
|
||||
/// Index into `extra` of a null-terminated string representing the parameter name.
|
||||
/// This is `.none` if debug info is stripped.
|
||||
name: enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
_,
|
||||
},
|
||||
},
|
||||
ty_op: struct {
|
||||
ty: Ref,
|
||||
|
||||
@ -1877,6 +1877,7 @@ pub fn destroy(comp: *Compilation) void {
|
||||
if (comp.module) |zcu| zcu.deinit();
|
||||
comp.cache_use.deinit();
|
||||
comp.work_queue.deinit();
|
||||
if (!InternPool.single_threaded) comp.codegen_work.queue.deinit();
|
||||
comp.c_object_work_queue.deinit();
|
||||
if (!build_options.only_core_functionality) {
|
||||
comp.win32_resource_work_queue.deinit();
|
||||
@ -2119,12 +2120,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
|
||||
}
|
||||
|
||||
if (comp.module) |zcu| {
|
||||
const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
|
||||
|
||||
zcu.compile_log_text.shrinkAndFree(gpa, 0);
|
||||
|
||||
// Make sure std.zig is inside the import_table. We unconditionally need
|
||||
// it for start.zig.
|
||||
const std_mod = zcu.std_mod;
|
||||
_ = try zcu.importPkg(std_mod);
|
||||
_ = try pt.importPkg(std_mod);
|
||||
|
||||
// Normally we rely on importing std to in turn import the root source file
|
||||
// in the start code, but when using the stage1 backend that won't happen,
|
||||
@ -2133,20 +2136,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
|
||||
// Likewise, in the case of `zig test`, the test runner is the root source file,
|
||||
// and so there is nothing to import the main file.
|
||||
if (comp.config.is_test) {
|
||||
_ = try zcu.importPkg(zcu.main_mod);
|
||||
_ = try pt.importPkg(zcu.main_mod);
|
||||
}
|
||||
|
||||
if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
|
||||
_ = try zcu.importPkg(compiler_rt_mod);
|
||||
_ = try pt.importPkg(compiler_rt_mod);
|
||||
}
|
||||
|
||||
// Put a work item in for every known source file to detect if
|
||||
// it changed, and, if so, re-compute ZIR and then queue the job
|
||||
// to update it.
|
||||
try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());
|
||||
for (zcu.import_table.values(), 0..) |file, file_index_usize| {
|
||||
const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
|
||||
if (file.mod.isBuiltin()) continue;
|
||||
for (zcu.import_table.values()) |file_index| {
|
||||
if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue;
|
||||
comp.astgen_work_queue.writeItemAssumeCapacity(file_index);
|
||||
}
|
||||
|
||||
@ -2641,7 +2643,8 @@ fn resolveEmitLoc(
|
||||
return slice.ptr;
|
||||
}
|
||||
|
||||
fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
fn reportMultiModuleErrors(pt: Zcu.PerThread) !void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
// Some cases can give you a whole bunch of multi-module errors, which it's not helpful to
|
||||
@ -2651,14 +2654,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
// Attach the "some omitted" note to the final error message
|
||||
var last_err: ?*Zcu.ErrorMsg = null;
|
||||
|
||||
for (zcu.import_table.values(), 0..) |file, file_index_usize| {
|
||||
for (zcu.import_table.values()) |file_index| {
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
if (!file.multi_pkg) continue;
|
||||
|
||||
num_errors += 1;
|
||||
if (num_errors > max_errors) continue;
|
||||
|
||||
const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
|
||||
|
||||
const err = err_blk: {
|
||||
// Like with errors, let's cap the number of notes to prevent a huge error spew.
|
||||
const max_notes = 5;
|
||||
@ -2674,7 +2676,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
.import => |import| try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = import.file,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .{ .token_abs = import.token },
|
||||
},
|
||||
"imported from module {s}",
|
||||
@ -2683,7 +2688,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
.root => |pkg| try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
"root of module {s}",
|
||||
@ -2697,7 +2705,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
notes[num_notes] = try Zcu.ErrorMsg.init(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
"{} more references omitted",
|
||||
@ -2709,7 +2720,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
const err = try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
"file exists in multiple modules",
|
||||
@ -2749,8 +2763,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
|
||||
// to add this flag after reporting the errors however, as otherwise
|
||||
// we'd get an error for every single downstream file, which wouldn't be
|
||||
// very useful.
|
||||
for (zcu.import_table.values()) |file| {
|
||||
if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu);
|
||||
for (zcu.import_table.values()) |file_index| {
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
if (file.multi_pkg) file.recursiveMarkMultiPkg(pt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2774,7 +2789,7 @@ const Header = extern struct {
|
||||
//extra_len: u32,
|
||||
//limbs_len: u32,
|
||||
//string_bytes_len: u32,
|
||||
tracked_insts_len: u32,
|
||||
//tracked_insts_len: u32,
|
||||
src_hash_deps_len: u32,
|
||||
decl_val_deps_len: u32,
|
||||
namespace_deps_len: u32,
|
||||
@ -2782,7 +2797,7 @@ const Header = extern struct {
|
||||
first_dependency_len: u32,
|
||||
dep_entries_len: u32,
|
||||
free_dep_entries_len: u32,
|
||||
files_len: u32,
|
||||
//files_len: u32,
|
||||
},
|
||||
};
|
||||
|
||||
@ -2803,7 +2818,7 @@ pub fn saveState(comp: *Compilation) !void {
|
||||
//.extra_len = @intCast(ip.extra.items.len),
|
||||
//.limbs_len = @intCast(ip.limbs.items.len),
|
||||
//.string_bytes_len = @intCast(ip.string_bytes.items.len),
|
||||
.tracked_insts_len = @intCast(ip.tracked_insts.count()),
|
||||
//.tracked_insts_len = @intCast(ip.tracked_insts.count()),
|
||||
.src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
|
||||
.decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
|
||||
.namespace_deps_len = @intCast(ip.namespace_deps.count()),
|
||||
@ -2811,7 +2826,7 @@ pub fn saveState(comp: *Compilation) !void {
|
||||
.first_dependency_len = @intCast(ip.first_dependency.count()),
|
||||
.dep_entries_len = @intCast(ip.dep_entries.items.len),
|
||||
.free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),
|
||||
.files_len = @intCast(ip.files.entries.len),
|
||||
//.files_len = @intCast(ip.files.entries.len),
|
||||
},
|
||||
};
|
||||
addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
|
||||
@ -2820,7 +2835,7 @@ pub fn saveState(comp: *Compilation) !void {
|
||||
//addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
|
||||
//addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
|
||||
//addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
|
||||
//addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
|
||||
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values()));
|
||||
@ -2836,8 +2851,8 @@ pub fn saveState(comp: *Compilation) !void {
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));
|
||||
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
|
||||
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
|
||||
//addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
|
||||
//addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
|
||||
|
||||
// TODO: compilation errors
|
||||
// TODO: namespaces
|
||||
@ -2929,7 +2944,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
|
||||
}
|
||||
}
|
||||
|
||||
if (zcu.global_error_set.entries.len - 1 > zcu.error_limit) {
|
||||
if (zcu.intern_pool.global_error_set.mutate.list.len > zcu.error_limit) {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
@ -3058,7 +3073,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
||||
try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
|
||||
}
|
||||
|
||||
const actual_error_count = zcu.global_error_set.entries.len - 1;
|
||||
const actual_error_count = zcu.intern_pool.global_error_set.mutate.list.len;
|
||||
if (actual_error_count > zcu.error_limit) {
|
||||
try bundle.addRootErrorMessage(.{
|
||||
.msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{
|
||||
@ -3443,11 +3458,12 @@ fn performAllTheWorkInner(
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.module) |mod| {
|
||||
try reportMultiModuleErrors(mod);
|
||||
try mod.flushRetryableFailures();
|
||||
mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
|
||||
mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);
|
||||
if (comp.module) |zcu| {
|
||||
const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main };
|
||||
try reportMultiModuleErrors(pt);
|
||||
try zcu.flushRetryableFailures();
|
||||
zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
|
||||
zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
|
||||
}
|
||||
|
||||
if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});
|
||||
@ -4131,14 +4147,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
|
||||
};
|
||||
}
|
||||
|
||||
const AstGenSrc = union(enum) {
|
||||
root,
|
||||
import: struct {
|
||||
importing_file: Zcu.File.Index,
|
||||
import_tok: std.zig.Ast.TokenIndex,
|
||||
},
|
||||
};
|
||||
|
||||
fn workerAstGenFile(
|
||||
tid: usize,
|
||||
comp: *Compilation,
|
||||
@ -4148,7 +4156,7 @@ fn workerAstGenFile(
|
||||
root_decl: Zcu.Decl.OptionalIndex,
|
||||
prog_node: std.Progress.Node,
|
||||
wg: *WaitGroup,
|
||||
src: AstGenSrc,
|
||||
src: Zcu.AstGenSrc,
|
||||
) void {
|
||||
const child_prog_node = prog_node.start(file.sub_file_path, 0);
|
||||
defer child_prog_node.end();
|
||||
@ -4158,7 +4166,7 @@ fn workerAstGenFile(
|
||||
error.AnalysisFail => return,
|
||||
else => {
|
||||
file.status = .retryable_failure;
|
||||
comp.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {
|
||||
pt.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {
|
||||
// Swallowing this error is OK because it's implied to be OOM when
|
||||
// there is a missing `failed_files` error message.
|
||||
error.OutOfMemory => {},
|
||||
@ -4189,9 +4197,9 @@ fn workerAstGenFile(
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
|
||||
const res = pt.zcu.importFile(file, import_path) catch continue;
|
||||
const res = pt.importFile(file, import_path) catch continue;
|
||||
if (!res.is_pkg) {
|
||||
res.file.addReference(pt.zcu.*, .{ .import = .{
|
||||
res.file.addReference(pt.zcu, .{ .import = .{
|
||||
.file = file_index,
|
||||
.token = item.data.token,
|
||||
} }) catch continue;
|
||||
@ -4204,7 +4212,7 @@ fn workerAstGenFile(
|
||||
log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
|
||||
file.sub_file_path, import_path, import_result.file.sub_file_path,
|
||||
});
|
||||
const sub_src: AstGenSrc = .{ .import = .{
|
||||
const sub_src: Zcu.AstGenSrc = .{ .import = .{
|
||||
.importing_file = file_index,
|
||||
.import_tok = item.data.token,
|
||||
} };
|
||||
@ -4557,41 +4565,6 @@ fn reportRetryableWin32ResourceError(
|
||||
}
|
||||
}
|
||||
|
||||
fn reportRetryableAstGenError(
|
||||
comp: *Compilation,
|
||||
src: AstGenSrc,
|
||||
file_index: Zcu.File.Index,
|
||||
err: anyerror,
|
||||
) error{OutOfMemory}!void {
|
||||
const zcu = comp.module.?;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
file.status = .retryable_failure;
|
||||
|
||||
const src_loc: Zcu.LazySrcLoc = switch (src) {
|
||||
.root => .{
|
||||
.base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
.import => |info| .{
|
||||
.base_node_inst = try zcu.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst),
|
||||
.offset = .{ .token_abs = info.import_tok },
|
||||
},
|
||||
};
|
||||
|
||||
const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
file.mod.root, file.sub_file_path, @errorName(err),
|
||||
});
|
||||
errdefer err_msg.destroy(gpa);
|
||||
|
||||
{
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
fn reportRetryableEmbedFileError(
|
||||
comp: *Compilation,
|
||||
embed_file: *Zcu.EmbedFile,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
113
src/Sema.zig
113
src/Sema.zig
@ -835,12 +835,11 @@ pub const Block = struct {
|
||||
}
|
||||
|
||||
fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
|
||||
const sema = block.sema;
|
||||
const gpa = sema.gpa;
|
||||
const zcu = sema.pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const file_index = block.getFileScopeIndex(zcu);
|
||||
return ip.trackZir(gpa, file_index, inst);
|
||||
const pt = block.sema.pt;
|
||||
return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{
|
||||
.file = block.getFileScopeIndex(pt.zcu),
|
||||
.inst = inst,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -2878,7 +2877,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
switch (name_strategy) {
|
||||
.anon => {}, // handled after switch
|
||||
.parent => {
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, block.type_name_ctx);
|
||||
try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none);
|
||||
return new_decl_index;
|
||||
},
|
||||
.func => func_strat: {
|
||||
@ -2923,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
|
||||
try writer.writeByte(')');
|
||||
const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
try pt.initNewAnonDecl(new_decl_index, val, name, .none);
|
||||
return new_decl_index;
|
||||
},
|
||||
.dbg_var => {
|
||||
@ -2937,7 +2936,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
|
||||
block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
|
||||
}, .no_embedded_nulls);
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
try pt.initNewAnonDecl(new_decl_index, val, name, .none);
|
||||
return new_decl_index;
|
||||
},
|
||||
else => {},
|
||||
@ -2958,7 +2957,7 @@ fn createAnonymousDeclTypeNamed(
|
||||
const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
|
||||
block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
|
||||
}, .no_embedded_nulls) catch unreachable;
|
||||
try zcu.initNewAnonDecl(new_decl_index, val, name);
|
||||
try pt.initNewAnonDecl(new_decl_index, val, name, .none);
|
||||
return new_decl_index;
|
||||
}
|
||||
|
||||
@ -3474,7 +3473,7 @@ fn zirErrorSetDecl(
|
||||
const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const name = sema.code.nullTerminatedString(name_index);
|
||||
const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
|
||||
_ = try mod.getErrorValue(name_ip);
|
||||
_ = try pt.getErrorValue(name_ip);
|
||||
const result = names.getOrPutAssumeCapacity(name_ip);
|
||||
assert(!result.found_existing); // verified in AstGen
|
||||
}
|
||||
@ -5527,13 +5526,12 @@ fn failWithBadStructFieldAccess(
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const decl = zcu.declPtr(struct_type.decl.unwrap().?);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
field_src,
|
||||
"no field named '{}' in struct '{}'",
|
||||
.{ field_name.fmt(ip), fqn.fmt(ip) },
|
||||
.{ field_name.fmt(ip), decl.fqn.fmt(ip) },
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
|
||||
@ -5554,15 +5552,13 @@ fn failWithBadUnionFieldAccess(
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = sema.gpa;
|
||||
|
||||
const decl = zcu.declPtr(union_obj.decl);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
field_src,
|
||||
"no field named '{}' in union '{}'",
|
||||
.{ field_name.fmt(ip), fqn.fmt(ip) },
|
||||
.{ field_name.fmt(ip), decl.fqn.fmt(ip) },
|
||||
);
|
||||
errdefer msg.destroy(gpa);
|
||||
try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
|
||||
@ -6059,7 +6055,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
const result = zcu.importPkg(c_import_mod) catch |err|
|
||||
const result = pt.importPkg(c_import_mod) catch |err|
|
||||
return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
|
||||
|
||||
const path_digest = zcu.filePathDigest(result.file_index);
|
||||
@ -6721,13 +6717,7 @@ fn addDbgVar(
|
||||
if (block.need_debug_scope) |ptr| ptr.* = true;
|
||||
|
||||
// Add the name to the AIR.
|
||||
const name_extra_index: u32 = @intCast(sema.air_extra.items.len);
|
||||
const elements_used = name.len / 4 + 1;
|
||||
try sema.air_extra.ensureUnusedCapacity(sema.gpa, elements_used);
|
||||
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
|
||||
@memcpy(buffer[0..name.len], name);
|
||||
buffer[name.len] = 0;
|
||||
sema.air_extra.items.len += elements_used;
|
||||
const name_extra_index = try sema.appendAirString(name);
|
||||
|
||||
_ = try block.addInst(.{
|
||||
.tag = air_tag,
|
||||
@ -6738,6 +6728,16 @@ fn addDbgVar(
|
||||
});
|
||||
}
|
||||
|
||||
pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 {
|
||||
const str_extra_index: u32 = @intCast(sema.air_extra.items.len);
|
||||
const elements_used = str.len / 4 + 1;
|
||||
const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);
|
||||
const buffer = mem.sliceAsBytes(elements);
|
||||
@memcpy(buffer[0..str.len], str);
|
||||
buffer[str.len] = 0;
|
||||
return str_extra_index;
|
||||
}
|
||||
|
||||
fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const pt = sema.pt;
|
||||
const mod = pt.zcu;
|
||||
@ -8357,13 +8357,6 @@ fn instantiateGenericCall(
|
||||
}
|
||||
} else {
|
||||
// The parameter is runtime-known.
|
||||
child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
|
||||
.tag = .arg,
|
||||
.data = .{ .arg = .{
|
||||
.ty = Air.internedToRef(arg_ty.toIntern()),
|
||||
.src_index = @intCast(arg_index),
|
||||
} },
|
||||
}));
|
||||
const param_name: Zir.NullTerminatedString = switch (param_tag) {
|
||||
.param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,
|
||||
.param => name: {
|
||||
@ -8373,6 +8366,16 @@ fn instantiateGenericCall(
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
|
||||
.tag = .arg,
|
||||
.data = .{ .arg = .{
|
||||
.ty = Air.internedToRef(arg_ty.toIntern()),
|
||||
.name = if (child_block.ownerModule().strip)
|
||||
.none
|
||||
else
|
||||
@enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))),
|
||||
} },
|
||||
}));
|
||||
try child_block.params.append(sema.arena, .{
|
||||
.ty = arg_ty.toIntern(), // This is the type after coercion
|
||||
.is_comptime = false, // We're adding only runtime args to the instantiation
|
||||
@ -8702,7 +8705,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
_ = try pt.zcu.getErrorValue(name);
|
||||
_ = try pt.getErrorValue(name);
|
||||
// Create an error set type with only this error value, and return the value.
|
||||
const error_set_type = try pt.singleErrorSetType(name);
|
||||
return Air.internedToRef((try pt.intern(.{ .err = .{
|
||||
@ -8732,7 +8735,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
|
||||
const err_name = ip.indexToKey(val.toIntern()).err.name;
|
||||
return Air.internedToRef((try pt.intValue(
|
||||
err_int_ty,
|
||||
try mod.getErrorValue(err_name),
|
||||
try pt.getErrorValue(err_name),
|
||||
)).toIntern());
|
||||
}
|
||||
|
||||
@ -8743,10 +8746,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
|
||||
const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
|
||||
switch (names.len) {
|
||||
0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),
|
||||
1 => {
|
||||
const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
|
||||
return pt.intRef(err_int_ty, int);
|
||||
},
|
||||
1 => return pt.intRef(err_int_ty, ip.getErrorValueIfExists(names.get(ip)[0]).?),
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
@ -8762,6 +8762,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
|
||||
|
||||
const pt = sema.pt;
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
const src = block.nodeOffset(extra.node);
|
||||
const operand_src = block.builtinCallArgSrc(extra.node, 0);
|
||||
@ -8771,11 +8772,16 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
|
||||
|
||||
if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
|
||||
const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
|
||||
if (int > mod.global_error_set.count() or int == 0)
|
||||
if (int > len: {
|
||||
const mutate = &ip.global_error_set.mutate;
|
||||
mutate.mutex.lock();
|
||||
defer mutate.mutex.unlock();
|
||||
break :len mutate.list.len;
|
||||
} or int == 0)
|
||||
return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
|
||||
return Air.internedToRef((try pt.intern(.{ .err = .{
|
||||
.ty = .anyerror_type,
|
||||
.name = mod.global_error_set.keys()[int],
|
||||
.name = ip.global_error_set.shared.names.acquire().view().items(.@"0")[int - 1],
|
||||
} })));
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||
@ -13943,7 +13949,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
||||
const operand_src = block.tokenOffset(inst_data.src_tok);
|
||||
const operand = inst_data.get(sema.code);
|
||||
|
||||
const result = zcu.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
|
||||
const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
|
||||
error.ImportOutsideModulePath => {
|
||||
return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
|
||||
},
|
||||
@ -14002,7 +14008,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
_ = try mod.getErrorValue(name);
|
||||
_ = try pt.getErrorValue(name);
|
||||
const error_set_type = try pt.singleErrorSetType(name);
|
||||
return Air.internedToRef((try pt.intern(.{ .err = .{
|
||||
.ty = error_set_type.toIntern(),
|
||||
@ -19561,7 +19567,7 @@ fn zirRetErrValue(
|
||||
inst_data.get(sema.code),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
_ = try mod.getErrorValue(err_name);
|
||||
_ = try pt.getErrorValue(err_name);
|
||||
// Return the error code from the function.
|
||||
const error_set_type = try pt.singleErrorSetType(err_name);
|
||||
const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{
|
||||
@ -21604,7 +21610,7 @@ fn zirReify(
|
||||
const name = try sema.sliceToIpString(block, src, name_val, .{
|
||||
.needed_comptime_reason = "error set contents must be comptime-known",
|
||||
});
|
||||
_ = try mod.getErrorValue(name);
|
||||
_ = try pt.getErrorValue(name);
|
||||
const gop = names.getOrPutAssumeCapacity(name);
|
||||
if (gop.found_existing) {
|
||||
return sema.fail(block, src, "duplicate error '{}'", .{
|
||||
@ -26500,7 +26506,7 @@ fn zirBuiltinExtern(
|
||||
const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);
|
||||
errdefer pt.destroyDecl(new_decl_index);
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
try mod.initNewAnonDecl(
|
||||
try pt.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
Value.fromInterned(
|
||||
if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
|
||||
@ -26522,6 +26528,7 @@ fn zirBuiltinExtern(
|
||||
} }),
|
||||
),
|
||||
options.name,
|
||||
.none,
|
||||
);
|
||||
new_decl.owns_tv = true;
|
||||
// Note that this will queue the anon decl for codegen, so that the backend can
|
||||
@ -27481,7 +27488,7 @@ fn fieldVal(
|
||||
},
|
||||
.simple_type => |t| {
|
||||
assert(t == .anyerror);
|
||||
_ = try mod.getErrorValue(field_name);
|
||||
_ = try pt.getErrorValue(field_name);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@ -27721,7 +27728,7 @@ fn fieldPtr(
|
||||
},
|
||||
.simple_type => |t| {
|
||||
assert(t == .anyerror);
|
||||
_ = try mod.getErrorValue(field_name);
|
||||
_ = try pt.getErrorValue(field_name);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@ -36735,24 +36742,23 @@ fn generateUnionTagTypeNumbered(
|
||||
|
||||
const new_decl_index = try pt.allocateNewDecl(block.namespace);
|
||||
errdefer pt.destroyDecl(new_decl_index);
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(pt);
|
||||
const name = try ip.getOrPutStringFmt(
|
||||
gpa,
|
||||
pt.tid,
|
||||
"@typeInfo({}).Union.tag_type.?",
|
||||
.{fqn.fmt(ip)},
|
||||
.{union_owner_decl.fqn.fmt(ip)},
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try mod.initNewAnonDecl(
|
||||
try pt.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
Value.@"unreachable",
|
||||
name,
|
||||
name.toOptional(),
|
||||
);
|
||||
errdefer pt.abortAnonDecl(new_decl_index);
|
||||
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
new_decl.owns_tv = true;
|
||||
new_decl.name_fully_qualified = true;
|
||||
|
||||
const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
|
||||
.decl = new_decl_index,
|
||||
@ -36784,22 +36790,21 @@ fn generateUnionTagTypeSimple(
|
||||
const gpa = sema.gpa;
|
||||
|
||||
const new_decl_index = new_decl_index: {
|
||||
const fqn = try union_owner_decl.fullyQualifiedName(pt);
|
||||
const new_decl_index = try pt.allocateNewDecl(block.namespace);
|
||||
errdefer pt.destroyDecl(new_decl_index);
|
||||
const name = try ip.getOrPutStringFmt(
|
||||
gpa,
|
||||
pt.tid,
|
||||
"@typeInfo({}).Union.tag_type.?",
|
||||
.{fqn.fmt(ip)},
|
||||
.{union_owner_decl.fqn.fmt(ip)},
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try mod.initNewAnonDecl(
|
||||
try pt.initNewAnonDecl(
|
||||
new_decl_index,
|
||||
Value.@"unreachable",
|
||||
name,
|
||||
name.toOptional(),
|
||||
);
|
||||
mod.declPtr(new_decl_index).name_fully_qualified = true;
|
||||
break :new_decl_index new_decl_index;
|
||||
};
|
||||
errdefer pt.abortAnonDecl(new_decl_index);
|
||||
|
||||
18
src/Type.zig
18
src/Type.zig
@ -268,10 +268,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
|
||||
return;
|
||||
},
|
||||
.inferred_error_set_type => |func_index| {
|
||||
try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
|
||||
const owner_decl = mod.funcOwnerDeclPtr(func_index);
|
||||
try owner_decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
|
||||
try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{
|
||||
owner_decl.fqn.fmt(ip),
|
||||
});
|
||||
},
|
||||
.error_set_type => |error_set_type| {
|
||||
const names = error_set_type.names;
|
||||
@ -334,10 +334,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
|
||||
const struct_type = ip.loadStructType(ty.toIntern());
|
||||
if (struct_type.decl.unwrap()) |decl_index| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.print("{}", .{decl.fqn.fmt(ip)});
|
||||
} else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
|
||||
const namespace = mod.namespacePtr(namespace_index);
|
||||
try namespace.renderFullyQualifiedName(mod, .empty, writer);
|
||||
try namespace.renderFullyQualifiedName(ip, .empty, writer);
|
||||
} else {
|
||||
try writer.writeAll("@TypeOf(.{})");
|
||||
}
|
||||
@ -367,15 +367,15 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
|
||||
|
||||
.union_type => {
|
||||
const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.print("{}", .{decl.fqn.fmt(ip)});
|
||||
},
|
||||
.opaque_type => {
|
||||
const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.print("{}", .{decl.fqn.fmt(ip)});
|
||||
},
|
||||
.enum_type => {
|
||||
const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);
|
||||
try decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.print("{}", .{decl.fqn.fmt(ip)});
|
||||
},
|
||||
.func_type => |fn_info| {
|
||||
if (fn_info.is_noinline) {
|
||||
@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {
|
||||
pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
|
||||
const ip = &zcu.intern_pool;
|
||||
const tracked = switch (ip.indexToKey(ty.toIntern())) {
|
||||
.struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
|
||||
|
||||
@ -417,7 +417,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
|
||||
var bigint_buffer: BigIntSpace = undefined;
|
||||
const bigint = BigIntMutable.init(
|
||||
&bigint_buffer.limbs,
|
||||
mod.global_error_set.getIndex(name).?,
|
||||
ip.getErrorValueIfExists(name).?,
|
||||
).toConst();
|
||||
bigint.writeTwosComplement(buffer[0..byte_count], endian);
|
||||
},
|
||||
@ -427,7 +427,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
|
||||
if (val.unionTag(mod)) |union_tag| {
|
||||
const union_obj = mod.typeToUnion(ty).?;
|
||||
const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
|
||||
const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]);
|
||||
const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
|
||||
const field_val = try val.fieldValue(pt, field_index);
|
||||
const byte_count: usize = @intCast(field_type.abiSize(pt));
|
||||
return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
|
||||
@ -1455,9 +1455,9 @@ pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTermi
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt {
|
||||
return if (getErrorName(val, mod).unwrap()) |err_name|
|
||||
@intCast(mod.global_error_set.getIndex(err_name).?)
|
||||
pub fn getErrorInt(val: Value, zcu: *Zcu) Module.ErrorInt {
|
||||
return if (getErrorName(val, zcu).unwrap()) |err_name|
|
||||
zcu.intern_pool.getErrorValueIfExists(err_name).?
|
||||
else
|
||||
0;
|
||||
}
|
||||
|
||||
373
src/Zcu.zig
373
src/Zcu.zig
@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
|
||||
/// `Compilation.update` of the process for a given `Compilation`.
|
||||
///
|
||||
/// Indexes correspond 1:1 to `files`.
|
||||
import_table: std.StringArrayHashMapUnmanaged(*File) = .{},
|
||||
import_table: std.StringArrayHashMapUnmanaged(File.Index) = .{},
|
||||
|
||||
/// The set of all the files which have been loaded with `@embedFile` in the Module.
|
||||
/// We keep track of this in order to iterate over it and check which files have been
|
||||
@ -141,9 +141,6 @@ failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .{},
|
||||
/// are stored here.
|
||||
cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .{},
|
||||
|
||||
/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
|
||||
global_error_set: GlobalErrorSet = .{},
|
||||
|
||||
/// Maximum amount of distinct error values, set by --error-limit
|
||||
error_limit: ErrorInt,
|
||||
|
||||
@ -326,7 +323,10 @@ pub const Reference = struct {
|
||||
};
|
||||
|
||||
pub const Decl = struct {
|
||||
/// Equal to `fqn` if already fully qualified.
|
||||
name: InternPool.NullTerminatedString,
|
||||
/// Fully qualified name.
|
||||
fqn: InternPool.NullTerminatedString,
|
||||
/// The most recent Value of the Decl after a successful semantic analysis.
|
||||
/// Populated when `has_tv`.
|
||||
val: Value,
|
||||
@ -384,8 +384,6 @@ pub const Decl = struct {
|
||||
is_pub: bool,
|
||||
/// Whether the corresponding AST decl has a `export` keyword.
|
||||
is_exported: bool,
|
||||
/// If true `name` is already fully qualified.
|
||||
name_fully_qualified: bool = false,
|
||||
/// What kind of a declaration is this.
|
||||
kind: Kind,
|
||||
|
||||
@ -408,25 +406,6 @@ pub const Decl = struct {
|
||||
return extra.data.getBodies(@intCast(extra.end), zir);
|
||||
}
|
||||
|
||||
pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
|
||||
if (decl.name_fully_qualified) {
|
||||
try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
|
||||
} else {
|
||||
try zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedName(zcu, decl.name, writer);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderFullyQualifiedDebugName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
|
||||
return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
|
||||
}
|
||||
|
||||
pub fn fullyQualifiedName(decl: Decl, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
|
||||
return if (decl.name_fully_qualified)
|
||||
decl.name
|
||||
else
|
||||
pt.zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(pt, decl.name);
|
||||
}
|
||||
|
||||
pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
|
||||
assert(decl.has_tv);
|
||||
return decl.val.typeOf(zcu);
|
||||
@ -646,23 +625,27 @@ pub const Namespace = struct {
|
||||
return zcu.fileByIndex(ns.file_scope);
|
||||
}
|
||||
|
||||
pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File {
|
||||
return ip.filePtr(ns.file_scope);
|
||||
}
|
||||
|
||||
// This renders e.g. "std.fs.Dir.OpenOptions"
|
||||
pub fn renderFullyQualifiedName(
|
||||
ns: Namespace,
|
||||
zcu: *Zcu,
|
||||
ip: *InternPool,
|
||||
name: InternPool.NullTerminatedString,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
if (ns.parent.unwrap()) |parent| {
|
||||
try zcu.namespacePtr(parent).renderFullyQualifiedName(
|
||||
zcu,
|
||||
zcu.declPtr(ns.decl_index).name,
|
||||
try ip.namespacePtr(parent).renderFullyQualifiedName(
|
||||
ip,
|
||||
ip.declPtr(ns.decl_index).name,
|
||||
writer,
|
||||
);
|
||||
} else {
|
||||
try ns.fileScope(zcu).renderFullyQualifiedName(writer);
|
||||
try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
|
||||
}
|
||||
if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
|
||||
if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
|
||||
}
|
||||
|
||||
/// This renders e.g. "std/fs.zig:Dir.OpenOptions"
|
||||
@ -686,46 +669,45 @@ pub const Namespace = struct {
|
||||
if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });
|
||||
}
|
||||
|
||||
pub fn fullyQualifiedName(
|
||||
pub fn internFullyQualifiedName(
|
||||
ns: Namespace,
|
||||
pt: Zcu.PerThread,
|
||||
ip: *InternPool,
|
||||
gpa: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) !InternPool.NullTerminatedString {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const gpa = zcu.gpa;
|
||||
const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
|
||||
const strings = ip.getLocal(tid).getMutableStrings(gpa);
|
||||
// Protects reads of interned strings from being reallocated during the call to
|
||||
// renderFullyQualifiedName.
|
||||
const slice = try strings.addManyAsSlice(count: {
|
||||
var count: usize = name.length(ip) + 1;
|
||||
var cur_ns = &ns;
|
||||
while (true) {
|
||||
const decl = zcu.declPtr(cur_ns.decl_index);
|
||||
cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
|
||||
count += ns.fileScope(zcu).fullyQualifiedNameLen();
|
||||
const decl = ip.declPtr(cur_ns.decl_index);
|
||||
cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
|
||||
count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
|
||||
break :count count;
|
||||
});
|
||||
count += decl.name.length(ip) + 1;
|
||||
}
|
||||
});
|
||||
var fbs = std.io.fixedBufferStream(slice[0]);
|
||||
ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;
|
||||
ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
|
||||
assert(fbs.pos == slice[0].len);
|
||||
|
||||
// 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.
|
||||
const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
|
||||
if (cpu_arch.isNvptx()) {
|
||||
for (slice[0]) |*byte| switch (byte.*) {
|
||||
'{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
|
||||
else => {},
|
||||
};
|
||||
}
|
||||
// FIXME This has bitrotted and is no longer able to be implemented here.
|
||||
//const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
|
||||
//if (cpu_arch.isNvptx()) {
|
||||
// for (slice[0]) |*byte| switch (byte.*) {
|
||||
// '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
|
||||
// else => {},
|
||||
// };
|
||||
//}
|
||||
|
||||
return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
|
||||
return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
|
||||
}
|
||||
|
||||
pub fn getType(ns: Namespace, zcu: *Zcu) Type {
|
||||
@ -882,7 +864,7 @@ pub const File = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
|
||||
pub fn internFullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
|
||||
const gpa = pt.zcu.gpa;
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
|
||||
@ -910,7 +892,7 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
/// Add a reference to this file during AstGen.
|
||||
pub fn addReference(file: *File, zcu: Zcu, ref: File.Reference) !void {
|
||||
pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void {
|
||||
// Don't add the same module root twice. Note that since we always add module roots at the
|
||||
// front of the references array (see below), this loop is actually O(1) on valid code.
|
||||
if (ref == .root) {
|
||||
@ -942,7 +924,7 @@ pub const File = struct {
|
||||
|
||||
/// Mark this file and every file referenced by it as multi_pkg and report an
|
||||
/// astgen_failure error for them. AstGen must have completed in its entirety.
|
||||
pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void {
|
||||
pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void {
|
||||
file.multi_pkg = true;
|
||||
file.status = .astgen_failure;
|
||||
|
||||
@ -962,9 +944,9 @@ pub const File = struct {
|
||||
const import_path = file.zir.nullTerminatedString(item.data.name);
|
||||
if (mem.eql(u8, import_path, "builtin")) continue;
|
||||
|
||||
const res = mod.importFile(file, import_path) catch continue;
|
||||
const res = pt.importFile(file, import_path) catch continue;
|
||||
if (!res.is_pkg and !res.file.multi_pkg) {
|
||||
res.file.recursiveMarkMultiPkg(mod);
|
||||
res.file.recursiveMarkMultiPkg(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1033,6 +1015,14 @@ pub const ErrorMsg = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const AstGenSrc = union(enum) {
|
||||
root,
|
||||
import: struct {
|
||||
importing_file: Zcu.File.Index,
|
||||
import_tok: std.zig.Ast.TokenIndex,
|
||||
},
|
||||
};
|
||||
|
||||
/// Canonical reference to a position within a source file.
|
||||
pub const SrcLoc = struct {
|
||||
file_scope: *File,
|
||||
@ -2406,7 +2396,6 @@ pub const CompileError = error{
|
||||
pub fn init(mod: *Module, thread_count: usize) !void {
|
||||
const gpa = mod.gpa;
|
||||
try mod.intern_pool.init(gpa, thread_count);
|
||||
try mod.global_error_set.put(gpa, .empty, {});
|
||||
}
|
||||
|
||||
pub fn deinit(zcu: *Zcu) void {
|
||||
@ -2421,8 +2410,7 @@ pub fn deinit(zcu: *Zcu) void {
|
||||
for (zcu.import_table.keys()) |key| {
|
||||
gpa.free(key);
|
||||
}
|
||||
for (0..zcu.import_table.entries.len) |file_index_usize| {
|
||||
const file_index: File.Index = @enumFromInt(file_index_usize);
|
||||
for (zcu.import_table.values()) |file_index| {
|
||||
pt.destroyFile(file_index);
|
||||
}
|
||||
zcu.import_table.deinit(gpa);
|
||||
@ -2479,8 +2467,6 @@ pub fn deinit(zcu: *Zcu) void {
|
||||
zcu.single_exports.deinit(gpa);
|
||||
zcu.multi_exports.deinit(gpa);
|
||||
|
||||
zcu.global_error_set.deinit(gpa);
|
||||
|
||||
zcu.potentially_outdated.deinit(gpa);
|
||||
zcu.outdated.deinit(gpa);
|
||||
zcu.outdated_ready.deinit(gpa);
|
||||
@ -3020,183 +3006,7 @@ pub const ImportFileResult = struct {
|
||||
is_pkg: bool,
|
||||
};
|
||||
|
||||
pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// The resolved path is used as the key in the import table, to detect if
|
||||
// an import refers to the same as another, despite different relative paths
|
||||
// or differently mapped package names.
|
||||
const resolved_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
mod.root_src_path,
|
||||
});
|
||||
var keep_resolved_path = false;
|
||||
defer if (!keep_resolved_path) gpa.free(resolved_path);
|
||||
|
||||
const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
|
||||
errdefer _ = zcu.import_table.pop();
|
||||
if (gop.found_existing) {
|
||||
try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
|
||||
return .{
|
||||
.file = gop.value_ptr.*,
|
||||
.file_index = @enumFromInt(gop.index),
|
||||
.is_new = false,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
try ip.files.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
if (mod.builtin_file) |builtin_file| {
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = builtin_file;
|
||||
try builtin_file.addReference(zcu.*, .{ .root = mod });
|
||||
const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
|
||||
ip.files.putAssumeCapacityNoClobber(path_digest, .none);
|
||||
return .{
|
||||
.file = builtin_file,
|
||||
.file_index = @enumFromInt(ip.files.entries.len - 1),
|
||||
.is_new = false,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
|
||||
errdefer gpa.free(sub_file_path);
|
||||
|
||||
const new_file = try gpa.create(File);
|
||||
errdefer gpa.destroy(new_file);
|
||||
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = new_file;
|
||||
new_file.* = .{
|
||||
.sub_file_path = sub_file_path,
|
||||
.source = undefined,
|
||||
.source_loaded = false,
|
||||
.tree_loaded = false,
|
||||
.zir_loaded = false,
|
||||
.stat = undefined,
|
||||
.tree = undefined,
|
||||
.zir = undefined,
|
||||
.status = .never_loaded,
|
||||
.mod = mod,
|
||||
};
|
||||
|
||||
const path_digest = computePathDigest(zcu, mod, sub_file_path);
|
||||
|
||||
try new_file.addReference(zcu.*, .{ .root = mod });
|
||||
ip.files.putAssumeCapacityNoClobber(path_digest, .none);
|
||||
return .{
|
||||
.file = new_file,
|
||||
.file_index = @enumFromInt(ip.files.entries.len - 1),
|
||||
.is_new = true,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Called from a worker thread during AstGen.
|
||||
/// Also called from Sema during semantic analysis.
|
||||
pub fn importFile(
|
||||
zcu: *Zcu,
|
||||
cur_file: *File,
|
||||
import_string: []const u8,
|
||||
) !ImportFileResult {
|
||||
const mod = cur_file.mod;
|
||||
|
||||
if (std.mem.eql(u8, import_string, "std")) {
|
||||
return zcu.importPkg(zcu.std_mod);
|
||||
}
|
||||
if (std.mem.eql(u8, import_string, "root")) {
|
||||
return zcu.importPkg(zcu.root_mod);
|
||||
}
|
||||
if (mod.deps.get(import_string)) |pkg| {
|
||||
return zcu.importPkg(pkg);
|
||||
}
|
||||
if (!mem.endsWith(u8, import_string, ".zig")) {
|
||||
return error.ModuleNotFound;
|
||||
}
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// The resolved path is used as the key in the import table, to detect if
|
||||
// an import refers to the same as another, despite different relative paths
|
||||
// or differently mapped package names.
|
||||
const resolved_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
cur_file.sub_file_path,
|
||||
"..",
|
||||
import_string,
|
||||
});
|
||||
|
||||
var keep_resolved_path = false;
|
||||
defer if (!keep_resolved_path) gpa.free(resolved_path);
|
||||
|
||||
const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
|
||||
errdefer _ = zcu.import_table.pop();
|
||||
if (gop.found_existing) return .{
|
||||
.file = gop.value_ptr.*,
|
||||
.file_index = @enumFromInt(gop.index),
|
||||
.is_new = false,
|
||||
.is_pkg = false,
|
||||
};
|
||||
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
try ip.files.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const new_file = try gpa.create(File);
|
||||
errdefer gpa.destroy(new_file);
|
||||
|
||||
const resolved_root_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
});
|
||||
defer gpa.free(resolved_root_path);
|
||||
|
||||
const sub_file_path = p: {
|
||||
const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
|
||||
errdefer gpa.free(relative);
|
||||
|
||||
if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
|
||||
break :p relative;
|
||||
}
|
||||
return error.ImportOutsideModulePath;
|
||||
};
|
||||
errdefer gpa.free(sub_file_path);
|
||||
|
||||
log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
|
||||
resolved_root_path, resolved_path, sub_file_path, import_string,
|
||||
});
|
||||
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = new_file;
|
||||
new_file.* = .{
|
||||
.sub_file_path = sub_file_path,
|
||||
.source = undefined,
|
||||
.source_loaded = false,
|
||||
.tree_loaded = false,
|
||||
.zir_loaded = false,
|
||||
.stat = undefined,
|
||||
.tree = undefined,
|
||||
.zir = undefined,
|
||||
.status = .never_loaded,
|
||||
.mod = mod,
|
||||
};
|
||||
|
||||
const path_digest = computePathDigest(zcu, mod, sub_file_path);
|
||||
ip.files.putAssumeCapacityNoClobber(path_digest, .none);
|
||||
return .{
|
||||
.file = new_file,
|
||||
.file_index = @enumFromInt(ip.files.entries.len - 1),
|
||||
.is_new = true,
|
||||
.is_pkg = false,
|
||||
};
|
||||
}
|
||||
|
||||
fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
|
||||
pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
|
||||
const want_local_cache = mod == zcu.main_mod;
|
||||
var path_hash: Cache.HashHelper = .{};
|
||||
path_hash.addBytes(build_options.version);
|
||||
@ -3292,43 +3102,11 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit
|
||||
gop.value_ptr.* = @intCast(ref_idx);
|
||||
}
|
||||
|
||||
pub fn getErrorValue(
|
||||
mod: *Module,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) Allocator.Error!ErrorInt {
|
||||
const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
|
||||
return @as(ErrorInt, @intCast(gop.index));
|
||||
}
|
||||
|
||||
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 errorSetBits(mod: *Module) u16 {
|
||||
if (mod.error_limit == 0) return 0;
|
||||
return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error
|
||||
}
|
||||
|
||||
pub fn initNewAnonDecl(
|
||||
mod: *Module,
|
||||
new_decl_index: Decl.Index,
|
||||
val: Value,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) Allocator.Error!void {
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
|
||||
new_decl.name = name;
|
||||
new_decl.val = val;
|
||||
new_decl.alignment = .none;
|
||||
new_decl.@"linksection" = .none;
|
||||
new_decl.has_tv = true;
|
||||
new_decl.analysis = .complete;
|
||||
}
|
||||
|
||||
pub fn errNote(
|
||||
mod: *Module,
|
||||
src_loc: LazySrcLoc,
|
||||
@ -3394,41 +3172,6 @@ pub fn handleUpdateExports(
|
||||
};
|
||||
}
|
||||
|
||||
pub fn reportRetryableFileError(
|
||||
zcu: *Zcu,
|
||||
file_index: File.Index,
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
file.status = .retryable_failure;
|
||||
|
||||
const err_msg = try ErrorMsg.create(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
format,
|
||||
args,
|
||||
);
|
||||
errdefer err_msg.destroy(gpa);
|
||||
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
|
||||
const gop = try zcu.failed_files.getOrPut(gpa, file);
|
||||
if (gop.found_existing) {
|
||||
if (gop.value_ptr.*) |old_err_msg| {
|
||||
old_err_msg.destroy(gpa);
|
||||
}
|
||||
}
|
||||
gop.value_ptr.* = err_msg;
|
||||
}
|
||||
|
||||
pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {
|
||||
const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
|
||||
if (gop.found_existing) {
|
||||
@ -3744,22 +3487,28 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {
|
||||
return zcu.import_table.values()[@intFromEnum(i)];
|
||||
pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {
|
||||
return zcu.intern_pool.filePtr(file_index);
|
||||
}
|
||||
|
||||
/// Returns the `Decl` of the struct that represents this `File`.
|
||||
pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex {
|
||||
pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex {
|
||||
const ip = &zcu.intern_pool;
|
||||
return ip.files.values()[@intFromEnum(i)];
|
||||
const file_index_unwrapped = file_index.unwrap(ip);
|
||||
const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
|
||||
return files.view().items(.root_decl)[file_index_unwrapped.index];
|
||||
}
|
||||
|
||||
pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void {
|
||||
pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void {
|
||||
const ip = &zcu.intern_pool;
|
||||
ip.files.values()[@intFromEnum(i)] = root_decl;
|
||||
const file_index_unwrapped = file_index.unwrap(ip);
|
||||
const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
|
||||
files.view().items(.root_decl)[file_index_unwrapped.index] = root_decl;
|
||||
}
|
||||
|
||||
pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest {
|
||||
pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
|
||||
const ip = &zcu.intern_pool;
|
||||
return ip.files.keys()[@intFromEnum(i)];
|
||||
const file_index_unwrapped = file_index.unwrap(ip);
|
||||
const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
|
||||
return files.view().items(.bin_digest)[file_index_unwrapped.index];
|
||||
}
|
||||
|
||||
@ -342,6 +342,7 @@ pub fn astGenFile(
|
||||
/// the Compilation mutex when acting on shared state.
|
||||
fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = zcu.gpa;
|
||||
const new_zir = file.zir;
|
||||
|
||||
@ -355,109 +356,117 @@ fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index,
|
||||
|
||||
// TODO: this should be done after all AstGen workers complete, to avoid
|
||||
// iterating over this full set for every updated file.
|
||||
for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
|
||||
const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
|
||||
if (ti.file != file_index) continue;
|
||||
const old_inst = ti.inst;
|
||||
ti.inst = inst_map.get(ti.inst) orelse {
|
||||
// Tracking failed for this instruction. Invalidate associated `src_hash` deps.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
log.debug("tracking failed for %{d}", .{old_inst});
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
continue;
|
||||
};
|
||||
for (ip.locals, 0..) |*local, tid| {
|
||||
local.mutate.tracked_insts.mutex.lock();
|
||||
defer local.mutate.tracked_insts.mutex.unlock();
|
||||
const tracked_insts_list = local.getMutableTrackedInsts(gpa);
|
||||
for (tracked_insts_list.view().items(.@"0"), 0..) |*tracked_inst, tracked_inst_unwrapped_index| {
|
||||
if (tracked_inst.file != file_index) continue;
|
||||
const old_inst = tracked_inst.inst;
|
||||
const tracked_inst_index = (InternPool.TrackedInst.Index.Unwrapped{
|
||||
.tid = @enumFromInt(tid),
|
||||
.index = @intCast(tracked_inst_unwrapped_index),
|
||||
}).wrap(ip);
|
||||
tracked_inst.inst = inst_map.get(old_inst) orelse {
|
||||
// Tracking failed for this instruction. Invalidate associated `src_hash` deps.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
log.debug("tracking failed for %{d}", .{old_inst});
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
|
||||
continue;
|
||||
};
|
||||
|
||||
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
|
||||
if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
|
||||
if (std.zig.srcHashEql(old_hash, new_hash)) {
|
||||
break :hash_changed;
|
||||
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
|
||||
if (new_zir.getAssociatedSrcHash(tracked_inst.inst)) |new_hash| {
|
||||
if (std.zig.srcHashEql(old_hash, new_hash)) {
|
||||
break :hash_changed;
|
||||
}
|
||||
log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
|
||||
old_inst,
|
||||
tracked_inst.inst,
|
||||
std.fmt.fmtSliceHexLower(&old_hash),
|
||||
std.fmt.fmtSliceHexLower(&new_hash),
|
||||
});
|
||||
}
|
||||
log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
|
||||
old_inst,
|
||||
ti.inst,
|
||||
std.fmt.fmtSliceHexLower(&old_hash),
|
||||
std.fmt.fmtSliceHexLower(&new_hash),
|
||||
});
|
||||
// The source hash associated with this instruction changed - invalidate relevant dependencies.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
|
||||
}
|
||||
// The source hash associated with this instruction changed - invalidate relevant dependencies.
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
|
||||
}
|
||||
|
||||
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
|
||||
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
|
||||
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
|
||||
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
|
||||
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
|
||||
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
|
||||
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
|
||||
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
if (!has_namespace) continue;
|
||||
};
|
||||
if (!has_namespace) continue;
|
||||
|
||||
var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer old_names.deinit(zcu.gpa);
|
||||
{
|
||||
var it = old_zir.declIterator(old_inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
|
||||
defer old_names.deinit(zcu.gpa);
|
||||
{
|
||||
var it = old_zir.declIterator(old_inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try old_names.put(zcu.gpa, name_ip, {});
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
try old_names.put(zcu.gpa, name_ip, {});
|
||||
}
|
||||
}
|
||||
var any_change = false;
|
||||
{
|
||||
var it = new_zir.declIterator(ti.inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
var any_change = false;
|
||||
{
|
||||
var it = new_zir.declIterator(tracked_inst.inst);
|
||||
while (it.next()) |decl_inst| {
|
||||
const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
|
||||
switch (decl_name) {
|
||||
.@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
|
||||
_ => if (decl_name.isNamedTest(old_zir)) continue,
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
if (!old_names.swapRemove(name_ip)) continue;
|
||||
// Name added
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = tracked_inst_index,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
const name_zir = decl_name.toString(old_zir).?;
|
||||
const name_ip = try zcu.intern_pool.getOrPutString(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
old_zir.nullTerminatedString(name_zir),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
if (!old_names.swapRemove(name_ip)) continue;
|
||||
// Name added
|
||||
}
|
||||
// The only elements remaining in `old_names` now are any names which were removed.
|
||||
for (old_names.keys()) |name_ip| {
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.namespace = tracked_inst_index,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
}
|
||||
// The only elements remaining in `old_names` now are any names which were removed.
|
||||
for (old_names.keys()) |name_ip| {
|
||||
any_change = true;
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace_name = .{
|
||||
.namespace = ti_idx,
|
||||
.name = name_ip,
|
||||
} });
|
||||
}
|
||||
|
||||
if (any_change) {
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
|
||||
if (any_change) {
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.markDependeeOutdated(.{ .namespace = tracked_inst_index });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -548,7 +557,7 @@ pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.Sem
|
||||
};
|
||||
}
|
||||
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
|
||||
defer decl_prog_node.end();
|
||||
|
||||
break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
|
||||
@ -747,10 +756,9 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
defer liveness.deinit(gpa);
|
||||
|
||||
if (build_options.enable_debug_extensions and comp.verbose_air) {
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
|
||||
std.debug.print("# Begin Function AIR: {}:\n", .{decl.fqn.fmt(ip)});
|
||||
@import("../print_air.zig").dump(pt, air, liveness);
|
||||
std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
|
||||
std.debug.print("# End Function AIR: {}\n\n", .{decl.fqn.fmt(ip)});
|
||||
}
|
||||
|
||||
if (std.debug.runtime_safety) {
|
||||
@ -781,7 +789,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
};
|
||||
}
|
||||
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(ip), 0);
|
||||
defer codegen_prog_node.end();
|
||||
|
||||
if (!air.typesFullyResolved(zcu)) {
|
||||
@ -818,7 +826,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
|
||||
/// https://github.com/ziglang/zig/issues/14307
|
||||
pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
|
||||
const import_file_result = try pt.zcu.importPkg(pkg);
|
||||
const import_file_result = try pt.importPkg(pkg);
|
||||
const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
|
||||
if (root_decl_index == .none) {
|
||||
return pt.semaFile(import_file_result.file_index);
|
||||
@ -855,7 +863,10 @@ fn getFileRootStruct(
|
||||
const decls = file.zir.bodySlice(extra_index, decls_len);
|
||||
extra_index += decls_len;
|
||||
|
||||
const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
|
||||
const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
});
|
||||
const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
|
||||
.layout = .auto,
|
||||
.fields_len = fields_len,
|
||||
@ -996,8 +1007,8 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
|
||||
zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
|
||||
zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
|
||||
|
||||
new_decl.name = try file.fullyQualifiedName(pt);
|
||||
new_decl.name_fully_qualified = true;
|
||||
new_decl.fqn = try file.internFullyQualifiedName(pt);
|
||||
new_decl.name = new_decl.fqn;
|
||||
new_decl.is_pub = true;
|
||||
new_decl.is_exported = false;
|
||||
new_decl.alignment = .none;
|
||||
@ -1016,7 +1027,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
|
||||
switch (zcu.comp.cache_use) {
|
||||
.whole => |whole| if (whole.cache_manifest) |man| {
|
||||
const source = file.getSource(gpa) catch |err| {
|
||||
try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});
|
||||
try pt.reportRetryableFileError(file_index, "unable to load source: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
|
||||
@ -1025,7 +1036,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
|
||||
file.mod.root.sub_path,
|
||||
file.sub_file_path,
|
||||
}) catch |err| {
|
||||
try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});
|
||||
try pt.reportRetryableFileError(file_index, "unable to resolve path: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
errdefer gpa.free(resolved_path);
|
||||
@ -1058,10 +1069,8 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
}
|
||||
|
||||
log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
|
||||
log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
|
||||
defer blk: {
|
||||
log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
|
||||
}
|
||||
log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});
|
||||
defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
|
||||
|
||||
const old_has_tv = decl.has_tv;
|
||||
// The following values are ignored if `!old_has_tv`
|
||||
@ -1084,7 +1093,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
const std_mod = zcu.std_mod;
|
||||
if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
|
||||
// We're in the std module.
|
||||
const std_file_imported = try zcu.importPkg(std_mod);
|
||||
const std_file_imported = try pt.importPkg(std_mod);
|
||||
const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
|
||||
const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
|
||||
const std_namespace = std_decl.getInnerNamespace(zcu).?;
|
||||
@ -1151,11 +1160,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
|
||||
defer sema.deinit();
|
||||
|
||||
// Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
|
||||
try sema.declareDependency(.{ .src_hash = try ip.trackZir(
|
||||
gpa,
|
||||
decl.getFileScopeIndex(zcu),
|
||||
decl_inst,
|
||||
) });
|
||||
try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = decl.getFileScopeIndex(zcu),
|
||||
.inst = decl_inst,
|
||||
}) });
|
||||
|
||||
var block_scope: Sema.Block = .{
|
||||
.parent = null,
|
||||
@ -1359,6 +1367,195 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem
|
||||
};
|
||||
}
|
||||
|
||||
pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// The resolved path is used as the key in the import table, to detect if
|
||||
// an import refers to the same as another, despite different relative paths
|
||||
// or differently mapped package names.
|
||||
const resolved_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
mod.root_src_path,
|
||||
});
|
||||
var keep_resolved_path = false;
|
||||
defer if (!keep_resolved_path) gpa.free(resolved_path);
|
||||
|
||||
const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
|
||||
errdefer _ = zcu.import_table.pop();
|
||||
if (gop.found_existing) {
|
||||
const file_index = gop.value_ptr.*;
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
try file.addReference(zcu, .{ .root = mod });
|
||||
return .{
|
||||
.file = file,
|
||||
.file_index = file_index,
|
||||
.is_new = false,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
const ip = &zcu.intern_pool;
|
||||
if (mod.builtin_file) |builtin_file| {
|
||||
const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path);
|
||||
const file_index = try ip.createFile(gpa, pt.tid, .{
|
||||
.bin_digest = path_digest,
|
||||
.file = builtin_file,
|
||||
.root_decl = .none,
|
||||
});
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = file_index;
|
||||
try builtin_file.addReference(zcu, .{ .root = mod });
|
||||
return .{
|
||||
.file = builtin_file,
|
||||
.file_index = file_index,
|
||||
.is_new = false,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
|
||||
errdefer gpa.free(sub_file_path);
|
||||
|
||||
const new_file = try gpa.create(Zcu.File);
|
||||
errdefer gpa.destroy(new_file);
|
||||
|
||||
const path_digest = zcu.computePathDigest(mod, sub_file_path);
|
||||
const new_file_index = try ip.createFile(gpa, pt.tid, .{
|
||||
.bin_digest = path_digest,
|
||||
.file = new_file,
|
||||
.root_decl = .none,
|
||||
});
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = new_file_index;
|
||||
new_file.* = .{
|
||||
.sub_file_path = sub_file_path,
|
||||
.source = undefined,
|
||||
.source_loaded = false,
|
||||
.tree_loaded = false,
|
||||
.zir_loaded = false,
|
||||
.stat = undefined,
|
||||
.tree = undefined,
|
||||
.zir = undefined,
|
||||
.status = .never_loaded,
|
||||
.mod = mod,
|
||||
};
|
||||
|
||||
try new_file.addReference(zcu, .{ .root = mod });
|
||||
return .{
|
||||
.file = new_file,
|
||||
.file_index = new_file_index,
|
||||
.is_new = true,
|
||||
.is_pkg = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Called from a worker thread during AstGen.
|
||||
/// Also called from Sema during semantic analysis.
|
||||
pub fn importFile(
|
||||
pt: Zcu.PerThread,
|
||||
cur_file: *Zcu.File,
|
||||
import_string: []const u8,
|
||||
) !Zcu.ImportFileResult {
|
||||
const zcu = pt.zcu;
|
||||
const mod = cur_file.mod;
|
||||
|
||||
if (std.mem.eql(u8, import_string, "std")) {
|
||||
return pt.importPkg(zcu.std_mod);
|
||||
}
|
||||
if (std.mem.eql(u8, import_string, "root")) {
|
||||
return pt.importPkg(zcu.root_mod);
|
||||
}
|
||||
if (mod.deps.get(import_string)) |pkg| {
|
||||
return pt.importPkg(pkg);
|
||||
}
|
||||
if (!std.mem.endsWith(u8, import_string, ".zig")) {
|
||||
return error.ModuleNotFound;
|
||||
}
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// The resolved path is used as the key in the import table, to detect if
|
||||
// an import refers to the same as another, despite different relative paths
|
||||
// or differently mapped package names.
|
||||
const resolved_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
cur_file.sub_file_path,
|
||||
"..",
|
||||
import_string,
|
||||
});
|
||||
|
||||
var keep_resolved_path = false;
|
||||
defer if (!keep_resolved_path) gpa.free(resolved_path);
|
||||
|
||||
const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
|
||||
errdefer _ = zcu.import_table.pop();
|
||||
if (gop.found_existing) {
|
||||
const file_index = gop.value_ptr.*;
|
||||
return .{
|
||||
.file = zcu.fileByIndex(file_index),
|
||||
.file_index = file_index,
|
||||
.is_new = false,
|
||||
.is_pkg = false,
|
||||
};
|
||||
}
|
||||
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const new_file = try gpa.create(Zcu.File);
|
||||
errdefer gpa.destroy(new_file);
|
||||
|
||||
const resolved_root_path = try std.fs.path.resolve(gpa, &.{
|
||||
mod.root.root_dir.path orelse ".",
|
||||
mod.root.sub_path,
|
||||
});
|
||||
defer gpa.free(resolved_root_path);
|
||||
|
||||
const sub_file_path = p: {
|
||||
const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
|
||||
errdefer gpa.free(relative);
|
||||
|
||||
if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
|
||||
break :p relative;
|
||||
}
|
||||
return error.ImportOutsideModulePath;
|
||||
};
|
||||
errdefer gpa.free(sub_file_path);
|
||||
|
||||
log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
|
||||
resolved_root_path, resolved_path, sub_file_path, import_string,
|
||||
});
|
||||
|
||||
const path_digest = zcu.computePathDigest(mod, sub_file_path);
|
||||
const new_file_index = try ip.createFile(gpa, pt.tid, .{
|
||||
.bin_digest = path_digest,
|
||||
.file = new_file,
|
||||
.root_decl = .none,
|
||||
});
|
||||
keep_resolved_path = true; // It's now owned by import_table.
|
||||
gop.value_ptr.* = new_file_index;
|
||||
new_file.* = .{
|
||||
.sub_file_path = sub_file_path,
|
||||
.source = undefined,
|
||||
.source_loaded = false,
|
||||
.tree_loaded = false,
|
||||
.zir_loaded = false,
|
||||
.stat = undefined,
|
||||
.tree = undefined,
|
||||
.zir = undefined,
|
||||
.status = .never_loaded,
|
||||
.mod = mod,
|
||||
};
|
||||
|
||||
return .{
|
||||
.file = new_file,
|
||||
.file_index = new_file_index,
|
||||
.is_new = true,
|
||||
.is_pkg = false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn embedFile(
|
||||
pt: Zcu.PerThread,
|
||||
cur_file: *Zcu.File,
|
||||
@ -1432,20 +1629,6 @@ pub fn embedFile(
|
||||
return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
|
||||
}
|
||||
|
||||
/// Cancel the creation of an anon decl and delete any references to it.
|
||||
/// If other decls depend on this decl, they must be aborted first.
|
||||
pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
|
||||
assert(!pt.zcu.declIsRoot(decl_index));
|
||||
pt.destroyDecl(decl_index);
|
||||
}
|
||||
|
||||
/// Finalize the creation of an anon decl.
|
||||
pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
|
||||
if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
|
||||
try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
|
||||
}
|
||||
}
|
||||
|
||||
/// https://github.com/ziglang/zig/issues/14307
|
||||
fn newEmbedFile(
|
||||
pt: Zcu.PerThread,
|
||||
@ -1718,7 +1901,10 @@ const ScanDeclIter = struct {
|
||||
}
|
||||
|
||||
const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
|
||||
const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
|
||||
const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = parent_file_scope_index,
|
||||
.inst = decl_inst,
|
||||
});
|
||||
|
||||
// We create a Decl for it regardless of analysis status.
|
||||
|
||||
@ -1728,6 +1914,7 @@ const ScanDeclIter = struct {
|
||||
const was_exported = decl.is_exported;
|
||||
assert(decl.kind == kind); // ZIR tracking should preserve this
|
||||
decl.name = decl_name;
|
||||
decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
|
||||
decl.is_pub = declaration.flags.is_pub;
|
||||
decl.is_exported = declaration.flags.is_export;
|
||||
break :decl_index .{ was_exported, decl_index };
|
||||
@ -1737,6 +1924,7 @@ const ScanDeclIter = struct {
|
||||
const new_decl = zcu.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
|
||||
new_decl.is_pub = declaration.flags.is_pub;
|
||||
new_decl.is_exported = declaration.flags.is_export;
|
||||
new_decl.zir_decl_index = tracked_inst.toOptional();
|
||||
@ -1761,10 +1949,9 @@ const ScanDeclIter = struct {
|
||||
if (!comp.config.is_test) break :a false;
|
||||
if (decl_mod != zcu.main_mod) break :a false;
|
||||
if (is_named_test and comp.test_filters.len > 0) {
|
||||
const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name);
|
||||
const decl_fqn_slice = decl_fqn.toSlice(ip);
|
||||
const decl_fqn = decl.fqn.toSlice(ip);
|
||||
for (comp.test_filters) |test_filter| {
|
||||
if (std.mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
|
||||
if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
|
||||
} else break :a false;
|
||||
}
|
||||
zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
|
||||
@ -1794,6 +1981,20 @@ const ScanDeclIter = struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// Cancel the creation of an anon decl and delete any references to it.
|
||||
/// If other decls depend on this decl, they must be aborted first.
|
||||
pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
|
||||
assert(!pt.zcu.declIsRoot(decl_index));
|
||||
pt.destroyDecl(decl_index);
|
||||
}
|
||||
|
||||
/// Finalize the creation of an anon decl.
|
||||
pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
|
||||
if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
|
||||
try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -1805,12 +2006,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
|
||||
defer blk: {
|
||||
log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
|
||||
}
|
||||
log.debug("func name '{}'", .{decl.fqn.fmt(ip)});
|
||||
defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
|
||||
|
||||
const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
|
||||
const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
|
||||
defer decl_prog_node.end();
|
||||
|
||||
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
|
||||
@ -1911,10 +2110,17 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
|
||||
runtime_params_len;
|
||||
|
||||
var runtime_param_index: usize = 0;
|
||||
for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {
|
||||
for (fn_info.param_body[0..src_params_len]) |inst| {
|
||||
const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
|
||||
if (gop.found_existing) continue; // provided above by comptime arg
|
||||
|
||||
const inst_info = sema.code.instructions.get(@intFromEnum(inst));
|
||||
const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {
|
||||
.param_anytype => inst_info.data.str_tok.start,
|
||||
.param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
|
||||
runtime_param_index += 1;
|
||||
|
||||
@ -1935,7 +2141,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
|
||||
.tag = .arg,
|
||||
.data = .{ .arg = .{
|
||||
.ty = Air.internedToRef(param_ty),
|
||||
.src_index = @intCast(src_param_index),
|
||||
.name = if (inner_block.ownerModule().strip)
|
||||
.none
|
||||
else
|
||||
@enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))),
|
||||
} },
|
||||
});
|
||||
}
|
||||
@ -2053,6 +2262,7 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
|
||||
const gpa = zcu.gpa;
|
||||
const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{
|
||||
.name = undefined,
|
||||
.fqn = undefined,
|
||||
.src_namespace = namespace,
|
||||
.has_tv = false,
|
||||
.owns_tv = false,
|
||||
@ -2077,6 +2287,36 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
|
||||
return decl_index;
|
||||
}
|
||||
|
||||
pub fn getErrorValue(
|
||||
pt: Zcu.PerThread,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) Allocator.Error!Zcu.ErrorInt {
|
||||
return pt.zcu.intern_pool.getErrorValue(pt.zcu.gpa, pt.tid, name);
|
||||
}
|
||||
|
||||
pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Zcu.ErrorInt {
|
||||
return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
|
||||
}
|
||||
|
||||
pub fn initNewAnonDecl(
|
||||
pt: Zcu.PerThread,
|
||||
new_decl_index: Zcu.Decl.Index,
|
||||
val: Value,
|
||||
name: InternPool.NullTerminatedString,
|
||||
fqn: InternPool.OptionalNullTerminatedString,
|
||||
) Allocator.Error!void {
|
||||
const new_decl = pt.zcu.declPtr(new_decl_index);
|
||||
|
||||
new_decl.name = name;
|
||||
new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
|
||||
.internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
|
||||
new_decl.val = val;
|
||||
new_decl.alignment = .none;
|
||||
new_decl.@"linksection" = .none;
|
||||
new_decl.has_tv = true;
|
||||
new_decl.analysis = .complete;
|
||||
}
|
||||
|
||||
fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
|
||||
switch (file.status) {
|
||||
.success_zir, .retryable_failure => {},
|
||||
@ -2229,7 +2469,7 @@ pub fn populateTestFunctions(
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
const builtin_mod = zcu.root_mod.getBuiltinDependency();
|
||||
const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;
|
||||
const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
|
||||
const root_decl_index = zcu.fileRootDecl(builtin_file_index);
|
||||
const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
|
||||
const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
|
||||
@ -2260,7 +2500,7 @@ pub fn populateTestFunctions(
|
||||
|
||||
for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
|
||||
const test_decl = zcu.declPtr(test_decl_index);
|
||||
const test_decl_name = try test_decl.fullyQualifiedName(pt);
|
||||
const test_decl_name = test_decl.fqn;
|
||||
const test_decl_name_len = test_decl_name.length(ip);
|
||||
const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
|
||||
const test_name_ty = try pt.arrayType(.{
|
||||
@ -2366,7 +2606,7 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
|
||||
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool), 0);
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0);
|
||||
defer codegen_prog_node.end();
|
||||
|
||||
if (comp.bin_file) |lf| {
|
||||
@ -2396,6 +2636,87 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reportRetryableAstGenError(
|
||||
pt: Zcu.PerThread,
|
||||
src: Zcu.AstGenSrc,
|
||||
file_index: Zcu.File.Index,
|
||||
err: anyerror,
|
||||
) error{OutOfMemory}!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
file.status = .retryable_failure;
|
||||
|
||||
const src_loc: Zcu.LazySrcLoc = switch (src) {
|
||||
.root => .{
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
.import => |info| .{
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = info.importing_file,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .{ .token_abs = info.import_tok },
|
||||
},
|
||||
};
|
||||
|
||||
const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
|
||||
file.mod.root, file.sub_file_path, @errorName(err),
|
||||
});
|
||||
errdefer err_msg.destroy(gpa);
|
||||
|
||||
{
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
try zcu.failed_files.putNoClobber(gpa, file, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reportRetryableFileError(
|
||||
pt: Zcu.PerThread,
|
||||
file_index: Zcu.File.Index,
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const file = zcu.fileByIndex(file_index);
|
||||
file.status = .retryable_failure;
|
||||
|
||||
const err_msg = try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
.{
|
||||
.base_node_inst = try ip.trackZir(gpa, pt.tid, .{
|
||||
.file = file_index,
|
||||
.inst = .main_struct_inst,
|
||||
}),
|
||||
.offset = .entire_file,
|
||||
},
|
||||
format,
|
||||
args,
|
||||
);
|
||||
errdefer err_msg.destroy(gpa);
|
||||
|
||||
zcu.comp.mutex.lock();
|
||||
defer zcu.comp.mutex.unlock();
|
||||
|
||||
const gop = try zcu.failed_files.getOrPut(gpa, file);
|
||||
if (gop.found_existing) {
|
||||
if (gop.value_ptr.*) |old_err_msg| {
|
||||
old_err_msg.destroy(gpa);
|
||||
}
|
||||
}
|
||||
gop.value_ptr.* = err_msg;
|
||||
}
|
||||
|
||||
/// Shortcut for calling `intern_pool.get`.
|
||||
pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
|
||||
return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
|
||||
@ -2897,7 +3218,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
|
||||
const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
|
||||
const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
|
||||
const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
|
||||
const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
|
||||
|
||||
@ -4231,19 +4231,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
while (self.args[arg_index] == .none) arg_index += 1;
|
||||
self.arg_index = arg_index + 1;
|
||||
|
||||
const pt = self.pt;
|
||||
const mod = pt.zcu;
|
||||
const ty = self.typeOfIndex(inst);
|
||||
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
|
||||
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const name = mod.getParamName(self.func_index, src_index);
|
||||
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
.ty = ty,
|
||||
.name = name,
|
||||
.mcv = self.args[arg_index],
|
||||
});
|
||||
const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
|
||||
if (name_nts != .none) {
|
||||
const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
.ty = ty,
|
||||
.name = name,
|
||||
.mcv = self.args[arg_index],
|
||||
});
|
||||
}
|
||||
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
|
||||
return self.finishAir(inst, result, .{ .none, .none, .none });
|
||||
|
||||
@ -4206,19 +4206,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
while (self.args[arg_index] == .none) arg_index += 1;
|
||||
self.arg_index = arg_index + 1;
|
||||
|
||||
const pt = self.pt;
|
||||
const mod = pt.zcu;
|
||||
const ty = self.typeOfIndex(inst);
|
||||
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
|
||||
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const name = mod.getParamName(self.func_index, src_index);
|
||||
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
.ty = ty,
|
||||
.name = name,
|
||||
.mcv = self.args[arg_index],
|
||||
});
|
||||
const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
|
||||
if (name_nts != .none) {
|
||||
const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
.ty = ty,
|
||||
.name = name,
|
||||
.mcv = self.args[arg_index],
|
||||
});
|
||||
}
|
||||
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
|
||||
return self.finishAir(inst, result, .{ .none, .none, .none });
|
||||
|
||||
@ -933,7 +933,7 @@ fn formatDecl(
|
||||
_: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer);
|
||||
try writer.print("{}", .{data.mod.declPtr(data.decl_index).fqn.fmt(&data.mod.intern_pool)});
|
||||
}
|
||||
fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
|
||||
return .{ .data = .{
|
||||
@ -4051,7 +4051,8 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
|
||||
const ty = arg.ty.toType();
|
||||
const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);
|
||||
const name = zcu.getParamName(func.func_index, arg.src_index);
|
||||
if (arg.name == .none) return;
|
||||
const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
|
||||
|
||||
switch (func.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
|
||||
@ -3614,7 +3614,8 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
|
||||
const ty = arg.ty.toType();
|
||||
const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
|
||||
const name = mod.getParamName(self.func_index, arg.src_index);
|
||||
if (arg.name == .none) return;
|
||||
const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
|
||||
@ -2585,11 +2585,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
switch (func.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
const src_index = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const name = mod.getParamName(func.func_index, src_index);
|
||||
try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
|
||||
.wasm_local = arg.local.value,
|
||||
});
|
||||
const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
|
||||
if (name_nts != .none) {
|
||||
const name = func.air.nullTerminatedString(@intFromEnum(name_nts));
|
||||
try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
|
||||
.wasm_local = arg.local.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -3302,7 +3304,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
|
||||
}
|
||||
},
|
||||
.err => |err| {
|
||||
const int = try mod.getErrorValue(err.name);
|
||||
const int = try pt.getErrorValue(err.name);
|
||||
return WValue{ .imm32 = int };
|
||||
},
|
||||
.error_union => |error_union| {
|
||||
@ -3450,30 +3452,25 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
|
||||
/// Returns a `Value` as a signed 32 bit value.
|
||||
/// It's illegal to provide a value with a type that cannot be represented
|
||||
/// as an integer value.
|
||||
fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
|
||||
fn valueAsI32(func: *const CodeGen, val: Value) i32 {
|
||||
const pt = func.pt;
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
switch (val.ip_index) {
|
||||
.none => {},
|
||||
switch (val.toIntern()) {
|
||||
.bool_true => return 1,
|
||||
.bool_false => return 0,
|
||||
else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
|
||||
.enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt),
|
||||
else => return switch (ip.indexToKey(val.ip_index)) {
|
||||
.enum_tag => |enum_tag| intIndexAsI32(ip, enum_tag.int, pt),
|
||||
.int => |int| intStorageAsI32(int.storage, pt),
|
||||
.ptr => |ptr| {
|
||||
assert(ptr.base_addr == .int);
|
||||
return @intCast(ptr.byte_offset);
|
||||
},
|
||||
.err => |err| @as(i32, @bitCast(@as(Zcu.ErrorInt, @intCast(mod.global_error_set.getIndex(err.name).?)))),
|
||||
.err => |err| @bitCast(ip.getErrorValueIfExists(err.name).?),
|
||||
else => unreachable,
|
||||
},
|
||||
}
|
||||
|
||||
return switch (ty.zigTypeTag(mod)) {
|
||||
.ErrorSet => @as(i32, @bitCast(val.getErrorInt(mod))),
|
||||
else => unreachable, // Programmer called this function for an illegal type
|
||||
};
|
||||
}
|
||||
|
||||
fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 {
|
||||
@ -4096,7 +4093,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
for (items, 0..) |ref, i| {
|
||||
const item_val = (try func.air.value(ref, pt)).?;
|
||||
const int_val = func.valueAsI32(item_val, target_ty);
|
||||
const int_val = func.valueAsI32(item_val);
|
||||
if (lowest_maybe == null or int_val < lowest_maybe.?) {
|
||||
lowest_maybe = int_val;
|
||||
}
|
||||
@ -7284,8 +7281,8 @@ 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).fullyQualifiedName(pt);
|
||||
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});
|
||||
const decl = mod.declPtr(enum_decl_index);
|
||||
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)});
|
||||
|
||||
// check if we already generated code for this.
|
||||
if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
|
||||
@ -7452,7 +7449,7 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
var lowest: ?u32 = null;
|
||||
var highest: ?u32 = null;
|
||||
for (0..names.len) |name_index| {
|
||||
const err_int: Zcu.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[name_index]).?);
|
||||
const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
|
||||
if (lowest) |*l| {
|
||||
if (err_int < l.*) {
|
||||
l.* = err_int;
|
||||
|
||||
@ -1077,7 +1077,7 @@ fn formatDecl(
|
||||
_: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
try data.zcu.declPtr(data.decl_index).renderFullyQualifiedName(data.zcu, writer);
|
||||
try writer.print("{}", .{data.zcu.declPtr(data.decl_index).fqn.fmt(&data.zcu.intern_pool)});
|
||||
}
|
||||
fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
|
||||
return .{ .data = .{
|
||||
@ -11920,9 +11920,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
else => return self.fail("TODO implement arg for {}", .{src_mcv}),
|
||||
};
|
||||
|
||||
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const name = mod.getParamName(self.owner.func_index, src_index);
|
||||
try self.genArgDbgInfo(arg_ty, name, src_mcv);
|
||||
const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
|
||||
switch (name_nts) {
|
||||
.none => {},
|
||||
_ => try self.genArgDbgInfo(arg_ty, self.air.nullTerminatedString(@intFromEnum(name_nts)), src_mcv),
|
||||
}
|
||||
|
||||
break :result dst_mcv;
|
||||
};
|
||||
@ -16433,7 +16435,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
|
||||
.size = .dword,
|
||||
.index = err_reg.to64(),
|
||||
.scale = .@"4",
|
||||
.disp = 4,
|
||||
.disp = (1 - 1) * 4,
|
||||
} },
|
||||
},
|
||||
);
|
||||
@ -16446,7 +16448,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
|
||||
.size = .dword,
|
||||
.index = err_reg.to64(),
|
||||
.scale = .@"4",
|
||||
.disp = 8,
|
||||
.disp = (2 - 1) * 4,
|
||||
} },
|
||||
},
|
||||
);
|
||||
|
||||
@ -137,10 +137,10 @@ pub fn generateLazySymbol(
|
||||
|
||||
if (lazy_sym.ty.isAnyError(pt.zcu)) {
|
||||
alignment.* = .@"4";
|
||||
const err_names = pt.zcu.global_error_set.keys();
|
||||
const err_names = ip.global_error_set.getNamesFromMainThread();
|
||||
mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
|
||||
var offset = code.items.len;
|
||||
try code.resize((1 + err_names.len + 1) * 4);
|
||||
try code.resize((err_names.len + 1) * 4);
|
||||
for (err_names) |err_name_nts| {
|
||||
const err_name = err_name_nts.toSlice(ip);
|
||||
mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
|
||||
@ -243,13 +243,13 @@ pub fn generateSymbol(
|
||||
int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
|
||||
},
|
||||
.err => |err| {
|
||||
const int = try mod.getErrorValue(err.name);
|
||||
const int = try pt.getErrorValue(err.name);
|
||||
try code.writer().writeInt(u16, @intCast(int), endian);
|
||||
},
|
||||
.error_union => |error_union| {
|
||||
const payload_ty = ty.errorUnionPayload(mod);
|
||||
const err_val: u16 = switch (error_union.val) {
|
||||
.err_name => |err_name| @intCast(try mod.getErrorValue(err_name)),
|
||||
.err_name => |err_name| @intCast(try pt.getErrorValue(err_name)),
|
||||
.payload => 0,
|
||||
};
|
||||
|
||||
@ -1058,7 +1058,7 @@ pub fn genTypedValue(
|
||||
},
|
||||
.ErrorSet => {
|
||||
const err_name = ip.indexToKey(val.toIntern()).err.name;
|
||||
const error_index = zcu.global_error_set.getIndex(err_name).?;
|
||||
const error_index = try pt.getErrorValue(err_name);
|
||||
return GenResult.mcv(.{ .immediate = error_index });
|
||||
},
|
||||
.ErrorUnion => {
|
||||
|
||||
@ -2194,13 +2194,9 @@ pub const DeclGen = struct {
|
||||
}) 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.
|
||||
var name: [100]u8 = undefined;
|
||||
var name_stream = std.io.fixedBufferStream(&name);
|
||||
decl.renderFullyQualifiedName(zcu, name_stream.writer()) catch |err| switch (err) {
|
||||
error.NoSpaceLeft => {},
|
||||
};
|
||||
const fqn_slice = decl.fqn.toSlice(ip);
|
||||
try writer.print("{}__{d}", .{
|
||||
fmtIdent(name_stream.getWritten()),
|
||||
fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
|
||||
@intFromEnum(decl_index),
|
||||
});
|
||||
}
|
||||
@ -2587,11 +2583,9 @@ pub fn genTypeDecl(
|
||||
try writer.writeByte(';');
|
||||
const owner_decl = zcu.declPtr(owner_decl_index);
|
||||
const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;
|
||||
if (!owner_mod.strip) {
|
||||
try writer.writeAll(" /* ");
|
||||
try owner_decl.renderFullyQualifiedName(zcu, writer);
|
||||
try writer.writeAll(" */");
|
||||
}
|
||||
if (!owner_mod.strip) try writer.print(" /* {} */", .{
|
||||
owner_decl.fqn.fmt(&zcu.intern_pool),
|
||||
});
|
||||
try writer.writeByte('\n');
|
||||
},
|
||||
},
|
||||
@ -2628,10 +2622,11 @@ pub fn genErrDecls(o: *Object) !void {
|
||||
|
||||
var max_name_len: usize = 0;
|
||||
// do not generate an invalid empty enum when the global error set is empty
|
||||
if (zcu.global_error_set.keys().len > 1) {
|
||||
const names = ip.global_error_set.getNamesFromMainThread();
|
||||
if (names.len > 0) {
|
||||
try writer.writeAll("enum {\n");
|
||||
o.indent_writer.pushIndent();
|
||||
for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {
|
||||
for (names, 1..) |name_nts, value| {
|
||||
const name = name_nts.toSlice(ip);
|
||||
max_name_len = @max(name.len, max_name_len);
|
||||
const err_val = try pt.intern(.{ .err = .{
|
||||
@ -2650,7 +2645,7 @@ pub fn genErrDecls(o: *Object) !void {
|
||||
defer o.dg.gpa.free(name_buf);
|
||||
|
||||
@memcpy(name_buf[0..name_prefix.len], name_prefix);
|
||||
for (zcu.global_error_set.keys()) |name| {
|
||||
for (names) |name| {
|
||||
const name_slice = name.toSlice(ip);
|
||||
@memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);
|
||||
const identifier = name_buf[0 .. name_prefix.len + name_slice.len];
|
||||
@ -2680,7 +2675,7 @@ pub fn genErrDecls(o: *Object) !void {
|
||||
}
|
||||
|
||||
const name_array_ty = try pt.arrayType(.{
|
||||
.len = zcu.global_error_set.count(),
|
||||
.len = 1 + names.len,
|
||||
.child = .slice_const_u8_sentinel_0_type,
|
||||
});
|
||||
|
||||
@ -2694,9 +2689,9 @@ pub fn genErrDecls(o: *Object) !void {
|
||||
.complete,
|
||||
);
|
||||
try writer.writeAll(" = {");
|
||||
for (zcu.global_error_set.keys(), 0..) |name_nts, value| {
|
||||
for (names, 1..) |name_nts, val| {
|
||||
const name = name_nts.toSlice(ip);
|
||||
if (value != 0) try writer.writeByte(',');
|
||||
if (val > 1) try writer.writeAll(", ");
|
||||
try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
|
||||
fmtIdent(name),
|
||||
try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer),
|
||||
@ -4563,9 +4558,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
|
||||
const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
|
||||
const writer = f.object.writer();
|
||||
try writer.writeAll("/* inline:");
|
||||
try owner_decl.renderFullyQualifiedName(zcu, writer);
|
||||
try writer.writeAll(" */\n");
|
||||
try writer.print("/* inline:{} */\n", .{owner_decl.fqn.fmt(&zcu.intern_pool)});
|
||||
return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
|
||||
}
|
||||
|
||||
@ -6881,7 +6874,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
try writer.writeAll(" = zig_errorName[");
|
||||
try f.writeCValue(writer, operand, .Other);
|
||||
try writer.writeAll("];\n");
|
||||
try writer.writeAll(" - 1];\n");
|
||||
return local;
|
||||
}
|
||||
|
||||
|
||||
@ -1036,20 +1036,21 @@ pub const Object = struct {
|
||||
|
||||
const pt = o.pt;
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
const error_name_list = mod.global_error_set.keys();
|
||||
const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len);
|
||||
const error_name_list = ip.global_error_set.getNamesFromMainThread();
|
||||
const llvm_errors = try mod.gpa.alloc(Builder.Constant, 1 + error_name_list.len);
|
||||
defer mod.gpa.free(llvm_errors);
|
||||
|
||||
// TODO: Address space
|
||||
const slice_ty = Type.slice_const_u8_sentinel_0;
|
||||
const llvm_usize_ty = try o.lowerType(Type.usize);
|
||||
const llvm_slice_ty = try o.lowerType(slice_ty);
|
||||
const llvm_table_ty = try o.builder.arrayType(error_name_list.len, llvm_slice_ty);
|
||||
const llvm_table_ty = try o.builder.arrayType(1 + error_name_list.len, llvm_slice_ty);
|
||||
|
||||
llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty);
|
||||
for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name| {
|
||||
const name_string = try o.builder.stringNull(name.toSlice(&mod.intern_pool));
|
||||
for (llvm_errors[1..], error_name_list) |*llvm_error, name| {
|
||||
const name_string = try o.builder.stringNull(name.toSlice(ip));
|
||||
const name_init = try o.builder.stringConst(name_string);
|
||||
const name_variable_index =
|
||||
try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
|
||||
@ -1085,7 +1086,7 @@ pub const Object = struct {
|
||||
// If there is no such function in the module, it means the source code does not need it.
|
||||
const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
|
||||
const llvm_fn = o.builder.getGlobal(name) orelse return;
|
||||
const errors_len = o.pt.zcu.global_error_set.count();
|
||||
const errors_len = o.pt.zcu.intern_pool.global_error_set.mutate.list.len;
|
||||
|
||||
var wip = try Builder.WipFunction.init(&o.builder, .{
|
||||
.function = llvm_fn.ptrConst(&o.builder).kind.function,
|
||||
@ -1096,12 +1097,12 @@ pub const Object = struct {
|
||||
|
||||
// Example source of the following LLVM IR:
|
||||
// fn __zig_lt_errors_len(index: u16) bool {
|
||||
// return index < total_errors_len;
|
||||
// return index <= total_errors_len;
|
||||
// }
|
||||
|
||||
const lhs = wip.arg(0);
|
||||
const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);
|
||||
const is_lt = try wip.icmp(.ult, lhs, rhs, "");
|
||||
const is_lt = try wip.icmp(.ule, lhs, rhs, "");
|
||||
_ = try wip.ret(is_lt);
|
||||
try wip.finish();
|
||||
}
|
||||
@ -1744,7 +1745,7 @@ pub const Object = struct {
|
||||
if (export_indices.len != 0) {
|
||||
return updateExportedGlobal(self, zcu, global_index, export_indices);
|
||||
} else {
|
||||
const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(pt)).toSlice(ip));
|
||||
const fqn = try self.builder.strtabString(decl.fqn.toSlice(ip));
|
||||
try global_index.rename(fqn, &self.builder);
|
||||
global_index.setLinkage(.internal, &self.builder);
|
||||
if (comp.config.dll_export_fns)
|
||||
@ -2811,7 +2812,7 @@ pub const Object = struct {
|
||||
const zcu = pt.zcu;
|
||||
|
||||
const std_mod = zcu.std_mod;
|
||||
const std_file_imported = zcu.importPkg(std_mod) catch unreachable;
|
||||
const std_file_imported = pt.importPkg(std_mod) catch unreachable;
|
||||
|
||||
const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
|
||||
const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
|
||||
@ -2863,10 +2864,7 @@ pub const Object = struct {
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.lowerType(zig_fn_type),
|
||||
try o.builder.strtabString((if (is_extern)
|
||||
decl.name
|
||||
else
|
||||
try decl.fullyQualifiedName(pt)).toSlice(ip)),
|
||||
try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
|
||||
toLlvmAddressSpace(decl.@"addrspace", target),
|
||||
);
|
||||
gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
|
||||
@ -3077,14 +3075,12 @@ pub const Object = struct {
|
||||
|
||||
const pt = o.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
|
||||
const variable_index = try o.builder.addVariable(
|
||||
try o.builder.strtabString((if (is_extern)
|
||||
decl.name
|
||||
else
|
||||
try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)),
|
||||
try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
|
||||
try o.lowerType(decl.typeOf(zcu)),
|
||||
toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
|
||||
);
|
||||
@ -3312,7 +3308,7 @@ pub const Object = struct {
|
||||
return int_ty;
|
||||
}
|
||||
|
||||
const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt);
|
||||
const decl = mod.declPtr(struct_type.decl.unwrap().?);
|
||||
|
||||
var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
|
||||
defer llvm_field_types.deinit(o.gpa);
|
||||
@ -3377,7 +3373,7 @@ pub const Object = struct {
|
||||
);
|
||||
}
|
||||
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
o.builder.namedTypeSetBody(
|
||||
@ -3466,7 +3462,7 @@ pub const Object = struct {
|
||||
return enum_tag_ty;
|
||||
}
|
||||
|
||||
const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt);
|
||||
const decl = mod.declPtr(union_obj.decl);
|
||||
|
||||
const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
|
||||
const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
|
||||
@ -3486,7 +3482,7 @@ pub const Object = struct {
|
||||
};
|
||||
|
||||
if (layout.tag_size == 0) {
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
o.builder.namedTypeSetBody(
|
||||
@ -3514,7 +3510,7 @@ pub const Object = struct {
|
||||
llvm_fields_len += 1;
|
||||
}
|
||||
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
|
||||
const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
|
||||
try o.type_map.put(o.gpa, t.toIntern(), ty);
|
||||
|
||||
o.builder.namedTypeSetBody(
|
||||
@ -3527,8 +3523,7 @@ pub const Object = struct {
|
||||
const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
|
||||
if (!gop.found_existing) {
|
||||
const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
|
||||
gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
|
||||
}
|
||||
return gop.value_ptr.*;
|
||||
},
|
||||
@ -3826,7 +3821,7 @@ pub const Object = struct {
|
||||
return lowerBigInt(o, ty, bigint);
|
||||
},
|
||||
.err => |err| {
|
||||
const int = try mod.getErrorValue(err.name);
|
||||
const int = try pt.getErrorValue(err.name);
|
||||
const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
|
||||
return llvm_int;
|
||||
},
|
||||
@ -4587,11 +4582,11 @@ pub const Object = struct {
|
||||
|
||||
const usize_ty = try o.lowerType(Type.usize);
|
||||
const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
|
||||
const decl = zcu.declPtr(enum_type.decl);
|
||||
const target = zcu.root_mod.resolved_target.result;
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
|
||||
try o.builder.strtabStringFmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
|
||||
try o.builder.strtabStringFmt("__zig_tag_name_{}", .{decl.fqn.fmt(ip)}),
|
||||
toLlvmAddressSpace(.generic, target),
|
||||
);
|
||||
|
||||
@ -5175,8 +5170,6 @@ pub const FuncGen = struct {
|
||||
const line_number = decl.navSrcLine(zcu) + 1;
|
||||
self.inlined = self.wip.debug_location;
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const fn_ty = try pt.funcType(.{
|
||||
.param_types = &.{},
|
||||
.return_type = .void_type,
|
||||
@ -5185,7 +5178,7 @@ pub const FuncGen = struct {
|
||||
self.scope = try o.builder.debugSubprogram(
|
||||
self.file,
|
||||
try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),
|
||||
try o.builder.metadataString(fqn.toSlice(&zcu.intern_pool)),
|
||||
try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
|
||||
line_number,
|
||||
line_number + func.lbrace_line,
|
||||
try o.lowerDebugType(fn_ty),
|
||||
@ -8867,19 +8860,21 @@ pub const FuncGen = struct {
|
||||
self.arg_index += 1;
|
||||
|
||||
// llvm does not support debug info for naked function arguments
|
||||
if (self.wip.strip or self.is_naked) return arg_val;
|
||||
if (self.is_naked) return arg_val;
|
||||
|
||||
const inst_ty = self.typeOfIndex(inst);
|
||||
if (needDbgVarWorkaround(o)) return arg_val;
|
||||
|
||||
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
|
||||
const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
|
||||
if (name == .none) return arg_val;
|
||||
|
||||
const func_index = self.dg.decl.getOwnedFunctionIndex();
|
||||
const func = mod.funcInfo(func_index);
|
||||
const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
|
||||
const lbrace_col = func.lbrace_column + 1;
|
||||
|
||||
const debug_parameter = try o.builder.debugParameter(
|
||||
try o.builder.metadataString(mod.getParamName(func_index, src_index)),
|
||||
try o.builder.metadataString(self.air.nullTerminatedString(@intFromEnum(name))),
|
||||
self.file,
|
||||
self.scope,
|
||||
lbrace_line,
|
||||
@ -9664,7 +9659,7 @@ pub const FuncGen = struct {
|
||||
defer wip_switch.finish(&self.wip);
|
||||
|
||||
for (0..names.len) |name_index| {
|
||||
const err_int = mod.global_error_set.getIndex(names.get(ip)[name_index]).?;
|
||||
const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
|
||||
const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
|
||||
try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
|
||||
}
|
||||
@ -9702,18 +9697,19 @@ pub const FuncGen = struct {
|
||||
const o = self.dg.object;
|
||||
const pt = o.pt;
|
||||
const zcu = pt.zcu;
|
||||
const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());
|
||||
const ip = &zcu.intern_pool;
|
||||
const enum_type = ip.loadEnumType(enum_ty.toIntern());
|
||||
|
||||
// TODO: detect when the type changes and re-emit this function.
|
||||
const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
|
||||
if (gop.found_existing) return gop.value_ptr.*;
|
||||
errdefer assert(o.named_enum_map.remove(enum_type.decl));
|
||||
|
||||
const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
|
||||
const decl = zcu.declPtr(enum_type.decl);
|
||||
const target = zcu.root_mod.resolved_target.result;
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
|
||||
try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}),
|
||||
try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{decl.fqn.fmt(ip)}),
|
||||
toLlvmAddressSpace(.generic, target),
|
||||
);
|
||||
|
||||
|
||||
@ -963,7 +963,7 @@ const DeclGen = struct {
|
||||
break :cache result_id;
|
||||
},
|
||||
.err => |err| {
|
||||
const value = try mod.getErrorValue(err.name);
|
||||
const value = try pt.getErrorValue(err.name);
|
||||
break :cache try self.constInt(ty, value, repr);
|
||||
},
|
||||
.error_union => |error_union| {
|
||||
@ -3012,12 +3012,11 @@ const DeclGen = struct {
|
||||
// Append the actual code into the functions section.
|
||||
try self.spv.addFunction(spv_decl_index, self.func);
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugName(result_id, fqn.toSlice(ip));
|
||||
try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
|
||||
|
||||
// Temporarily generate a test kernel declaration if this is a test function.
|
||||
if (self.pt.zcu.test_functions.contains(self.decl_index)) {
|
||||
try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index);
|
||||
try self.generateTestEntryPoint(decl.fqn.toSlice(ip), spv_decl_index);
|
||||
}
|
||||
},
|
||||
.global => {
|
||||
@ -3041,8 +3040,7 @@ const DeclGen = struct {
|
||||
.storage_class = final_storage_class,
|
||||
});
|
||||
|
||||
const fqn = try decl.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugName(result_id, fqn.toSlice(ip));
|
||||
try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
|
||||
try self.spv.declareDeclDeps(spv_decl_index, &.{});
|
||||
},
|
||||
.invocation_global => {
|
||||
@ -3086,8 +3084,7 @@ 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.fullyQualifiedName(self.pt);
|
||||
try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});
|
||||
try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{decl.fqn.fmt(ip)});
|
||||
|
||||
try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
|
||||
.id_result_type = ptr_ty_id,
|
||||
|
||||
@ -1176,9 +1176,10 @@ pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index:
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{
|
||||
decl.fqn.fmt(&mod.intern_pool), index,
|
||||
});
|
||||
defer gpa.free(sym_name);
|
||||
const ty = val.typeOf(mod);
|
||||
const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {
|
||||
@ -1427,9 +1428,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
const mod = pt.zcu;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(&mod.intern_pool), decl });
|
||||
const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
|
||||
|
||||
const decl_metadata = self.decls.get(decl_index).?;
|
||||
@ -1441,7 +1440,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
|
||||
if (atom.size != 0) {
|
||||
const sym = atom.getSymbolPtr(self);
|
||||
try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));
|
||||
try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
|
||||
sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
|
||||
sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
|
||||
|
||||
@ -1449,7 +1448,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
|
||||
if (need_realloc) {
|
||||
const vaddr = try self.growAtom(atom_index, code_len, required_alignment);
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), sym.value, vaddr });
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), sym.value, vaddr });
|
||||
log.debug(" (required alignment 0x{x}", .{required_alignment});
|
||||
|
||||
if (vaddr != sym.value) {
|
||||
@ -1465,13 +1464,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
|
||||
self.getAtomPtr(atom_index).size = code_len;
|
||||
} else {
|
||||
const sym = atom.getSymbolPtr(self);
|
||||
try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));
|
||||
try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
|
||||
sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
|
||||
sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
|
||||
|
||||
const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
|
||||
errdefer self.freeAtom(atom_index);
|
||||
log.debug("allocated atom for {} at 0x{x}", .{ decl_name.fmt(&mod.intern_pool), vaddr });
|
||||
log.debug("allocated atom for {} at 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), vaddr });
|
||||
self.getAtomPtr(atom_index).size = code_len;
|
||||
sym.value = vaddr;
|
||||
|
||||
|
||||
@ -1082,9 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
|
||||
defer tracy.end();
|
||||
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_linkage_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
const gpa = self.allocator;
|
||||
var decl_state: DeclState = .{
|
||||
@ -1157,7 +1155,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
|
||||
|
||||
// .debug_info subprogram
|
||||
const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);
|
||||
const decl_linkage_name_slice = decl_linkage_name.toSlice(&pt.zcu.intern_pool);
|
||||
const decl_linkage_name_slice = decl.fqn.toSlice(&pt.zcu.intern_pool);
|
||||
try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
|
||||
(decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
|
||||
|
||||
@ -2700,7 +2698,7 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
|
||||
try addDbgInfoErrorSetNames(
|
||||
pt,
|
||||
Type.anyerror,
|
||||
pt.zcu.global_error_set.keys(),
|
||||
pt.zcu.intern_pool.global_error_set.getNamesFromMainThread(),
|
||||
target,
|
||||
&dbg_info_buffer,
|
||||
);
|
||||
@ -2869,7 +2867,7 @@ fn addDbgInfoErrorSetNames(
|
||||
mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
|
||||
|
||||
for (error_names) |error_name| {
|
||||
const int = try pt.zcu.getErrorValue(error_name);
|
||||
const int = try pt.getErrorValue(error_name);
|
||||
const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
|
||||
// DW.AT.enumerator
|
||||
try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));
|
||||
|
||||
@ -907,10 +907,10 @@ fn updateDeclCode(
|
||||
) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
|
||||
|
||||
const required_alignment = decl.getAlignment(pt).max(
|
||||
target_util.minFunctionAlignment(mod.getTarget()),
|
||||
@ -923,7 +923,7 @@ fn updateDeclCode(
|
||||
sym.output_section_index = shdr_index;
|
||||
atom_ptr.output_section_index = shdr_index;
|
||||
|
||||
sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
|
||||
sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
|
||||
atom_ptr.flags.alive = true;
|
||||
atom_ptr.name_offset = sym.name_offset;
|
||||
esym.st_name = sym.name_offset;
|
||||
@ -940,7 +940,7 @@ fn updateDeclCode(
|
||||
const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
|
||||
if (need_realloc) {
|
||||
try atom_ptr.grow(elf_file);
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom_ptr.value });
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom_ptr.value });
|
||||
if (old_vaddr != atom_ptr.value) {
|
||||
sym.value = 0;
|
||||
esym.st_value = 0;
|
||||
@ -1007,11 +1007,11 @@ fn updateTlv(
|
||||
code: []const u8,
|
||||
) !void {
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
const gpa = mod.gpa;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(ip), decl });
|
||||
|
||||
const required_alignment = decl.getAlignment(pt);
|
||||
|
||||
@ -1023,7 +1023,7 @@ fn updateTlv(
|
||||
sym.output_section_index = shndx;
|
||||
atom_ptr.output_section_index = shndx;
|
||||
|
||||
sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
|
||||
sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
|
||||
atom_ptr.flags.alive = true;
|
||||
atom_ptr.name_offset = sym.name_offset;
|
||||
esym.st_value = 0;
|
||||
@ -1286,9 +1286,8 @@ pub fn lowerUnnamedConst(
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
|
||||
defer gpa.free(name);
|
||||
const ty = val.typeOf(mod);
|
||||
const sym_index = switch (try self.lowerConst(
|
||||
@ -1473,9 +1472,8 @@ pub fn updateDeclLineNumber(
|
||||
defer tracy.end();
|
||||
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
if (self.dwarf) |*dw| {
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
|
||||
@ -809,10 +809,10 @@ fn updateDeclCode(
|
||||
) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const mod = pt.zcu;
|
||||
const ip = &mod.intern_pool;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
|
||||
log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
|
||||
|
||||
const required_alignment = decl.getAlignment(pt);
|
||||
|
||||
@ -824,7 +824,7 @@ fn updateDeclCode(
|
||||
sym.out_n_sect = sect_index;
|
||||
atom.out_n_sect = sect_index;
|
||||
|
||||
sym.name = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
|
||||
sym.name = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
|
||||
atom.flags.alive = true;
|
||||
atom.name = sym.name;
|
||||
nlist.n_strx = sym.name;
|
||||
@ -843,7 +843,7 @@ fn updateDeclCode(
|
||||
|
||||
if (need_realloc) {
|
||||
try atom.grow(macho_file);
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom.value });
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom.value });
|
||||
if (old_vaddr != atom.value) {
|
||||
sym.value = 0;
|
||||
nlist.n_value = 0;
|
||||
@ -893,25 +893,22 @@ fn updateTlv(
|
||||
sect_index: u8,
|
||||
code: []const u8,
|
||||
) !void {
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
const decl_name_slice = decl_name.toSlice(&pt.zcu.intern_pool);
|
||||
const required_alignment = decl.getAlignment(pt);
|
||||
log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
|
||||
|
||||
// 1. Lower TLV initializer
|
||||
const init_sym_index = try self.createTlvInitializer(
|
||||
macho_file,
|
||||
decl_name_slice,
|
||||
required_alignment,
|
||||
decl.fqn.toSlice(ip),
|
||||
decl.getAlignment(pt),
|
||||
sect_index,
|
||||
code,
|
||||
);
|
||||
|
||||
// 2. Create TLV descriptor
|
||||
try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl_name_slice);
|
||||
try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl.fqn.toSlice(ip));
|
||||
}
|
||||
|
||||
fn createTlvInitializer(
|
||||
@ -1099,9 +1096,8 @@ pub fn lowerUnnamedConst(
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
|
||||
defer gpa.free(name);
|
||||
const sym_index = switch (try self.lowerConst(
|
||||
macho_file,
|
||||
|
||||
@ -483,11 +483,9 @@ pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index
|
||||
}
|
||||
const unnamed_consts = gop.value_ptr;
|
||||
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
const index = unnamed_consts.items.len;
|
||||
// name is freed when the unnamed const is freed
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
|
||||
|
||||
const sym_index = try self.allocateSymbolIndex();
|
||||
const new_atom_idx = try self.createAtom();
|
||||
|
||||
@ -227,9 +227,9 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
var error_info = std.ArrayList(u8).init(self.object.gpa);
|
||||
defer error_info.deinit();
|
||||
|
||||
try error_info.appendSlice("zig_errors");
|
||||
const mod = self.base.comp.module.?;
|
||||
for (mod.global_error_set.keys()) |name| {
|
||||
try error_info.appendSlice("zig_errors:");
|
||||
const ip = &self.base.comp.module.?.intern_pool;
|
||||
for (ip.global_error_set.getNamesFromMainThread()) |name| {
|
||||
// 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.
|
||||
@ -238,7 +238,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
try error_info.append(':');
|
||||
try std.Uri.Component.percentEncode(
|
||||
error_info.writer(),
|
||||
name.toSlice(&mod.intern_pool),
|
||||
name.toSlice(ip),
|
||||
struct {
|
||||
fn isValidChar(c: u8) bool {
|
||||
return switch (c) {
|
||||
|
||||
@ -346,8 +346,7 @@ fn finishUpdateDecl(
|
||||
const atom_index = decl_info.atom;
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
const sym = zig_object.symbol(atom.sym_index);
|
||||
const full_name = try decl.fullyQualifiedName(pt);
|
||||
sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip));
|
||||
sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(ip));
|
||||
try atom.code.appendSlice(gpa, code);
|
||||
atom.size = @intCast(code.len);
|
||||
|
||||
@ -387,7 +386,7 @@ fn finishUpdateDecl(
|
||||
// Will be freed upon freeing of decl or after cleanup of Wasm binary.
|
||||
const full_segment_name = try std.mem.concat(gpa, u8, &.{
|
||||
segment_name,
|
||||
full_name.toSlice(ip),
|
||||
decl.fqn.toSlice(ip),
|
||||
});
|
||||
errdefer gpa.free(full_segment_name);
|
||||
sym.tag = .data;
|
||||
@ -436,9 +435,8 @@ pub fn getOrCreateAtomForDecl(
|
||||
const sym_index = try zig_object.allocateSymbol(gpa);
|
||||
gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const full_name = try decl.fullyQualifiedName(pt);
|
||||
const sym = zig_object.symbol(sym_index);
|
||||
sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&pt.zcu.intern_pool));
|
||||
sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(&pt.zcu.intern_pool));
|
||||
}
|
||||
return gop.value_ptr.atom;
|
||||
}
|
||||
@ -494,9 +492,8 @@ pub fn lowerUnnamedConst(
|
||||
const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
|
||||
const parent_atom = wasm_file.getAtom(parent_atom_index);
|
||||
const local_index = parent_atom.locals.items.len;
|
||||
const fqn = try decl.fullyQualifiedName(pt);
|
||||
const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
|
||||
fqn.fmt(&mod.intern_pool), local_index,
|
||||
decl.fqn.fmt(&mod.intern_pool), local_index,
|
||||
});
|
||||
defer gpa.free(name);
|
||||
|
||||
@ -655,13 +652,22 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
|
||||
// Addend for each relocation to the table
|
||||
var addend: u32 = 0;
|
||||
const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };
|
||||
for (pt.zcu.global_error_set.keys()) |error_name| {
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
const slice_ty = Type.slice_const_u8_sentinel_0;
|
||||
const atom = wasm_file.getAtomPtr(atom_index);
|
||||
{
|
||||
// TODO: remove this unreachable entry
|
||||
try atom.code.appendNTimes(gpa, 0, 4);
|
||||
try atom.code.writer(gpa).writeInt(u32, 0, .little);
|
||||
atom.size += @intCast(slice_ty.abiSize(pt));
|
||||
addend += 1;
|
||||
|
||||
const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
|
||||
try names_atom.code.append(gpa, 0);
|
||||
}
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
for (ip.global_error_set.getNamesFromMainThread()) |error_name| {
|
||||
const error_name_slice = error_name.toSlice(ip);
|
||||
const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated
|
||||
|
||||
const slice_ty = Type.slice_const_u8_sentinel_0;
|
||||
const offset = @as(u32, @intCast(atom.code.items.len));
|
||||
// first we create the data for the slice of the name
|
||||
try atom.code.appendNTimes(gpa, 0, 4); // ptr to name, will be relocated
|
||||
@ -680,7 +686,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
|
||||
try names_atom.code.ensureUnusedCapacity(gpa, len);
|
||||
names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);
|
||||
|
||||
log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)});
|
||||
log.debug("Populated error name: '{}'", .{error_name.fmt(ip)});
|
||||
}
|
||||
names_atom.size = addend;
|
||||
zig_object.error_names_atom = names_atom_index;
|
||||
@ -1045,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
|
||||
const gpa = wasm_file.base.comp.gpa;
|
||||
const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;
|
||||
|
||||
const errors_len = wasm_file.base.comp.module.?.global_error_set.count();
|
||||
const errors_len = 1 + wasm_file.base.comp.module.?.intern_pool.global_error_set.mutate.list.len;
|
||||
// overwrite existing atom if it already exists (maybe the error set has increased)
|
||||
// if not, allcoate a new atom.
|
||||
const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {
|
||||
@ -1127,9 +1133,7 @@ pub fn updateDeclLineNumber(
|
||||
) !void {
|
||||
if (zig_object.dwarf) |*dw| {
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
const decl_name = try decl.fullyQualifiedName(pt);
|
||||
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +356,13 @@ const Writer = struct {
|
||||
fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
|
||||
try w.writeType(s, arg.ty.toType());
|
||||
try s.print(", {d}", .{arg.src_index});
|
||||
switch (arg.name) {
|
||||
.none => {},
|
||||
_ => {
|
||||
const name = w.air.nullTerminatedString(@intFromEnum(arg.name));
|
||||
try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
|
||||
@ -299,8 +299,8 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
|
||||
int.ptr_ty.fmt(pt),
|
||||
int.addr,
|
||||
}),
|
||||
.decl_ptr => |decl| {
|
||||
try zcu.declPtr(decl).renderFullyQualifiedName(zcu, writer);
|
||||
.decl_ptr => |decl_index| {
|
||||
try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)});
|
||||
},
|
||||
.anon_decl_ptr => |anon| {
|
||||
const ty = Value.fromInterned(anon.val).typeOf(zcu);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user