| author | |
| committer | |
| log | a271f12a149239ab6e6361423589687e32f64cda |
| tree | ea35c9389e0b01a24bba957525cabda86e8847ff |
| parent | edd75d03e312d6020623df4e06c9bb19c2f217c5 |
4 files changed, 56 insertions(+), 17 deletions(-)
BRANCH_TODO-1| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | * look for cached zir code |
| 2 | 2 | * save zir code to cache |
| 3 | * store list of imported strings | |
| 4 | 3 | * use list of imported strings to queue up more astgen tasks |
| 5 | 4 | * keep track of file dependencies/dependants |
| 6 | 5 | * unload files from memory when a dependency is dropped |
src/AstGen.zig+25-5| ... | ... | @@ -35,6 +35,8 @@ string_bytes: ArrayListUnmanaged(u8) = .{}, |
| 35 | 35 | arena: *Allocator, |
| 36 | 36 | string_table: std.StringHashMapUnmanaged(u32) = .{}, |
| 37 | 37 | compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{}, |
| 38 | /// String table indexes, keeps track of all `@import` operands. | |
| 39 | imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, | |
| 38 | 40 | |
| 39 | 41 | pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 40 | 42 | const fields = std.meta.fields(@TypeOf(extra)); |
| ... | ... | @@ -76,8 +78,8 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 76 | 78 | }; |
| 77 | 79 | defer astgen.deinit(gpa); |
| 78 | 80 | |
| 79 | // Indexes 0,1 of extra are reserved and set at the end. | |
| 80 | try astgen.extra.resize(gpa, 2); | |
| 81 | // First few indexes of extra are reserved and set at the end. | |
| 82 | try astgen.extra.resize(gpa, @typeInfo(Zir.ExtraIndex).Enum.fields.len); | |
| 81 | 83 | |
| 82 | 84 | var gen_scope: Scope.GenZir = .{ |
| 83 | 85 | .force_comptime = true, |
| ... | ... | @@ -103,20 +105,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 103 | 105 | container_decl, |
| 104 | 106 | .struct_decl, |
| 105 | 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 | 109 | } else |err| switch (err) { |
| 108 | 110 | error.OutOfMemory => return error.OutOfMemory, |
| 109 | 111 | error.AnalysisFail => {}, // Handled via compile_errors below. |
| 110 | 112 | } |
| 111 | 113 | |
| 114 | const err_index = @enumToInt(Zir.ExtraIndex.compile_errors); | |
| 112 | 115 | if (astgen.compile_errors.items.len == 0) { |
| 113 | astgen.extra.items[1] = 0; | |
| 116 | astgen.extra.items[err_index] = 0; | |
| 114 | 117 | } else { |
| 115 | 118 | try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len + |
| 116 | 119 | 1 + astgen.compile_errors.items.len * |
| 117 | 120 | @typeInfo(Zir.Inst.CompileErrors.Item).Struct.fields.len); |
| 118 | 121 | |
| 119 | astgen.extra.items[1] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{ | |
| 122 | astgen.extra.items[err_index] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{ | |
| 120 | 123 | .items_len = @intCast(u32, astgen.compile_errors.items.len), |
| 121 | 124 | }); |
| 122 | 125 | |
| ... | ... | @@ -125,6 +128,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 125 | 128 | } |
| 126 | 129 | } |
| 127 | 130 | |
| 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 | 146 | return Zir{ |
| 129 | 147 | .instructions = astgen.instructions.toOwnedSlice(), |
| 130 | 148 | .string_bytes = astgen.string_bytes.toOwnedSlice(gpa), |
| ... | ... | @@ -138,6 +156,7 @@ pub fn deinit(astgen: *AstGen, gpa: *Allocator) void { |
| 138 | 156 | astgen.string_table.deinit(gpa); |
| 139 | 157 | astgen.string_bytes.deinit(gpa); |
| 140 | 158 | astgen.compile_errors.deinit(gpa); |
| 159 | astgen.imports.deinit(gpa); | |
| 141 | 160 | } |
| 142 | 161 | |
| 143 | 162 | pub const ResultLoc = union(enum) { |
| ... | ... | @@ -4684,6 +4703,7 @@ fn builtinCall( |
| 4684 | 4703 | } |
| 4685 | 4704 | const str_lit_token = main_tokens[operand_node]; |
| 4686 | 4705 | const str = try gz.strLitAsString(str_lit_token); |
| 4706 | try astgen.imports.put(astgen.gpa, str.index, {}); | |
| 4687 | 4707 | const result = try gz.addStrTok(.import, str.index, str_lit_token); |
| 4688 | 4708 | return rvalue(gz, scope, rl, result, node); |
| 4689 | 4709 | }, |
src/Compilation.zig+1-1| ... | ... | @@ -432,7 +432,7 @@ pub const AllErrors = struct { |
| 432 | 432 | assert(file.zir_loaded); |
| 433 | 433 | assert(file.tree_loaded); |
| 434 | 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 | 436 | assert(payload_index != 0); |
| 437 | 437 | |
| 438 | 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 | 34 | /// `string_bytes` array is agnostic to either usage. |
| 35 | 35 | string_bytes: []u8, |
| 36 | 36 | /// The meaning of this data is determined by `Inst.Tag` value. |
| 37 | /// Indexes 0 and 1 are reserved for: | |
| 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. | |
| 37 | /// The first few indexes are reserved. See `ExtraIndex` for the values. | |
| 43 | 38 | extra: []u32, |
| 44 | 39 | |
| 45 | pub const main_struct_extra_index = 0; | |
| 46 | pub const compile_error_extra_index = 1; | |
| 40 | pub const ExtraIndex = enum(u32) { | |
| 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 | }; | |
| 47 | 52 | |
| 48 | 53 | /// Returns the requested data, as well as the new index which is at the start of the |
| 49 | 54 | /// trailers for the object. |
| ... | ... | @@ -80,7 +85,7 @@ pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref { |
| 80 | 85 | } |
| 81 | 86 | |
| 82 | 87 | pub 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 | } |
| 85 | 90 | |
| 86 | 91 | pub fn deinit(code: *Zir, gpa: *Allocator) void { |
| ... | ... | @@ -109,10 +114,20 @@ pub fn renderAsTextToFile( |
| 109 | 114 | .param_count = 0, |
| 110 | 115 | }; |
| 111 | 116 | |
| 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 | 119 | try fs_file.writer().print("%{d} ", .{main_struct_inst}); |
| 114 | 120 | try writer.writeInstToStream(fs_file.writer(), main_struct_inst); |
| 115 | 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 | } |
| 117 | 132 | |
| 118 | 133 | /// These are untyped instructions generated from an Abstract Syntax Tree. |
| ... | ... | @@ -1649,6 +1664,11 @@ pub const Inst = struct { |
| 1649 | 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 | }; |
| 1653 | 1673 | |
| 1654 | 1674 | pub const SpecialProng = enum { none, @"else", under }; |