mirror of
https://github.com/ziglang/zig.git
synced 2024-11-28 08:02:32 +00:00
Zir: store extra source hashes required for incremental
Also add corresponding invaidation logic to Zcu. Therefore, the only invalidation logic which is not yet in place is `decl_val` dependencies.
This commit is contained in:
parent
7f4bd247c7
commit
1e91ee1e05
@ -27,11 +27,12 @@ pub const parseNumberLiteral = number_literal.parseNumberLiteral;
|
||||
pub const c_builtins = @import("zig/c_builtins.zig");
|
||||
pub const c_translation = @import("zig/c_translation.zig");
|
||||
|
||||
pub const SrcHasher = std.crypto.hash.Blake3;
|
||||
pub const SrcHash = [16]u8;
|
||||
|
||||
pub fn hashSrc(src: []const u8) SrcHash {
|
||||
var out: SrcHash = undefined;
|
||||
std.crypto.hash.Blake3.hash(src, &out, .{});
|
||||
SrcHasher.hash(src, &out, .{});
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -41,7 +42,7 @@ pub fn srcHashEql(a: SrcHash, b: SrcHash) bool {
|
||||
|
||||
pub fn hashName(parent_hash: SrcHash, sep: []const u8, name: []const u8) SrcHash {
|
||||
var out: SrcHash = undefined;
|
||||
var hasher = std.crypto.hash.Blake3.init(.{});
|
||||
var hasher = SrcHasher.init(.{});
|
||||
hasher.update(&parent_hash);
|
||||
hasher.update(sep);
|
||||
hasher.update(name);
|
||||
|
109
src/AstGen.zig
109
src/AstGen.zig
@ -4815,6 +4815,7 @@ fn structDeclInner(
|
||||
.any_comptime_fields = false,
|
||||
.any_default_inits = false,
|
||||
.any_aligned_fields = false,
|
||||
.fields_hash = std.zig.hashSrc(@tagName(layout)),
|
||||
});
|
||||
return decl_inst.toRef();
|
||||
}
|
||||
@ -4936,6 +4937,12 @@ fn structDeclInner(
|
||||
}
|
||||
};
|
||||
|
||||
var fields_hasher = std.zig.SrcHasher.init(.{});
|
||||
fields_hasher.update(@tagName(layout));
|
||||
if (backing_int_node != 0) {
|
||||
fields_hasher.update(tree.getNodeSource(backing_int_node));
|
||||
}
|
||||
|
||||
var sfba = std.heap.stackFallback(256, astgen.arena);
|
||||
const sfba_allocator = sfba.get();
|
||||
|
||||
@ -4956,6 +4963,8 @@ fn structDeclInner(
|
||||
.field => |field| field,
|
||||
};
|
||||
|
||||
fields_hasher.update(tree.getNodeSource(member_node));
|
||||
|
||||
if (!is_tuple) {
|
||||
const field_name = try astgen.identAsString(member.ast.main_token);
|
||||
|
||||
@ -5083,6 +5092,9 @@ fn structDeclInner(
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
var fields_hash: std.zig.SrcHash = undefined;
|
||||
fields_hasher.final(&fields_hash);
|
||||
|
||||
try gz.setStruct(decl_inst, .{
|
||||
.src_node = node,
|
||||
.layout = layout,
|
||||
@ -5096,6 +5108,7 @@ fn structDeclInner(
|
||||
.any_comptime_fields = any_comptime_fields,
|
||||
.any_default_inits = any_default_inits,
|
||||
.any_aligned_fields = any_aligned_fields,
|
||||
.fields_hash = fields_hash,
|
||||
});
|
||||
|
||||
wip_members.finishBits(bits_per_field);
|
||||
@ -5174,6 +5187,13 @@ fn unionDeclInner(
|
||||
var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
|
||||
defer wip_members.deinit();
|
||||
|
||||
var fields_hasher = std.zig.SrcHasher.init(.{});
|
||||
fields_hasher.update(@tagName(layout));
|
||||
fields_hasher.update(&.{@intFromBool(auto_enum_tok != null)});
|
||||
if (arg_node != 0) {
|
||||
fields_hasher.update(astgen.tree.getNodeSource(arg_node));
|
||||
}
|
||||
|
||||
var sfba = std.heap.stackFallback(256, astgen.arena);
|
||||
const sfba_allocator = sfba.get();
|
||||
|
||||
@ -5188,6 +5208,7 @@ fn unionDeclInner(
|
||||
.decl => continue,
|
||||
.field => |field| field,
|
||||
};
|
||||
fields_hasher.update(astgen.tree.getNodeSource(member_node));
|
||||
member.convertToNonTupleLike(astgen.tree.nodes);
|
||||
if (member.ast.tuple_like) {
|
||||
return astgen.failTok(member.ast.main_token, "union field missing name", .{});
|
||||
@ -5289,6 +5310,9 @@ fn unionDeclInner(
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
var fields_hash: std.zig.SrcHash = undefined;
|
||||
fields_hasher.final(&fields_hash);
|
||||
|
||||
if (!block_scope.isEmpty()) {
|
||||
_ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
|
||||
}
|
||||
@ -5305,6 +5329,7 @@ fn unionDeclInner(
|
||||
.decls_len = decl_count,
|
||||
.auto_enum_tag = auto_enum_tok != null,
|
||||
.any_aligned_fields = any_aligned_fields,
|
||||
.fields_hash = fields_hash,
|
||||
});
|
||||
|
||||
wip_members.finishBits(bits_per_field);
|
||||
@ -5498,6 +5523,12 @@ fn containerDecl(
|
||||
var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(counts.decls), @intCast(counts.total_fields), bits_per_field, max_field_size);
|
||||
defer wip_members.deinit();
|
||||
|
||||
var fields_hasher = std.zig.SrcHasher.init(.{});
|
||||
if (container_decl.ast.arg != 0) {
|
||||
fields_hasher.update(tree.getNodeSource(container_decl.ast.arg));
|
||||
}
|
||||
fields_hasher.update(&.{@intFromBool(nonexhaustive)});
|
||||
|
||||
var sfba = std.heap.stackFallback(256, astgen.arena);
|
||||
const sfba_allocator = sfba.get();
|
||||
|
||||
@ -5510,6 +5541,7 @@ fn containerDecl(
|
||||
for (container_decl.ast.members) |member_node| {
|
||||
if (member_node == counts.nonexhaustive_node)
|
||||
continue;
|
||||
fields_hasher.update(tree.getNodeSource(member_node));
|
||||
namespace.base.tag = .namespace;
|
||||
var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
|
||||
.decl => continue,
|
||||
@ -5590,6 +5622,9 @@ fn containerDecl(
|
||||
_ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
|
||||
}
|
||||
|
||||
var fields_hash: std.zig.SrcHash = undefined;
|
||||
fields_hasher.final(&fields_hash);
|
||||
|
||||
const body = block_scope.instructionsSlice();
|
||||
const body_len = astgen.countBodyLenAfterFixups(body);
|
||||
|
||||
@ -5600,6 +5635,7 @@ fn containerDecl(
|
||||
.body_len = body_len,
|
||||
.fields_len = @intCast(counts.total_fields),
|
||||
.decls_len = @intCast(counts.decls),
|
||||
.fields_hash = fields_hash,
|
||||
});
|
||||
|
||||
wip_members.finishBits(bits_per_field);
|
||||
@ -11900,8 +11936,8 @@ const GenZir = struct {
|
||||
|
||||
var body: []Zir.Inst.Index = &[0]Zir.Inst.Index{};
|
||||
var ret_body: []Zir.Inst.Index = &[0]Zir.Inst.Index{};
|
||||
var src_locs_buffer: [3]u32 = undefined;
|
||||
var src_locs: []u32 = src_locs_buffer[0..0];
|
||||
var src_locs_and_hash_buffer: [7]u32 = undefined;
|
||||
var src_locs_and_hash: []u32 = src_locs_and_hash_buffer[0..0];
|
||||
if (args.body_gz) |body_gz| {
|
||||
const tree = astgen.tree;
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
@ -11916,10 +11952,27 @@ const GenZir = struct {
|
||||
const rbrace_column: u32 = @intCast(astgen.source_column);
|
||||
|
||||
const columns = args.lbrace_column | (rbrace_column << 16);
|
||||
src_locs_buffer[0] = args.lbrace_line;
|
||||
src_locs_buffer[1] = rbrace_line;
|
||||
src_locs_buffer[2] = columns;
|
||||
src_locs = &src_locs_buffer;
|
||||
|
||||
const proto_hash: std.zig.SrcHash = switch (node_tags[fn_decl]) {
|
||||
.fn_decl => sig_hash: {
|
||||
const proto_node = node_datas[fn_decl].lhs;
|
||||
break :sig_hash std.zig.hashSrc(tree.getNodeSource(proto_node));
|
||||
},
|
||||
.test_decl => std.zig.hashSrc(""), // tests don't have a prototype
|
||||
else => unreachable,
|
||||
};
|
||||
const proto_hash_arr: [4]u32 = @bitCast(proto_hash);
|
||||
|
||||
src_locs_and_hash_buffer = .{
|
||||
args.lbrace_line,
|
||||
rbrace_line,
|
||||
columns,
|
||||
proto_hash_arr[0],
|
||||
proto_hash_arr[1],
|
||||
proto_hash_arr[2],
|
||||
proto_hash_arr[3],
|
||||
};
|
||||
src_locs_and_hash = &src_locs_and_hash_buffer;
|
||||
|
||||
body = body_gz.instructionsSlice();
|
||||
if (args.ret_gz) |ret_gz|
|
||||
@ -11953,7 +12006,7 @@ const GenZir = struct {
|
||||
fancyFnExprExtraLen(astgen, section_body, args.section_ref) +
|
||||
fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
|
||||
fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
|
||||
body_len + src_locs.len +
|
||||
body_len + src_locs_and_hash.len +
|
||||
@intFromBool(args.lib_name != .empty) +
|
||||
@intFromBool(args.noalias_bits != 0),
|
||||
);
|
||||
@ -12040,7 +12093,7 @@ const GenZir = struct {
|
||||
}
|
||||
|
||||
astgen.appendBodyWithFixups(body);
|
||||
astgen.extra.appendSliceAssumeCapacity(src_locs);
|
||||
astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);
|
||||
|
||||
// Order is important when unstacking.
|
||||
if (args.body_gz) |body_gz| body_gz.unstack();
|
||||
@ -12068,7 +12121,7 @@ const GenZir = struct {
|
||||
gpa,
|
||||
@typeInfo(Zir.Inst.Func).Struct.fields.len + 1 +
|
||||
fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
|
||||
body_len + src_locs.len,
|
||||
body_len + src_locs_and_hash.len,
|
||||
);
|
||||
|
||||
const ret_body_len = if (ret_body.len != 0)
|
||||
@ -12092,7 +12145,7 @@ const GenZir = struct {
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));
|
||||
}
|
||||
astgen.appendBodyWithFixups(body);
|
||||
astgen.extra.appendSliceAssumeCapacity(src_locs);
|
||||
astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);
|
||||
|
||||
// Order is important when unstacking.
|
||||
if (args.body_gz) |body_gz| body_gz.unstack();
|
||||
@ -12853,12 +12906,20 @@ const GenZir = struct {
|
||||
any_comptime_fields: bool,
|
||||
any_default_inits: bool,
|
||||
any_aligned_fields: bool,
|
||||
fields_hash: std.zig.SrcHash,
|
||||
}) !void {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, 6);
|
||||
const payload_index: u32 = @intCast(astgen.extra.items.len);
|
||||
const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).Struct.fields.len + 6);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.StructDecl{
|
||||
.fields_hash_0 = fields_hash_arr[0],
|
||||
.fields_hash_1 = fields_hash_arr[1],
|
||||
.fields_hash_2 = fields_hash_arr[2],
|
||||
.fields_hash_3 = fields_hash_arr[3],
|
||||
});
|
||||
|
||||
if (args.src_node != 0) {
|
||||
const node_offset = gz.nodeIndexToRelative(args.src_node);
|
||||
@ -12908,12 +12969,20 @@ const GenZir = struct {
|
||||
layout: std.builtin.Type.ContainerLayout,
|
||||
auto_enum_tag: bool,
|
||||
any_aligned_fields: bool,
|
||||
fields_hash: std.zig.SrcHash,
|
||||
}) !void {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, 5);
|
||||
const payload_index: u32 = @intCast(astgen.extra.items.len);
|
||||
const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).Struct.fields.len + 5);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.UnionDecl{
|
||||
.fields_hash_0 = fields_hash_arr[0],
|
||||
.fields_hash_1 = fields_hash_arr[1],
|
||||
.fields_hash_2 = fields_hash_arr[2],
|
||||
.fields_hash_3 = fields_hash_arr[3],
|
||||
});
|
||||
|
||||
if (args.src_node != 0) {
|
||||
const node_offset = gz.nodeIndexToRelative(args.src_node);
|
||||
@ -12958,12 +13027,20 @@ const GenZir = struct {
|
||||
fields_len: u32,
|
||||
decls_len: u32,
|
||||
nonexhaustive: bool,
|
||||
fields_hash: std.zig.SrcHash,
|
||||
}) !void {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, 5);
|
||||
const payload_index: u32 = @intCast(astgen.extra.items.len);
|
||||
const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).Struct.fields.len + 5);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.EnumDecl{
|
||||
.fields_hash_0 = fields_hash_arr[0],
|
||||
.fields_hash_1 = fields_hash_arr[1],
|
||||
.fields_hash_2 = fields_hash_arr[2],
|
||||
.fields_hash_3 = fields_hash_arr[3],
|
||||
});
|
||||
|
||||
if (args.src_node != 0) {
|
||||
const node_offset = gz.nodeIndexToRelative(args.src_node);
|
||||
|
@ -3497,7 +3497,7 @@ fn walkInstruction(
|
||||
};
|
||||
|
||||
const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.UnionDecl).Struct.fields.len;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(file.zir.extra[extra_index]));
|
||||
@ -3627,7 +3627,7 @@ fn walkInstruction(
|
||||
};
|
||||
|
||||
const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.EnumDecl).Struct.fields.len;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(file.zir.extra[extra_index]));
|
||||
@ -3778,7 +3778,7 @@ fn walkInstruction(
|
||||
};
|
||||
|
||||
const small = @as(Zir.Inst.StructDecl.Small, @bitCast(extended.small));
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(file.zir.extra[extra_index]));
|
||||
|
@ -2957,6 +2957,18 @@ fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void {
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
|
14
src/Sema.zig
14
src/Sema.zig
@ -2718,7 +2718,7 @@ pub fn getStructType(
|
||||
assert(extended.opcode == .struct_decl);
|
||||
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
const fields_len = if (small.has_fields_len) blk: {
|
||||
const fields_len = sema.code.extra[extra_index];
|
||||
@ -2773,7 +2773,7 @@ fn zirStructDecl(
|
||||
const ip = &mod.intern_pool;
|
||||
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
const src: LazySrcLoc = if (small.has_src_node) blk: {
|
||||
const node_offset: i32 = @bitCast(sema.code.extra[extended.operand]);
|
||||
const node_offset: i32 = @bitCast(sema.code.extra[extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len]);
|
||||
break :blk LazySrcLoc.nodeOffset(node_offset);
|
||||
} else sema.src;
|
||||
|
||||
@ -2933,7 +2933,7 @@ fn zirEnumDecl(
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.EnumDecl).Struct.fields.len;
|
||||
|
||||
const src: LazySrcLoc = if (small.has_src_node) blk: {
|
||||
const node_offset: i32 = @bitCast(sema.code.extra[extra_index]);
|
||||
@ -3204,7 +3204,7 @@ fn zirUnionDecl(
|
||||
const mod = sema.mod;
|
||||
const gpa = sema.gpa;
|
||||
const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.UnionDecl).Struct.fields.len;
|
||||
|
||||
const src: LazySrcLoc = if (small.has_src_node) blk: {
|
||||
const node_offset: i32 = @bitCast(sema.code.extra[extra_index]);
|
||||
@ -35742,7 +35742,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
|
||||
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
|
||||
if (small.has_backing_int) {
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
extra_index += @intFromBool(small.has_fields_len);
|
||||
extra_index += @intFromBool(small.has_decls_len);
|
||||
@ -36457,7 +36457,7 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
|
||||
const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
|
||||
assert(extended.opcode == .struct_decl);
|
||||
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
|
||||
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
|
||||
@ -36925,7 +36925,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
|
||||
const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
|
||||
assert(extended.opcode == .union_decl);
|
||||
const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: usize = extended.operand;
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.UnionDecl).Struct.fields.len;
|
||||
|
||||
const src = LazySrcLoc.nodeOffset(0);
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
|
134
src/Zir.zig
134
src/Zir.zig
@ -2497,6 +2497,7 @@ pub const Inst = struct {
|
||||
/// }
|
||||
/// 2. body: Index // for each body_len
|
||||
/// 3. src_locs: SrcLocs // if body_len != 0
|
||||
/// 4. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype
|
||||
pub const Func = struct {
|
||||
/// If this is 0 it means a void return type.
|
||||
/// If this is 1 it means return_type is a simple Ref
|
||||
@ -2558,6 +2559,7 @@ pub const Inst = struct {
|
||||
/// - each bit starting with LSB corresponds to parameter indexes
|
||||
/// 17. body: Index // for each body_len
|
||||
/// 18. src_locs: Func.SrcLocs // if body_len != 0
|
||||
/// 19. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype
|
||||
pub const FuncFancy = struct {
|
||||
/// Points to the block that contains the param instructions for this function.
|
||||
/// If this is a `declaration`, it refers to the declaration's value body.
|
||||
@ -3040,6 +3042,12 @@ pub const Inst = struct {
|
||||
/// init_body_inst: Inst, // for each init_body_len
|
||||
/// }
|
||||
pub const StructDecl = struct {
|
||||
// These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
|
||||
// This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).
|
||||
fields_hash_0: u32,
|
||||
fields_hash_1: u32,
|
||||
fields_hash_2: u32,
|
||||
fields_hash_3: u32,
|
||||
pub const Small = packed struct {
|
||||
has_src_node: bool,
|
||||
has_fields_len: bool,
|
||||
@ -3102,6 +3110,12 @@ pub const Inst = struct {
|
||||
/// value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const EnumDecl = struct {
|
||||
// These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
|
||||
// This hash contains the source of all fields, and the backing type if specified.
|
||||
fields_hash_0: u32,
|
||||
fields_hash_1: u32,
|
||||
fields_hash_2: u32,
|
||||
fields_hash_3: u32,
|
||||
pub const Small = packed struct {
|
||||
has_src_node: bool,
|
||||
has_tag_type: bool,
|
||||
@ -3137,6 +3151,12 @@ pub const Inst = struct {
|
||||
/// tag_value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const UnionDecl = struct {
|
||||
// These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
|
||||
// This hash contains the source of all fields, and any specified attributes (`extern` etc).
|
||||
fields_hash_0: u32,
|
||||
fields_hash_1: u32,
|
||||
fields_hash_2: u32,
|
||||
fields_hash_3: u32,
|
||||
pub const Small = packed struct {
|
||||
has_src_node: bool,
|
||||
has_tag_type: bool,
|
||||
@ -3455,7 +3475,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
|
||||
switch (extended.opcode) {
|
||||
.struct_decl => {
|
||||
const small: Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: u32 = extended.operand;
|
||||
var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.StructDecl).Struct.fields.len);
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
extra_index += @intFromBool(small.has_fields_len);
|
||||
const decls_len = if (small.has_decls_len) decls_len: {
|
||||
@ -3482,7 +3502,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
|
||||
},
|
||||
.enum_decl => {
|
||||
const small: Inst.EnumDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: u32 = extended.operand;
|
||||
var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.EnumDecl).Struct.fields.len);
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
extra_index += @intFromBool(small.has_tag_type);
|
||||
extra_index += @intFromBool(small.has_body_len);
|
||||
@ -3501,7 +3521,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
|
||||
},
|
||||
.union_decl => {
|
||||
const small: Inst.UnionDecl.Small = @bitCast(extended.small);
|
||||
var extra_index: u32 = extended.operand;
|
||||
var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.UnionDecl).Struct.fields.len);
|
||||
extra_index += @intFromBool(small.has_src_node);
|
||||
extra_index += @intFromBool(small.has_tag_type);
|
||||
extra_index += @intFromBool(small.has_body_len);
|
||||
@ -3938,3 +3958,111 @@ pub fn getDeclaration(zir: Zir, inst: Zir.Inst.Index) struct { Inst.Declaration,
|
||||
@intCast(extra.end),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash {
|
||||
const tag = zir.instructions.items(.tag);
|
||||
const data = zir.instructions.items(.data);
|
||||
switch (tag[@intFromEnum(inst)]) {
|
||||
.declaration => {
|
||||
const pl_node = data[@intFromEnum(inst)].pl_node;
|
||||
const extra = zir.extraData(Inst.Declaration, pl_node.payload_index);
|
||||
return @bitCast([4]u32{
|
||||
extra.data.src_hash_0,
|
||||
extra.data.src_hash_1,
|
||||
extra.data.src_hash_2,
|
||||
extra.data.src_hash_3,
|
||||
});
|
||||
},
|
||||
.func, .func_inferred => {
|
||||
const pl_node = data[@intFromEnum(inst)].pl_node;
|
||||
const extra = zir.extraData(Inst.Func, pl_node.payload_index);
|
||||
if (extra.data.body_len == 0) {
|
||||
// Function type or extern fn - no associated hash
|
||||
return null;
|
||||
}
|
||||
const extra_index = extra.end +
|
||||
1 +
|
||||
extra.data.body_len +
|
||||
@typeInfo(Inst.Func.SrcLocs).Struct.fields.len;
|
||||
return @bitCast([4]u32{
|
||||
zir.extra[extra_index + 0],
|
||||
zir.extra[extra_index + 1],
|
||||
zir.extra[extra_index + 2],
|
||||
zir.extra[extra_index + 3],
|
||||
});
|
||||
},
|
||||
.func_fancy => {
|
||||
const pl_node = data[@intFromEnum(inst)].pl_node;
|
||||
const extra = zir.extraData(Inst.FuncFancy, pl_node.payload_index);
|
||||
if (extra.data.body_len == 0) {
|
||||
// Function type or extern fn - no associated hash
|
||||
return null;
|
||||
}
|
||||
const bits = extra.data.bits;
|
||||
var extra_index = extra.end;
|
||||
extra_index += @intFromBool(bits.has_lib_name);
|
||||
if (bits.has_align_body) {
|
||||
const body_len = zir.extra[extra_index];
|
||||
extra_index += 1 + body_len;
|
||||
} else extra_index += @intFromBool(bits.has_align_ref);
|
||||
if (bits.has_addrspace_body) {
|
||||
const body_len = zir.extra[extra_index];
|
||||
extra_index += 1 + body_len;
|
||||
} else extra_index += @intFromBool(bits.has_addrspace_ref);
|
||||
if (bits.has_section_body) {
|
||||
const body_len = zir.extra[extra_index];
|
||||
extra_index += 1 + body_len;
|
||||
} else extra_index += @intFromBool(bits.has_section_ref);
|
||||
if (bits.has_cc_body) {
|
||||
const body_len = zir.extra[extra_index];
|
||||
extra_index += 1 + body_len;
|
||||
} else extra_index += @intFromBool(bits.has_cc_ref);
|
||||
if (bits.has_ret_ty_body) {
|
||||
const body_len = zir.extra[extra_index];
|
||||
extra_index += 1 + body_len;
|
||||
} else extra_index += @intFromBool(bits.has_ret_ty_ref);
|
||||
extra_index += @intFromBool(bits.has_any_noalias);
|
||||
extra_index += extra.data.body_len;
|
||||
extra_index += @typeInfo(Zir.Inst.Func.SrcLocs).Struct.fields.len;
|
||||
return @bitCast([4]u32{
|
||||
zir.extra[extra_index + 0],
|
||||
zir.extra[extra_index + 1],
|
||||
zir.extra[extra_index + 2],
|
||||
zir.extra[extra_index + 3],
|
||||
});
|
||||
},
|
||||
.extended => {},
|
||||
else => return null,
|
||||
}
|
||||
const extended = data[@intFromEnum(inst)].extended;
|
||||
switch (extended.opcode) {
|
||||
.struct_decl => {
|
||||
const extra = zir.extraData(Inst.StructDecl, extended.operand).data;
|
||||
return @bitCast([4]u32{
|
||||
extra.fields_hash_0,
|
||||
extra.fields_hash_1,
|
||||
extra.fields_hash_2,
|
||||
extra.fields_hash_3,
|
||||
});
|
||||
},
|
||||
.union_decl => {
|
||||
const extra = zir.extraData(Inst.UnionDecl, extended.operand).data;
|
||||
return @bitCast([4]u32{
|
||||
extra.fields_hash_0,
|
||||
extra.fields_hash_1,
|
||||
extra.fields_hash_2,
|
||||
extra.fields_hash_3,
|
||||
});
|
||||
},
|
||||
.enum_decl => {
|
||||
const extra = zir.extraData(Inst.EnumDecl, extended.operand).data;
|
||||
return @bitCast([4]u32{
|
||||
extra.fields_hash_0,
|
||||
extra.fields_hash_1,
|
||||
extra.fields_hash_2,
|
||||
extra.fields_hash_3,
|
||||
});
|
||||
},
|
||||
else => return null,
|
||||
}
|
||||
}
|
||||
|
@ -1401,7 +1401,17 @@ const Writer = struct {
|
||||
fn writeStructDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
|
||||
const small = @as(Zir.Inst.StructDecl.Small, @bitCast(extended.small));
|
||||
|
||||
var extra_index: usize = extended.operand;
|
||||
const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);
|
||||
const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
|
||||
extra.data.fields_hash_0,
|
||||
extra.data.fields_hash_1,
|
||||
extra.data.fields_hash_2,
|
||||
extra.data.fields_hash_3,
|
||||
});
|
||||
|
||||
try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(self.code.extra[extra_index]));
|
||||
@ -1591,7 +1601,17 @@ const Writer = struct {
|
||||
fn writeUnionDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
|
||||
const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));
|
||||
|
||||
var extra_index: usize = extended.operand;
|
||||
const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);
|
||||
const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
|
||||
extra.data.fields_hash_0,
|
||||
extra.data.fields_hash_1,
|
||||
extra.data.fields_hash_2,
|
||||
extra.data.fields_hash_3,
|
||||
});
|
||||
|
||||
try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(self.code.extra[extra_index]));
|
||||
@ -1733,7 +1753,18 @@ const Writer = struct {
|
||||
|
||||
fn writeEnumDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
|
||||
const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));
|
||||
var extra_index: usize = extended.operand;
|
||||
|
||||
const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);
|
||||
const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
|
||||
extra.data.fields_hash_0,
|
||||
extra.data.fields_hash_1,
|
||||
extra.data.fields_hash_2,
|
||||
extra.data.fields_hash_3,
|
||||
});
|
||||
|
||||
try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
|
||||
const src_node: ?i32 = if (small.has_src_node) blk: {
|
||||
const src_node = @as(i32, @bitCast(self.code.extra[extra_index]));
|
||||
|
Loading…
Reference in New Issue
Block a user