mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
integrate CBE with Compilation.update pipeline (closes #7589)
* 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 enabled
This commit is contained in:
parent
6c4924408b
commit
9360e5887c
@ -291,7 +291,7 @@ pub const File = struct {
|
||||
.coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl),
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl),
|
||||
.c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl),
|
||||
.c => {},
|
||||
.wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl),
|
||||
}
|
||||
}
|
||||
@ -412,7 +412,7 @@ pub const File = struct {
|
||||
.coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl),
|
||||
.elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl),
|
||||
.macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl),
|
||||
.c => unreachable,
|
||||
.c => {},
|
||||
.wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl),
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,10 +8,9 @@ const fs = std.fs;
|
||||
const codegen = @import("../codegen/c.zig");
|
||||
const link = @import("../link.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
const File = link.File;
|
||||
const C = @This();
|
||||
|
||||
pub const base_tag: File.Tag = .c;
|
||||
pub const base_tag: link.File.Tag = .c;
|
||||
|
||||
pub const Header = struct {
|
||||
buf: std.ArrayList(u8),
|
||||
@ -40,13 +39,16 @@ pub const Header = struct {
|
||||
}
|
||||
};
|
||||
|
||||
base: File,
|
||||
base: link.File,
|
||||
|
||||
path: []const u8,
|
||||
|
||||
// These are only valid during a flush()!
|
||||
header: Header,
|
||||
constants: std.ArrayList(u8),
|
||||
main: std.ArrayList(u8),
|
||||
|
||||
called: std.StringHashMap(void),
|
||||
|
||||
error_msg: *Compilation.ErrorMsg = undefined,
|
||||
|
||||
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
|
||||
if (options.use_llvm) return error.LLVMHasNoCBackend;
|
||||
if (options.use_lld) return error.LLDHasNoCBackend;
|
||||
|
||||
const file = try options.emit.?.directory.handle.createFile(sub_path, .{ .truncate = true, .read = true, .mode = link.determineMode(options) });
|
||||
errdefer file.close();
|
||||
|
||||
var c_file = try allocator.create(C);
|
||||
errdefer allocator.destroy(c_file);
|
||||
|
||||
@ -65,13 +64,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
.base = .{
|
||||
.tag = .c,
|
||||
.options = options,
|
||||
.file = file,
|
||||
.file = null,
|
||||
.allocator = allocator,
|
||||
},
|
||||
.main = std.ArrayList(u8).init(allocator),
|
||||
.header = Header.init(allocator, null),
|
||||
.constants = std.ArrayList(u8).init(allocator),
|
||||
.called = std.StringHashMap(void).init(allocator),
|
||||
.main = undefined,
|
||||
.header = undefined,
|
||||
.constants = undefined,
|
||||
.called = undefined,
|
||||
.path = sub_path,
|
||||
};
|
||||
|
||||
return c_file;
|
||||
@ -82,21 +82,7 @@ pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) er
|
||||
return error.AnalysisFail;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *C) void {
|
||||
self.main.deinit();
|
||||
self.header.deinit();
|
||||
self.constants.deinit();
|
||||
self.called.deinit();
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
|
||||
codegen.generate(self, module, decl) catch |err| {
|
||||
if (err == error.AnalysisFail) {
|
||||
try module.failed_decls.put(module.gpa, decl, self.error_msg);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: *C) void {}
|
||||
|
||||
pub fn flush(self: *C, comp: *Compilation) !void {
|
||||
return self.flushModule(comp);
|
||||
@ -106,7 +92,29 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const writer = self.base.file.?.writer();
|
||||
self.main = std.ArrayList(u8).init(self.base.allocator);
|
||||
self.header = Header.init(self.base.allocator, null);
|
||||
self.constants = std.ArrayList(u8).init(self.base.allocator);
|
||||
self.called = std.StringHashMap(void).init(self.base.allocator);
|
||||
defer self.main.deinit();
|
||||
defer self.header.deinit();
|
||||
defer self.constants.deinit();
|
||||
defer self.called.deinit();
|
||||
|
||||
const module = self.base.options.module.?;
|
||||
for (self.base.options.module.?.decl_table.entries.items) |kv| {
|
||||
codegen.generate(self, module, kv.value) catch |err| {
|
||||
if (err == error.AnalysisFail) {
|
||||
try module.failed_decls.put(module.gpa, kv.value, self.error_msg);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
const file = try self.base.options.emit.?.directory.handle.createFile(self.path, .{ .truncate = true, .read = true, .mode = link.determineMode(self.base.options) });
|
||||
defer file.close();
|
||||
|
||||
const writer = file.writer();
|
||||
try self.header.flush(writer);
|
||||
if (self.header.buf.items.len > 0) {
|
||||
try writer.writeByte('\n');
|
||||
@ -121,6 +129,4 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
try writer.writeAll(self.main.items);
|
||||
self.base.file.?.close();
|
||||
self.base.file = null;
|
||||
}
|
||||
|
||||
@ -24,13 +24,13 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
// Now change the message only
|
||||
// TODO fix C backend not supporting updates
|
||||
// https://github.com/ziglang/zig/issues/7589
|
||||
//case.addCompareOutput(
|
||||
// \\extern fn puts(s: [*:0]const u8) c_int;
|
||||
// \\export fn main() c_int {
|
||||
// \\ _ = puts("yo");
|
||||
// \\ return 0;
|
||||
// \\}
|
||||
//, "yo" ++ std.cstr.line_sep);
|
||||
case.addCompareOutput(
|
||||
\\extern fn puts(s: [*:0]const u8) c_int;
|
||||
\\export fn main() c_int {
|
||||
\\ _ = puts("yo");
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "yo" ++ std.cstr.line_sep);
|
||||
}
|
||||
|
||||
{
|
||||
@ -111,15 +111,15 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
,
|
||||
\\static zig_noreturn void main(void);
|
||||
\\
|
||||
\\zig_noreturn void _start(void) {
|
||||
\\ main();
|
||||
\\}
|
||||
\\
|
||||
\\static zig_noreturn void main(void) {
|
||||
\\ zig_breakpoint();
|
||||
\\ zig_unreachable();
|
||||
\\}
|
||||
\\
|
||||
\\zig_noreturn void _start(void) {
|
||||
\\ main();
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
// TODO: implement return values
|
||||
// TODO: figure out a way to prevent asm constants from being generated
|
||||
@ -143,10 +143,6 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\static uint8_t exitGood__anon_1[6] = "{rdi}";
|
||||
\\static uint8_t exitGood__anon_2[8] = "syscall";
|
||||
\\
|
||||
\\zig_noreturn void _start(void) {
|
||||
\\ exitGood();
|
||||
\\}
|
||||
\\
|
||||
\\static zig_noreturn void exitGood(void) {
|
||||
\\ register uintptr_t rax_constant __asm__("rax") = 231;
|
||||
\\ register uintptr_t rdi_constant __asm__("rdi") = 0;
|
||||
@ -155,6 +151,10 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\ zig_unreachable();
|
||||
\\}
|
||||
\\
|
||||
\\zig_noreturn void _start(void) {
|
||||
\\ exitGood();
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
ctx.c("exit with parameter", linux_x64,
|
||||
\\export fn _start() noreturn {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user