| author | |
| committer | |
| log | a271f12a149239ab6e6361423589687e32f64cda |
| tree | ea35c9389e0b01a24bba957525cabda86e8847ff |
| parent | edd75d03e312d6020623df4e06c9bb19c2f217c5 |
4 files changed, 56 insertions(+), 17 deletions(-)
BRANCH_TODO-1| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | * look for cached zir code | 1 | * look for cached zir code |
| 2 | * save zir code to cache | 2 | * save zir code to cache |
| 3 | * store list of imported strings | ||
| 4 | * use list of imported strings to queue up more astgen tasks | 3 | * use list of imported strings to queue up more astgen tasks |
| 5 | * keep track of file dependencies/dependants | 4 | * keep track of file dependencies/dependants |
| 6 | * unload files from memory when a dependency is dropped | 5 | * 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) = .{}, |
| 35 | arena: *Allocator, | 35 | arena: *Allocator, |
| 36 | string_table: std.StringHashMapUnmanaged(u32) = .{}, | 36 | string_table: std.StringHashMapUnmanaged(u32) = .{}, |
| 37 | compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{}, | 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 | pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { | 41 | pub 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); |
| 78 | 80 | ||
| 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); |
| 81 | 83 | ||
| 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 | } |
| 111 | 113 | ||
| 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); |
| 118 | 121 | ||
| 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 | }); |
| 122 | 125 | ||
| ... | @@ -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 | } |
| 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 | 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 | } |
| 142 | 161 | ||
| 143 | pub const ResultLoc = union(enum) { | 162 | pub 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); |
| 437 | 437 | ||
| 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. |
| 35 | string_bytes: []u8, | 35 | string_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. | ||
| 43 | extra: []u32, | 38 | extra: []u32, |
| 44 | 39 | ||
| 45 | pub const main_struct_extra_index = 0; | 40 | pub const ExtraIndex = enum(u32) { |
| 46 | pub 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 | }; | ||
| 47 | 52 | ||
| 48 | /// Returns the requested data, as well as the new index which is at the start of the | 53 | /// 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 | } |
| 81 | 86 | ||
| 82 | pub fn hasCompileErrors(code: Zir) bool { | 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 | pub fn deinit(code: *Zir, gpa: *Allocator) void { | 91 | pub 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 | }; |
| 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 | 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 | } |
| 117 | 132 | ||
| 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 | }; |
| 1653 | 1673 | ||
| 1654 | pub const SpecialProng = enum { none, @"else", under }; | 1674 | pub const SpecialProng = enum { none, @"else", under }; |