authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-16 16:20:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-16 16:20:29-07:00
loga271f12a149239ab6e6361423589687e32f64cda
treeea35c9389e0b01a24bba957525cabda86e8847ff
parentedd75d03e312d6020623df4e06c9bb19c2f217c5

AstGen: store list of imports


4 files changed, 56 insertions(+), 17 deletions(-)

BRANCH_TODO-1
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1 * look for cached zir code1 * look for cached zir code
2 * save zir code to cache2 * save zir code to cache
3 * store list of imported strings
4 * use list of imported strings to queue up more astgen tasks3 * use list of imported strings to queue up more astgen tasks
5 * keep track of file dependencies/dependants4 * keep track of file dependencies/dependants
6 * unload files from memory when a dependency is dropped5 * unload files from memory when a dependency is dropped
src/AstGen.zig+25-5
...@@ -35,6 +35,8 @@ string_bytes: ArrayListUnmanaged(u8) = .{},...@@ -35,6 +35,8 @@ string_bytes: ArrayListUnmanaged(u8) = .{},
35arena: *Allocator,35arena: *Allocator,
36string_table: std.StringHashMapUnmanaged(u32) = .{},36string_table: std.StringHashMapUnmanaged(u32) = .{},
37compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},37compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
38/// String table indexes, keeps track of all `@import` operands.
39imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
3840
39pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 {41pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 {
40 const fields = std.meta.fields(@TypeOf(extra));42 const fields = std.meta.fields(@TypeOf(extra));
...@@ -76,8 +78,8 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {...@@ -76,8 +78,8 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
76 };78 };
77 defer astgen.deinit(gpa);79 defer astgen.deinit(gpa);
7880
79 // Indexes 0,1 of extra are reserved and set at the end.81 // First few indexes of extra are reserved and set at the end.
80 try astgen.extra.resize(gpa, 2);82 try astgen.extra.resize(gpa, @typeInfo(Zir.ExtraIndex).Enum.fields.len);
8183
82 var gen_scope: Scope.GenZir = .{84 var gen_scope: Scope.GenZir = .{
83 .force_comptime = true,85 .force_comptime = true,
...@@ -103,20 +105,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {...@@ -103,20 +105,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
103 container_decl,105 container_decl,
104 .struct_decl,106 .struct_decl,
105 )) |struct_decl_ref| {107 )) |struct_decl_ref| {
106 astgen.extra.items[0] = @enumToInt(struct_decl_ref);108 astgen.extra.items[@enumToInt(Zir.ExtraIndex.main_struct)] = @enumToInt(struct_decl_ref);
107 } else |err| switch (err) {109 } else |err| switch (err) {
108 error.OutOfMemory => return error.OutOfMemory,110 error.OutOfMemory => return error.OutOfMemory,
109 error.AnalysisFail => {}, // Handled via compile_errors below.111 error.AnalysisFail => {}, // Handled via compile_errors below.
110 }112 }
111113
114 const err_index = @enumToInt(Zir.ExtraIndex.compile_errors);
112 if (astgen.compile_errors.items.len == 0) {115 if (astgen.compile_errors.items.len == 0) {
113 astgen.extra.items[1] = 0;116 astgen.extra.items[err_index] = 0;
114 } else {117 } else {
115 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +118 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
116 1 + astgen.compile_errors.items.len *119 1 + astgen.compile_errors.items.len *
117 @typeInfo(Zir.Inst.CompileErrors.Item).Struct.fields.len);120 @typeInfo(Zir.Inst.CompileErrors.Item).Struct.fields.len);
118121
119 astgen.extra.items[1] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{122 astgen.extra.items[err_index] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{
120 .items_len = @intCast(u32, astgen.compile_errors.items.len),123 .items_len = @intCast(u32, astgen.compile_errors.items.len),
121 });124 });
122125
...@@ -125,6 +128,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {...@@ -125,6 +128,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
125 }128 }
126 }129 }
127130
131 const imports_index = @enumToInt(Zir.ExtraIndex.imports);
132 if (astgen.imports.count() == 0) {
133 astgen.extra.items[imports_index] = 0;
134 } else {
135 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
136 @typeInfo(Zir.Inst.Imports).Struct.fields.len + astgen.imports.count());
137
138 astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{
139 .imports_len = @intCast(u32, astgen.imports.count()),
140 });
141 for (astgen.imports.items()) |entry| {
142 astgen.extra.appendAssumeCapacity(entry.key);
143 }
144 }
145
128 return Zir{146 return Zir{
129 .instructions = astgen.instructions.toOwnedSlice(),147 .instructions = astgen.instructions.toOwnedSlice(),
130 .string_bytes = astgen.string_bytes.toOwnedSlice(gpa),148 .string_bytes = astgen.string_bytes.toOwnedSlice(gpa),
...@@ -138,6 +156,7 @@ pub fn deinit(astgen: *AstGen, gpa: *Allocator) void {...@@ -138,6 +156,7 @@ pub fn deinit(astgen: *AstGen, gpa: *Allocator) void {
138 astgen.string_table.deinit(gpa);156 astgen.string_table.deinit(gpa);
139 astgen.string_bytes.deinit(gpa);157 astgen.string_bytes.deinit(gpa);
140 astgen.compile_errors.deinit(gpa);158 astgen.compile_errors.deinit(gpa);
159 astgen.imports.deinit(gpa);
141}160}
142161
143pub const ResultLoc = union(enum) {162pub const ResultLoc = union(enum) {
...@@ -4684,6 +4703,7 @@ fn builtinCall(...@@ -4684,6 +4703,7 @@ fn builtinCall(
4684 }4703 }
4685 const str_lit_token = main_tokens[operand_node];4704 const str_lit_token = main_tokens[operand_node];
4686 const str = try gz.strLitAsString(str_lit_token);4705 const str = try gz.strLitAsString(str_lit_token);
4706 try astgen.imports.put(astgen.gpa, str.index, {});
4687 const result = try gz.addStrTok(.import, str.index, str_lit_token);4707 const result = try gz.addStrTok(.import, str.index, str_lit_token);
4688 return rvalue(gz, scope, rl, result, node);4708 return rvalue(gz, scope, rl, result, node);
4689 },4709 },
src/Compilation.zig+1-1
...@@ -432,7 +432,7 @@ pub const AllErrors = struct {...@@ -432,7 +432,7 @@ pub const AllErrors = struct {
432 assert(file.zir_loaded);432 assert(file.zir_loaded);
433 assert(file.tree_loaded);433 assert(file.tree_loaded);
434 const Zir = @import("Zir.zig");434 const Zir = @import("Zir.zig");
435 const payload_index = file.zir.extra[Zir.compile_error_extra_index];435 const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)];
436 assert(payload_index != 0);436 assert(payload_index != 0);
437437
438 const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index);438 const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index);
src/Zir.zig+30-10
...@@ -34,16 +34,21 @@ instructions: std.MultiArrayList(Inst).Slice,...@@ -34,16 +34,21 @@ instructions: std.MultiArrayList(Inst).Slice,
34/// `string_bytes` array is agnostic to either usage.34/// `string_bytes` array is agnostic to either usage.
35string_bytes: []u8,35string_bytes: []u8,
36/// The meaning of this data is determined by `Inst.Tag` value.36/// The meaning of this data is determined by `Inst.Tag` value.
37/// Indexes 0 and 1 are reserved for:37/// The first few indexes are reserved. See `ExtraIndex` for the values.
38/// 0. struct_decl: Ref
39/// - the main struct decl for this file
40/// 1. errors_payload_index: u32
41/// - if this is 0, no compile errors. Otherwise there is a `CompileErrors`
42/// payload at this index.
43extra: []u32,38extra: []u32,
4439
45pub const main_struct_extra_index = 0;40pub const ExtraIndex = enum(u32) {
46pub const compile_error_extra_index = 1;41 /// Ref. The main struct decl for this file.
42 main_struct,
43 /// If this is 0, no compile errors. Otherwise there is a `CompileErrors`
44 /// payload at this index.
45 compile_errors,
46 /// If this is 0, this file contains no imports. Otherwise there is a `Imports`
47 /// payload at this index.
48 imports,
49
50 _,
51};
4752
48/// Returns the requested data, as well as the new index which is at the start of the53/// Returns the requested data, as well as the new index which is at the start of the
49/// trailers for the object.54/// trailers for the object.
...@@ -80,7 +85,7 @@ pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref {...@@ -80,7 +85,7 @@ pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref {
80}85}
8186
82pub fn hasCompileErrors(code: Zir) bool {87pub fn hasCompileErrors(code: Zir) bool {
83 return code.extra[compile_error_extra_index] != 0;88 return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0;
84}89}
8590
86pub fn deinit(code: *Zir, gpa: *Allocator) void {91pub fn deinit(code: *Zir, gpa: *Allocator) void {
...@@ -109,10 +114,20 @@ pub fn renderAsTextToFile(...@@ -109,10 +114,20 @@ pub fn renderAsTextToFile(
109 .param_count = 0,114 .param_count = 0,
110 };115 };
111116
112 const main_struct_inst = scope_file.zir.extra[0] - @intCast(u32, Inst.Ref.typed_value_map.len);117 const main_struct_inst = scope_file.zir.extra[@enumToInt(ExtraIndex.main_struct)] -
118 @intCast(u32, Inst.Ref.typed_value_map.len);
113 try fs_file.writer().print("%{d} ", .{main_struct_inst});119 try fs_file.writer().print("%{d} ", .{main_struct_inst});
114 try writer.writeInstToStream(fs_file.writer(), main_struct_inst);120 try writer.writeInstToStream(fs_file.writer(), main_struct_inst);
115 try fs_file.writeAll("\n");121 try fs_file.writeAll("\n");
122 const imports_index = scope_file.zir.extra[@enumToInt(ExtraIndex.imports)];
123 if (imports_index != 0) {
124 try fs_file.writeAll("Imports:\n");
125 const imports_len = scope_file.zir.extra[imports_index];
126 for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {
127 const import_path = scope_file.zir.nullTerminatedString(str_index);
128 try fs_file.writer().print(" {s}\n", .{import_path});
129 }
130 }
116}131}
117132
118/// These are untyped instructions generated from an Abstract Syntax Tree.133/// These are untyped instructions generated from an Abstract Syntax Tree.
...@@ -1649,6 +1664,11 @@ pub const Inst = struct {...@@ -1649,6 +1664,11 @@ pub const Inst = struct {
1649 notes: u32,1664 notes: u32,
1650 };1665 };
1651 };1666 };
1667
1668 /// Trailing: for each `imports_len` there is a string table index.
1669 pub const Imports = struct {
1670 imports_len: u32,
1671 };
1652};1672};
16531673
1654pub const SpecialProng = enum { none, @"else", under };1674pub const SpecialProng = enum { none, @"else", under };