authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-10 12:28:20-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-10 12:28:20-04:00
log0df485d4dc764afc582b8ab684106b71d765d74f
tree8b97f40f278ba9d444ed60acab25e299b1d5afa4
parentd40f3fac7458577e1de81dceadd6fb6330df9097

self-hosted: reorganize creation and destruction of Compilation


6 files changed, 147 insertions(+), 105 deletions(-)

src-self-hosted/codegen.zig+2-2
...@@ -19,8 +19,8 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)...@@ -19,8 +19,8 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
19 var output_path = try await (async comp.createRandomOutputPath(comp.target.objFileExt()) catch unreachable);19 var output_path = try await (async comp.createRandomOutputPath(comp.target.objFileExt()) catch unreachable);
20 errdefer output_path.deinit();20 errdefer output_path.deinit();
2121
22 const llvm_handle = try comp.event_loop_local.getAnyLlvmContext();22 const llvm_handle = try comp.zig_compiler.getAnyLlvmContext();
23 defer llvm_handle.release(comp.event_loop_local);23 defer llvm_handle.release(comp.zig_compiler);
2424
25 const context = llvm_handle.node.data;25 const context = llvm_handle.node.data;
2626
src-self-hosted/compilation.zig+111-69
...@@ -35,7 +35,7 @@ const fs = event.fs;...@@ -35,7 +35,7 @@ const fs = event.fs;
35const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB35const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
3636
37/// Data that is local to the event loop.37/// Data that is local to the event loop.
38pub const EventLoopLocal = struct {38pub const ZigCompiler = struct {
39 loop: *event.Loop,39 loop: *event.Loop,
40 llvm_handle_pool: std.atomic.Stack(llvm.ContextRef),40 llvm_handle_pool: std.atomic.Stack(llvm.ContextRef),
41 lld_lock: event.Lock,41 lld_lock: event.Lock,
...@@ -47,7 +47,7 @@ pub const EventLoopLocal = struct {...@@ -47,7 +47,7 @@ pub const EventLoopLocal = struct {
4747
48 var lazy_init_targets = std.lazyInit(void);48 var lazy_init_targets = std.lazyInit(void);
4949
50 fn init(loop: *event.Loop) !EventLoopLocal {50 fn init(loop: *event.Loop) !ZigCompiler {
51 lazy_init_targets.get() orelse {51 lazy_init_targets.get() orelse {
52 Target.initializeAll();52 Target.initializeAll();
53 lazy_init_targets.resolve();53 lazy_init_targets.resolve();
...@@ -57,7 +57,7 @@ pub const EventLoopLocal = struct {...@@ -57,7 +57,7 @@ pub const EventLoopLocal = struct {
57 try std.os.getRandomBytes(seed_bytes[0..]);57 try std.os.getRandomBytes(seed_bytes[0..]);
58 const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big);58 const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big);
5959
60 return EventLoopLocal{60 return ZigCompiler{
61 .loop = loop,61 .loop = loop,
62 .lld_lock = event.Lock.init(loop),62 .lld_lock = event.Lock.init(loop),
63 .llvm_handle_pool = std.atomic.Stack(llvm.ContextRef).init(),63 .llvm_handle_pool = std.atomic.Stack(llvm.ContextRef).init(),
...@@ -67,7 +67,7 @@ pub const EventLoopLocal = struct {...@@ -67,7 +67,7 @@ pub const EventLoopLocal = struct {
67 }67 }
6868
69 /// Must be called only after EventLoop.run completes.69 /// Must be called only after EventLoop.run completes.
70 fn deinit(self: *EventLoopLocal) void {70 fn deinit(self: *ZigCompiler) void {
71 self.lld_lock.deinit();71 self.lld_lock.deinit();
72 while (self.llvm_handle_pool.pop()) |node| {72 while (self.llvm_handle_pool.pop()) |node| {
73 c.LLVMContextDispose(node.data);73 c.LLVMContextDispose(node.data);
...@@ -77,7 +77,7 @@ pub const EventLoopLocal = struct {...@@ -77,7 +77,7 @@ pub const EventLoopLocal = struct {
7777
78 /// Gets an exclusive handle on any LlvmContext.78 /// Gets an exclusive handle on any LlvmContext.
79 /// Caller must release the handle when done.79 /// Caller must release the handle when done.
80 pub fn getAnyLlvmContext(self: *EventLoopLocal) !LlvmHandle {80 pub fn getAnyLlvmContext(self: *ZigCompiler) !LlvmHandle {
81 if (self.llvm_handle_pool.pop()) |node| return LlvmHandle{ .node = node };81 if (self.llvm_handle_pool.pop()) |node| return LlvmHandle{ .node = node };
8282
83 const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;83 const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
...@@ -92,24 +92,36 @@ pub const EventLoopLocal = struct {...@@ -92,24 +92,36 @@ pub const EventLoopLocal = struct {
92 return LlvmHandle{ .node = node };92 return LlvmHandle{ .node = node };
93 }93 }
9494
95 pub async fn getNativeLibC(self: *EventLoopLocal) !*LibCInstallation {95 pub async fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation {
96 if (await (async self.native_libc.start() catch unreachable)) |ptr| return ptr;96 if (await (async self.native_libc.start() catch unreachable)) |ptr| return ptr;
97 try await (async self.native_libc.data.findNative(self.loop) catch unreachable);97 try await (async self.native_libc.data.findNative(self.loop) catch unreachable);
98 self.native_libc.resolve();98 self.native_libc.resolve();
99 return &self.native_libc.data;99 return &self.native_libc.data;
100 }100 }
101
102 /// Must be called only once, ever. Sets global state.
103 pub fn setLlvmArgv(allocator: *Allocator, llvm_argv: []const []const u8) !void {
104 if (llvm_argv.len != 0) {
105 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(allocator, [][]const []const u8{
106 [][]const u8{"zig (LLVM option parsing)"},
107 llvm_argv,
108 });
109 defer c_compatible_args.deinit();
110 c.ZigLLVMParseCommandLineOptions(llvm_argv.len + 1, c_compatible_args.ptr);
111 }
112 }
101};113};
102114
103pub const LlvmHandle = struct {115pub const LlvmHandle = struct {
104 node: *std.atomic.Stack(llvm.ContextRef).Node,116 node: *std.atomic.Stack(llvm.ContextRef).Node,
105117
106 pub fn release(self: LlvmHandle, event_loop_local: *EventLoopLocal) void {118 pub fn release(self: LlvmHandle, zig_compiler: *ZigCompiler) void {
107 event_loop_local.llvm_handle_pool.push(self.node);119 zig_compiler.llvm_handle_pool.push(self.node);
108 }120 }
109};121};
110122
111pub const Compilation = struct {123pub const Compilation = struct {
112 event_loop_local: *EventLoopLocal,124 zig_compiler: *ZigCompiler,
113 loop: *event.Loop,125 loop: *event.Loop,
114 name: Buffer,126 name: Buffer,
115 llvm_triple: Buffer,127 llvm_triple: Buffer,
...@@ -137,7 +149,6 @@ pub const Compilation = struct {...@@ -137,7 +149,6 @@ pub const Compilation = struct {
137 linker_rdynamic: bool,149 linker_rdynamic: bool,
138150
139 clang_argv: []const []const u8,151 clang_argv: []const []const u8,
140 llvm_argv: []const []const u8,
141 lib_dirs: []const []const u8,152 lib_dirs: []const []const u8,
142 rpath_list: []const []const u8,153 rpath_list: []const []const u8,
143 assembly_files: []const []const u8,154 assembly_files: []const []const u8,
...@@ -217,6 +228,8 @@ pub const Compilation = struct {...@@ -217,6 +228,8 @@ pub const Compilation = struct {
217 deinit_group: event.Group(void),228 deinit_group: event.Group(void),
218229
219 destroy_handle: promise,230 destroy_handle: promise,
231 main_loop_handle: promise,
232 main_loop_future: event.Future(void),
220233
221 have_err_ret_tracing: bool,234 have_err_ret_tracing: bool,
222235
...@@ -325,7 +338,7 @@ pub const Compilation = struct {...@@ -325,7 +338,7 @@ pub const Compilation = struct {
325 };338 };
326339
327 pub fn create(340 pub fn create(
328 event_loop_local: *EventLoopLocal,341 zig_compiler: *ZigCompiler,
329 name: []const u8,342 name: []const u8,
330 root_src_path: ?[]const u8,343 root_src_path: ?[]const u8,
331 target: Target,344 target: Target,
...@@ -334,12 +347,45 @@ pub const Compilation = struct {...@@ -334,12 +347,45 @@ pub const Compilation = struct {
334 is_static: bool,347 is_static: bool,
335 zig_lib_dir: []const u8,348 zig_lib_dir: []const u8,
336 ) !*Compilation {349 ) !*Compilation {
337 const loop = event_loop_local.loop;350 var optional_comp: ?*Compilation = null;
338 const comp = try event_loop_local.loop.allocator.createOne(Compilation);351 const handle = try async<zig_compiler.loop.allocator> createAsync(
339 comp.* = Compilation{352 &optional_comp,
353 zig_compiler,
354 name,
355 root_src_path,
356 target,
357 kind,
358 build_mode,
359 is_static,
360 zig_lib_dir,
361 );
362 return optional_comp orelse if (getAwaitResult(
363 zig_compiler.loop.allocator,
364 handle,
365 )) |_| unreachable else |err| err;
366 }
367
368 async fn createAsync(
369 out_comp: *?*Compilation,
370 zig_compiler: *ZigCompiler,
371 name: []const u8,
372 root_src_path: ?[]const u8,
373 target: Target,
374 kind: Kind,
375 build_mode: builtin.Mode,
376 is_static: bool,
377 zig_lib_dir: []const u8,
378 ) !void {
379 // workaround for https://github.com/ziglang/zig/issues/1194
380 suspend {
381 resume @handle();
382 }
383
384 const loop = zig_compiler.loop;
385 var comp = Compilation{
340 .loop = loop,386 .loop = loop,
341 .arena_allocator = std.heap.ArenaAllocator.init(loop.allocator),387 .arena_allocator = std.heap.ArenaAllocator.init(loop.allocator),
342 .event_loop_local = event_loop_local,388 .zig_compiler = zig_compiler,
343 .events = undefined,389 .events = undefined,
344 .root_src_path = root_src_path,390 .root_src_path = root_src_path,
345 .target = target,391 .target = target,
...@@ -349,6 +395,9 @@ pub const Compilation = struct {...@@ -349,6 +395,9 @@ pub const Compilation = struct {
349 .zig_lib_dir = zig_lib_dir,395 .zig_lib_dir = zig_lib_dir,
350 .zig_std_dir = undefined,396 .zig_std_dir = undefined,
351 .tmp_dir = event.Future(BuildError![]u8).init(loop),397 .tmp_dir = event.Future(BuildError![]u8).init(loop),
398 .destroy_handle = @handle(),
399 .main_loop_handle = undefined,
400 .main_loop_future = event.Future(void).init(loop),
352401
353 .name = undefined,402 .name = undefined,
354 .llvm_triple = undefined,403 .llvm_triple = undefined,
...@@ -373,7 +422,6 @@ pub const Compilation = struct {...@@ -373,7 +422,6 @@ pub const Compilation = struct {
373 .is_static = is_static,422 .is_static = is_static,
374 .linker_rdynamic = false,423 .linker_rdynamic = false,
375 .clang_argv = [][]const u8{},424 .clang_argv = [][]const u8{},
376 .llvm_argv = [][]const u8{},
377 .lib_dirs = [][]const u8{},425 .lib_dirs = [][]const u8{},
378 .rpath_list = [][]const u8{},426 .rpath_list = [][]const u8{},
379 .assembly_files = [][]const u8{},427 .assembly_files = [][]const u8{},
...@@ -381,7 +429,7 @@ pub const Compilation = struct {...@@ -381,7 +429,7 @@ pub const Compilation = struct {
381 .fn_link_set = event.Locked(FnLinkSet).init(loop, FnLinkSet.init()),429 .fn_link_set = event.Locked(FnLinkSet).init(loop, FnLinkSet.init()),
382 .windows_subsystem_windows = false,430 .windows_subsystem_windows = false,
383 .windows_subsystem_console = false,431 .windows_subsystem_console = false,
384 .link_libs_list = ArrayList(*LinkLib).init(comp.arena()),432 .link_libs_list = undefined,
385 .libc_link_lib = null,433 .libc_link_lib = null,
386 .err_color = errmsg.Color.Auto,434 .err_color = errmsg.Color.Auto,
387 .darwin_frameworks = [][]const u8{},435 .darwin_frameworks = [][]const u8{},
...@@ -420,19 +468,20 @@ pub const Compilation = struct {...@@ -420,19 +468,20 @@ pub const Compilation = struct {
420 .std_package = undefined,468 .std_package = undefined,
421469
422 .override_libc = null,470 .override_libc = null,
423 .destroy_handle = undefined,
424 .have_err_ret_tracing = false,471 .have_err_ret_tracing = false,
425 .primitive_type_table = TypeTable.init(comp.arena()),472 .primitive_type_table = undefined,
426473
427 .fs_watch = undefined,474 .fs_watch = undefined,
428 };475 };
429 errdefer {476 comp.link_libs_list = ArrayList(*LinkLib).init(comp.arena());
477 comp.primitive_type_table = TypeTable.init(comp.arena());
478
479 defer {
430 comp.int_type_table.private_data.deinit();480 comp.int_type_table.private_data.deinit();
431 comp.array_type_table.private_data.deinit();481 comp.array_type_table.private_data.deinit();
432 comp.ptr_type_table.private_data.deinit();482 comp.ptr_type_table.private_data.deinit();
433 comp.fn_type_table.private_data.deinit();483 comp.fn_type_table.private_data.deinit();
434 comp.arena_allocator.deinit();484 comp.arena_allocator.deinit();
435 comp.loop.allocator.destroy(comp);
436 }485 }
437486
438 comp.name = try Buffer.init(comp.arena(), name);487 comp.name = try Buffer.init(comp.arena(), name);
...@@ -452,8 +501,8 @@ pub const Compilation = struct {...@@ -452,8 +501,8 @@ pub const Compilation = struct {
452 // As a workaround we do not use target native features on Windows.501 // As a workaround we do not use target native features on Windows.
453 var target_specific_cpu_args: ?[*]u8 = null;502 var target_specific_cpu_args: ?[*]u8 = null;
454 var target_specific_cpu_features: ?[*]u8 = null;503 var target_specific_cpu_features: ?[*]u8 = null;
455 errdefer llvm.DisposeMessage(target_specific_cpu_args);504 defer llvm.DisposeMessage(target_specific_cpu_args);
456 errdefer llvm.DisposeMessage(target_specific_cpu_features);505 defer llvm.DisposeMessage(target_specific_cpu_features);
457 if (target == Target.Native and !target.isWindows()) {506 if (target == Target.Native and !target.isWindows()) {
458 target_specific_cpu_args = llvm.GetHostCPUName() orelse return error.OutOfMemory;507 target_specific_cpu_args = llvm.GetHostCPUName() orelse return error.OutOfMemory;
459 target_specific_cpu_features = llvm.GetNativeFeatures() orelse return error.OutOfMemory;508 target_specific_cpu_features = llvm.GetNativeFeatures() orelse return error.OutOfMemory;
...@@ -468,16 +517,16 @@ pub const Compilation = struct {...@@ -468,16 +517,16 @@ pub const Compilation = struct {
468 reloc_mode,517 reloc_mode,
469 llvm.CodeModelDefault,518 llvm.CodeModelDefault,
470 ) orelse return error.OutOfMemory;519 ) orelse return error.OutOfMemory;
471 errdefer llvm.DisposeTargetMachine(comp.target_machine);520 defer llvm.DisposeTargetMachine(comp.target_machine);
472521
473 comp.target_data_ref = llvm.CreateTargetDataLayout(comp.target_machine) orelse return error.OutOfMemory;522 comp.target_data_ref = llvm.CreateTargetDataLayout(comp.target_machine) orelse return error.OutOfMemory;
474 errdefer llvm.DisposeTargetData(comp.target_data_ref);523 defer llvm.DisposeTargetData(comp.target_data_ref);
475524
476 comp.target_layout_str = llvm.CopyStringRepOfTargetData(comp.target_data_ref) orelse return error.OutOfMemory;525 comp.target_layout_str = llvm.CopyStringRepOfTargetData(comp.target_data_ref) orelse return error.OutOfMemory;
477 errdefer llvm.DisposeMessage(comp.target_layout_str);526 defer llvm.DisposeMessage(comp.target_layout_str);
478527
479 comp.events = try event.Channel(Event).create(comp.loop, 0);528 comp.events = try event.Channel(Event).create(comp.loop, 0);
480 errdefer comp.events.destroy();529 defer comp.events.destroy();
481530
482 if (root_src_path) |root_src| {531 if (root_src_path) |root_src| {
483 const dirname = std.os.path.dirname(root_src) orelse ".";532 const dirname = std.os.path.dirname(root_src) orelse ".";
...@@ -491,13 +540,25 @@ pub const Compilation = struct {...@@ -491,13 +540,25 @@ pub const Compilation = struct {
491 }540 }
492541
493 comp.fs_watch = try fs.Watch(*Scope.Root).create(loop, 16);542 comp.fs_watch = try fs.Watch(*Scope.Root).create(loop, 16);
494 errdefer comp.fs_watch.destroy();543 defer comp.fs_watch.destroy();
495544
496 try comp.initTypes();545 try comp.initTypes();
546 defer comp.primitive_type_table.deinit();
547
548 // Set this to indicate that initialization completed successfully.
549 // from here on out we must not return an error.
550 // This must occur before the first suspend/await.
551 comp.main_loop_handle = async comp.mainLoop() catch unreachable;
552 out_comp.* = &comp;
553 suspend;
497554
498 comp.destroy_handle = try async<loop.allocator> comp.internalDeinit();555 // From here on is cleanup.
556 await (async comp.deinit_group.wait() catch unreachable);
499557
500 return comp;558 if (comp.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
559 // TODO evented I/O?
560 os.deleteTree(comp.arena(), tmp_dir) catch {};
561 } else |_| {};
501 }562 }
502563
503 /// it does ref the result because it could be an arbitrary integer size564 /// it does ref the result because it could be an arbitrary integer size
...@@ -683,49 +744,19 @@ pub const Compilation = struct {...@@ -683,49 +744,19 @@ pub const Compilation = struct {
683 assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);744 assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);
684 }745 }
685746
686 /// This function can safely use async/await, because it manages Compilation's lifetime,
687 /// and EventLoopLocal.deinit will not be called until the event.Loop.run() completes.
688 async fn internalDeinit(self: *Compilation) void {
689 suspend;
690
691 await (async self.deinit_group.wait() catch unreachable);
692 if (self.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
693 // TODO evented I/O?
694 os.deleteTree(self.arena(), tmp_dir) catch {};
695 } else |_| {};
696
697 self.fs_watch.destroy();
698 self.events.destroy();
699
700 llvm.DisposeMessage(self.target_layout_str);
701 llvm.DisposeTargetData(self.target_data_ref);
702 llvm.DisposeTargetMachine(self.target_machine);
703
704 self.primitive_type_table.deinit();
705
706 self.arena_allocator.deinit();
707 self.gpa().destroy(self);
708 }
709
710 pub fn destroy(self: *Compilation) void {747 pub fn destroy(self: *Compilation) void {
748 cancel self.main_loop_handle;
711 resume self.destroy_handle;749 resume self.destroy_handle;
712 }750 }
713751
714 pub fn build(self: *Compilation) !void {752 fn start(self: *Compilation) void {
715 if (self.llvm_argv.len != 0) {753 self.main_loop_future.resolve();
716 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.arena(), [][]const []const u8{
717 [][]const u8{"zig (LLVM option parsing)"},
718 self.llvm_argv,
719 });
720 defer c_compatible_args.deinit();
721 // TODO this sets global state
722 c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
723 }
724
725 _ = try async<self.gpa()> self.buildAsync();
726 }754 }
727755
728 async fn buildAsync(self: *Compilation) void {756 async fn mainLoop(self: *Compilation) void {
757 // wait until start() is called
758 _ = await (async self.main_loop_future.get() catch unreachable);
759
729 var build_result = await (async self.initialCompile() catch unreachable);760 var build_result = await (async self.initialCompile() catch unreachable);
730761
731 while (true) {762 while (true) {
...@@ -1131,7 +1162,7 @@ pub const Compilation = struct {...@@ -1131,7 +1162,7 @@ pub const Compilation = struct {
1131 async fn startFindingNativeLibC(self: *Compilation) void {1162 async fn startFindingNativeLibC(self: *Compilation) void {
1132 await (async self.loop.yield() catch unreachable);1163 await (async self.loop.yield() catch unreachable);
1133 // we don't care if it fails, we're just trying to kick off the future resolution1164 // we don't care if it fails, we're just trying to kick off the future resolution
1134 _ = (await (async self.event_loop_local.getNativeLibC() catch unreachable)) catch return;1165 _ = (await (async self.zig_compiler.getNativeLibC() catch unreachable)) catch return;
1135 }1166 }
11361167
1137 /// General Purpose Allocator. Must free when done.1168 /// General Purpose Allocator. Must free when done.
...@@ -1189,7 +1220,7 @@ pub const Compilation = struct {...@@ -1189,7 +1220,7 @@ pub const Compilation = struct {
1189 var rand_bytes: [9]u8 = undefined;1220 var rand_bytes: [9]u8 = undefined;
11901221
1191 {1222 {
1192 const held = await (async self.event_loop_local.prng.acquire() catch unreachable);1223 const held = await (async self.zig_compiler.prng.acquire() catch unreachable);
1193 defer held.release();1224 defer held.release();
11941225
1195 held.value.random.bytes(rand_bytes[0..]);1226 held.value.random.bytes(rand_bytes[0..]);
...@@ -1424,3 +1455,14 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {...@@ -1424,3 +1455,14 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
1424 fn_decl.value = Decl.Fn.Val{ .FnProto = fn_proto_val };1455 fn_decl.value = Decl.Fn.Val{ .FnProto = fn_proto_val };
1425 symbol_name_consumed = true;1456 symbol_name_consumed = true;
1426}1457}
1458
1459// TODO these are hacks which should probably be solved by the language
1460fn getAwaitResult(allocator: *Allocator, handle: var) @typeInfo(@typeOf(handle)).Promise.child.? {
1461 var result: ?@typeInfo(@typeOf(handle)).Promise.child.? = null;
1462 cancel (async<allocator> getAwaitResultAsync(handle, &result) catch unreachable);
1463 return result.?;
1464}
1465
1466async fn getAwaitResultAsync(handle: var, out: *?@typeInfo(@typeOf(handle)).Promise.child.?) void {
1467 out.* = await handle;
1468}
src-self-hosted/link.zig+2-2
...@@ -61,7 +61,7 @@ pub async fn link(comp: *Compilation) !void {...@@ -61,7 +61,7 @@ pub async fn link(comp: *Compilation) !void {
61 ctx.libc = ctx.comp.override_libc orelse blk: {61 ctx.libc = ctx.comp.override_libc orelse blk: {
62 switch (comp.target) {62 switch (comp.target) {
63 Target.Native => {63 Target.Native => {
64 break :blk (await (async comp.event_loop_local.getNativeLibC() catch unreachable)) catch return error.LibCRequiredButNotProvidedOrFound;64 break :blk (await (async comp.zig_compiler.getNativeLibC() catch unreachable)) catch return error.LibCRequiredButNotProvidedOrFound;
65 },65 },
66 else => return error.LibCRequiredButNotProvidedOrFound,66 else => return error.LibCRequiredButNotProvidedOrFound,
67 }67 }
...@@ -83,7 +83,7 @@ pub async fn link(comp: *Compilation) !void {...@@ -83,7 +83,7 @@ pub async fn link(comp: *Compilation) !void {
8383
84 {84 {
85 // LLD is not thread-safe, so we grab a global lock.85 // LLD is not thread-safe, so we grab a global lock.
86 const held = await (async comp.event_loop_local.lld_lock.acquire() catch unreachable);86 const held = await (async comp.zig_compiler.lld_lock.acquire() catch unreachable);
87 defer held.release();87 defer held.release();
8888
89 // Not evented I/O. LLD does its own multithreading internally.89 // Not evented I/O. LLD does its own multithreading internally.
src-self-hosted/main.zig+20-20
...@@ -14,7 +14,7 @@ const c = @import("c.zig");...@@ -14,7 +14,7 @@ const c = @import("c.zig");
14const introspect = @import("introspect.zig");14const introspect = @import("introspect.zig");
15const Args = arg.Args;15const Args = arg.Args;
16const Flag = arg.Flag;16const Flag = arg.Flag;
17const EventLoopLocal = @import("compilation.zig").EventLoopLocal;17const ZigCompiler = @import("compilation.zig").ZigCompiler;
18const Compilation = @import("compilation.zig").Compilation;18const Compilation = @import("compilation.zig").Compilation;
19const Target = @import("target.zig").Target;19const Target = @import("target.zig").Target;
20const errmsg = @import("errmsg.zig");20const errmsg = @import("errmsg.zig");
...@@ -373,6 +373,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -373,6 +373,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
373 os.exit(1);373 os.exit(1);
374 }374 }
375375
376 var clang_argv_buf = ArrayList([]const u8).init(allocator);
377 defer clang_argv_buf.deinit();
378
379 const mllvm_flags = flags.many("mllvm");
380 for (mllvm_flags) |mllvm| {
381 try clang_argv_buf.append("-mllvm");
382 try clang_argv_buf.append(mllvm);
383 }
384 try ZigCompiler.setLlvmArgv(allocator, mllvm_flags);
385
376 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);386 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
377 defer allocator.free(zig_lib_dir);387 defer allocator.free(zig_lib_dir);
378388
...@@ -382,11 +392,11 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -382,11 +392,11 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
382 try loop.initMultiThreaded(allocator);392 try loop.initMultiThreaded(allocator);
383 defer loop.deinit();393 defer loop.deinit();
384394
385 var event_loop_local = try EventLoopLocal.init(&loop);395 var zig_compiler = try ZigCompiler.init(&loop);
386 defer event_loop_local.deinit();396 defer zig_compiler.deinit();
387397
388 var comp = try Compilation.create(398 var comp = try Compilation.create(
389 &event_loop_local,399 &zig_compiler,
390 root_name,400 root_name,
391 root_source_file,401 root_source_file,
392 Target.Native,402 Target.Native,
...@@ -415,16 +425,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -415,16 +425,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
415 comp.linker_script = flags.single("linker-script");425 comp.linker_script = flags.single("linker-script");
416 comp.each_lib_rpath = flags.present("each-lib-rpath");426 comp.each_lib_rpath = flags.present("each-lib-rpath");
417427
418 var clang_argv_buf = ArrayList([]const u8).init(allocator);
419 defer clang_argv_buf.deinit();
420
421 const mllvm_flags = flags.many("mllvm");
422 for (mllvm_flags) |mllvm| {
423 try clang_argv_buf.append("-mllvm");
424 try clang_argv_buf.append(mllvm);
425 }
426
427 comp.llvm_argv = mllvm_flags;
428 comp.clang_argv = clang_argv_buf.toSliceConst();428 comp.clang_argv = clang_argv_buf.toSliceConst();
429429
430 comp.strip = flags.present("strip");430 comp.strip = flags.present("strip");
...@@ -467,7 +467,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -467,7 +467,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
467 comp.link_out_file = flags.single("output");467 comp.link_out_file = flags.single("output");
468 comp.link_objects = link_objects;468 comp.link_objects = link_objects;
469469
470 try comp.build();470 comp.start();
471 const process_build_events_handle = try async<loop.allocator> processBuildEvents(comp, color);471 const process_build_events_handle = try async<loop.allocator> processBuildEvents(comp, color);
472 defer cancel process_build_events_handle;472 defer cancel process_build_events_handle;
473 loop.run();473 loop.run();
...@@ -572,17 +572,17 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {...@@ -572,17 +572,17 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
572 try loop.initMultiThreaded(allocator);572 try loop.initMultiThreaded(allocator);
573 defer loop.deinit();573 defer loop.deinit();
574574
575 var event_loop_local = try EventLoopLocal.init(&loop);575 var zig_compiler = try ZigCompiler.init(&loop);
576 defer event_loop_local.deinit();576 defer zig_compiler.deinit();
577577
578 const handle = try async<loop.allocator> findLibCAsync(&event_loop_local);578 const handle = try async<loop.allocator> findLibCAsync(&zig_compiler);
579 defer cancel handle;579 defer cancel handle;
580580
581 loop.run();581 loop.run();
582}582}
583583
584async fn findLibCAsync(event_loop_local: *EventLoopLocal) void {584async fn findLibCAsync(zig_compiler: *ZigCompiler) void {
585 const libc = (await (async event_loop_local.getNativeLibC() catch unreachable)) catch |err| {585 const libc = (await (async zig_compiler.getNativeLibC() catch unreachable)) catch |err| {
586 stderr.print("unable to find libc: {}\n", @errorName(err)) catch os.exit(1);586 stderr.print("unable to find libc: {}\n", @errorName(err)) catch os.exit(1);
587 os.exit(1);587 os.exit(1);
588 };588 };
src-self-hosted/test.zig+10-10
...@@ -6,7 +6,7 @@ const Compilation = @import("compilation.zig").Compilation;...@@ -6,7 +6,7 @@ const Compilation = @import("compilation.zig").Compilation;
6const introspect = @import("introspect.zig");6const introspect = @import("introspect.zig");
7const assertOrPanic = std.debug.assertOrPanic;7const assertOrPanic = std.debug.assertOrPanic;
8const errmsg = @import("errmsg.zig");8const errmsg = @import("errmsg.zig");
9const EventLoopLocal = @import("compilation.zig").EventLoopLocal;9const ZigCompiler = @import("compilation.zig").ZigCompiler;
1010
11var ctx: TestContext = undefined;11var ctx: TestContext = undefined;
1212
...@@ -25,7 +25,7 @@ const allocator = std.heap.c_allocator;...@@ -25,7 +25,7 @@ const allocator = std.heap.c_allocator;
2525
26pub const TestContext = struct {26pub const TestContext = struct {
27 loop: std.event.Loop,27 loop: std.event.Loop,
28 event_loop_local: EventLoopLocal,28 zig_compiler: ZigCompiler,
29 zig_lib_dir: []u8,29 zig_lib_dir: []u8,
30 file_index: std.atomic.Int(usize),30 file_index: std.atomic.Int(usize),
31 group: std.event.Group(error!void),31 group: std.event.Group(error!void),
...@@ -37,7 +37,7 @@ pub const TestContext = struct {...@@ -37,7 +37,7 @@ pub const TestContext = struct {
37 self.* = TestContext{37 self.* = TestContext{
38 .any_err = {},38 .any_err = {},
39 .loop = undefined,39 .loop = undefined,
40 .event_loop_local = undefined,40 .zig_compiler = undefined,
41 .zig_lib_dir = undefined,41 .zig_lib_dir = undefined,
42 .group = undefined,42 .group = undefined,
43 .file_index = std.atomic.Int(usize).init(0),43 .file_index = std.atomic.Int(usize).init(0),
...@@ -46,8 +46,8 @@ pub const TestContext = struct {...@@ -46,8 +46,8 @@ pub const TestContext = struct {
46 try self.loop.initMultiThreaded(allocator);46 try self.loop.initMultiThreaded(allocator);
47 errdefer self.loop.deinit();47 errdefer self.loop.deinit();
4848
49 self.event_loop_local = try EventLoopLocal.init(&self.loop);49 self.zig_compiler = try ZigCompiler.init(&self.loop);
50 errdefer self.event_loop_local.deinit();50 errdefer self.zig_compiler.deinit();
5151
52 self.group = std.event.Group(error!void).init(&self.loop);52 self.group = std.event.Group(error!void).init(&self.loop);
53 errdefer self.group.deinit();53 errdefer self.group.deinit();
...@@ -62,7 +62,7 @@ pub const TestContext = struct {...@@ -62,7 +62,7 @@ pub const TestContext = struct {
62 fn deinit(self: *TestContext) void {62 fn deinit(self: *TestContext) void {
63 std.os.deleteTree(allocator, tmp_dir_name) catch {};63 std.os.deleteTree(allocator, tmp_dir_name) catch {};
64 allocator.free(self.zig_lib_dir);64 allocator.free(self.zig_lib_dir);
65 self.event_loop_local.deinit();65 self.zig_compiler.deinit();
66 self.loop.deinit();66 self.loop.deinit();
67 }67 }
6868
...@@ -97,7 +97,7 @@ pub const TestContext = struct {...@@ -97,7 +97,7 @@ pub const TestContext = struct {
97 try std.io.writeFile(allocator, file1_path, source);97 try std.io.writeFile(allocator, file1_path, source);
9898
99 var comp = try Compilation.create(99 var comp = try Compilation.create(
100 &self.event_loop_local,100 &self.zig_compiler,
101 "test",101 "test",
102 file1_path,102 file1_path,
103 Target.Native,103 Target.Native,
...@@ -108,7 +108,7 @@ pub const TestContext = struct {...@@ -108,7 +108,7 @@ pub const TestContext = struct {
108 );108 );
109 errdefer comp.destroy();109 errdefer comp.destroy();
110110
111 try comp.build();111 comp.start();
112112
113 try self.group.call(getModuleEvent, comp, source, path, line, column, msg);113 try self.group.call(getModuleEvent, comp, source, path, line, column, msg);
114 }114 }
...@@ -131,7 +131,7 @@ pub const TestContext = struct {...@@ -131,7 +131,7 @@ pub const TestContext = struct {
131 try std.io.writeFile(allocator, file1_path, source);131 try std.io.writeFile(allocator, file1_path, source);
132132
133 var comp = try Compilation.create(133 var comp = try Compilation.create(
134 &self.event_loop_local,134 &self.zig_compiler,
135 "test",135 "test",
136 file1_path,136 file1_path,
137 Target.Native,137 Target.Native,
...@@ -144,7 +144,7 @@ pub const TestContext = struct {...@@ -144,7 +144,7 @@ pub const TestContext = struct {
144144
145 _ = try comp.addLinkLib("c", true);145 _ = try comp.addLinkLib("c", true);
146 comp.link_out_file = output_file;146 comp.link_out_file = output_file;
147 try comp.build();147 comp.start();
148148
149 try self.group.call(getModuleEventSuccess, comp, output_file, expected_output);149 try self.group.call(getModuleEventSuccess, comp, output_file, expected_output);
150 }150 }
src-self-hosted/type.zig+2-2
...@@ -184,8 +184,8 @@ pub const Type = struct {...@@ -184,8 +184,8 @@ pub const Type = struct {
184 if (await (async base.abi_alignment.start() catch unreachable)) |ptr| return ptr.*;184 if (await (async base.abi_alignment.start() catch unreachable)) |ptr| return ptr.*;
185185
186 {186 {
187 const held = try comp.event_loop_local.getAnyLlvmContext();187 const held = try comp.zig_compiler.getAnyLlvmContext();
188 defer held.release(comp.event_loop_local);188 defer held.release(comp.zig_compiler);
189189
190 const llvm_context = held.node.data;190 const llvm_context = held.node.data;
191191