Commit 294bfb3321

Andrew Kelley <andrew@ziglang.org>
2020-05-16 05:54:13
stage2 zir tests passing
1 parent f2feb4e
Changed files (3)
src-self-hosted/main.zig
@@ -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();
src-self-hosted/Module.zig
@@ -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);
src-self-hosted/test.zig
@@ -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;
-        }
-
-        var link_result = x: {
-            var link_node = prg_node.start("link", null);
-            link_node.activate();
-            defer link_node.end();
+            defer module.deinit();
 
-            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();