stage2 zir tests passing
parent
f2feb4e47a
commit
294bfb3321
|
@ -18,12 +18,11 @@ const Inst = ir.Inst;
|
|||
|
||||
/// General-purpose allocator.
|
||||
allocator: *Allocator,
|
||||
/// Module owns this resource.
|
||||
/// Pointer to externally managed resource.
|
||||
root_pkg: *Package,
|
||||
/// Module owns this resource.
|
||||
root_scope: *Scope.ZIRModule,
|
||||
/// Pointer to externally managed resource.
|
||||
bin_file: *link.ElfFile,
|
||||
bin_file: link.ElfFile,
|
||||
/// It's rare for a decl to be exported, so we save memory by having a sparse map of
|
||||
/// Decl pointers to details about them being exported.
|
||||
/// The Export memory is owned by the `export_owners` table; the slice itself is owned by this table.
|
||||
|
@ -422,7 +421,55 @@ pub const AllErrors = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const InitOptions = struct {
|
||||
target: std.Target,
|
||||
root_pkg: *Package,
|
||||
output_mode: std.builtin.OutputMode,
|
||||
bin_file_dir: ?std.fs.Dir = null,
|
||||
bin_file_path: []const u8,
|
||||
link_mode: ?std.builtin.LinkMode = null,
|
||||
object_format: ?std.builtin.ObjectFormat = null,
|
||||
optimize_mode: std.builtin.Mode = .Debug,
|
||||
};
|
||||
|
||||
pub fn init(gpa: *Allocator, options: InitOptions) !Module {
|
||||
const root_scope = try gpa.create(Scope.ZIRModule);
|
||||
errdefer gpa.destroy(root_scope);
|
||||
|
||||
root_scope.* = .{
|
||||
.sub_file_path = options.root_pkg.root_src_path,
|
||||
.source = .{ .unloaded = {} },
|
||||
.contents = .{ .not_available = {} },
|
||||
.status = .never_loaded,
|
||||
};
|
||||
|
||||
const bin_file_dir = options.bin_file_dir orelse std.fs.cwd();
|
||||
var bin_file = try link.openBinFilePath(gpa, bin_file_dir, options.bin_file_path, .{
|
||||
.target = options.target,
|
||||
.output_mode = options.output_mode,
|
||||
.link_mode = options.link_mode orelse .Static,
|
||||
.object_format = options.object_format orelse options.target.getObjectFormat(),
|
||||
});
|
||||
errdefer bin_file.deinit();
|
||||
|
||||
return Module{
|
||||
.allocator = gpa,
|
||||
.root_pkg = options.root_pkg,
|
||||
.root_scope = root_scope,
|
||||
.bin_file = bin_file,
|
||||
.optimize_mode = options.optimize_mode,
|
||||
.decl_table = std.AutoHashMap(Decl.Hash, *Decl).init(gpa),
|
||||
.decl_exports = std.AutoHashMap(*Decl, []*Export).init(gpa),
|
||||
.export_owners = std.AutoHashMap(*Decl, []*Export).init(gpa),
|
||||
.failed_decls = std.AutoHashMap(*Decl, *ErrorMsg).init(gpa),
|
||||
.failed_files = std.AutoHashMap(*Scope.ZIRModule, *ErrorMsg).init(gpa),
|
||||
.failed_exports = std.AutoHashMap(*Export, *ErrorMsg).init(gpa),
|
||||
.work_queue = std.fifo.LinearFifo(WorkItem, .Dynamic).init(gpa),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Module) void {
|
||||
self.bin_file.deinit();
|
||||
const allocator = self.allocator;
|
||||
self.work_queue.deinit();
|
||||
{
|
||||
|
@ -472,7 +519,6 @@ pub fn deinit(self: *Module) void {
|
|||
}
|
||||
self.export_owners.deinit();
|
||||
}
|
||||
self.root_pkg.destroy();
|
||||
{
|
||||
self.root_scope.deinit(allocator);
|
||||
allocator.destroy(self.root_scope);
|
||||
|
|
|
@ -157,7 +157,7 @@ fn buildOutputType(
|
|||
var color: Color = .Auto;
|
||||
var build_mode: std.builtin.Mode = .Debug;
|
||||
var provided_name: ?[]const u8 = null;
|
||||
var is_dynamic = false;
|
||||
var link_mode: ?std.builtin.LinkMode = null;
|
||||
var root_src_file: ?[]const u8 = null;
|
||||
var version: std.builtin.Version = .{ .major = 0, .minor = 0, .patch = 0 };
|
||||
var strip = false;
|
||||
|
@ -286,7 +286,9 @@ fn buildOutputType(
|
|||
} else if (mem.eql(u8, arg, "-fno-emit-zir")) {
|
||||
emit_zir = .no;
|
||||
} else if (mem.eql(u8, arg, "-dynamic")) {
|
||||
is_dynamic = true;
|
||||
link_mode = .Dynamic;
|
||||
} else if (mem.eql(u8, arg, "-static")) {
|
||||
link_mode = .Static;
|
||||
} else if (mem.eql(u8, arg, "--strip")) {
|
||||
strip = true;
|
||||
} else if (mem.eql(u8, arg, "--debug-tokenize")) {
|
||||
|
@ -427,42 +429,19 @@ fn buildOutputType(
|
|||
.yes => |p| p,
|
||||
};
|
||||
|
||||
var bin_file = try link.openBinFilePath(gpa, fs.cwd(), bin_path, .{
|
||||
const root_pkg = try Package.create(gpa, fs.cwd(), ".", src_path);
|
||||
defer root_pkg.destroy();
|
||||
|
||||
var module = try Module.init(gpa, .{
|
||||
.target = target_info.target,
|
||||
.output_mode = output_mode,
|
||||
.link_mode = if (is_dynamic) .Dynamic else .Static,
|
||||
.object_format = object_format orelse target_info.target.getObjectFormat(),
|
||||
.root_pkg = root_pkg,
|
||||
.bin_file_dir = fs.cwd(),
|
||||
.bin_file_path = bin_path,
|
||||
.link_mode = link_mode,
|
||||
.object_format = object_format,
|
||||
.optimize_mode = build_mode,
|
||||
});
|
||||
defer bin_file.deinit();
|
||||
|
||||
var module = blk: {
|
||||
const root_pkg = try Package.create(gpa, fs.cwd(), ".", src_path);
|
||||
errdefer root_pkg.destroy();
|
||||
|
||||
const root_scope = try gpa.create(Module.Scope.ZIRModule);
|
||||
errdefer gpa.destroy(root_scope);
|
||||
root_scope.* = .{
|
||||
.sub_file_path = root_pkg.root_src_path,
|
||||
.source = .{ .unloaded = {} },
|
||||
.contents = .{ .not_available = {} },
|
||||
.status = .never_loaded,
|
||||
};
|
||||
|
||||
break :blk Module{
|
||||
.allocator = gpa,
|
||||
.root_pkg = root_pkg,
|
||||
.root_scope = root_scope,
|
||||
.bin_file = &bin_file,
|
||||
.optimize_mode = .Debug,
|
||||
.decl_table = std.AutoHashMap(Module.Decl.Hash, *Module.Decl).init(gpa),
|
||||
.decl_exports = std.AutoHashMap(*Module.Decl, []*Module.Export).init(gpa),
|
||||
.export_owners = std.AutoHashMap(*Module.Decl, []*Module.Export).init(gpa),
|
||||
.failed_decls = std.AutoHashMap(*Module.Decl, *Module.ErrorMsg).init(gpa),
|
||||
.failed_files = std.AutoHashMap(*Module.Scope.ZIRModule, *Module.ErrorMsg).init(gpa),
|
||||
.failed_exports = std.AutoHashMap(*Module.Export, *Module.ErrorMsg).init(gpa),
|
||||
.work_queue = std.fifo.LinearFifo(Module.WorkItem, .Dynamic).init(gpa),
|
||||
};
|
||||
};
|
||||
defer module.deinit();
|
||||
|
||||
const stdin = std.io.getStdIn().inStream();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const std = @import("std");
|
||||
const link = @import("link.zig");
|
||||
const ir = @import("ir.zig");
|
||||
const Module = @import("Module.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const zir = @import("zir.zig");
|
||||
const Package = @import("Package.zig");
|
||||
|
||||
test "self-hosted" {
|
||||
var ctx: TestContext = undefined;
|
||||
|
@ -98,52 +100,31 @@ pub const TestContext = struct {
|
|||
var tmp = std.testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
|
||||
var prg_node = root_node.start(case.name, 4);
|
||||
var prg_node = root_node.start(case.name, 2);
|
||||
prg_node.activate();
|
||||
defer prg_node.end();
|
||||
|
||||
var zir_module = x: {
|
||||
var parse_node = prg_node.start("parse", null);
|
||||
parse_node.activate();
|
||||
defer parse_node.end();
|
||||
const tmp_src_path = "test-case.zir";
|
||||
try tmp.dir.writeFile(tmp_src_path, case.src);
|
||||
|
||||
break :x try ir.text.parse(allocator, case.src);
|
||||
};
|
||||
defer zir_module.deinit(allocator);
|
||||
if (zir_module.errors.len != 0) {
|
||||
debugPrintErrors(case.src, zir_module.errors);
|
||||
return error.ParseFailure;
|
||||
}
|
||||
const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path);
|
||||
defer root_pkg.destroy();
|
||||
|
||||
var analyzed_module = x: {
|
||||
var analyze_node = prg_node.start("analyze", null);
|
||||
analyze_node.activate();
|
||||
defer analyze_node.end();
|
||||
|
||||
break :x try ir.analyze(allocator, zir_module, .{
|
||||
{
|
||||
var module = try Module.init(allocator, .{
|
||||
.target = target,
|
||||
.output_mode = .Exe,
|
||||
.link_mode = .Static,
|
||||
.optimize_mode = .Debug,
|
||||
.bin_file_dir = tmp.dir,
|
||||
.bin_file_path = "a.out",
|
||||
.root_pkg = root_pkg,
|
||||
});
|
||||
};
|
||||
defer analyzed_module.deinit(allocator);
|
||||
if (analyzed_module.errors.len != 0) {
|
||||
debugPrintErrors(case.src, analyzed_module.errors);
|
||||
return error.ParseFailure;
|
||||
}
|
||||
defer module.deinit();
|
||||
|
||||
var link_result = x: {
|
||||
var link_node = prg_node.start("link", null);
|
||||
link_node.activate();
|
||||
defer link_node.end();
|
||||
|
||||
break :x try link.updateFilePath(allocator, analyzed_module, tmp.dir, "a.out");
|
||||
};
|
||||
defer link_result.deinit(allocator);
|
||||
if (link_result.errors.len != 0) {
|
||||
debugPrintErrors(case.src, link_result.errors);
|
||||
return error.LinkFailure;
|
||||
var module_node = prg_node.start("parse,analysis,codegen", null);
|
||||
module_node.activate();
|
||||
try module.update();
|
||||
module_node.end();
|
||||
}
|
||||
|
||||
var exec_result = x: {
|
||||
|
@ -178,38 +159,37 @@ pub const TestContext = struct {
|
|||
case: ZIRTransformCase,
|
||||
target: std.Target,
|
||||
) !void {
|
||||
var prg_node = root_node.start(case.name, 4);
|
||||
var tmp = std.testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
|
||||
var prg_node = root_node.start(case.name, 3);
|
||||
prg_node.activate();
|
||||
defer prg_node.end();
|
||||
|
||||
var parse_node = prg_node.start("parse", null);
|
||||
parse_node.activate();
|
||||
var zir_module = try ir.text.parse(allocator, case.src);
|
||||
defer zir_module.deinit(allocator);
|
||||
if (zir_module.errors.len != 0) {
|
||||
debugPrintErrors(case.src, zir_module.errors);
|
||||
return error.ParseFailure;
|
||||
}
|
||||
parse_node.end();
|
||||
const tmp_src_path = "test-case.zir";
|
||||
try tmp.dir.writeFile(tmp_src_path, case.src);
|
||||
|
||||
var analyze_node = prg_node.start("analyze", null);
|
||||
analyze_node.activate();
|
||||
var analyzed_module = try ir.analyze(allocator, zir_module, .{
|
||||
const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path);
|
||||
defer root_pkg.destroy();
|
||||
|
||||
var module = try Module.init(allocator, .{
|
||||
.target = target,
|
||||
.output_mode = .Obj,
|
||||
.link_mode = .Static,
|
||||
.optimize_mode = .Debug,
|
||||
.bin_file_dir = tmp.dir,
|
||||
.bin_file_path = "test-case.o",
|
||||
.root_pkg = root_pkg,
|
||||
});
|
||||
defer analyzed_module.deinit(allocator);
|
||||
if (analyzed_module.errors.len != 0) {
|
||||
debugPrintErrors(case.src, analyzed_module.errors);
|
||||
return error.ParseFailure;
|
||||
}
|
||||
analyze_node.end();
|
||||
defer module.deinit();
|
||||
|
||||
var module_node = prg_node.start("parse/analysis/codegen", null);
|
||||
module_node.activate();
|
||||
try module.update();
|
||||
module_node.end();
|
||||
|
||||
var emit_node = prg_node.start("emit", null);
|
||||
emit_node.activate();
|
||||
var new_zir_module = try ir.text.emit_zir(allocator, analyzed_module);
|
||||
var new_zir_module = try zir.emit(allocator, module);
|
||||
defer new_zir_module.deinit(allocator);
|
||||
emit_node.end();
|
||||
|
||||
|
|
Loading…
Reference in New Issue