| author | |
| committer | |
| log | 9360e5887ce0bf0ce204eb49f0d0b253348ef557 |
| tree | 30d5775253ec1f8a913c8c87aa952534b6bc19ea |
| parent | 6c4924408b1957d493568271a0158b1190574dd0 |
* CBE buffers are only valid during a flush()
* the file is reopened and truncated during each flush()
* CBE now explicitly ignores updateDecl and deleteDecl
* CBE updateDecl is gone
* test case is enabled3 files changed, 53 insertions(+), 47 deletions(-)
src/link.zig+2-2| ... | @@ -291,7 +291,7 @@ pub const File = struct { | ... | @@ -291,7 +291,7 @@ pub const File = struct { |
| 291 | .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl), | 291 | .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl), |
| 292 | .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl), | 292 | .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl), |
| 293 | .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl), | 293 | .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl), |
| 294 | .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl), | 294 | .c => {}, |
| 295 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl), | 295 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl), |
| 296 | } | 296 | } |
| 297 | } | 297 | } |
| ... | @@ -412,7 +412,7 @@ pub const File = struct { | ... | @@ -412,7 +412,7 @@ pub const File = struct { |
| 412 | .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl), | 412 | .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl), |
| 413 | .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl), | 413 | .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl), |
| 414 | .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl), | 414 | .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl), |
| 415 | .c => unreachable, | 415 | .c => {}, |
| 416 | .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl), | 416 | .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl), |
| 417 | } | 417 | } |
| 418 | } | 418 | } |
src/link/C.zig+36-30| ... | @@ -8,10 +8,9 @@ const fs = std.fs; | ... | @@ -8,10 +8,9 @@ const fs = std.fs; |
| 8 | const codegen = @import("../codegen/c.zig"); | 8 | const codegen = @import("../codegen/c.zig"); |
| 9 | const link = @import("../link.zig"); | 9 | const link = @import("../link.zig"); |
| 10 | const trace = @import("../tracy.zig").trace; | 10 | const trace = @import("../tracy.zig").trace; |
| 11 | const File = link.File; | ||
| 12 | const C = @This(); | 11 | const C = @This(); |
| 13 | 12 | ||
| 14 | pub const base_tag: File.Tag = .c; | 13 | pub const base_tag: link.File.Tag = .c; |
| 15 | 14 | ||
| 16 | pub const Header = struct { | 15 | pub const Header = struct { |
| 17 | buf: std.ArrayList(u8), | 16 | buf: std.ArrayList(u8), |
| ... | @@ -40,13 +39,16 @@ pub const Header = struct { | ... | @@ -40,13 +39,16 @@ pub const Header = struct { |
| 40 | } | 39 | } |
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| 43 | base: File, | 42 | base: link.File, |
| 44 | 43 | ||
| 44 | path: []const u8, | ||
| 45 | |||
| 46 | // These are only valid during a flush()! | ||
| 45 | header: Header, | 47 | header: Header, |
| 46 | constants: std.ArrayList(u8), | 48 | constants: std.ArrayList(u8), |
| 47 | main: std.ArrayList(u8), | 49 | main: std.ArrayList(u8), |
| 48 | |||
| 49 | called: std.StringHashMap(void), | 50 | called: std.StringHashMap(void), |
| 51 | |||
| 50 | error_msg: *Compilation.ErrorMsg = undefined, | 52 | error_msg: *Compilation.ErrorMsg = undefined, |
| 51 | 53 | ||
| 52 | pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*C { | 54 | pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*C { |
| ... | @@ -55,9 +57,6 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -55,9 +57,6 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 55 | if (options.use_llvm) return error.LLVMHasNoCBackend; | 57 | if (options.use_llvm) return error.LLVMHasNoCBackend; |
| 56 | if (options.use_lld) return error.LLDHasNoCBackend; | 58 | if (options.use_lld) return error.LLDHasNoCBackend; |
| 57 | 59 | ||
| 58 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ .truncate = true, .read = true, .mode = link.determineMode(options) }); | ||
| 59 | errdefer file.close(); | ||
| 60 | |||
| 61 | var c_file = try allocator.create(C); | 60 | var c_file = try allocator.create(C); |
| 62 | errdefer allocator.destroy(c_file); | 61 | errdefer allocator.destroy(c_file); |
| 63 | 62 | ||
| ... | @@ -65,13 +64,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -65,13 +64,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 65 | .base = .{ | 64 | .base = .{ |
| 66 | .tag = .c, | 65 | .tag = .c, |
| 67 | .options = options, | 66 | .options = options, |
| 68 | .file = file, | 67 | .file = null, |
| 69 | .allocator = allocator, | 68 | .allocator = allocator, |
| 70 | }, | 69 | }, |
| 71 | .main = std.ArrayList(u8).init(allocator), | 70 | .main = undefined, |
| 72 | .header = Header.init(allocator, null), | 71 | .header = undefined, |
| 73 | .constants = std.ArrayList(u8).init(allocator), | 72 | .constants = undefined, |
| 74 | .called = std.StringHashMap(void).init(allocator), | 73 | .called = undefined, |
| 74 | .path = sub_path, | ||
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | return c_file; | 77 | return c_file; |
| ... | @@ -82,21 +82,7 @@ pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) er | ... | @@ -82,21 +82,7 @@ pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) er |
| 82 | return error.AnalysisFail; | 82 | return error.AnalysisFail; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | pub fn deinit(self: *C) void { | 85 | pub fn deinit(self: *C) void {} |
| 86 | self.main.deinit(); | ||
| 87 | self.header.deinit(); | ||
| 88 | self.constants.deinit(); | ||
| 89 | self.called.deinit(); | ||
| 90 | } | ||
| 91 | |||
| 92 | pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { | ||
| 93 | codegen.generate(self, module, decl) catch |err| { | ||
| 94 | if (err == error.AnalysisFail) { | ||
| 95 | try module.failed_decls.put(module.gpa, decl, self.error_msg); | ||
| 96 | } | ||
| 97 | return err; | ||
| 98 | }; | ||
| 99 | } | ||
| 100 | 86 | ||
| 101 | pub fn flush(self: *C, comp: *Compilation) !void { | 87 | pub fn flush(self: *C, comp: *Compilation) !void { |
| 102 | return self.flushModule(comp); | 88 | return self.flushModule(comp); |
| ... | @@ -106,7 +92,29 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { | ... | @@ -106,7 +92,29 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { |
| 106 | const tracy = trace(@src()); | 92 | const tracy = trace(@src()); |
| 107 | defer tracy.end(); | 93 | defer tracy.end(); |
| 108 | 94 | ||
| 109 | const writer = self.base.file.?.writer(); | 95 | self.main = std.ArrayList(u8).init(self.base.allocator); |
| 96 | self.header = Header.init(self.base.allocator, null); | ||
| 97 | self.constants = std.ArrayList(u8).init(self.base.allocator); | ||
| 98 | self.called = std.StringHashMap(void).init(self.base.allocator); | ||
| 99 | defer self.main.deinit(); | ||
| 100 | defer self.header.deinit(); | ||
| 101 | defer self.constants.deinit(); | ||
| 102 | defer self.called.deinit(); | ||
| 103 | |||
| 104 | const module = self.base.options.module.?; | ||
| 105 | for (self.base.options.module.?.decl_table.entries.items) |kv| { | ||
| 106 | codegen.generate(self, module, kv.value) catch |err| { | ||
| 107 | if (err == error.AnalysisFail) { | ||
| 108 | try module.failed_decls.put(module.gpa, kv.value, self.error_msg); | ||
| 109 | } | ||
| 110 | return err; | ||
| 111 | }; | ||
| 112 | } | ||
| 113 | |||
| 114 | const file = try self.base.options.emit.?.directory.handle.createFile(self.path, .{ .truncate = true, .read = true, .mode = link.determineMode(self.base.options) }); | ||
| 115 | defer file.close(); | ||
| 116 | |||
| 117 | const writer = file.writer(); | ||
| 110 | try self.header.flush(writer); | 118 | try self.header.flush(writer); |
| 111 | if (self.header.buf.items.len > 0) { | 119 | if (self.header.buf.items.len > 0) { |
| 112 | try writer.writeByte('\n'); | 120 | try writer.writeByte('\n'); |
| ... | @@ -121,6 +129,4 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { | ... | @@ -121,6 +129,4 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { |
| 121 | } | 129 | } |
| 122 | } | 130 | } |
| 123 | try writer.writeAll(self.main.items); | 131 | try writer.writeAll(self.main.items); |
| 124 | self.base.file.?.close(); | ||
| 125 | self.base.file = null; | ||
| 126 | } | 132 | } |
test/stage2/cbe.zig+15-15| ... | @@ -24,13 +24,13 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -24,13 +24,13 @@ pub fn addCases(ctx: *TestContext) !void { |
| 24 | // Now change the message only | 24 | // Now change the message only |
| 25 | // TODO fix C backend not supporting updates | 25 | // TODO fix C backend not supporting updates |
| 26 | // https://github.com/ziglang/zig/issues/7589 | 26 | // https://github.com/ziglang/zig/issues/7589 |
| 27 | //case.addCompareOutput( | 27 | case.addCompareOutput( |
| 28 | // \\extern fn puts(s: [*:0]const u8) c_int; | 28 | \\extern fn puts(s: [*:0]const u8) c_int; |
| 29 | // \\export fn main() c_int { | 29 | \\export fn main() c_int { |
| 30 | // \\ _ = puts("yo"); | 30 | \\ _ = puts("yo"); |
| 31 | // \\ return 0; | 31 | \\ return 0; |
| 32 | // \\} | 32 | \\} |
| 33 | //, "yo" ++ std.cstr.line_sep); | 33 | , "yo" ++ std.cstr.line_sep); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | { | 36 | { |
| ... | @@ -111,15 +111,15 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -111,15 +111,15 @@ pub fn addCases(ctx: *TestContext) !void { |
| 111 | , | 111 | , |
| 112 | \\static zig_noreturn void main(void); | 112 | \\static zig_noreturn void main(void); |
| 113 | \\ | 113 | \\ |
| 114 | \\zig_noreturn void _start(void) { | ||
| 115 | \\ main(); | ||
| 116 | \\} | ||
| 117 | \\ | ||
| 118 | \\static zig_noreturn void main(void) { | 114 | \\static zig_noreturn void main(void) { |
| 119 | \\ zig_breakpoint(); | 115 | \\ zig_breakpoint(); |
| 120 | \\ zig_unreachable(); | 116 | \\ zig_unreachable(); |
| 121 | \\} | 117 | \\} |
| 122 | \\ | 118 | \\ |
| 119 | \\zig_noreturn void _start(void) { | ||
| 120 | \\ main(); | ||
| 121 | \\} | ||
| 122 | \\ | ||
| 123 | ); | 123 | ); |
| 124 | // TODO: implement return values | 124 | // TODO: implement return values |
| 125 | // TODO: figure out a way to prevent asm constants from being generated | 125 | // TODO: figure out a way to prevent asm constants from being generated |
| ... | @@ -143,10 +143,6 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -143,10 +143,6 @@ pub fn addCases(ctx: *TestContext) !void { |
| 143 | \\static uint8_t exitGood__anon_1[6] = "{rdi}"; | 143 | \\static uint8_t exitGood__anon_1[6] = "{rdi}"; |
| 144 | \\static uint8_t exitGood__anon_2[8] = "syscall"; | 144 | \\static uint8_t exitGood__anon_2[8] = "syscall"; |
| 145 | \\ | 145 | \\ |
| 146 | \\zig_noreturn void _start(void) { | ||
| 147 | \\ exitGood(); | ||
| 148 | \\} | ||
| 149 | \\ | ||
| 150 | \\static zig_noreturn void exitGood(void) { | 146 | \\static zig_noreturn void exitGood(void) { |
| 151 | \\ register uintptr_t rax_constant __asm__("rax") = 231; | 147 | \\ register uintptr_t rax_constant __asm__("rax") = 231; |
| 152 | \\ register uintptr_t rdi_constant __asm__("rdi") = 0; | 148 | \\ register uintptr_t rdi_constant __asm__("rdi") = 0; |
| ... | @@ -155,6 +151,10 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -155,6 +151,10 @@ pub fn addCases(ctx: *TestContext) !void { |
| 155 | \\ zig_unreachable(); | 151 | \\ zig_unreachable(); |
| 156 | \\} | 152 | \\} |
| 157 | \\ | 153 | \\ |
| 154 | \\zig_noreturn void _start(void) { | ||
| 155 | \\ exitGood(); | ||
| 156 | \\} | ||
| 157 | \\ | ||
| 158 | ); | 158 | ); |
| 159 | ctx.c("exit with parameter", linux_x64, | 159 | ctx.c("exit with parameter", linux_x64, |
| 160 | \\export fn _start() noreturn { | 160 | \\export fn _start() noreturn { |