mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
AstGen: store list of imports
This commit is contained in:
parent
edd75d03e3
commit
a271f12a14
@ -1,6 +1,5 @@
|
||||
* look for cached zir code
|
||||
* save zir code to cache
|
||||
* store list of imported strings
|
||||
* use list of imported strings to queue up more astgen tasks
|
||||
* keep track of file dependencies/dependants
|
||||
* unload files from memory when a dependency is dropped
|
||||
|
||||
@ -35,6 +35,8 @@ string_bytes: ArrayListUnmanaged(u8) = .{},
|
||||
arena: *Allocator,
|
||||
string_table: std.StringHashMapUnmanaged(u32) = .{},
|
||||
compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
|
||||
/// String table indexes, keeps track of all `@import` operands.
|
||||
imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
|
||||
|
||||
pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 {
|
||||
const fields = std.meta.fields(@TypeOf(extra));
|
||||
@ -76,8 +78,8 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
|
||||
};
|
||||
defer astgen.deinit(gpa);
|
||||
|
||||
// Indexes 0,1 of extra are reserved and set at the end.
|
||||
try astgen.extra.resize(gpa, 2);
|
||||
// First few indexes of extra are reserved and set at the end.
|
||||
try astgen.extra.resize(gpa, @typeInfo(Zir.ExtraIndex).Enum.fields.len);
|
||||
|
||||
var gen_scope: Scope.GenZir = .{
|
||||
.force_comptime = true,
|
||||
@ -103,20 +105,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
|
||||
container_decl,
|
||||
.struct_decl,
|
||||
)) |struct_decl_ref| {
|
||||
astgen.extra.items[0] = @enumToInt(struct_decl_ref);
|
||||
astgen.extra.items[@enumToInt(Zir.ExtraIndex.main_struct)] = @enumToInt(struct_decl_ref);
|
||||
} else |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.AnalysisFail => {}, // Handled via compile_errors below.
|
||||
}
|
||||
|
||||
const err_index = @enumToInt(Zir.ExtraIndex.compile_errors);
|
||||
if (astgen.compile_errors.items.len == 0) {
|
||||
astgen.extra.items[1] = 0;
|
||||
astgen.extra.items[err_index] = 0;
|
||||
} else {
|
||||
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
|
||||
1 + astgen.compile_errors.items.len *
|
||||
@typeInfo(Zir.Inst.CompileErrors.Item).Struct.fields.len);
|
||||
|
||||
astgen.extra.items[1] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{
|
||||
astgen.extra.items[err_index] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{
|
||||
.items_len = @intCast(u32, astgen.compile_errors.items.len),
|
||||
});
|
||||
|
||||
@ -125,6 +128,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
|
||||
}
|
||||
}
|
||||
|
||||
const imports_index = @enumToInt(Zir.ExtraIndex.imports);
|
||||
if (astgen.imports.count() == 0) {
|
||||
astgen.extra.items[imports_index] = 0;
|
||||
} else {
|
||||
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
|
||||
@typeInfo(Zir.Inst.Imports).Struct.fields.len + astgen.imports.count());
|
||||
|
||||
astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{
|
||||
.imports_len = @intCast(u32, astgen.imports.count()),
|
||||
});
|
||||
for (astgen.imports.items()) |entry| {
|
||||
astgen.extra.appendAssumeCapacity(entry.key);
|
||||
}
|
||||
}
|
||||
|
||||
return Zir{
|
||||
.instructions = astgen.instructions.toOwnedSlice(),
|
||||
.string_bytes = astgen.string_bytes.toOwnedSlice(gpa),
|
||||
@ -138,6 +156,7 @@ pub fn deinit(astgen: *AstGen, gpa: *Allocator) void {
|
||||
astgen.string_table.deinit(gpa);
|
||||
astgen.string_bytes.deinit(gpa);
|
||||
astgen.compile_errors.deinit(gpa);
|
||||
astgen.imports.deinit(gpa);
|
||||
}
|
||||
|
||||
pub const ResultLoc = union(enum) {
|
||||
@ -4684,6 +4703,7 @@ fn builtinCall(
|
||||
}
|
||||
const str_lit_token = main_tokens[operand_node];
|
||||
const str = try gz.strLitAsString(str_lit_token);
|
||||
try astgen.imports.put(astgen.gpa, str.index, {});
|
||||
const result = try gz.addStrTok(.import, str.index, str_lit_token);
|
||||
return rvalue(gz, scope, rl, result, node);
|
||||
},
|
||||
|
||||
@ -432,7 +432,7 @@ pub const AllErrors = struct {
|
||||
assert(file.zir_loaded);
|
||||
assert(file.tree_loaded);
|
||||
const Zir = @import("Zir.zig");
|
||||
const payload_index = file.zir.extra[Zir.compile_error_extra_index];
|
||||
const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)];
|
||||
assert(payload_index != 0);
|
||||
|
||||
const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index);
|
||||
|
||||
40
src/Zir.zig
40
src/Zir.zig
@ -34,16 +34,21 @@ instructions: std.MultiArrayList(Inst).Slice,
|
||||
/// `string_bytes` array is agnostic to either usage.
|
||||
string_bytes: []u8,
|
||||
/// The meaning of this data is determined by `Inst.Tag` value.
|
||||
/// Indexes 0 and 1 are reserved for:
|
||||
/// 0. struct_decl: Ref
|
||||
/// - the main struct decl for this file
|
||||
/// 1. errors_payload_index: u32
|
||||
/// - if this is 0, no compile errors. Otherwise there is a `CompileErrors`
|
||||
/// payload at this index.
|
||||
/// The first few indexes are reserved. See `ExtraIndex` for the values.
|
||||
extra: []u32,
|
||||
|
||||
pub const main_struct_extra_index = 0;
|
||||
pub const compile_error_extra_index = 1;
|
||||
pub const ExtraIndex = enum(u32) {
|
||||
/// Ref. The main struct decl for this file.
|
||||
main_struct,
|
||||
/// If this is 0, no compile errors. Otherwise there is a `CompileErrors`
|
||||
/// payload at this index.
|
||||
compile_errors,
|
||||
/// If this is 0, this file contains no imports. Otherwise there is a `Imports`
|
||||
/// payload at this index.
|
||||
imports,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
/// Returns the requested data, as well as the new index which is at the start of the
|
||||
/// trailers for the object.
|
||||
@ -80,7 +85,7 @@ pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref {
|
||||
}
|
||||
|
||||
pub fn hasCompileErrors(code: Zir) bool {
|
||||
return code.extra[compile_error_extra_index] != 0;
|
||||
return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0;
|
||||
}
|
||||
|
||||
pub fn deinit(code: *Zir, gpa: *Allocator) void {
|
||||
@ -109,10 +114,20 @@ pub fn renderAsTextToFile(
|
||||
.param_count = 0,
|
||||
};
|
||||
|
||||
const main_struct_inst = scope_file.zir.extra[0] - @intCast(u32, Inst.Ref.typed_value_map.len);
|
||||
const main_struct_inst = scope_file.zir.extra[@enumToInt(ExtraIndex.main_struct)] -
|
||||
@intCast(u32, Inst.Ref.typed_value_map.len);
|
||||
try fs_file.writer().print("%{d} ", .{main_struct_inst});
|
||||
try writer.writeInstToStream(fs_file.writer(), main_struct_inst);
|
||||
try fs_file.writeAll("\n");
|
||||
const imports_index = scope_file.zir.extra[@enumToInt(ExtraIndex.imports)];
|
||||
if (imports_index != 0) {
|
||||
try fs_file.writeAll("Imports:\n");
|
||||
const imports_len = scope_file.zir.extra[imports_index];
|
||||
for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {
|
||||
const import_path = scope_file.zir.nullTerminatedString(str_index);
|
||||
try fs_file.writer().print(" {s}\n", .{import_path});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// These are untyped instructions generated from an Abstract Syntax Tree.
|
||||
@ -1649,6 +1664,11 @@ pub const Inst = struct {
|
||||
notes: u32,
|
||||
};
|
||||
};
|
||||
|
||||
/// Trailing: for each `imports_len` there is a string table index.
|
||||
pub const Imports = struct {
|
||||
imports_len: u32,
|
||||
};
|
||||
};
|
||||
|
||||
pub const SpecialProng = enum { none, @"else", under };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user