| ... | @@ -35,7 +35,7 @@ const fs = event.fs; | ... | @@ -35,7 +35,7 @@ const fs = event.fs; |
| 35 | const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB | 35 | const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB |
| 36 | | 36 | |
| 37 | /// Data that is local to the event loop. | 37 | /// Data that is local to the event loop. |
| 38 | pub const EventLoopLocal = struct { | 38 | pub 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 { |
| 47 | | 47 | |
| 48 | var lazy_init_targets = std.lazyInit(void); | 48 | var lazy_init_targets = std.lazyInit(void); |
| 49 | | 49 | |
| 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); |
| 59 | | 59 | |
| 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 | } |
| 68 | | 68 | |
| 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 { |
| 77 | | 77 | |
| 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 }; |
| 82 | | 82 | |
| 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 | } |
| 94 | | 94 | |
| 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 | }; |
| 102 | | 114 | |
| 103 | pub const LlvmHandle = struct { | 115 | pub const LlvmHandle = struct { |
| 104 | node: *std.atomic.Stack(llvm.ContextRef).Node, | 116 | node: *std.atomic.Stack(llvm.ContextRef).Node, |
| 105 | | 117 | |
| 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 | }; |
| 110 | | 122 | |
| 111 | pub const Compilation = struct { | 123 | pub 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, |
| 138 | | 150 | |
| 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), |
| 218 | | 229 | |
| 219 | destroy_handle: promise, | 230 | destroy_handle: promise, |
| | 231 | main_loop_handle: promise, |
| | 232 | main_loop_future: event.Future(void), |
| 220 | | 233 | |
| 221 | have_err_ret_tracing: bool, | 234 | have_err_ret_tracing: bool, |
| 222 | | 235 | |
| ... | @@ -325,7 +338,7 @@ pub const Compilation = struct { | ... | @@ -325,7 +338,7 @@ pub const Compilation = struct { |
| 325 | }; | 338 | }; |
| 326 | | 339 | |
| 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), |
| 352 | | 401 | |
| 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, |
| 421 | | 469 | |
| 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, |
| 426 | | 473 | |
| 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 | } |
| 437 | | 486 | |
| 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); |
| 472 | | 521 | |
| 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); |
| 475 | | 524 | |
| 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); |
| 478 | | 527 | |
| 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(); |
| 481 | | 530 | |
| 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 | } |
| 492 | | 541 | |
| 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(); |
| 495 | | 544 | |
| 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; |
| 497 | | 554 | |
| 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); |
| 499 | | 557 | |
| 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 | } |
| 502 | | 563 | |
| 503 | /// it does ref the result because it could be an arbitrary integer size | 564 | /// 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 | } |
| 685 | | 746 | |
| 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 | } |
| 713 | | 751 | |
| 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 | } |
| 727 | | 755 | |
| 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); |
| 730 | | 761 | |
| 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 resolution | 1164 | // 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 | } |
| 1136 | | 1167 | |
| 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; |
| 1190 | | 1221 | |
| 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(); |
| 1194 | | 1225 | |
| 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 |
| | 1460 | fn 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 | |
| | 1466 | async fn getAwaitResultAsync(handle: var, out: *?@typeInfo(@typeOf(handle)).Promise.child.?) void { |
| | 1467 | out.* = await handle; |
| | 1468 | } |