authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-27 13:38:49-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-11-27 13:38:49-05:00
log83c664eaa080669cff83f7c30046376f3399eafb
tree06cccc09052be4459e924d04a867ff34a889d87c
parent63300a21ddf4cfe209a39796c6d7ea7773e14fd6
parent4d8a8e65df79ddd5edf52f961552036ccfca6e8e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3780 from Vexu/stage2-async-review

Update use of async functions in self hosted compiler

13 files changed, 346 insertions(+), 368 deletions(-)

lib/std/event/fs.zig+15-13
......@@ -735,24 +735,26 @@ pub fn Watch(comptime V: type) type {
735735 allocator: *Allocator,
736736
737737 const OsData = switch (builtin.os) {
738 .macosx, .freebsd, .netbsd, .dragonfly => struct {
739 file_table: FileTable,
740 table_lock: event.Lock,
741
742 const FileTable = std.StringHashMap(*Put);
743 const Put = struct {
744 putter_frame: @Frame(kqPutEvents),
745 cancelled: bool = false,
746 value: V,
747 };
748 },
749
738 // TODO https://github.com/ziglang/zig/issues/3778
739 .macosx, .freebsd, .netbsd, .dragonfly => KqOsData,
750740 .linux => LinuxOsData,
751741 .windows => WindowsOsData,
752742
753743 else => @compileError("Unsupported OS"),
754744 };
755745
746 const KqOsData = struct {
747 file_table: FileTable,
748 table_lock: event.Lock,
749
750 const FileTable = std.StringHashMap(*Put);
751 const Put = struct {
752 putter_frame: @Frame(kqPutEvents),
753 cancelled: bool = false,
754 value: V,
755 };
756 };
757
756758 const WindowsOsData = struct {
757759 table_lock: event.Lock,
758760 dir_table: DirTable,
......@@ -1291,7 +1293,7 @@ pub fn Watch(comptime V: type) type {
12911293 os.linux.EINVAL => unreachable,
12921294 os.linux.EFAULT => unreachable,
12931295 os.linux.EAGAIN => {
1294 global_event_loop.linuxWaitFd(self.os_data.inotify_fd, os.linux.EPOLLET | os.linux.EPOLLIN);
1296 global_event_loop.linuxWaitFd(self.os_data.inotify_fd, os.linux.EPOLLET | os.linux.EPOLLIN | os.EPOLLONESHOT);
12951297 },
12961298 else => unreachable,
12971299 }
src-self-hosted/codegen.zig+15-15
......@@ -25,10 +25,10 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
2525
2626 const context = llvm_handle.node.data;
2727
28 const module = llvm.ModuleCreateWithNameInContext(comp.name.ptr(), context) orelse return error.OutOfMemory;
28 const module = llvm.ModuleCreateWithNameInContext(comp.name.toSliceConst(), context) orelse return error.OutOfMemory;
2929 defer llvm.DisposeModule(module);
3030
31 llvm.SetTarget(module, comp.llvm_triple.ptr());
31 llvm.SetTarget(module, comp.llvm_triple.toSliceConst());
3232 llvm.SetDataLayout(module, comp.target_layout_str);
3333
3434 if (util.getObjectFormat(comp.target) == .coff) {
......@@ -48,23 +48,23 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
4848 const producer = try std.Buffer.allocPrint(
4949 &code.arena.allocator,
5050 "zig {}.{}.{}",
51 u32(c.ZIG_VERSION_MAJOR),
52 u32(c.ZIG_VERSION_MINOR),
53 u32(c.ZIG_VERSION_PATCH),
51 @as(u32, c.ZIG_VERSION_MAJOR),
52 @as(u32, c.ZIG_VERSION_MINOR),
53 @as(u32, c.ZIG_VERSION_PATCH),
5454 );
5555 const flags = "";
5656 const runtime_version = 0;
5757 const compile_unit_file = llvm.CreateFile(
5858 dibuilder,
59 comp.name.ptr(),
60 comp.root_package.root_src_dir.ptr(),
59 comp.name.toSliceConst(),
60 comp.root_package.root_src_dir.toSliceConst(),
6161 ) orelse return error.OutOfMemory;
6262 const is_optimized = comp.build_mode != .Debug;
6363 const compile_unit = llvm.CreateCompileUnit(
6464 dibuilder,
6565 DW.LANG_C99,
6666 compile_unit_file,
67 producer.ptr(),
67 producer.toSliceConst(),
6868 is_optimized,
6969 flags,
7070 runtime_version,
......@@ -99,7 +99,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
9999
100100 // verify the llvm module when safety is on
101101 if (std.debug.runtime_safety) {
102 var error_ptr: ?[*]u8 = null;
102 var error_ptr: ?[*:0]u8 = null;
103103 _ = llvm.VerifyModule(ofile.module, llvm.AbortProcessAction, &error_ptr);
104104 }
105105
......@@ -108,12 +108,12 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
108108 const is_small = comp.build_mode == .ReleaseSmall;
109109 const is_debug = comp.build_mode == .Debug;
110110
111 var err_msg: [*]u8 = undefined;
111 var err_msg: [*:0]u8 = undefined;
112112 // TODO integrate this with evented I/O
113113 if (llvm.TargetMachineEmitToFile(
114114 comp.target_machine,
115115 module,
116 output_path.ptr(),
116 output_path.toSliceConst(),
117117 llvm.EmitBinary,
118118 &err_msg,
119119 is_debug,
......@@ -154,7 +154,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
154154 const llvm_fn_type = try fn_val.base.typ.getLlvmType(ofile.arena, ofile.context);
155155 const llvm_fn = llvm.AddFunction(
156156 ofile.module,
157 fn_val.symbol_name.ptr(),
157 fn_val.symbol_name.toSliceConst(),
158158 llvm_fn_type,
159159 ) orelse return error.OutOfMemory;
160160
......@@ -379,7 +379,7 @@ fn renderLoadUntyped(
379379 ptr: *llvm.Value,
380380 alignment: Type.Pointer.Align,
381381 vol: Type.Pointer.Vol,
382 name: [*]const u8,
382 name: [*:0]const u8,
383383) !*llvm.Value {
384384 const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory;
385385 switch (vol) {
......@@ -390,7 +390,7 @@ fn renderLoadUntyped(
390390 return result;
391391}
392392
393fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*]const u8) !*llvm.Value {
393fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*:0]const u8) !*llvm.Value {
394394 return renderLoadUntyped(ofile, ptr, ptr_type.key.alignment, ptr_type.key.vol, name);
395395}
396396
......@@ -438,7 +438,7 @@ pub fn renderAlloca(
438438) !*llvm.Value {
439439 const llvm_var_type = try var_type.getLlvmType(ofile.arena, ofile.context);
440440 const name_with_null = try std.cstr.addNullByte(ofile.arena, name);
441 const result = llvm.BuildAlloca(ofile.builder, llvm_var_type, name_with_null.ptr) orelse return error.OutOfMemory;
441 const result = llvm.BuildAlloca(ofile.builder, llvm_var_type, @ptrCast([*:0]const u8, name_with_null.ptr)) orelse return error.OutOfMemory;
442442 llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm_var_type));
443443 return result;
444444}
src-self-hosted/compilation.zig+130-149
......@@ -93,7 +93,7 @@ pub const ZigCompiler = struct {
9393 return LlvmHandle{ .node = node };
9494 }
9595
96 pub async fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation {
96 pub fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation {
9797 if (self.native_libc.start()) |ptr| return ptr;
9898 try self.native_libc.data.findNative(self.allocator);
9999 self.native_libc.resolve();
......@@ -133,62 +133,62 @@ pub const Compilation = struct {
133133 zig_std_dir: []const u8,
134134
135135 /// lazily created when we need it
136 tmp_dir: event.Future(BuildError![]u8),
136 tmp_dir: event.Future(BuildError![]u8) = event.Future(BuildError![]u8).init(),
137137
138 version_major: u32,
139 version_minor: u32,
140 version_patch: u32,
138 version_major: u32 = 0,
139 version_minor: u32 = 0,
140 version_patch: u32 = 0,
141141
142 linker_script: ?[]const u8,
143 out_h_path: ?[]const u8,
142 linker_script: ?[]const u8 = null,
143 out_h_path: ?[]const u8 = null,
144144
145 is_test: bool,
146 each_lib_rpath: bool,
147 strip: bool,
145 is_test: bool = false,
146 each_lib_rpath: bool = false,
147 strip: bool = false,
148148 is_static: bool,
149 linker_rdynamic: bool,
149 linker_rdynamic: bool = false,
150150
151 clang_argv: []const []const u8,
152 lib_dirs: []const []const u8,
153 rpath_list: []const []const u8,
154 assembly_files: []const []const u8,
151 clang_argv: []const []const u8 = [_][]const u8{},
152 lib_dirs: []const []const u8 = [_][]const u8{},
153 rpath_list: []const []const u8 = [_][]const u8{},
154 assembly_files: []const []const u8 = [_][]const u8{},
155155
156156 /// paths that are explicitly provided by the user to link against
157 link_objects: []const []const u8,
157 link_objects: []const []const u8 = [_][]const u8{},
158158
159159 /// functions that have their own objects that we need to link
160160 /// it uses an optional pointer so that tombstone removals are possible
161 fn_link_set: event.Locked(FnLinkSet),
161 fn_link_set: event.Locked(FnLinkSet) = event.Locked(FnLinkSet).init(FnLinkSet.init()),
162162
163163 pub const FnLinkSet = std.TailQueue(?*Value.Fn);
164164
165 windows_subsystem_windows: bool,
166 windows_subsystem_console: bool,
165 windows_subsystem_windows: bool = false,
166 windows_subsystem_console: bool = false,
167167
168168 link_libs_list: ArrayList(*LinkLib),
169 libc_link_lib: ?*LinkLib,
169 libc_link_lib: ?*LinkLib = null,
170170
171 err_color: errmsg.Color,
171 err_color: errmsg.Color = .Auto,
172172
173 verbose_tokenize: bool,
174 verbose_ast_tree: bool,
175 verbose_ast_fmt: bool,
176 verbose_cimport: bool,
177 verbose_ir: bool,
178 verbose_llvm_ir: bool,
179 verbose_link: bool,
173 verbose_tokenize: bool = false,
174 verbose_ast_tree: bool = false,
175 verbose_ast_fmt: bool = false,
176 verbose_cimport: bool = false,
177 verbose_ir: bool = false,
178 verbose_llvm_ir: bool = false,
179 verbose_link: bool = false,
180180
181 darwin_frameworks: []const []const u8,
182 darwin_version_min: DarwinVersionMin,
181 darwin_frameworks: []const []const u8 = [_][]const u8{},
182 darwin_version_min: DarwinVersionMin = .None,
183183
184 test_filters: []const []const u8,
185 test_name_prefix: ?[]const u8,
184 test_filters: []const []const u8 = [_][]const u8{},
185 test_name_prefix: ?[]const u8 = null,
186186
187 emit_file_type: Emit,
187 emit_file_type: Emit = .Binary,
188188
189189 kind: Kind,
190190
191 link_out_file: ?[]const u8,
191 link_out_file: ?[]const u8 = null,
192192 events: *event.Channel(Event),
193193
194194 exported_symbol_names: event.Locked(Decl.Table),
......@@ -213,7 +213,7 @@ pub const Compilation = struct {
213213
214214 target_machine: *llvm.TargetMachine,
215215 target_data_ref: *llvm.TargetData,
216 target_layout_str: [*]u8,
216 target_layout_str: [*:0]u8,
217217 target_ptr_bits: u32,
218218
219219 /// for allocating things which have the same lifetime as this Compilation
......@@ -222,16 +222,16 @@ pub const Compilation = struct {
222222 root_package: *Package,
223223 std_package: *Package,
224224
225 override_libc: ?*LibCInstallation,
225 override_libc: ?*LibCInstallation = null,
226226
227227 /// need to wait on this group before deinitializing
228228 deinit_group: event.Group(void),
229229
230 // destroy_frame: @Frame(createAsync),
231 // main_loop_frame: @Frame(Compilation.mainLoop),
232 main_loop_future: event.Future(void),
230 destroy_frame: *@Frame(createAsync),
231 main_loop_frame: *@Frame(Compilation.mainLoop),
232 main_loop_future: event.Future(void) = event.Future(void).init(),
233233
234 have_err_ret_tracing: bool,
234 have_err_ret_tracing: bool = false,
235235
236236 /// not locked because it is read-only
237237 primitive_type_table: TypeTable,
......@@ -243,7 +243,9 @@ pub const Compilation = struct {
243243
244244 c_int_types: [CInt.list.len]*Type.Int,
245245
246 // fs_watch: *fs.Watch(*Scope.Root),
246 fs_watch: *fs.Watch(*Scope.Root),
247
248 cancelled: bool = false,
247249
248250 const IntTypeTable = std.HashMap(*const Type.Int.Key, *Type.Int, Type.Int.Key.hash, Type.Int.Key.eql);
249251 const ArrayTypeTable = std.HashMap(*const Type.Array.Key, *Type.Array, Type.Array.Key.hash, Type.Array.Key.eql);
......@@ -348,7 +350,9 @@ pub const Compilation = struct {
348350 zig_lib_dir: []const u8,
349351 ) !*Compilation {
350352 var optional_comp: ?*Compilation = null;
351 var frame = async createAsync(
353 var frame = try zig_compiler.allocator.create(@Frame(createAsync));
354 errdefer zig_compiler.allocator.destroy(frame);
355 frame.* = async createAsync(
352356 &optional_comp,
353357 zig_compiler,
354358 name,
......@@ -359,7 +363,11 @@ pub const Compilation = struct {
359363 is_static,
360364 zig_lib_dir,
361365 );
362 return optional_comp orelse if (await frame) |_| unreachable else |err| err;
366 // TODO causes segfault
367 // return optional_comp orelse if (await frame) |_| unreachable else |err| err;
368 if (optional_comp) |comp| {
369 return comp;
370 } else if (await frame) |_| unreachable else |err| return err;
363371 }
364372
365373 async fn createAsync(
......@@ -385,50 +393,14 @@ pub const Compilation = struct {
385393 .build_mode = build_mode,
386394 .zig_lib_dir = zig_lib_dir,
387395 .zig_std_dir = undefined,
388 .tmp_dir = event.Future(BuildError![]u8).init(),
389 // .destroy_frame = @frame(),
390 // .main_loop_frame = undefined,
391 .main_loop_future = event.Future(void).init(),
396 .destroy_frame = @frame(),
397 .main_loop_frame = undefined,
392398
393399 .name = undefined,
394400 .llvm_triple = undefined,
395
396 .version_major = 0,
397 .version_minor = 0,
398 .version_patch = 0,
399
400 .verbose_tokenize = false,
401 .verbose_ast_tree = false,
402 .verbose_ast_fmt = false,
403 .verbose_cimport = false,
404 .verbose_ir = false,
405 .verbose_llvm_ir = false,
406 .verbose_link = false,
407
408 .linker_script = null,
409 .out_h_path = null,
410 .is_test = false,
411 .each_lib_rpath = false,
412 .strip = false,
413401 .is_static = is_static,
414 .linker_rdynamic = false,
415 .clang_argv = [_][]const u8{},
416 .lib_dirs = [_][]const u8{},
417 .rpath_list = [_][]const u8{},
418 .assembly_files = [_][]const u8{},
419 .link_objects = [_][]const u8{},
420 .fn_link_set = event.Locked(FnLinkSet).init(FnLinkSet.init()),
421 .windows_subsystem_windows = false,
422 .windows_subsystem_console = false,
423402 .link_libs_list = undefined,
424 .libc_link_lib = null,
425 .err_color = errmsg.Color.Auto,
426 .darwin_frameworks = [_][]const u8{},
427 .darwin_version_min = DarwinVersionMin.None,
428 .test_filters = [_][]const u8{},
429 .test_name_prefix = null,
430 .emit_file_type = Emit.Binary,
431 .link_out_file = null,
403
432404 .exported_symbol_names = event.Locked(Decl.Table).init(Decl.Table.init(allocator)),
433405 .prelink_group = event.Group(BuildError!void).init(allocator),
434406 .deinit_group = event.Group(void).init(allocator),
......@@ -458,11 +430,9 @@ pub const Compilation = struct {
458430 .root_package = undefined,
459431 .std_package = undefined,
460432
461 .override_libc = null,
462 .have_err_ret_tracing = false,
463433 .primitive_type_table = undefined,
464434
465 // .fs_watch = undefined,
435 .fs_watch = undefined,
466436 };
467437 comp.link_libs_list = ArrayList(*LinkLib).init(comp.arena());
468438 comp.primitive_type_table = TypeTable.init(comp.arena());
......@@ -534,13 +504,16 @@ pub const Compilation = struct {
534504 comp.root_package = try Package.create(comp.arena(), ".", "");
535505 }
536506
537 // comp.fs_watch = try fs.Watch(*Scope.Root).create(16);
538 // defer comp.fs_watch.destroy();
507 comp.fs_watch = try fs.Watch(*Scope.Root).init(allocator, 16);
508 defer comp.fs_watch.deinit();
539509
540510 try comp.initTypes();
541511 defer comp.primitive_type_table.deinit();
542512
543 // comp.main_loop_frame = async comp.mainLoop();
513 comp.main_loop_frame = try allocator.create(@Frame(mainLoop));
514 defer allocator.destroy(comp.main_loop_frame);
515
516 comp.main_loop_frame.* = async comp.mainLoop();
544517 // Set this to indicate that initialization completed successfully.
545518 // from here on out we must not return an error.
546519 // This must occur before the first suspend/await.
......@@ -559,7 +532,7 @@ pub const Compilation = struct {
559532 }
560533
561534 /// it does ref the result because it could be an arbitrary integer size
562 pub async fn getPrimitiveType(comp: *Compilation, name: []const u8) !?*Type {
535 pub fn getPrimitiveType(comp: *Compilation, name: []const u8) !?*Type {
563536 if (name.len >= 2) {
564537 switch (name[0]) {
565538 'i', 'u' => blk: {
......@@ -753,8 +726,11 @@ pub const Compilation = struct {
753726 }
754727
755728 pub fn destroy(self: *Compilation) void {
756 // await self.main_loop_frame;
757 // resume self.destroy_frame;
729 const allocator = self.gpa();
730 self.cancelled = true;
731 await self.main_loop_frame;
732 resume self.destroy_frame;
733 allocator.destroy(self.destroy_frame);
758734 }
759735
760736 fn start(self: *Compilation) void {
......@@ -767,7 +743,7 @@ pub const Compilation = struct {
767743
768744 var build_result = self.initialCompile();
769745
770 while (true) {
746 while (!self.cancelled) {
771747 const link_result = if (build_result) blk: {
772748 break :blk self.maybeLink();
773749 } else |err| err;
......@@ -795,47 +771,47 @@ pub const Compilation = struct {
795771 self.events.put(Event{ .Error = err });
796772 }
797773
798 // // First, get an item from the watch channel, waiting on the channel.
799 // var group = event.Group(BuildError!void).init(self.gpa());
800 // {
801 // const ev = (self.fs_watch.channel.get()) catch |err| {
802 // build_result = err;
803 // continue;
804 // };
805 // const root_scope = ev.data;
806 // group.call(rebuildFile, self, root_scope) catch |err| {
807 // build_result = err;
808 // continue;
809 // };
810 // }
811 // // Next, get all the items from the channel that are buffered up.
812 // while (self.fs_watch.channel.getOrNull()) |ev_or_err| {
813 // if (ev_or_err) |ev| {
814 // const root_scope = ev.data;
815 // group.call(rebuildFile, self, root_scope) catch |err| {
816 // build_result = err;
817 // continue;
818 // };
819 // } else |err| {
820 // build_result = err;
821 // continue;
822 // }
823 // }
824 // build_result = group.wait();
774 // First, get an item from the watch channel, waiting on the channel.
775 var group = event.Group(BuildError!void).init(self.gpa());
776 {
777 const ev = (self.fs_watch.channel.get()) catch |err| {
778 build_result = err;
779 continue;
780 };
781 const root_scope = ev.data;
782 group.call(rebuildFile, self, root_scope) catch |err| {
783 build_result = err;
784 continue;
785 };
786 }
787 // Next, get all the items from the channel that are buffered up.
788 while (self.fs_watch.channel.getOrNull()) |ev_or_err| {
789 if (ev_or_err) |ev| {
790 const root_scope = ev.data;
791 group.call(rebuildFile, self, root_scope) catch |err| {
792 build_result = err;
793 continue;
794 };
795 } else |err| {
796 build_result = err;
797 continue;
798 }
799 }
800 build_result = group.wait();
825801 }
826802 }
827803
828 async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) !void {
804 async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) BuildError!void {
829805 const tree_scope = blk: {
830 const source_code = "";
831 // const source_code = fs.readFile(
832 // root_scope.realpath,
833 // max_src_size,
834 // ) catch |err| {
835 // try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err));
836 // return;
837 // };
838 // errdefer self.gpa().free(source_code);
806 const source_code = fs.readFile(
807 self.gpa(),
808 root_scope.realpath,
809 max_src_size,
810 ) catch |err| {
811 try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err));
812 return;
813 };
814 errdefer self.gpa().free(source_code);
839815
840816 const tree = try std.zig.parse(self.gpa(), source_code);
841817 errdefer {
......@@ -873,7 +849,7 @@ pub const Compilation = struct {
873849 try decl_group.wait();
874850 }
875851
876 async fn rebuildChangedDecls(
852 fn rebuildChangedDecls(
877853 self: *Compilation,
878854 group: *event.Group(BuildError!void),
879855 locked_table: *Decl.Table,
......@@ -962,7 +938,7 @@ pub const Compilation = struct {
962938 }
963939 }
964940
965 async fn initialCompile(self: *Compilation) !void {
941 fn initialCompile(self: *Compilation) !void {
966942 if (self.root_src_path) |root_src_path| {
967943 const root_scope = blk: {
968944 // TODO async/await std.fs.realpath
......@@ -981,7 +957,7 @@ pub const Compilation = struct {
981957 }
982958 }
983959
984 async fn maybeLink(self: *Compilation) !void {
960 fn maybeLink(self: *Compilation) !void {
985961 (self.prelink_group.wait()) catch |err| switch (err) {
986962 error.SemanticAnalysisFailed => {},
987963 else => return err,
......@@ -1165,11 +1141,10 @@ pub const Compilation = struct {
11651141 return link_lib;
11661142 }
11671143
1168 /// cancels itself so no need to await or cancel the promise.
11691144 async fn startFindingNativeLibC(self: *Compilation) void {
1170 std.event.Loop.instance.?.yield();
1145 event.Loop.startCpuBoundOperation();
11711146 // we don't care if it fails, we're just trying to kick off the future resolution
1172 _ = (self.zig_compiler.getNativeLibC()) catch return;
1147 _ = self.zig_compiler.getNativeLibC() catch return;
11731148 }
11741149
11751150 /// General Purpose Allocator. Must free when done.
......@@ -1184,7 +1159,7 @@ pub const Compilation = struct {
11841159
11851160 /// If the temporary directory for this compilation has not been created, it creates it.
11861161 /// Then it creates a random file name in that dir and returns it.
1187 pub async fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {
1162 pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {
11881163 const tmp_dir = try self.getTmpDir();
11891164 const file_prefix = self.getRandomFileName();
11901165
......@@ -1200,14 +1175,14 @@ pub const Compilation = struct {
12001175 /// If the temporary directory for this Compilation has not been created, creates it.
12011176 /// Then returns it. The directory is unique to this Compilation and cleaned up when
12021177 /// the Compilation deinitializes.
1203 async fn getTmpDir(self: *Compilation) ![]const u8 {
1178 fn getTmpDir(self: *Compilation) ![]const u8 {
12041179 if (self.tmp_dir.start()) |ptr| return ptr.*;
12051180 self.tmp_dir.data = self.getTmpDirImpl();
12061181 self.tmp_dir.resolve();
12071182 return self.tmp_dir.data;
12081183 }
12091184
1210 async fn getTmpDirImpl(self: *Compilation) ![]u8 {
1185 fn getTmpDirImpl(self: *Compilation) ![]u8 {
12111186 const comp_dir_name = self.getRandomFileName();
12121187 const zig_dir_path = try getZigDir(self.gpa());
12131188 defer self.gpa().free(zig_dir_path);
......@@ -1217,7 +1192,7 @@ pub const Compilation = struct {
12171192 return tmp_dir;
12181193 }
12191194
1220 async fn getRandomFileName(self: *Compilation) [12]u8 {
1195 fn getRandomFileName(self: *Compilation) [12]u8 {
12211196 // here we replace the standard +/ with -_ so that it can be used in a file name
12221197 const b64_fs_encoder = std.base64.Base64Encoder.init(
12231198 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
......@@ -1243,20 +1218,23 @@ pub const Compilation = struct {
12431218 }
12441219
12451220 /// Returns a value which has been ref()'d once
1246 async fn analyzeConstValue(
1221 fn analyzeConstValue(
12471222 comp: *Compilation,
12481223 tree_scope: *Scope.AstTree,
12491224 scope: *Scope,
12501225 node: *ast.Node,
12511226 expected_type: *Type,
12521227 ) !*Value {
1253 const analyzed_code = try comp.genAndAnalyzeCode(tree_scope, scope, node, expected_type);
1228 var frame = try comp.gpa().create(@Frame(genAndAnalyzeCode));
1229 defer comp.gpa().destroy(frame);
1230 frame.* = async comp.genAndAnalyzeCode(tree_scope, scope, node, expected_type);
1231 const analyzed_code = try await frame;
12541232 defer analyzed_code.destroy(comp.gpa());
12551233
12561234 return analyzed_code.getCompTimeResult(comp);
12571235 }
12581236
1259 async fn analyzeTypeExpr(comp: *Compilation, tree_scope: *Scope.AstTree, scope: *Scope, node: *ast.Node) !*Type {
1237 fn analyzeTypeExpr(comp: *Compilation, tree_scope: *Scope.AstTree, scope: *Scope, node: *ast.Node) !*Type {
12601238 const meta_type = &Type.MetaType.get(comp).base;
12611239 defer meta_type.base.deref(comp);
12621240
......@@ -1287,7 +1265,7 @@ fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib
12871265}
12881266
12891267/// The function that actually does the generation.
1290async fn generateDecl(comp: *Compilation, decl: *Decl) !void {
1268fn generateDecl(comp: *Compilation, decl: *Decl) !void {
12911269 switch (decl.id) {
12921270 .Var => @panic("TODO"),
12931271 .Fn => {
......@@ -1298,7 +1276,7 @@ async fn generateDecl(comp: *Compilation, decl: *Decl) !void {
12981276 }
12991277}
13001278
1301async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
1279fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
13021280 const tree_scope = fn_decl.base.tree_scope;
13031281
13041282 const body_node = fn_decl.fn_proto.body_node orelse return generateDeclFnProto(comp, fn_decl);
......@@ -1315,7 +1293,7 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
13151293
13161294 // The Decl.Fn owns the initial 1 reference count
13171295 const fn_val = try Value.Fn.create(comp, fn_type, fndef_scope, symbol_name);
1318 fn_decl.value = Decl.Fn.Val{ .Fn = fn_val };
1296 fn_decl.value = .{ .Fn = fn_val };
13191297 symbol_name_consumed = true;
13201298
13211299 // Define local parameter variables
......@@ -1350,12 +1328,15 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
13501328 try fn_type.non_key.Normal.variable_list.append(var_scope);
13511329 }
13521330
1353 const analyzed_code = try comp.genAndAnalyzeCode(
1331 var frame = try comp.gpa().create(@Frame(Compilation.genAndAnalyzeCode));
1332 defer comp.gpa().destroy(frame);
1333 frame.* = async comp.genAndAnalyzeCode(
13541334 tree_scope,
13551335 fn_val.child_scope,
13561336 body_node,
13571337 fn_type.key.data.Normal.return_type,
13581338 );
1339 const analyzed_code = try await frame;
13591340 errdefer analyzed_code.destroy(comp.gpa());
13601341
13611342 assert(fn_val.block_scope != null);
......@@ -1382,7 +1363,7 @@ fn getZigDir(allocator: *mem.Allocator) ![]u8 {
13821363 return std.fs.getAppDataDir(allocator, "zig");
13831364}
13841365
1385async fn analyzeFnType(
1366fn analyzeFnType(
13861367 comp: *Compilation,
13871368 tree_scope: *Scope.AstTree,
13881369 scope: *Scope,
......@@ -1444,7 +1425,7 @@ async fn analyzeFnType(
14441425 return fn_type;
14451426}
14461427
1447async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
1428fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
14481429 const fn_type = try analyzeFnType(
14491430 comp,
14501431 fn_decl.base.tree_scope,
......@@ -1459,6 +1440,6 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
14591440
14601441 // The Decl.Fn owns the initial 1 reference count
14611442 const fn_proto_val = try Value.FnProto.create(comp, fn_type, symbol_name);
1462 fn_decl.value = Decl.Fn.Val{ .FnProto = fn_proto_val };
1443 fn_decl.value = .{ .FnProto = fn_proto_val };
14631444 symbol_name_consumed = true;
14641445}
src-self-hosted/decl.zig+3-6
......@@ -69,15 +69,12 @@ pub const Decl = struct {
6969
7070 pub const Fn = struct {
7171 base: Decl,
72 value: Val,
73 fn_proto: *ast.Node.FnProto,
74
75 // TODO https://github.com/ziglang/zig/issues/683 and then make this anonymous
76 pub const Val = union(enum) {
72 value: union(enum) {
7773 Unresolved,
7874 Fn: *Value.Fn,
7975 FnProto: *Value.FnProto,
80 };
76 },
77 fn_proto: *ast.Node.FnProto,
8178
8279 pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 {
8380 return if (self.fn_proto.extern_export_inline_token) |tok_index| x: {
src-self-hosted/ir.zig+38-30
......@@ -110,7 +110,7 @@ pub const Inst = struct {
110110 unreachable;
111111 }
112112
113 pub async fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst {
113 pub fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst {
114114 switch (base.id) {
115115 .Return => return @fieldParentPtr(Return, "base", base).analyze(ira),
116116 .Const => return @fieldParentPtr(Const, "base", base).analyze(ira),
......@@ -422,7 +422,7 @@ pub const Inst = struct {
422422 return false;
423423 }
424424
425 pub async fn analyze(self: *const Ref, ira: *Analyze) !*Inst {
425 pub fn analyze(self: *const Ref, ira: *Analyze) !*Inst {
426426 const target = try self.params.target.getAsParam();
427427
428428 if (ira.getCompTimeValOrNullUndefOk(target)) |val| {
......@@ -472,7 +472,7 @@ pub const Inst = struct {
472472 return false;
473473 }
474474
475 pub async fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst {
475 pub fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst {
476476 (ira.irb.comp.resolveDecl(self.params.decl)) catch |err| switch (err) {
477477 error.OutOfMemory => return error.OutOfMemory,
478478 else => return error.SemanticAnalysisFailed,
......@@ -516,7 +516,7 @@ pub const Inst = struct {
516516 return false;
517517 }
518518
519 pub async fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst {
519 pub fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst {
520520 switch (self.params.var_scope.data) {
521521 .Const => @panic("TODO"),
522522 .Param => |param| {
......@@ -563,7 +563,7 @@ pub const Inst = struct {
563563 return false;
564564 }
565565
566 pub async fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst {
566 pub fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst {
567567 const target = try self.params.target.getAsParam();
568568 const target_type = target.getKnownType();
569569 if (target_type.id != .Pointer) {
......@@ -645,7 +645,7 @@ pub const Inst = struct {
645645 return false;
646646 }
647647
648 pub async fn analyze(self: *const PtrType, ira: *Analyze) !*Inst {
648 pub fn analyze(self: *const PtrType, ira: *Analyze) !*Inst {
649649 const child_type = try self.params.child_type.getAsConstType(ira);
650650 // if (child_type->id == TypeTableEntryIdUnreachable) {
651651 // ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
......@@ -658,7 +658,7 @@ pub const Inst = struct {
658658 const amt = try align_inst.getAsConstAlign(ira);
659659 break :blk Type.Pointer.Align{ .Override = amt };
660660 } else blk: {
661 break :blk Type.Pointer.Align{ .Abi = {} };
661 break :blk .Abi;
662662 };
663663 const ptr_type = try Type.Pointer.get(ira.irb.comp, Type.Pointer.Key{
664664 .child_type = child_type,
......@@ -927,7 +927,7 @@ pub const Variable = struct {
927927
928928pub const BasicBlock = struct {
929929 ref_count: usize,
930 name_hint: [*]const u8, // must be a C string literal
930 name_hint: [*:0]const u8,
931931 debug_id: usize,
932932 scope: *Scope,
933933 instruction_list: std.ArrayList(*Inst),
......@@ -1051,7 +1051,7 @@ pub const Builder = struct {
10511051 }
10521052
10531053 /// No need to clean up resources thanks to the arena allocator.
1054 pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
1054 pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*:0]const u8) !*BasicBlock {
10551055 const basic_block = try self.arena().create(BasicBlock);
10561056 basic_block.* = BasicBlock{
10571057 .ref_count = 0,
......@@ -1078,6 +1078,14 @@ pub const Builder = struct {
10781078 self.current_basic_block = basic_block;
10791079 }
10801080
1081 pub fn genNodeRecursive(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst {
1082 const alloc = irb.comp.gpa();
1083 var frame = try alloc.create(@Frame(genNode));
1084 defer alloc.destroy(frame);
1085 frame.* = async irb.genNode(node, scope, lval);
1086 return await frame;
1087 }
1088
10811089 pub async fn genNode(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst {
10821090 switch (node.id) {
10831091 .Root => unreachable,
......@@ -1157,7 +1165,7 @@ pub const Builder = struct {
11571165 },
11581166 .GroupedExpression => {
11591167 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", node);
1160 return irb.genNode(grouped_expr.expr, scope, lval);
1168 return irb.genNodeRecursive(grouped_expr.expr, scope, lval);
11611169 },
11621170 .BuiltinCall => return error.Unimplemented,
11631171 .ErrorSetDecl => return error.Unimplemented,
......@@ -1186,14 +1194,14 @@ pub const Builder = struct {
11861194 }
11871195 }
11881196
1189 async fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
1190 const fn_ref = try irb.genNode(suffix_op.lhs, scope, .None);
1197 fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
1198 const fn_ref = try irb.genNodeRecursive(suffix_op.lhs.node, scope, .None);
11911199
11921200 const args = try irb.arena().alloc(*Inst, call.params.len);
11931201 var it = call.params.iterator(0);
11941202 var i: usize = 0;
11951203 while (it.next()) |arg_node_ptr| : (i += 1) {
1196 args[i] = try irb.genNode(arg_node_ptr.*, scope, .None);
1204 args[i] = try irb.genNodeRecursive(arg_node_ptr.*, scope, .None);
11971205 }
11981206
11991207 //bool is_async = node->data.fn_call_expr.is_async;
......@@ -1214,7 +1222,7 @@ pub const Builder = struct {
12141222 //return ir_lval_wrap(irb, scope, fn_call, lval);
12151223 }
12161224
1217 async fn genPtrType(
1225 fn genPtrType(
12181226 irb: *Builder,
12191227 prefix_op: *ast.Node.PrefixOp,
12201228 ptr_info: ast.Node.PrefixOp.PtrInfo,
......@@ -1238,7 +1246,7 @@ pub const Builder = struct {
12381246 //} else {
12391247 // align_value = nullptr;
12401248 //}
1241 const child_type = try irb.genNode(prefix_op.rhs, scope, .None);
1249 const child_type = try irb.genNodeRecursive(prefix_op.rhs, scope, .None);
12421250
12431251 //uint32_t bit_offset_start = 0;
12441252 //if (node->data.pointer_type.bit_offset_start != nullptr) {
......@@ -1307,9 +1315,9 @@ pub const Builder = struct {
13071315 var rest: []const u8 = undefined;
13081316 if (int_token.len >= 3 and int_token[0] == '0') {
13091317 base = switch (int_token[1]) {
1310 'b' => u8(2),
1311 'o' => u8(8),
1312 'x' => u8(16),
1318 'b' => 2,
1319 'o' => 8,
1320 'x' => 16,
13131321 else => unreachable,
13141322 };
13151323 rest = int_token[2..];
......@@ -1339,7 +1347,7 @@ pub const Builder = struct {
13391347 return inst;
13401348 }
13411349
1342 pub async fn genStrLit(irb: *Builder, str_lit: *ast.Node.StringLiteral, scope: *Scope) !*Inst {
1350 pub fn genStrLit(irb: *Builder, str_lit: *ast.Node.StringLiteral, scope: *Scope) !*Inst {
13431351 const str_token = irb.code.tree_scope.tree.tokenSlice(str_lit.token);
13441352 const src_span = Span.token(str_lit.token);
13451353
......@@ -1389,7 +1397,7 @@ pub const Builder = struct {
13891397 }
13901398 }
13911399
1392 pub async fn genBlock(irb: *Builder, block: *ast.Node.Block, parent_scope: *Scope) !*Inst {
1400 pub fn genBlock(irb: *Builder, block: *ast.Node.Block, parent_scope: *Scope) !*Inst {
13931401 const block_scope = try Scope.Block.create(irb.comp, parent_scope);
13941402
13951403 const outer_block_scope = &block_scope.base;
......@@ -1437,7 +1445,7 @@ pub const Builder = struct {
14371445 child_scope = &defer_child_scope.base;
14381446 continue;
14391447 }
1440 const statement_value = try irb.genNode(statement_node, child_scope, .None);
1448 const statement_value = try irb.genNodeRecursive(statement_node, child_scope, .None);
14411449
14421450 is_continuation_unreachable = statement_value.isNoReturn();
14431451 if (is_continuation_unreachable) {
......@@ -1499,7 +1507,7 @@ pub const Builder = struct {
14991507 return irb.buildConstVoid(child_scope, Span.token(block.rbrace), true);
15001508 }
15011509
1502 pub async fn genControlFlowExpr(
1510 pub fn genControlFlowExpr(
15031511 irb: *Builder,
15041512 control_flow_expr: *ast.Node.ControlFlowExpression,
15051513 scope: *Scope,
......@@ -1533,7 +1541,7 @@ pub const Builder = struct {
15331541
15341542 const outer_scope = irb.begin_scope.?;
15351543 const return_value = if (control_flow_expr.rhs) |rhs| blk: {
1536 break :blk try irb.genNode(rhs, scope, .None);
1544 break :blk try irb.genNodeRecursive(rhs, scope, .None);
15371545 } else blk: {
15381546 break :blk try irb.buildConstVoid(scope, src_span, true);
15391547 };
......@@ -1596,7 +1604,7 @@ pub const Builder = struct {
15961604 }
15971605 }
15981606
1599 pub async fn genIdentifier(irb: *Builder, identifier: *ast.Node.Identifier, scope: *Scope, lval: LVal) !*Inst {
1607 pub fn genIdentifier(irb: *Builder, identifier: *ast.Node.Identifier, scope: *Scope, lval: LVal) !*Inst {
16001608 const src_span = Span.token(identifier.token);
16011609 const name = irb.code.tree_scope.tree.tokenSlice(identifier.token);
16021610
......@@ -1694,7 +1702,7 @@ pub const Builder = struct {
16941702 return result;
16951703 }
16961704
1697 async fn genDefersForBlock(
1705 fn genDefersForBlock(
16981706 irb: *Builder,
16991707 inner_scope: *Scope,
17001708 outer_scope: *Scope,
......@@ -1712,7 +1720,7 @@ pub const Builder = struct {
17121720 };
17131721 if (generate) {
17141722 const defer_expr_scope = defer_scope.defer_expr_scope;
1715 const instruction = try irb.genNode(
1723 const instruction = try irb.genNodeRecursive(
17161724 defer_expr_scope.expr_node,
17171725 &defer_expr_scope.base,
17181726 .None,
......@@ -1797,7 +1805,7 @@ pub const Builder = struct {
17971805 // Look at the params and ref() other instructions
17981806 comptime var i = 0;
17991807 inline while (i < @memberCount(I.Params)) : (i += 1) {
1800 const FieldType = comptime @typeOf(@field(I.Params(undefined), @memberName(I.Params, i)));
1808 const FieldType = comptime @typeOf(@field(@as(I.Params, undefined), @memberName(I.Params, i)));
18011809 switch (FieldType) {
18021810 *Inst => @field(inst.params, @memberName(I.Params, i)).ref(self),
18031811 *BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self),
......@@ -1909,7 +1917,7 @@ pub const Builder = struct {
19091917 VarScope: *Scope.Var,
19101918 };
19111919
1912 async fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident {
1920 fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident {
19131921 var s = scope;
19141922 while (true) {
19151923 switch (s.id) {
......@@ -2519,7 +2527,7 @@ const Analyze = struct {
25192527 }
25202528};
25212529
2522pub async fn gen(
2530pub fn gen(
25232531 comp: *Compilation,
25242532 body_node: *ast.Node,
25252533 tree_scope: *Scope.AstTree,
......@@ -2541,7 +2549,7 @@ pub async fn gen(
25412549 return irb.finish();
25422550}
25432551
2544pub async fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code {
2552pub fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code {
25452553 const old_entry_bb = old_code.basic_block_list.at(0);
25462554
25472555 var ira = try Analyze.init(comp, old_code.tree_scope, expected_type);
src-self-hosted/libc_installation.zig+3-3
......@@ -143,7 +143,7 @@ pub const LibCInstallation = struct {
143143 }
144144
145145 /// Finds the default, native libc.
146 pub async fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {
146 pub fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {
147147 self.initEmpty();
148148 var group = event.Group(FindError!void).init(allocator);
149149 errdefer group.wait() catch {};
......@@ -393,14 +393,14 @@ pub const LibCInstallation = struct {
393393};
394394
395395/// caller owns returned memory
396async fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {
396fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {
397397 const cc_exe = std.os.getenv("CC") orelse "cc";
398398 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", o_file);
399399 defer allocator.free(arg1);
400400 const argv = [_][]const u8{ cc_exe, arg1 };
401401
402402 // TODO This simulates evented I/O for the child process exec
403 std.event.Loop.instance.?.yield();
403 event.Loop.startCpuBoundOperation();
404404 const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
405405 const exec_result = if (std.debug.runtime_safety) blk: {
406406 break :blk errorable_result catch unreachable;
src-self-hosted/link.zig+33-35
......@@ -11,7 +11,7 @@ const util = @import("util.zig");
1111const Context = struct {
1212 comp: *Compilation,
1313 arena: std.heap.ArenaAllocator,
14 args: std.ArrayList([*]const u8),
14 args: std.ArrayList([*:0]const u8),
1515 link_in_crt: bool,
1616
1717 link_err: error{OutOfMemory}!void,
......@@ -21,7 +21,7 @@ const Context = struct {
2121 out_file_path: std.Buffer,
2222};
2323
24pub async fn link(comp: *Compilation) !void {
24pub fn link(comp: *Compilation) !void {
2525 var ctx = Context{
2626 .comp = comp,
2727 .arena = std.heap.ArenaAllocator.init(comp.gpa()),
......@@ -33,7 +33,7 @@ pub async fn link(comp: *Compilation) !void {
3333 .out_file_path = undefined,
3434 };
3535 defer ctx.arena.deinit();
36 ctx.args = std.ArrayList([*]const u8).init(&ctx.arena.allocator);
36 ctx.args = std.ArrayList([*:0]const u8).init(&ctx.arena.allocator);
3737 ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator);
3838
3939 if (comp.link_out_file) |out_file| {
......@@ -58,7 +58,8 @@ pub async fn link(comp: *Compilation) !void {
5858 try ctx.args.append("lld");
5959
6060 if (comp.haveLibC()) {
61 ctx.libc = ctx.comp.override_libc orelse blk: {
61 // TODO https://github.com/ziglang/zig/issues/3190
62 var libc = ctx.comp.override_libc orelse blk: {
6263 switch (comp.target) {
6364 Target.Native => {
6465 break :blk comp.zig_compiler.getNativeLibC() catch return error.LibCRequiredButNotProvidedOrFound;
......@@ -66,6 +67,7 @@ pub async fn link(comp: *Compilation) !void {
6667 else => return error.LibCRequiredButNotProvidedOrFound,
6768 }
6869 };
70 ctx.libc = libc;
6971 }
7072
7173 try constructLinkerArgs(&ctx);
......@@ -171,7 +173,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
171173 //}
172174
173175 try ctx.args.append("-o");
174 try ctx.args.append(ctx.out_file_path.ptr());
176 try ctx.args.append(ctx.out_file_path.toSliceConst());
175177
176178 if (ctx.link_in_crt) {
177179 const crt1o = if (ctx.comp.is_static) "crt1.o" else "Scrt1.o";
......@@ -214,10 +216,11 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
214216
215217 if (ctx.comp.haveLibC()) {
216218 try ctx.args.append("-L");
217 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr);
219 // TODO addNullByte should probably return [:0]u8
220 try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr));
218221
219222 try ctx.args.append("-L");
220 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr);
223 try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr));
221224
222225 if (!ctx.comp.is_static) {
223226 const dl = blk: {
......@@ -226,7 +229,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
226229 return error.LibCMissingDynamicLinker;
227230 };
228231 try ctx.args.append("-dynamic-linker");
229 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr);
232 try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr));
230233 }
231234 }
232235
......@@ -238,7 +241,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
238241 // .o files
239242 for (ctx.comp.link_objects) |link_object| {
240243 const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
241 try ctx.args.append(link_obj_with_null.ptr);
244 try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
242245 }
243246 try addFnObjects(ctx);
244247
......@@ -313,7 +316,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
313316fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
314317 const full_path = try std.fs.path.join(&ctx.arena.allocator, [_][]const u8{ dirname, basename });
315318 const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path);
316 try ctx.args.append(full_path_with_null.ptr);
319 try ctx.args.append(@ptrCast([*:0]const u8, full_path_with_null.ptr));
317320}
318321
319322fn constructLinkerArgsCoff(ctx: *Context) !void {
......@@ -339,12 +342,12 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
339342 const is_library = ctx.comp.kind == .Lib;
340343
341344 const out_arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-OUT:{}\x00", ctx.out_file_path.toSliceConst());
342 try ctx.args.append(out_arg.ptr);
345 try ctx.args.append(@ptrCast([*:0]const u8, out_arg.ptr));
343346
344347 if (ctx.comp.haveLibC()) {
345 try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_lib_dir.?)).ptr);
346 try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_lib_dir.?)).ptr);
347 try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.lib_dir.?)).ptr);
348 try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_lib_dir.?)).ptr));
349 try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_lib_dir.?)).ptr));
350 try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.lib_dir.?)).ptr));
348351 }
349352
350353 if (ctx.link_in_crt) {
......@@ -353,17 +356,17 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
353356
354357 if (ctx.comp.is_static) {
355358 const cmt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "libcmt{}.lib\x00", d_str);
356 try ctx.args.append(cmt_lib_name.ptr);
359 try ctx.args.append(@ptrCast([*:0]const u8, cmt_lib_name.ptr));
357360 } else {
358361 const msvcrt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "msvcrt{}.lib\x00", d_str);
359 try ctx.args.append(msvcrt_lib_name.ptr);
362 try ctx.args.append(@ptrCast([*:0]const u8, msvcrt_lib_name.ptr));
360363 }
361364
362365 const vcruntime_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}vcruntime{}.lib\x00", lib_str, d_str);
363 try ctx.args.append(vcruntime_lib_name.ptr);
366 try ctx.args.append(@ptrCast([*:0]const u8, vcruntime_lib_name.ptr));
364367
365368 const crt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}ucrt{}.lib\x00", lib_str, d_str);
366 try ctx.args.append(crt_lib_name.ptr);
369 try ctx.args.append(@ptrCast([*:0]const u8, crt_lib_name.ptr));
367370
368371 // Visual C++ 2015 Conformance Changes
369372 // https://msdn.microsoft.com/en-us/library/bb531344.aspx
......@@ -395,7 +398,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
395398
396399 for (ctx.comp.link_objects) |link_object| {
397400 const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
398 try ctx.args.append(link_obj_with_null.ptr);
401 try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
399402 }
400403 try addFnObjects(ctx);
401404
......@@ -504,11 +507,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
504507 //}
505508
506509 try ctx.args.append("-arch");
507 const darwin_arch_str = try std.cstr.addNullByte(
508 &ctx.arena.allocator,
509 ctx.comp.target.getDarwinArchString(),
510 );
511 try ctx.args.append(darwin_arch_str.ptr);
510 try ctx.args.append(util.getDarwinArchString(ctx.comp.target));
512511
513512 const platform = try DarwinPlatform.get(ctx.comp);
514513 switch (platform.kind) {
......@@ -517,7 +516,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
517516 .IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"),
518517 }
519518 const ver_str = try std.fmt.allocPrint(&ctx.arena.allocator, "{}.{}.{}\x00", platform.major, platform.minor, platform.micro);
520 try ctx.args.append(ver_str.ptr);
519 try ctx.args.append(@ptrCast([*:0]const u8, ver_str.ptr));
521520
522521 if (ctx.comp.kind == .Exe) {
523522 if (ctx.comp.is_static) {
......@@ -528,7 +527,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
528527 }
529528
530529 try ctx.args.append("-o");
531 try ctx.args.append(ctx.out_file_path.ptr());
530 try ctx.args.append(ctx.out_file_path.toSliceConst());
532531
533532 //for (size_t i = 0; i < g->rpath_list.length; i += 1) {
534533 // Buf *rpath = g->rpath_list.at(i);
......@@ -572,7 +571,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
572571
573572 for (ctx.comp.link_objects) |link_object| {
574573 const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
575 try ctx.args.append(link_obj_with_null.ptr);
574 try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
576575 }
577576 try addFnObjects(ctx);
578577
......@@ -593,10 +592,10 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
593592 } else {
594593 if (mem.indexOfScalar(u8, lib.name, '/') == null) {
595594 const arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-l{}\x00", lib.name);
596 try ctx.args.append(arg.ptr);
595 try ctx.args.append(@ptrCast([*:0]const u8, arg.ptr));
597596 } else {
598597 const arg = try std.cstr.addNullByte(&ctx.arena.allocator, lib.name);
599 try ctx.args.append(arg.ptr);
598 try ctx.args.append(@ptrCast([*:0]const u8, arg.ptr));
600599 }
601600 }
602601 }
......@@ -626,20 +625,19 @@ fn constructLinkerArgsWasm(ctx: *Context) void {
626625}
627626
628627fn addFnObjects(ctx: *Context) !void {
629 // at this point it's guaranteed nobody else has this lock, so we circumvent it
630 // and avoid having to be an async function
631 const fn_link_set = &ctx.comp.fn_link_set.private_data;
628 const held = ctx.comp.fn_link_set.acquire();
629 defer held.release();
632630
633 var it = fn_link_set.first;
631 var it = held.value.first;
634632 while (it) |node| {
635633 const fn_val = node.data orelse {
636634 // handle the tombstone. See Value.Fn.destroy.
637635 it = node.next;
638 fn_link_set.remove(node);
636 held.value.remove(node);
639637 ctx.comp.gpa().destroy(node);
640638 continue;
641639 };
642 try ctx.args.append(fn_val.containing_object.ptr());
640 try ctx.args.append(fn_val.containing_object.toSliceConst());
643641 it = node.next;
644642 }
645643}
src-self-hosted/llvm.zig+1-1
......@@ -86,7 +86,7 @@ pub const AddGlobal = LLVMAddGlobal;
8686extern fn LLVMAddGlobal(M: *Module, Ty: *Type, Name: [*:0]const u8) ?*Value;
8787
8888pub const ConstStringInContext = LLVMConstStringInContext;
89extern fn LLVMConstStringInContext(C: *Context, Str: [*:0]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value;
89extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value;
9090
9191pub const ConstInt = LLVMConstInt;
9292extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) ?*Value;
src-self-hosted/main.zig+64-73
......@@ -49,14 +49,15 @@ const usage =
4949
5050const Command = struct {
5151 name: []const u8,
52 exec: fn (*Allocator, []const []const u8) anyerror!void,
52 exec: async fn (*Allocator, []const []const u8) anyerror!void,
5353};
5454
5555pub fn main() !void {
5656 // This allocator needs to be thread-safe because we use it for the event.Loop
5757 // which multiplexes async functions onto kernel threads.
5858 // libc allocator is guaranteed to have this property.
59 const allocator = std.heap.c_allocator;
59 // TODO https://github.com/ziglang/zig/issues/3783
60 const allocator = std.heap.page_allocator;
6061
6162 stdout = &std.io.getStdOut().outStream().stream;
6263
......@@ -118,14 +119,18 @@ pub fn main() !void {
118119 },
119120 };
120121
121 for (commands) |command| {
122 inline for (commands) |command| {
122123 if (mem.eql(u8, command.name, args[1])) {
123 return command.exec(allocator, args[2..]);
124 var frame = try allocator.create(@Frame(command.exec));
125 defer allocator.destroy(frame);
126 frame.* = async command.exec(allocator, args[2..]);
127 return await frame;
124128 }
125129 }
126130
127131 try stderr.print("unknown command: {}\n\n", args[1]);
128132 try stderr.write(usage);
133 process.argsFree(allocator, args);
129134 process.exit(1);
130135}
131136
......@@ -461,13 +466,12 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
461466 comp.link_objects = link_objects;
462467
463468 comp.start();
464 const frame = async processBuildEvents(comp, color);
469 processBuildEvents(comp, color);
465470}
466471
467async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
472fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
468473 var count: usize = 0;
469 while (true) {
470 // TODO directly awaiting async should guarantee memory allocation elision
474 while (!comp.cancelled) {
471475 const build_event = comp.events.get();
472476 count += 1;
473477
......@@ -545,7 +549,7 @@ fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_fil
545549 "Try running `zig libc` to see an example for the native target.\n",
546550 libc_paths_file,
547551 @errorName(err),
548 ) catch process.exit(1);
552 ) catch {};
549553 process.exit(1);
550554 };
551555}
......@@ -567,12 +571,8 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
567571 var zig_compiler = try ZigCompiler.init(allocator);
568572 defer zig_compiler.deinit();
569573
570 const frame = async findLibCAsync(&zig_compiler);
571}
572
573async fn findLibCAsync(zig_compiler: *ZigCompiler) void {
574574 const libc = zig_compiler.getNativeLibC() catch |err| {
575 stderr.print("unable to find libc: {}\n", @errorName(err)) catch process.exit(1);
575 stderr.print("unable to find libc: {}\n", @errorName(err)) catch {};
576576 process.exit(1);
577577 };
578578 libc.render(stdout) catch process.exit(1);
......@@ -644,11 +644,23 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
644644 process.exit(1);
645645 }
646646
647 return asyncFmtMain(
648 allocator,
649 &flags,
650 color,
651 );
647 var fmt = Fmt{
648 .allocator = allocator,
649 .seen = event.Locked(Fmt.SeenMap).init(Fmt.SeenMap.init(allocator)),
650 .any_error = false,
651 .color = color,
652 };
653
654 const check_mode = flags.present("check");
655
656 var group = event.Group(FmtError!void).init(allocator);
657 for (flags.positionals.toSliceConst()) |file_path| {
658 try group.call(fmtPath, &fmt, file_path, check_mode);
659 }
660 try group.wait();
661 if (fmt.any_error) {
662 process.exit(1);
663 }
652664}
653665
654666const FmtError = error{
......@@ -673,30 +685,6 @@ const FmtError = error{
673685 CurrentWorkingDirectoryUnlinked,
674686} || fs.File.OpenError;
675687
676async fn asyncFmtMain(
677 allocator: *Allocator,
678 flags: *const Args,
679 color: errmsg.Color,
680) FmtError!void {
681 var fmt = Fmt{
682 .allocator = allocator,
683 .seen = event.Locked(Fmt.SeenMap).init(Fmt.SeenMap.init(allocator)),
684 .any_error = false,
685 .color = color,
686 };
687
688 const check_mode = flags.present("check");
689
690 var group = event.Group(FmtError!void).init(allocator);
691 for (flags.positionals.toSliceConst()) |file_path| {
692 try group.call(fmtPath, &fmt, file_path, check_mode);
693 }
694 try group.wait();
695 if (fmt.any_error) {
696 process.exit(1);
697 }
698}
699
700688async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
701689 const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
702690 defer fmt.allocator.free(file_path);
......@@ -708,33 +696,34 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
708696 if (try held.value.put(file_path, {})) |_| return;
709697 }
710698
711 const source_code = "";
712 // const source_code = event.fs.readFile(
713 // file_path,
714 // max_src_size,
715 // ) catch |err| switch (err) {
716 // error.IsDir, error.AccessDenied => {
717 // // TODO make event based (and dir.next())
718 // var dir = try fs.Dir.cwd().openDirList(file_path);
719 // defer dir.close();
720
721 // var group = event.Group(FmtError!void).init(fmt.allocator);
722 // while (try dir.next()) |entry| {
723 // if (entry.kind == fs.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
724 // const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name });
725 // try group.call(fmtPath, fmt, full_path, check_mode);
726 // }
727 // }
728 // return group.wait();
729 // },
730 // else => {
731 // // TODO lock stderr printing
732 // try stderr.print("unable to open '{}': {}\n", file_path, err);
733 // fmt.any_error = true;
734 // return;
735 // },
736 // };
737 // defer fmt.allocator.free(source_code);
699 const source_code = event.fs.readFile(
700 fmt.allocator,
701 file_path,
702 max_src_size,
703 ) catch |err| switch (err) {
704 error.IsDir, error.AccessDenied => {
705 var dir = try fs.Dir.cwd().openDirList(file_path);
706 defer dir.close();
707
708 var group = event.Group(FmtError!void).init(fmt.allocator);
709 var it = dir.iterate();
710 while (try it.next()) |entry| {
711 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
712 const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name });
713 @panic("TODO https://github.com/ziglang/zig/issues/3777");
714 // try group.call(fmtPath, fmt, full_path, check_mode);
715 }
716 }
717 return group.wait();
718 },
719 else => {
720 // TODO lock stderr printing
721 try stderr.print("unable to open '{}': {}\n", file_path, err);
722 fmt.any_error = true;
723 return;
724 },
725 };
726 defer fmt.allocator.free(source_code);
738727
739728 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
740729 try stderr.print("error parsing file '{}': {}\n", file_path, err);
......@@ -867,10 +856,12 @@ fn cmdInternal(allocator: *Allocator, args: []const []const u8) !void {
867856 .exec = cmdInternalBuildInfo,
868857 }};
869858
870 for (sub_commands) |sub_command| {
859 inline for (sub_commands) |sub_command| {
871860 if (mem.eql(u8, sub_command.name, args[0])) {
872 try sub_command.exec(allocator, args[1..]);
873 return;
861 var frame = try allocator.create(@Frame(sub_command.exec));
862 defer allocator.destroy(frame);
863 frame.* = async sub_command.exec(allocator, args[1..]);
864 return await frame;
874865 }
875866 }
876867
src-self-hosted/test.zig+11-13
......@@ -26,7 +26,8 @@ test "stage2" {
2626}
2727
2828const file1 = "1.zig";
29const allocator = std.heap.c_allocator;
29// TODO https://github.com/ziglang/zig/issues/3783
30const allocator = std.heap.page_allocator;
3031
3132pub const TestContext = struct {
3233 zig_compiler: ZigCompiler,
......@@ -94,8 +95,8 @@ pub const TestContext = struct {
9495 &self.zig_compiler,
9596 "test",
9697 file1_path,
97 Target.Native,
98 Compilation.Kind.Obj,
98 .Native,
99 .Obj,
99100 .Debug,
100101 true, // is_static
101102 self.zig_lib_dir,
......@@ -116,7 +117,7 @@ pub const TestContext = struct {
116117 const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
117118 const file1_path = try std.fs.path.join(allocator, [_][]const u8{ tmp_dir_name, file_index, file1 });
118119
119 const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, (Target{.Native = {}}).exeFileExt());
120 const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, (Target{ .Native = {} }).exeFileExt());
120121 if (std.fs.path.dirname(file1_path)) |dirname| {
121122 try std.fs.makePath(allocator, dirname);
122123 }
......@@ -128,8 +129,8 @@ pub const TestContext = struct {
128129 &self.zig_compiler,
129130 "test",
130131 file1_path,
131 Target.Native,
132 Compilation.Kind.Exe,
132 .Native,
133 .Exe,
133134 .Debug,
134135 false,
135136 self.zig_lib_dir,
......@@ -148,15 +149,12 @@ pub const TestContext = struct {
148149 exe_file: []const u8,
149150 expected_output: []const u8,
150151 ) anyerror!void {
151 // TODO this should not be necessary
152 const exe_file_2 = try std.mem.dupe(allocator, u8, exe_file);
153
154152 defer comp.destroy();
155153 const build_event = comp.events.get();
156154
157155 switch (build_event) {
158156 .Ok => {
159 const argv = [_][]const u8{exe_file_2};
157 const argv = [_][]const u8{exe_file};
160158 // TODO use event loop
161159 const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
162160 switch (child.term) {
......@@ -173,13 +171,13 @@ pub const TestContext = struct {
173171 return error.OutputMismatch;
174172 }
175173 },
176 Compilation.Event.Error => |err| return err,
177 Compilation.Event.Fail => |msgs| {
174 .Error => @panic("Cannot return error: https://github.com/ziglang/zig/issues/3190"), // |err| return err,
175 .Fail => |msgs| {
178176 const stderr = std.io.getStdErr();
179177 try stderr.write("build incorrectly failed:\n");
180178 for (msgs) |msg| {
181179 defer msg.destroy();
182 try msg.printToFile(stderr, errmsg.Color.Auto);
180 try msg.printToFile(stderr, .Auto);
183181 }
184182 },
185183 }
src-self-hosted/type.zig+14-12
......@@ -53,7 +53,7 @@ pub const Type = struct {
5353 base: *Type,
5454 allocator: *Allocator,
5555 llvm_context: *llvm.Context,
56 ) (error{OutOfMemory}!*llvm.Type) {
56 ) error{OutOfMemory}!*llvm.Type {
5757 switch (base.id) {
5858 .Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context),
5959 .Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context),
......@@ -184,7 +184,7 @@ pub const Type = struct {
184184
185185 /// If you happen to have an llvm context handy, use getAbiAlignmentInContext instead.
186186 /// Otherwise, this one will grab one from the pool and then release it.
187 pub async fn getAbiAlignment(base: *Type, comp: *Compilation) !u32 {
187 pub fn getAbiAlignment(base: *Type, comp: *Compilation) !u32 {
188188 if (base.abi_alignment.start()) |ptr| return ptr.*;
189189
190190 {
......@@ -200,7 +200,7 @@ pub const Type = struct {
200200 }
201201
202202 /// If you have an llvm conext handy, you can use it here.
203 pub async fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
203 pub fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
204204 if (base.abi_alignment.start()) |ptr| return ptr.*;
205205
206206 base.abi_alignment.data = base.resolveAbiAlignment(comp, llvm_context);
......@@ -209,7 +209,7 @@ pub const Type = struct {
209209 }
210210
211211 /// Lower level function that does the work. See getAbiAlignment.
212 async fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
212 fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
213213 const llvm_type = try base.getLlvmType(comp.gpa(), llvm_context);
214214 return @intCast(u32, llvm.ABIAlignmentOfType(comp.target_data_ref, llvm_type));
215215 }
......@@ -367,7 +367,7 @@ pub const Type = struct {
367367 }
368368
369369 /// takes ownership of key.Normal.params on success
370 pub async fn get(comp: *Compilation, key: Key) !*Fn {
370 pub fn get(comp: *Compilation, key: Key) !*Fn {
371371 {
372372 const held = comp.fn_type_table.acquire();
373373 defer held.release();
......@@ -564,7 +564,7 @@ pub const Type = struct {
564564 return comp.u8_type;
565565 }
566566
567 pub async fn get(comp: *Compilation, key: Key) !*Int {
567 pub fn get(comp: *Compilation, key: Key) !*Int {
568568 {
569569 const held = comp.int_type_table.acquire();
570570 defer held.release();
......@@ -606,7 +606,7 @@ pub const Type = struct {
606606 comp.registerGarbage(Int, &self.garbage_node);
607607 }
608608
609 pub async fn gcDestroy(self: *Int, comp: *Compilation) void {
609 pub fn gcDestroy(self: *Int, comp: *Compilation) void {
610610 {
611611 const held = comp.int_type_table.acquire();
612612 defer held.release();
......@@ -700,7 +700,7 @@ pub const Type = struct {
700700 comp.registerGarbage(Pointer, &self.garbage_node);
701701 }
702702
703 pub async fn gcDestroy(self: *Pointer, comp: *Compilation) void {
703 pub fn gcDestroy(self: *Pointer, comp: *Compilation) void {
704704 {
705705 const held = comp.ptr_type_table.acquire();
706706 defer held.release();
......@@ -711,14 +711,14 @@ pub const Type = struct {
711711 comp.gpa().destroy(self);
712712 }
713713
714 pub async fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 {
714 pub fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 {
715715 switch (self.key.alignment) {
716716 .Abi => return self.key.child_type.getAbiAlignment(comp),
717717 .Override => |alignment| return alignment,
718718 }
719719 }
720720
721 pub async fn get(
721 pub fn get(
722722 comp: *Compilation,
723723 key: Key,
724724 ) !*Pointer {
......@@ -726,8 +726,10 @@ pub const Type = struct {
726726 switch (key.alignment) {
727727 .Abi => {},
728728 .Override => |alignment| {
729 // TODO https://github.com/ziglang/zig/issues/3190
730 var align_spill = alignment;
729731 const abi_align = try key.child_type.getAbiAlignment(comp);
730 if (abi_align == alignment) {
732 if (abi_align == align_spill) {
731733 normal_key.alignment = .Abi;
732734 }
733735 },
......@@ -828,7 +830,7 @@ pub const Type = struct {
828830 comp.gpa().destroy(self);
829831 }
830832
831 pub async fn get(comp: *Compilation, key: Key) !*Array {
833 pub fn get(comp: *Compilation, key: Key) !*Array {
832834 key.elem_type.base.ref();
833835 errdefer key.elem_type.base.deref(comp);
834836
src-self-hosted/util.zig+12-11
......@@ -32,21 +32,21 @@ pub fn getFloatAbi(self: Target) FloatAbi {
3232 };
3333}
3434
35pub fn getObjectFormat(self: Target) Target.ObjectFormat {
36 return switch (self) {
37 .Native => @import("builtin").object_format,
38 .Cross => {
35pub fn getObjectFormat(target: Target) Target.ObjectFormat {
36 switch (target) {
37 .Native => return @import("builtin").object_format,
38 .Cross => blk: {
3939 if (target.isWindows() or target.isUefi()) {
40 break .coff;
40 return .coff;
4141 } else if (target.isDarwin()) {
42 break .macho;
42 return .macho;
4343 }
4444 if (target.isWasm()) {
45 break .wasm;
45 return .wasm;
4646 }
47 break .elf;
47 return .elf;
4848 },
49 };
49 }
5050}
5151
5252pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
......@@ -156,7 +156,7 @@ pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
156156 }
157157}
158158
159pub fn getDarwinArchString(self: Target) []const u8 {
159pub fn getDarwinArchString(self: Target) [:0]const u8 {
160160 const arch = self.getArch();
161161 switch (arch) {
162162 .aarch64 => return "arm64",
......@@ -166,7 +166,8 @@ pub fn getDarwinArchString(self: Target) []const u8 {
166166 .powerpc => return "ppc",
167167 .powerpc64 => return "ppc64",
168168 .powerpc64le => return "ppc64le",
169 else => return @tagName(arch),
169 // @tagName should be able to return sentinel terminated slice
170 else => @panic("TODO https://github.com/ziglang/zig/issues/3779"), //return @tagName(arch),
170171 }
171172}
172173
src-self-hosted/value.zig+7-7
......@@ -156,7 +156,7 @@ pub const Value = struct {
156156 const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
157157 const llvm_fn = llvm.AddFunction(
158158 ofile.module,
159 self.symbol_name.ptr(),
159 self.symbol_name.toSliceConst(),
160160 llvm_fn_type,
161161 ) orelse return error.OutOfMemory;
162162
......@@ -241,7 +241,7 @@ pub const Value = struct {
241241 const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
242242 const llvm_fn = llvm.AddFunction(
243243 ofile.module,
244 self.symbol_name.ptr(),
244 self.symbol_name.toSliceConst(),
245245 llvm_fn_type,
246246 ) orelse return error.OutOfMemory;
247247
......@@ -334,7 +334,7 @@ pub const Value = struct {
334334 field_index: usize,
335335 };
336336
337 pub async fn createArrayElemPtr(
337 pub fn createArrayElemPtr(
338338 comp: *Compilation,
339339 array_val: *Array,
340340 mut: Type.Pointer.Mut,
......@@ -350,7 +350,7 @@ pub const Value = struct {
350350 .mut = mut,
351351 .vol = Type.Pointer.Vol.Non,
352352 .size = size,
353 .alignment = Type.Pointer.Align.Abi,
353 .alignment = .Abi,
354354 });
355355 var ptr_type_consumed = false;
356356 errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);
......@@ -390,13 +390,13 @@ pub const Value = struct {
390390 const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?;
391391 const ptr_bit_count = ofile.comp.target_ptr_bits;
392392 const usize_llvm_type = llvm.IntTypeInContext(ofile.context, ptr_bit_count) orelse return error.OutOfMemory;
393 const indices = [_]*llvm.Value{
393 var indices = [_]*llvm.Value{
394394 llvm.ConstNull(usize_llvm_type) orelse return error.OutOfMemory,
395395 llvm.ConstInt(usize_llvm_type, base_array.elem_index, 0) orelse return error.OutOfMemory,
396396 };
397397 return llvm.ConstInBoundsGEP(
398398 array_llvm_value,
399 &indices,
399 @ptrCast([*]*llvm.Value, &indices),
400400 @intCast(c_uint, indices.len),
401401 ) orelse return error.OutOfMemory;
402402 },
......@@ -423,7 +423,7 @@ pub const Value = struct {
423423 };
424424
425425 /// Takes ownership of buffer
426 pub async fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array {
426 pub fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array {
427427 const u8_type = Type.Int.get_u8(comp);
428428 defer u8_type.base.base.deref(comp);
429429