| author | |
| committer | |
| log | 83c664eaa080669cff83f7c30046376f3399eafb |
| tree | 06cccc09052be4459e924d04a867ff34a889d87c |
| parent | 63300a21ddf4cfe209a39796c6d7ea7773e14fd6 |
| parent | 4d8a8e65df79ddd5edf52f961552036ccfca6e8e |
| signature |
Update use of async functions in self hosted compiler13 files changed, 346 insertions(+), 368 deletions(-)
lib/std/event/fs.zig+15-13| ... | @@ -735,24 +735,26 @@ pub fn Watch(comptime V: type) type { | ... | @@ -735,24 +735,26 @@ pub fn Watch(comptime V: type) type { |
| 735 | allocator: *Allocator, | 735 | allocator: *Allocator, |
| 736 | 736 | ||
| 737 | const OsData = switch (builtin.os) { | 737 | const OsData = switch (builtin.os) { |
| 738 | .macosx, .freebsd, .netbsd, .dragonfly => struct { | 738 | // TODO https://github.com/ziglang/zig/issues/3778 |
| 739 | file_table: FileTable, | 739 | .macosx, .freebsd, .netbsd, .dragonfly => KqOsData, |
| 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 | |||
| 750 | .linux => LinuxOsData, | 740 | .linux => LinuxOsData, |
| 751 | .windows => WindowsOsData, | 741 | .windows => WindowsOsData, |
| 752 | 742 | ||
| 753 | else => @compileError("Unsupported OS"), | 743 | else => @compileError("Unsupported OS"), |
| 754 | }; | 744 | }; |
| 755 | 745 | ||
| 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 | |||
| 756 | const WindowsOsData = struct { | 758 | const WindowsOsData = struct { |
| 757 | table_lock: event.Lock, | 759 | table_lock: event.Lock, |
| 758 | dir_table: DirTable, | 760 | dir_table: DirTable, |
| ... | @@ -1291,7 +1293,7 @@ pub fn Watch(comptime V: type) type { | ... | @@ -1291,7 +1293,7 @@ pub fn Watch(comptime V: type) type { |
| 1291 | os.linux.EINVAL => unreachable, | 1293 | os.linux.EINVAL => unreachable, |
| 1292 | os.linux.EFAULT => unreachable, | 1294 | os.linux.EFAULT => unreachable, |
| 1293 | os.linux.EAGAIN => { | 1295 | 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); |
| 1295 | }, | 1297 | }, |
| 1296 | else => unreachable, | 1298 | else => unreachable, |
| 1297 | } | 1299 | } |
src-self-hosted/codegen.zig+15-15| ... | @@ -25,10 +25,10 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) | ... | @@ -25,10 +25,10 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) |
| 25 | 25 | ||
| 26 | const context = llvm_handle.node.data; | 26 | const context = llvm_handle.node.data; |
| 27 | 27 | ||
| 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; |
| 29 | defer llvm.DisposeModule(module); | 29 | defer llvm.DisposeModule(module); |
| 30 | 30 | ||
| 31 | llvm.SetTarget(module, comp.llvm_triple.ptr()); | 31 | llvm.SetTarget(module, comp.llvm_triple.toSliceConst()); |
| 32 | llvm.SetDataLayout(module, comp.target_layout_str); | 32 | llvm.SetDataLayout(module, comp.target_layout_str); |
| 33 | 33 | ||
| 34 | if (util.getObjectFormat(comp.target) == .coff) { | 34 | if (util.getObjectFormat(comp.target) == .coff) { |
| ... | @@ -48,23 +48,23 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) | ... | @@ -48,23 +48,23 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) |
| 48 | const producer = try std.Buffer.allocPrint( | 48 | const producer = try std.Buffer.allocPrint( |
| 49 | &code.arena.allocator, | 49 | &code.arena.allocator, |
| 50 | "zig {}.{}.{}", | 50 | "zig {}.{}.{}", |
| 51 | u32(c.ZIG_VERSION_MAJOR), | 51 | @as(u32, c.ZIG_VERSION_MAJOR), |
| 52 | u32(c.ZIG_VERSION_MINOR), | 52 | @as(u32, c.ZIG_VERSION_MINOR), |
| 53 | u32(c.ZIG_VERSION_PATCH), | 53 | @as(u32, c.ZIG_VERSION_PATCH), |
| 54 | ); | 54 | ); |
| 55 | const flags = ""; | 55 | const flags = ""; |
| 56 | const runtime_version = 0; | 56 | const runtime_version = 0; |
| 57 | const compile_unit_file = llvm.CreateFile( | 57 | const compile_unit_file = llvm.CreateFile( |
| 58 | dibuilder, | 58 | dibuilder, |
| 59 | comp.name.ptr(), | 59 | comp.name.toSliceConst(), |
| 60 | comp.root_package.root_src_dir.ptr(), | 60 | comp.root_package.root_src_dir.toSliceConst(), |
| 61 | ) orelse return error.OutOfMemory; | 61 | ) orelse return error.OutOfMemory; |
| 62 | const is_optimized = comp.build_mode != .Debug; | 62 | const is_optimized = comp.build_mode != .Debug; |
| 63 | const compile_unit = llvm.CreateCompileUnit( | 63 | const compile_unit = llvm.CreateCompileUnit( |
| 64 | dibuilder, | 64 | dibuilder, |
| 65 | DW.LANG_C99, | 65 | DW.LANG_C99, |
| 66 | compile_unit_file, | 66 | compile_unit_file, |
| 67 | producer.ptr(), | 67 | producer.toSliceConst(), |
| 68 | is_optimized, | 68 | is_optimized, |
| 69 | flags, | 69 | flags, |
| 70 | runtime_version, | 70 | runtime_version, |
| ... | @@ -99,7 +99,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) | ... | @@ -99,7 +99,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) |
| 99 | 99 | ||
| 100 | // verify the llvm module when safety is on | 100 | // verify the llvm module when safety is on |
| 101 | if (std.debug.runtime_safety) { | 101 | if (std.debug.runtime_safety) { |
| 102 | var error_ptr: ?[*]u8 = null; | 102 | var error_ptr: ?[*:0]u8 = null; |
| 103 | _ = llvm.VerifyModule(ofile.module, llvm.AbortProcessAction, &error_ptr); | 103 | _ = llvm.VerifyModule(ofile.module, llvm.AbortProcessAction, &error_ptr); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| ... | @@ -108,12 +108,12 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) | ... | @@ -108,12 +108,12 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) |
| 108 | const is_small = comp.build_mode == .ReleaseSmall; | 108 | const is_small = comp.build_mode == .ReleaseSmall; |
| 109 | const is_debug = comp.build_mode == .Debug; | 109 | const is_debug = comp.build_mode == .Debug; |
| 110 | 110 | ||
| 111 | var err_msg: [*]u8 = undefined; | 111 | var err_msg: [*:0]u8 = undefined; |
| 112 | // TODO integrate this with evented I/O | 112 | // TODO integrate this with evented I/O |
| 113 | if (llvm.TargetMachineEmitToFile( | 113 | if (llvm.TargetMachineEmitToFile( |
| 114 | comp.target_machine, | 114 | comp.target_machine, |
| 115 | module, | 115 | module, |
| 116 | output_path.ptr(), | 116 | output_path.toSliceConst(), |
| 117 | llvm.EmitBinary, | 117 | llvm.EmitBinary, |
| 118 | &err_msg, | 118 | &err_msg, |
| 119 | is_debug, | 119 | is_debug, |
| ... | @@ -154,7 +154,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code) | ... | @@ -154,7 +154,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code) |
| 154 | const llvm_fn_type = try fn_val.base.typ.getLlvmType(ofile.arena, ofile.context); | 154 | const llvm_fn_type = try fn_val.base.typ.getLlvmType(ofile.arena, ofile.context); |
| 155 | const llvm_fn = llvm.AddFunction( | 155 | const llvm_fn = llvm.AddFunction( |
| 156 | ofile.module, | 156 | ofile.module, |
| 157 | fn_val.symbol_name.ptr(), | 157 | fn_val.symbol_name.toSliceConst(), |
| 158 | llvm_fn_type, | 158 | llvm_fn_type, |
| 159 | ) orelse return error.OutOfMemory; | 159 | ) orelse return error.OutOfMemory; |
| 160 | 160 | ||
| ... | @@ -379,7 +379,7 @@ fn renderLoadUntyped( | ... | @@ -379,7 +379,7 @@ fn renderLoadUntyped( |
| 379 | ptr: *llvm.Value, | 379 | ptr: *llvm.Value, |
| 380 | alignment: Type.Pointer.Align, | 380 | alignment: Type.Pointer.Align, |
| 381 | vol: Type.Pointer.Vol, | 381 | vol: Type.Pointer.Vol, |
| 382 | name: [*]const u8, | 382 | name: [*:0]const u8, |
| 383 | ) !*llvm.Value { | 383 | ) !*llvm.Value { |
| 384 | const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory; | 384 | const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory; |
| 385 | switch (vol) { | 385 | switch (vol) { |
| ... | @@ -390,7 +390,7 @@ fn renderLoadUntyped( | ... | @@ -390,7 +390,7 @@ fn renderLoadUntyped( |
| 390 | return result; | 390 | return result; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*]const u8) !*llvm.Value { | 393 | fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*:0]const u8) !*llvm.Value { |
| 394 | return renderLoadUntyped(ofile, ptr, ptr_type.key.alignment, ptr_type.key.vol, name); | 394 | return renderLoadUntyped(ofile, ptr, ptr_type.key.alignment, ptr_type.key.vol, name); |
| 395 | } | 395 | } |
| 396 | 396 | ||
| ... | @@ -438,7 +438,7 @@ pub fn renderAlloca( | ... | @@ -438,7 +438,7 @@ pub fn renderAlloca( |
| 438 | ) !*llvm.Value { | 438 | ) !*llvm.Value { |
| 439 | const llvm_var_type = try var_type.getLlvmType(ofile.arena, ofile.context); | 439 | const llvm_var_type = try var_type.getLlvmType(ofile.arena, ofile.context); |
| 440 | const name_with_null = try std.cstr.addNullByte(ofile.arena, name); | 440 | 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; |
| 442 | llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm_var_type)); | 442 | llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm_var_type)); |
| 443 | return result; | 443 | return result; |
| 444 | } | 444 | } |
src-self-hosted/compilation.zig+130-149| ... | @@ -93,7 +93,7 @@ pub const ZigCompiler = struct { | ... | @@ -93,7 +93,7 @@ pub const ZigCompiler = struct { |
| 93 | return LlvmHandle{ .node = node }; | 93 | return LlvmHandle{ .node = node }; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | pub async fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation { | 96 | pub fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation { |
| 97 | if (self.native_libc.start()) |ptr| return ptr; | 97 | if (self.native_libc.start()) |ptr| return ptr; |
| 98 | try self.native_libc.data.findNative(self.allocator); | 98 | try self.native_libc.data.findNative(self.allocator); |
| 99 | self.native_libc.resolve(); | 99 | self.native_libc.resolve(); |
| ... | @@ -133,62 +133,62 @@ pub const Compilation = struct { | ... | @@ -133,62 +133,62 @@ pub const Compilation = struct { |
| 133 | zig_std_dir: []const u8, | 133 | zig_std_dir: []const u8, |
| 134 | 134 | ||
| 135 | /// lazily created when we need it | 135 | /// 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(), |
| 137 | 137 | ||
| 138 | version_major: u32, | 138 | version_major: u32 = 0, |
| 139 | version_minor: u32, | 139 | version_minor: u32 = 0, |
| 140 | version_patch: u32, | 140 | version_patch: u32 = 0, |
| 141 | 141 | ||
| 142 | linker_script: ?[]const u8, | 142 | linker_script: ?[]const u8 = null, |
| 143 | out_h_path: ?[]const u8, | 143 | out_h_path: ?[]const u8 = null, |
| 144 | 144 | ||
| 145 | is_test: bool, | 145 | is_test: bool = false, |
| 146 | each_lib_rpath: bool, | 146 | each_lib_rpath: bool = false, |
| 147 | strip: bool, | 147 | strip: bool = false, |
| 148 | is_static: bool, | 148 | is_static: bool, |
| 149 | linker_rdynamic: bool, | 149 | linker_rdynamic: bool = false, |
| 150 | 150 | ||
| 151 | clang_argv: []const []const u8, | 151 | clang_argv: []const []const u8 = [_][]const u8{}, |
| 152 | lib_dirs: []const []const u8, | 152 | lib_dirs: []const []const u8 = [_][]const u8{}, |
| 153 | rpath_list: []const []const u8, | 153 | rpath_list: []const []const u8 = [_][]const u8{}, |
| 154 | assembly_files: []const []const u8, | 154 | assembly_files: []const []const u8 = [_][]const u8{}, |
| 155 | 155 | ||
| 156 | /// paths that are explicitly provided by the user to link against | 156 | /// 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{}, |
| 158 | 158 | ||
| 159 | /// functions that have their own objects that we need to link | 159 | /// functions that have their own objects that we need to link |
| 160 | /// it uses an optional pointer so that tombstone removals are possible | 160 | /// 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()), |
| 162 | 162 | ||
| 163 | pub const FnLinkSet = std.TailQueue(?*Value.Fn); | 163 | pub const FnLinkSet = std.TailQueue(?*Value.Fn); |
| 164 | 164 | ||
| 165 | windows_subsystem_windows: bool, | 165 | windows_subsystem_windows: bool = false, |
| 166 | windows_subsystem_console: bool, | 166 | windows_subsystem_console: bool = false, |
| 167 | 167 | ||
| 168 | link_libs_list: ArrayList(*LinkLib), | 168 | link_libs_list: ArrayList(*LinkLib), |
| 169 | libc_link_lib: ?*LinkLib, | 169 | libc_link_lib: ?*LinkLib = null, |
| 170 | 170 | ||
| 171 | err_color: errmsg.Color, | 171 | err_color: errmsg.Color = .Auto, |
| 172 | 172 | ||
| 173 | verbose_tokenize: bool, | 173 | verbose_tokenize: bool = false, |
| 174 | verbose_ast_tree: bool, | 174 | verbose_ast_tree: bool = false, |
| 175 | verbose_ast_fmt: bool, | 175 | verbose_ast_fmt: bool = false, |
| 176 | verbose_cimport: bool, | 176 | verbose_cimport: bool = false, |
| 177 | verbose_ir: bool, | 177 | verbose_ir: bool = false, |
| 178 | verbose_llvm_ir: bool, | 178 | verbose_llvm_ir: bool = false, |
| 179 | verbose_link: bool, | 179 | verbose_link: bool = false, |
| 180 | 180 | ||
| 181 | darwin_frameworks: []const []const u8, | 181 | darwin_frameworks: []const []const u8 = [_][]const u8{}, |
| 182 | darwin_version_min: DarwinVersionMin, | 182 | darwin_version_min: DarwinVersionMin = .None, |
| 183 | 183 | ||
| 184 | test_filters: []const []const u8, | 184 | test_filters: []const []const u8 = [_][]const u8{}, |
| 185 | test_name_prefix: ?[]const u8, | 185 | test_name_prefix: ?[]const u8 = null, |
| 186 | 186 | ||
| 187 | emit_file_type: Emit, | 187 | emit_file_type: Emit = .Binary, |
| 188 | 188 | ||
| 189 | kind: Kind, | 189 | kind: Kind, |
| 190 | 190 | ||
| 191 | link_out_file: ?[]const u8, | 191 | link_out_file: ?[]const u8 = null, |
| 192 | events: *event.Channel(Event), | 192 | events: *event.Channel(Event), |
| 193 | 193 | ||
| 194 | exported_symbol_names: event.Locked(Decl.Table), | 194 | exported_symbol_names: event.Locked(Decl.Table), |
| ... | @@ -213,7 +213,7 @@ pub const Compilation = struct { | ... | @@ -213,7 +213,7 @@ pub const Compilation = struct { |
| 213 | 213 | ||
| 214 | target_machine: *llvm.TargetMachine, | 214 | target_machine: *llvm.TargetMachine, |
| 215 | target_data_ref: *llvm.TargetData, | 215 | target_data_ref: *llvm.TargetData, |
| 216 | target_layout_str: [*]u8, | 216 | target_layout_str: [*:0]u8, |
| 217 | target_ptr_bits: u32, | 217 | target_ptr_bits: u32, |
| 218 | 218 | ||
| 219 | /// for allocating things which have the same lifetime as this Compilation | 219 | /// for allocating things which have the same lifetime as this Compilation |
| ... | @@ -222,16 +222,16 @@ pub const Compilation = struct { | ... | @@ -222,16 +222,16 @@ pub const Compilation = struct { |
| 222 | root_package: *Package, | 222 | root_package: *Package, |
| 223 | std_package: *Package, | 223 | std_package: *Package, |
| 224 | 224 | ||
| 225 | override_libc: ?*LibCInstallation, | 225 | override_libc: ?*LibCInstallation = null, |
| 226 | 226 | ||
| 227 | /// need to wait on this group before deinitializing | 227 | /// need to wait on this group before deinitializing |
| 228 | deinit_group: event.Group(void), | 228 | deinit_group: event.Group(void), |
| 229 | 229 | ||
| 230 | // destroy_frame: @Frame(createAsync), | 230 | destroy_frame: *@Frame(createAsync), |
| 231 | // main_loop_frame: @Frame(Compilation.mainLoop), | 231 | main_loop_frame: *@Frame(Compilation.mainLoop), |
| 232 | main_loop_future: event.Future(void), | 232 | main_loop_future: event.Future(void) = event.Future(void).init(), |
| 233 | 233 | ||
| 234 | have_err_ret_tracing: bool, | 234 | have_err_ret_tracing: bool = false, |
| 235 | 235 | ||
| 236 | /// not locked because it is read-only | 236 | /// not locked because it is read-only |
| 237 | primitive_type_table: TypeTable, | 237 | primitive_type_table: TypeTable, |
| ... | @@ -243,7 +243,9 @@ pub const Compilation = struct { | ... | @@ -243,7 +243,9 @@ pub const Compilation = struct { |
| 243 | 243 | ||
| 244 | c_int_types: [CInt.list.len]*Type.Int, | 244 | c_int_types: [CInt.list.len]*Type.Int, |
| 245 | 245 | ||
| 246 | // fs_watch: *fs.Watch(*Scope.Root), | 246 | fs_watch: *fs.Watch(*Scope.Root), |
| 247 | |||
| 248 | cancelled: bool = false, | ||
| 247 | 249 | ||
| 248 | const IntTypeTable = std.HashMap(*const Type.Int.Key, *Type.Int, Type.Int.Key.hash, Type.Int.Key.eql); | 250 | const IntTypeTable = std.HashMap(*const Type.Int.Key, *Type.Int, Type.Int.Key.hash, Type.Int.Key.eql); |
| 249 | const ArrayTypeTable = std.HashMap(*const Type.Array.Key, *Type.Array, Type.Array.Key.hash, Type.Array.Key.eql); | 251 | 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 { | ... | @@ -348,7 +350,9 @@ pub const Compilation = struct { |
| 348 | zig_lib_dir: []const u8, | 350 | zig_lib_dir: []const u8, |
| 349 | ) !*Compilation { | 351 | ) !*Compilation { |
| 350 | var optional_comp: ?*Compilation = null; | 352 | 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( | ||
| 352 | &optional_comp, | 356 | &optional_comp, |
| 353 | zig_compiler, | 357 | zig_compiler, |
| 354 | name, | 358 | name, |
| ... | @@ -359,7 +363,11 @@ pub const Compilation = struct { | ... | @@ -359,7 +363,11 @@ pub const Compilation = struct { |
| 359 | is_static, | 363 | is_static, |
| 360 | zig_lib_dir, | 364 | zig_lib_dir, |
| 361 | ); | 365 | ); |
| 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; | ||
| 363 | } | 371 | } |
| 364 | 372 | ||
| 365 | async fn createAsync( | 373 | async fn createAsync( |
| ... | @@ -385,50 +393,14 @@ pub const Compilation = struct { | ... | @@ -385,50 +393,14 @@ pub const Compilation = struct { |
| 385 | .build_mode = build_mode, | 393 | .build_mode = build_mode, |
| 386 | .zig_lib_dir = zig_lib_dir, | 394 | .zig_lib_dir = zig_lib_dir, |
| 387 | .zig_std_dir = undefined, | 395 | .zig_std_dir = undefined, |
| 388 | .tmp_dir = event.Future(BuildError![]u8).init(), | 396 | .destroy_frame = @frame(), |
| 389 | // .destroy_frame = @frame(), | 397 | .main_loop_frame = undefined, |
| 390 | // .main_loop_frame = undefined, | ||
| 391 | .main_loop_future = event.Future(void).init(), | ||
| 392 | 398 | ||
| 393 | .name = undefined, | 399 | .name = undefined, |
| 394 | .llvm_triple = undefined, | 400 | .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, | ||
| 413 | .is_static = is_static, | 401 | .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, | ||
| 423 | .link_libs_list = undefined, | 402 | .link_libs_list = undefined, |
| 424 | .libc_link_lib = null, | 403 | |
| 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, | ||
| 432 | .exported_symbol_names = event.Locked(Decl.Table).init(Decl.Table.init(allocator)), | 404 | .exported_symbol_names = event.Locked(Decl.Table).init(Decl.Table.init(allocator)), |
| 433 | .prelink_group = event.Group(BuildError!void).init(allocator), | 405 | .prelink_group = event.Group(BuildError!void).init(allocator), |
| 434 | .deinit_group = event.Group(void).init(allocator), | 406 | .deinit_group = event.Group(void).init(allocator), |
| ... | @@ -458,11 +430,9 @@ pub const Compilation = struct { | ... | @@ -458,11 +430,9 @@ pub const Compilation = struct { |
| 458 | .root_package = undefined, | 430 | .root_package = undefined, |
| 459 | .std_package = undefined, | 431 | .std_package = undefined, |
| 460 | 432 | ||
| 461 | .override_libc = null, | ||
| 462 | .have_err_ret_tracing = false, | ||
| 463 | .primitive_type_table = undefined, | 433 | .primitive_type_table = undefined, |
| 464 | 434 | ||
| 465 | // .fs_watch = undefined, | 435 | .fs_watch = undefined, |
| 466 | }; | 436 | }; |
| 467 | comp.link_libs_list = ArrayList(*LinkLib).init(comp.arena()); | 437 | comp.link_libs_list = ArrayList(*LinkLib).init(comp.arena()); |
| 468 | comp.primitive_type_table = TypeTable.init(comp.arena()); | 438 | comp.primitive_type_table = TypeTable.init(comp.arena()); |
| ... | @@ -534,13 +504,16 @@ pub const Compilation = struct { | ... | @@ -534,13 +504,16 @@ pub const Compilation = struct { |
| 534 | comp.root_package = try Package.create(comp.arena(), ".", ""); | 504 | comp.root_package = try Package.create(comp.arena(), ".", ""); |
| 535 | } | 505 | } |
| 536 | 506 | ||
| 537 | // comp.fs_watch = try fs.Watch(*Scope.Root).create(16); | 507 | comp.fs_watch = try fs.Watch(*Scope.Root).init(allocator, 16); |
| 538 | // defer comp.fs_watch.destroy(); | 508 | defer comp.fs_watch.deinit(); |
| 539 | 509 | ||
| 540 | try comp.initTypes(); | 510 | try comp.initTypes(); |
| 541 | defer comp.primitive_type_table.deinit(); | 511 | defer comp.primitive_type_table.deinit(); |
| 542 | 512 | ||
| 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(); | ||
| 544 | // Set this to indicate that initialization completed successfully. | 517 | // Set this to indicate that initialization completed successfully. |
| 545 | // from here on out we must not return an error. | 518 | // from here on out we must not return an error. |
| 546 | // This must occur before the first suspend/await. | 519 | // This must occur before the first suspend/await. |
| ... | @@ -559,7 +532,7 @@ pub const Compilation = struct { | ... | @@ -559,7 +532,7 @@ pub const Compilation = struct { |
| 559 | } | 532 | } |
| 560 | 533 | ||
| 561 | /// it does ref the result because it could be an arbitrary integer size | 534 | /// 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 { |
| 563 | if (name.len >= 2) { | 536 | if (name.len >= 2) { |
| 564 | switch (name[0]) { | 537 | switch (name[0]) { |
| 565 | 'i', 'u' => blk: { | 538 | 'i', 'u' => blk: { |
| ... | @@ -753,8 +726,11 @@ pub const Compilation = struct { | ... | @@ -753,8 +726,11 @@ pub const Compilation = struct { |
| 753 | } | 726 | } |
| 754 | 727 | ||
| 755 | pub fn destroy(self: *Compilation) void { | 728 | pub fn destroy(self: *Compilation) void { |
| 756 | // await self.main_loop_frame; | 729 | const allocator = self.gpa(); |
| 757 | // resume self.destroy_frame; | 730 | self.cancelled = true; |
| 731 | await self.main_loop_frame; | ||
| 732 | resume self.destroy_frame; | ||
| 733 | allocator.destroy(self.destroy_frame); | ||
| 758 | } | 734 | } |
| 759 | 735 | ||
| 760 | fn start(self: *Compilation) void { | 736 | fn start(self: *Compilation) void { |
| ... | @@ -767,7 +743,7 @@ pub const Compilation = struct { | ... | @@ -767,7 +743,7 @@ pub const Compilation = struct { |
| 767 | 743 | ||
| 768 | var build_result = self.initialCompile(); | 744 | var build_result = self.initialCompile(); |
| 769 | 745 | ||
| 770 | while (true) { | 746 | while (!self.cancelled) { |
| 771 | const link_result = if (build_result) blk: { | 747 | const link_result = if (build_result) blk: { |
| 772 | break :blk self.maybeLink(); | 748 | break :blk self.maybeLink(); |
| 773 | } else |err| err; | 749 | } else |err| err; |
| ... | @@ -795,47 +771,47 @@ pub const Compilation = struct { | ... | @@ -795,47 +771,47 @@ pub const Compilation = struct { |
| 795 | self.events.put(Event{ .Error = err }); | 771 | self.events.put(Event{ .Error = err }); |
| 796 | } | 772 | } |
| 797 | 773 | ||
| 798 | // // First, get an item from the watch channel, waiting on the channel. | 774 | // First, get an item from the watch channel, waiting on the channel. |
| 799 | // var group = event.Group(BuildError!void).init(self.gpa()); | 775 | var group = event.Group(BuildError!void).init(self.gpa()); |
| 800 | // { | 776 | { |
| 801 | // const ev = (self.fs_watch.channel.get()) catch |err| { | 777 | const ev = (self.fs_watch.channel.get()) catch |err| { |
| 802 | // build_result = err; | 778 | build_result = err; |
| 803 | // continue; | 779 | continue; |
| 804 | // }; | 780 | }; |
| 805 | // const root_scope = ev.data; | 781 | const root_scope = ev.data; |
| 806 | // group.call(rebuildFile, self, root_scope) catch |err| { | 782 | group.call(rebuildFile, self, root_scope) catch |err| { |
| 807 | // build_result = err; | 783 | build_result = err; |
| 808 | // continue; | 784 | continue; |
| 809 | // }; | 785 | }; |
| 810 | // } | 786 | } |
| 811 | // // Next, get all the items from the channel that are buffered up. | 787 | // Next, get all the items from the channel that are buffered up. |
| 812 | // while (self.fs_watch.channel.getOrNull()) |ev_or_err| { | 788 | while (self.fs_watch.channel.getOrNull()) |ev_or_err| { |
| 813 | // if (ev_or_err) |ev| { | 789 | if (ev_or_err) |ev| { |
| 814 | // const root_scope = ev.data; | 790 | const root_scope = ev.data; |
| 815 | // group.call(rebuildFile, self, root_scope) catch |err| { | 791 | group.call(rebuildFile, self, root_scope) catch |err| { |
| 816 | // build_result = err; | 792 | build_result = err; |
| 817 | // continue; | 793 | continue; |
| 818 | // }; | 794 | }; |
| 819 | // } else |err| { | 795 | } else |err| { |
| 820 | // build_result = err; | 796 | build_result = err; |
| 821 | // continue; | 797 | continue; |
| 822 | // } | 798 | } |
| 823 | // } | 799 | } |
| 824 | // build_result = group.wait(); | 800 | build_result = group.wait(); |
| 825 | } | 801 | } |
| 826 | } | 802 | } |
| 827 | 803 | ||
| 828 | async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) !void { | 804 | async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) BuildError!void { |
| 829 | const tree_scope = blk: { | 805 | const tree_scope = blk: { |
| 830 | const source_code = ""; | 806 | const source_code = fs.readFile( |
| 831 | // const source_code = fs.readFile( | 807 | self.gpa(), |
| 832 | // root_scope.realpath, | 808 | root_scope.realpath, |
| 833 | // max_src_size, | 809 | max_src_size, |
| 834 | // ) catch |err| { | 810 | ) catch |err| { |
| 835 | // try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err)); | 811 | try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err)); |
| 836 | // return; | 812 | return; |
| 837 | // }; | 813 | }; |
| 838 | // errdefer self.gpa().free(source_code); | 814 | errdefer self.gpa().free(source_code); |
| 839 | 815 | ||
| 840 | const tree = try std.zig.parse(self.gpa(), source_code); | 816 | const tree = try std.zig.parse(self.gpa(), source_code); |
| 841 | errdefer { | 817 | errdefer { |
| ... | @@ -873,7 +849,7 @@ pub const Compilation = struct { | ... | @@ -873,7 +849,7 @@ pub const Compilation = struct { |
| 873 | try decl_group.wait(); | 849 | try decl_group.wait(); |
| 874 | } | 850 | } |
| 875 | 851 | ||
| 876 | async fn rebuildChangedDecls( | 852 | fn rebuildChangedDecls( |
| 877 | self: *Compilation, | 853 | self: *Compilation, |
| 878 | group: *event.Group(BuildError!void), | 854 | group: *event.Group(BuildError!void), |
| 879 | locked_table: *Decl.Table, | 855 | locked_table: *Decl.Table, |
| ... | @@ -962,7 +938,7 @@ pub const Compilation = struct { | ... | @@ -962,7 +938,7 @@ pub const Compilation = struct { |
| 962 | } | 938 | } |
| 963 | } | 939 | } |
| 964 | 940 | ||
| 965 | async fn initialCompile(self: *Compilation) !void { | 941 | fn initialCompile(self: *Compilation) !void { |
| 966 | if (self.root_src_path) |root_src_path| { | 942 | if (self.root_src_path) |root_src_path| { |
| 967 | const root_scope = blk: { | 943 | const root_scope = blk: { |
| 968 | // TODO async/await std.fs.realpath | 944 | // TODO async/await std.fs.realpath |
| ... | @@ -981,7 +957,7 @@ pub const Compilation = struct { | ... | @@ -981,7 +957,7 @@ pub const Compilation = struct { |
| 981 | } | 957 | } |
| 982 | } | 958 | } |
| 983 | 959 | ||
| 984 | async fn maybeLink(self: *Compilation) !void { | 960 | fn maybeLink(self: *Compilation) !void { |
| 985 | (self.prelink_group.wait()) catch |err| switch (err) { | 961 | (self.prelink_group.wait()) catch |err| switch (err) { |
| 986 | error.SemanticAnalysisFailed => {}, | 962 | error.SemanticAnalysisFailed => {}, |
| 987 | else => return err, | 963 | else => return err, |
| ... | @@ -1165,11 +1141,10 @@ pub const Compilation = struct { | ... | @@ -1165,11 +1141,10 @@ pub const Compilation = struct { |
| 1165 | return link_lib; | 1141 | return link_lib; |
| 1166 | } | 1142 | } |
| 1167 | 1143 | ||
| 1168 | /// cancels itself so no need to await or cancel the promise. | ||
| 1169 | async fn startFindingNativeLibC(self: *Compilation) void { | 1144 | async fn startFindingNativeLibC(self: *Compilation) void { |
| 1170 | std.event.Loop.instance.?.yield(); | 1145 | event.Loop.startCpuBoundOperation(); |
| 1171 | // we don't care if it fails, we're just trying to kick off the future resolution | 1146 | // 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; |
| 1173 | } | 1148 | } |
| 1174 | 1149 | ||
| 1175 | /// General Purpose Allocator. Must free when done. | 1150 | /// General Purpose Allocator. Must free when done. |
| ... | @@ -1184,7 +1159,7 @@ pub const Compilation = struct { | ... | @@ -1184,7 +1159,7 @@ pub const Compilation = struct { |
| 1184 | 1159 | ||
| 1185 | /// If the temporary directory for this compilation has not been created, it creates it. | 1160 | /// If the temporary directory for this compilation has not been created, it creates it. |
| 1186 | /// Then it creates a random file name in that dir and returns it. | 1161 | /// 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 { |
| 1188 | const tmp_dir = try self.getTmpDir(); | 1163 | const tmp_dir = try self.getTmpDir(); |
| 1189 | const file_prefix = self.getRandomFileName(); | 1164 | const file_prefix = self.getRandomFileName(); |
| 1190 | 1165 | ||
| ... | @@ -1200,14 +1175,14 @@ pub const Compilation = struct { | ... | @@ -1200,14 +1175,14 @@ pub const Compilation = struct { |
| 1200 | /// If the temporary directory for this Compilation has not been created, creates it. | 1175 | /// If the temporary directory for this Compilation has not been created, creates it. |
| 1201 | /// Then returns it. The directory is unique to this Compilation and cleaned up when | 1176 | /// Then returns it. The directory is unique to this Compilation and cleaned up when |
| 1202 | /// the Compilation deinitializes. | 1177 | /// the Compilation deinitializes. |
| 1203 | async fn getTmpDir(self: *Compilation) ![]const u8 { | 1178 | fn getTmpDir(self: *Compilation) ![]const u8 { |
| 1204 | if (self.tmp_dir.start()) |ptr| return ptr.*; | 1179 | if (self.tmp_dir.start()) |ptr| return ptr.*; |
| 1205 | self.tmp_dir.data = self.getTmpDirImpl(); | 1180 | self.tmp_dir.data = self.getTmpDirImpl(); |
| 1206 | self.tmp_dir.resolve(); | 1181 | self.tmp_dir.resolve(); |
| 1207 | return self.tmp_dir.data; | 1182 | return self.tmp_dir.data; |
| 1208 | } | 1183 | } |
| 1209 | 1184 | ||
| 1210 | async fn getTmpDirImpl(self: *Compilation) ![]u8 { | 1185 | fn getTmpDirImpl(self: *Compilation) ![]u8 { |
| 1211 | const comp_dir_name = self.getRandomFileName(); | 1186 | const comp_dir_name = self.getRandomFileName(); |
| 1212 | const zig_dir_path = try getZigDir(self.gpa()); | 1187 | const zig_dir_path = try getZigDir(self.gpa()); |
| 1213 | defer self.gpa().free(zig_dir_path); | 1188 | defer self.gpa().free(zig_dir_path); |
| ... | @@ -1217,7 +1192,7 @@ pub const Compilation = struct { | ... | @@ -1217,7 +1192,7 @@ pub const Compilation = struct { |
| 1217 | return tmp_dir; | 1192 | return tmp_dir; |
| 1218 | } | 1193 | } |
| 1219 | 1194 | ||
| 1220 | async fn getRandomFileName(self: *Compilation) [12]u8 { | 1195 | fn getRandomFileName(self: *Compilation) [12]u8 { |
| 1221 | // here we replace the standard +/ with -_ so that it can be used in a file name | 1196 | // here we replace the standard +/ with -_ so that it can be used in a file name |
| 1222 | const b64_fs_encoder = std.base64.Base64Encoder.init( | 1197 | const b64_fs_encoder = std.base64.Base64Encoder.init( |
| 1223 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", | 1198 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", |
| ... | @@ -1243,20 +1218,23 @@ pub const Compilation = struct { | ... | @@ -1243,20 +1218,23 @@ pub const Compilation = struct { |
| 1243 | } | 1218 | } |
| 1244 | 1219 | ||
| 1245 | /// Returns a value which has been ref()'d once | 1220 | /// Returns a value which has been ref()'d once |
| 1246 | async fn analyzeConstValue( | 1221 | fn analyzeConstValue( |
| 1247 | comp: *Compilation, | 1222 | comp: *Compilation, |
| 1248 | tree_scope: *Scope.AstTree, | 1223 | tree_scope: *Scope.AstTree, |
| 1249 | scope: *Scope, | 1224 | scope: *Scope, |
| 1250 | node: *ast.Node, | 1225 | node: *ast.Node, |
| 1251 | expected_type: *Type, | 1226 | expected_type: *Type, |
| 1252 | ) !*Value { | 1227 | ) !*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; | ||
| 1254 | defer analyzed_code.destroy(comp.gpa()); | 1232 | defer analyzed_code.destroy(comp.gpa()); |
| 1255 | 1233 | ||
| 1256 | return analyzed_code.getCompTimeResult(comp); | 1234 | return analyzed_code.getCompTimeResult(comp); |
| 1257 | } | 1235 | } |
| 1258 | 1236 | ||
| 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 { |
| 1260 | const meta_type = &Type.MetaType.get(comp).base; | 1238 | const meta_type = &Type.MetaType.get(comp).base; |
| 1261 | defer meta_type.base.deref(comp); | 1239 | defer meta_type.base.deref(comp); |
| 1262 | 1240 | ||
| ... | @@ -1287,7 +1265,7 @@ fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib | ... | @@ -1287,7 +1265,7 @@ fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib |
| 1287 | } | 1265 | } |
| 1288 | 1266 | ||
| 1289 | /// The function that actually does the generation. | 1267 | /// The function that actually does the generation. |
| 1290 | async fn generateDecl(comp: *Compilation, decl: *Decl) !void { | 1268 | fn generateDecl(comp: *Compilation, decl: *Decl) !void { |
| 1291 | switch (decl.id) { | 1269 | switch (decl.id) { |
| 1292 | .Var => @panic("TODO"), | 1270 | .Var => @panic("TODO"), |
| 1293 | .Fn => { | 1271 | .Fn => { |
| ... | @@ -1298,7 +1276,7 @@ async fn generateDecl(comp: *Compilation, decl: *Decl) !void { | ... | @@ -1298,7 +1276,7 @@ async fn generateDecl(comp: *Compilation, decl: *Decl) !void { |
| 1298 | } | 1276 | } |
| 1299 | } | 1277 | } |
| 1300 | 1278 | ||
| 1301 | async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { | 1279 | fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1302 | const tree_scope = fn_decl.base.tree_scope; | 1280 | const tree_scope = fn_decl.base.tree_scope; |
| 1303 | 1281 | ||
| 1304 | const body_node = fn_decl.fn_proto.body_node orelse return generateDeclFnProto(comp, fn_decl); | 1282 | 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 { | ... | @@ -1315,7 +1293,7 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1315 | 1293 | ||
| 1316 | // The Decl.Fn owns the initial 1 reference count | 1294 | // The Decl.Fn owns the initial 1 reference count |
| 1317 | const fn_val = try Value.Fn.create(comp, fn_type, fndef_scope, symbol_name); | 1295 | 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 }; |
| 1319 | symbol_name_consumed = true; | 1297 | symbol_name_consumed = true; |
| 1320 | 1298 | ||
| 1321 | // Define local parameter variables | 1299 | // Define local parameter variables |
| ... | @@ -1350,12 +1328,15 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { | ... | @@ -1350,12 +1328,15 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1350 | try fn_type.non_key.Normal.variable_list.append(var_scope); | 1328 | try fn_type.non_key.Normal.variable_list.append(var_scope); |
| 1351 | } | 1329 | } |
| 1352 | 1330 | ||
| 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( | ||
| 1354 | tree_scope, | 1334 | tree_scope, |
| 1355 | fn_val.child_scope, | 1335 | fn_val.child_scope, |
| 1356 | body_node, | 1336 | body_node, |
| 1357 | fn_type.key.data.Normal.return_type, | 1337 | fn_type.key.data.Normal.return_type, |
| 1358 | ); | 1338 | ); |
| 1339 | const analyzed_code = try await frame; | ||
| 1359 | errdefer analyzed_code.destroy(comp.gpa()); | 1340 | errdefer analyzed_code.destroy(comp.gpa()); |
| 1360 | 1341 | ||
| 1361 | assert(fn_val.block_scope != null); | 1342 | assert(fn_val.block_scope != null); |
| ... | @@ -1382,7 +1363,7 @@ fn getZigDir(allocator: *mem.Allocator) ![]u8 { | ... | @@ -1382,7 +1363,7 @@ fn getZigDir(allocator: *mem.Allocator) ![]u8 { |
| 1382 | return std.fs.getAppDataDir(allocator, "zig"); | 1363 | return std.fs.getAppDataDir(allocator, "zig"); |
| 1383 | } | 1364 | } |
| 1384 | 1365 | ||
| 1385 | async fn analyzeFnType( | 1366 | fn analyzeFnType( |
| 1386 | comp: *Compilation, | 1367 | comp: *Compilation, |
| 1387 | tree_scope: *Scope.AstTree, | 1368 | tree_scope: *Scope.AstTree, |
| 1388 | scope: *Scope, | 1369 | scope: *Scope, |
| ... | @@ -1444,7 +1425,7 @@ async fn analyzeFnType( | ... | @@ -1444,7 +1425,7 @@ async fn analyzeFnType( |
| 1444 | return fn_type; | 1425 | return fn_type; |
| 1445 | } | 1426 | } |
| 1446 | 1427 | ||
| 1447 | async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void { | 1428 | fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1448 | const fn_type = try analyzeFnType( | 1429 | const fn_type = try analyzeFnType( |
| 1449 | comp, | 1430 | comp, |
| 1450 | fn_decl.base.tree_scope, | 1431 | fn_decl.base.tree_scope, |
| ... | @@ -1459,6 +1440,6 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void { | ... | @@ -1459,6 +1440,6 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1459 | 1440 | ||
| 1460 | // The Decl.Fn owns the initial 1 reference count | 1441 | // The Decl.Fn owns the initial 1 reference count |
| 1461 | const fn_proto_val = try Value.FnProto.create(comp, fn_type, symbol_name); | 1442 | 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 }; |
| 1463 | symbol_name_consumed = true; | 1444 | symbol_name_consumed = true; |
| 1464 | } | 1445 | } |
src-self-hosted/decl.zig+3-6| ... | @@ -69,15 +69,12 @@ pub const Decl = struct { | ... | @@ -69,15 +69,12 @@ pub const Decl = struct { |
| 69 | 69 | ||
| 70 | pub const Fn = struct { | 70 | pub const Fn = struct { |
| 71 | base: Decl, | 71 | base: Decl, |
| 72 | value: Val, | 72 | value: union(enum) { |
| 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) { | ||
| 77 | Unresolved, | 73 | Unresolved, |
| 78 | Fn: *Value.Fn, | 74 | Fn: *Value.Fn, |
| 79 | FnProto: *Value.FnProto, | 75 | FnProto: *Value.FnProto, |
| 80 | }; | 76 | }, |
| 77 | fn_proto: *ast.Node.FnProto, | ||
| 81 | 78 | ||
| 82 | pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 { | 79 | pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 { |
| 83 | return if (self.fn_proto.extern_export_inline_token) |tok_index| x: { | 80 | 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 { | ... | @@ -110,7 +110,7 @@ pub const Inst = struct { |
| 110 | unreachable; | 110 | unreachable; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | pub async fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst { | 113 | pub fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst { |
| 114 | switch (base.id) { | 114 | switch (base.id) { |
| 115 | .Return => return @fieldParentPtr(Return, "base", base).analyze(ira), | 115 | .Return => return @fieldParentPtr(Return, "base", base).analyze(ira), |
| 116 | .Const => return @fieldParentPtr(Const, "base", base).analyze(ira), | 116 | .Const => return @fieldParentPtr(Const, "base", base).analyze(ira), |
| ... | @@ -422,7 +422,7 @@ pub const Inst = struct { | ... | @@ -422,7 +422,7 @@ pub const Inst = struct { |
| 422 | return false; | 422 | return false; |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | pub async fn analyze(self: *const Ref, ira: *Analyze) !*Inst { | 425 | pub fn analyze(self: *const Ref, ira: *Analyze) !*Inst { |
| 426 | const target = try self.params.target.getAsParam(); | 426 | const target = try self.params.target.getAsParam(); |
| 427 | 427 | ||
| 428 | if (ira.getCompTimeValOrNullUndefOk(target)) |val| { | 428 | if (ira.getCompTimeValOrNullUndefOk(target)) |val| { |
| ... | @@ -472,7 +472,7 @@ pub const Inst = struct { | ... | @@ -472,7 +472,7 @@ pub const Inst = struct { |
| 472 | return false; | 472 | return false; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | pub async fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst { | 475 | pub fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst { |
| 476 | (ira.irb.comp.resolveDecl(self.params.decl)) catch |err| switch (err) { | 476 | (ira.irb.comp.resolveDecl(self.params.decl)) catch |err| switch (err) { |
| 477 | error.OutOfMemory => return error.OutOfMemory, | 477 | error.OutOfMemory => return error.OutOfMemory, |
| 478 | else => return error.SemanticAnalysisFailed, | 478 | else => return error.SemanticAnalysisFailed, |
| ... | @@ -516,7 +516,7 @@ pub const Inst = struct { | ... | @@ -516,7 +516,7 @@ pub const Inst = struct { |
| 516 | return false; | 516 | return false; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | pub async fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst { | 519 | pub fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst { |
| 520 | switch (self.params.var_scope.data) { | 520 | switch (self.params.var_scope.data) { |
| 521 | .Const => @panic("TODO"), | 521 | .Const => @panic("TODO"), |
| 522 | .Param => |param| { | 522 | .Param => |param| { |
| ... | @@ -563,7 +563,7 @@ pub const Inst = struct { | ... | @@ -563,7 +563,7 @@ pub const Inst = struct { |
| 563 | return false; | 563 | return false; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | pub async fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst { | 566 | pub fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst { |
| 567 | const target = try self.params.target.getAsParam(); | 567 | const target = try self.params.target.getAsParam(); |
| 568 | const target_type = target.getKnownType(); | 568 | const target_type = target.getKnownType(); |
| 569 | if (target_type.id != .Pointer) { | 569 | if (target_type.id != .Pointer) { |
| ... | @@ -645,7 +645,7 @@ pub const Inst = struct { | ... | @@ -645,7 +645,7 @@ pub const Inst = struct { |
| 645 | return false; | 645 | return false; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | pub async fn analyze(self: *const PtrType, ira: *Analyze) !*Inst { | 648 | pub fn analyze(self: *const PtrType, ira: *Analyze) !*Inst { |
| 649 | const child_type = try self.params.child_type.getAsConstType(ira); | 649 | const child_type = try self.params.child_type.getAsConstType(ira); |
| 650 | // if (child_type->id == TypeTableEntryIdUnreachable) { | 650 | // if (child_type->id == TypeTableEntryIdUnreachable) { |
| 651 | // ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); | 651 | // ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); |
| ... | @@ -658,7 +658,7 @@ pub const Inst = struct { | ... | @@ -658,7 +658,7 @@ pub const Inst = struct { |
| 658 | const amt = try align_inst.getAsConstAlign(ira); | 658 | const amt = try align_inst.getAsConstAlign(ira); |
| 659 | break :blk Type.Pointer.Align{ .Override = amt }; | 659 | break :blk Type.Pointer.Align{ .Override = amt }; |
| 660 | } else blk: { | 660 | } else blk: { |
| 661 | break :blk Type.Pointer.Align{ .Abi = {} }; | 661 | break :blk .Abi; |
| 662 | }; | 662 | }; |
| 663 | const ptr_type = try Type.Pointer.get(ira.irb.comp, Type.Pointer.Key{ | 663 | const ptr_type = try Type.Pointer.get(ira.irb.comp, Type.Pointer.Key{ |
| 664 | .child_type = child_type, | 664 | .child_type = child_type, |
| ... | @@ -927,7 +927,7 @@ pub const Variable = struct { | ... | @@ -927,7 +927,7 @@ pub const Variable = struct { |
| 927 | 927 | ||
| 928 | pub const BasicBlock = struct { | 928 | pub const BasicBlock = struct { |
| 929 | ref_count: usize, | 929 | ref_count: usize, |
| 930 | name_hint: [*]const u8, // must be a C string literal | 930 | name_hint: [*:0]const u8, |
| 931 | debug_id: usize, | 931 | debug_id: usize, |
| 932 | scope: *Scope, | 932 | scope: *Scope, |
| 933 | instruction_list: std.ArrayList(*Inst), | 933 | instruction_list: std.ArrayList(*Inst), |
| ... | @@ -1051,7 +1051,7 @@ pub const Builder = struct { | ... | @@ -1051,7 +1051,7 @@ pub const Builder = struct { |
| 1051 | } | 1051 | } |
| 1052 | 1052 | ||
| 1053 | /// No need to clean up resources thanks to the arena allocator. | 1053 | /// 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 { |
| 1055 | const basic_block = try self.arena().create(BasicBlock); | 1055 | const basic_block = try self.arena().create(BasicBlock); |
| 1056 | basic_block.* = BasicBlock{ | 1056 | basic_block.* = BasicBlock{ |
| 1057 | .ref_count = 0, | 1057 | .ref_count = 0, |
| ... | @@ -1078,6 +1078,14 @@ pub const Builder = struct { | ... | @@ -1078,6 +1078,14 @@ pub const Builder = struct { |
| 1078 | self.current_basic_block = basic_block; | 1078 | self.current_basic_block = basic_block; |
| 1079 | } | 1079 | } |
| 1080 | 1080 | ||
| 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 | |||
| 1081 | pub async fn genNode(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst { | 1089 | pub async fn genNode(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst { |
| 1082 | switch (node.id) { | 1090 | switch (node.id) { |
| 1083 | .Root => unreachable, | 1091 | .Root => unreachable, |
| ... | @@ -1157,7 +1165,7 @@ pub const Builder = struct { | ... | @@ -1157,7 +1165,7 @@ pub const Builder = struct { |
| 1157 | }, | 1165 | }, |
| 1158 | .GroupedExpression => { | 1166 | .GroupedExpression => { |
| 1159 | const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", node); | 1167 | 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); |
| 1161 | }, | 1169 | }, |
| 1162 | .BuiltinCall => return error.Unimplemented, | 1170 | .BuiltinCall => return error.Unimplemented, |
| 1163 | .ErrorSetDecl => return error.Unimplemented, | 1171 | .ErrorSetDecl => return error.Unimplemented, |
| ... | @@ -1186,14 +1194,14 @@ pub const Builder = struct { | ... | @@ -1186,14 +1194,14 @@ pub const Builder = struct { |
| 1186 | } | 1194 | } |
| 1187 | } | 1195 | } |
| 1188 | 1196 | ||
| 1189 | async fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst { | 1197 | 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); | 1198 | const fn_ref = try irb.genNodeRecursive(suffix_op.lhs.node, scope, .None); |
| 1191 | 1199 | ||
| 1192 | const args = try irb.arena().alloc(*Inst, call.params.len); | 1200 | const args = try irb.arena().alloc(*Inst, call.params.len); |
| 1193 | var it = call.params.iterator(0); | 1201 | var it = call.params.iterator(0); |
| 1194 | var i: usize = 0; | 1202 | var i: usize = 0; |
| 1195 | while (it.next()) |arg_node_ptr| : (i += 1) { | 1203 | 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); |
| 1197 | } | 1205 | } |
| 1198 | 1206 | ||
| 1199 | //bool is_async = node->data.fn_call_expr.is_async; | 1207 | //bool is_async = node->data.fn_call_expr.is_async; |
| ... | @@ -1214,7 +1222,7 @@ pub const Builder = struct { | ... | @@ -1214,7 +1222,7 @@ pub const Builder = struct { |
| 1214 | //return ir_lval_wrap(irb, scope, fn_call, lval); | 1222 | //return ir_lval_wrap(irb, scope, fn_call, lval); |
| 1215 | } | 1223 | } |
| 1216 | 1224 | ||
| 1217 | async fn genPtrType( | 1225 | fn genPtrType( |
| 1218 | irb: *Builder, | 1226 | irb: *Builder, |
| 1219 | prefix_op: *ast.Node.PrefixOp, | 1227 | prefix_op: *ast.Node.PrefixOp, |
| 1220 | ptr_info: ast.Node.PrefixOp.PtrInfo, | 1228 | ptr_info: ast.Node.PrefixOp.PtrInfo, |
| ... | @@ -1238,7 +1246,7 @@ pub const Builder = struct { | ... | @@ -1238,7 +1246,7 @@ pub const Builder = struct { |
| 1238 | //} else { | 1246 | //} else { |
| 1239 | // align_value = nullptr; | 1247 | // align_value = nullptr; |
| 1240 | //} | 1248 | //} |
| 1241 | const child_type = try irb.genNode(prefix_op.rhs, scope, .None); | 1249 | const child_type = try irb.genNodeRecursive(prefix_op.rhs, scope, .None); |
| 1242 | 1250 | ||
| 1243 | //uint32_t bit_offset_start = 0; | 1251 | //uint32_t bit_offset_start = 0; |
| 1244 | //if (node->data.pointer_type.bit_offset_start != nullptr) { | 1252 | //if (node->data.pointer_type.bit_offset_start != nullptr) { |
| ... | @@ -1307,9 +1315,9 @@ pub const Builder = struct { | ... | @@ -1307,9 +1315,9 @@ pub const Builder = struct { |
| 1307 | var rest: []const u8 = undefined; | 1315 | var rest: []const u8 = undefined; |
| 1308 | if (int_token.len >= 3 and int_token[0] == '0') { | 1316 | if (int_token.len >= 3 and int_token[0] == '0') { |
| 1309 | base = switch (int_token[1]) { | 1317 | base = switch (int_token[1]) { |
| 1310 | 'b' => u8(2), | 1318 | 'b' => 2, |
| 1311 | 'o' => u8(8), | 1319 | 'o' => 8, |
| 1312 | 'x' => u8(16), | 1320 | 'x' => 16, |
| 1313 | else => unreachable, | 1321 | else => unreachable, |
| 1314 | }; | 1322 | }; |
| 1315 | rest = int_token[2..]; | 1323 | rest = int_token[2..]; |
| ... | @@ -1339,7 +1347,7 @@ pub const Builder = struct { | ... | @@ -1339,7 +1347,7 @@ pub const Builder = struct { |
| 1339 | return inst; | 1347 | return inst; |
| 1340 | } | 1348 | } |
| 1341 | 1349 | ||
| 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 { |
| 1343 | const str_token = irb.code.tree_scope.tree.tokenSlice(str_lit.token); | 1351 | const str_token = irb.code.tree_scope.tree.tokenSlice(str_lit.token); |
| 1344 | const src_span = Span.token(str_lit.token); | 1352 | const src_span = Span.token(str_lit.token); |
| 1345 | 1353 | ||
| ... | @@ -1389,7 +1397,7 @@ pub const Builder = struct { | ... | @@ -1389,7 +1397,7 @@ pub const Builder = struct { |
| 1389 | } | 1397 | } |
| 1390 | } | 1398 | } |
| 1391 | 1399 | ||
| 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 { |
| 1393 | const block_scope = try Scope.Block.create(irb.comp, parent_scope); | 1401 | const block_scope = try Scope.Block.create(irb.comp, parent_scope); |
| 1394 | 1402 | ||
| 1395 | const outer_block_scope = &block_scope.base; | 1403 | const outer_block_scope = &block_scope.base; |
| ... | @@ -1437,7 +1445,7 @@ pub const Builder = struct { | ... | @@ -1437,7 +1445,7 @@ pub const Builder = struct { |
| 1437 | child_scope = &defer_child_scope.base; | 1445 | child_scope = &defer_child_scope.base; |
| 1438 | continue; | 1446 | continue; |
| 1439 | } | 1447 | } |
| 1440 | const statement_value = try irb.genNode(statement_node, child_scope, .None); | 1448 | const statement_value = try irb.genNodeRecursive(statement_node, child_scope, .None); |
| 1441 | 1449 | ||
| 1442 | is_continuation_unreachable = statement_value.isNoReturn(); | 1450 | is_continuation_unreachable = statement_value.isNoReturn(); |
| 1443 | if (is_continuation_unreachable) { | 1451 | if (is_continuation_unreachable) { |
| ... | @@ -1499,7 +1507,7 @@ pub const Builder = struct { | ... | @@ -1499,7 +1507,7 @@ pub const Builder = struct { |
| 1499 | return irb.buildConstVoid(child_scope, Span.token(block.rbrace), true); | 1507 | return irb.buildConstVoid(child_scope, Span.token(block.rbrace), true); |
| 1500 | } | 1508 | } |
| 1501 | 1509 | ||
| 1502 | pub async fn genControlFlowExpr( | 1510 | pub fn genControlFlowExpr( |
| 1503 | irb: *Builder, | 1511 | irb: *Builder, |
| 1504 | control_flow_expr: *ast.Node.ControlFlowExpression, | 1512 | control_flow_expr: *ast.Node.ControlFlowExpression, |
| 1505 | scope: *Scope, | 1513 | scope: *Scope, |
| ... | @@ -1533,7 +1541,7 @@ pub const Builder = struct { | ... | @@ -1533,7 +1541,7 @@ pub const Builder = struct { |
| 1533 | 1541 | ||
| 1534 | const outer_scope = irb.begin_scope.?; | 1542 | const outer_scope = irb.begin_scope.?; |
| 1535 | const return_value = if (control_flow_expr.rhs) |rhs| blk: { | 1543 | 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); |
| 1537 | } else blk: { | 1545 | } else blk: { |
| 1538 | break :blk try irb.buildConstVoid(scope, src_span, true); | 1546 | break :blk try irb.buildConstVoid(scope, src_span, true); |
| 1539 | }; | 1547 | }; |
| ... | @@ -1596,7 +1604,7 @@ pub const Builder = struct { | ... | @@ -1596,7 +1604,7 @@ pub const Builder = struct { |
| 1596 | } | 1604 | } |
| 1597 | } | 1605 | } |
| 1598 | 1606 | ||
| 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 { |
| 1600 | const src_span = Span.token(identifier.token); | 1608 | const src_span = Span.token(identifier.token); |
| 1601 | const name = irb.code.tree_scope.tree.tokenSlice(identifier.token); | 1609 | const name = irb.code.tree_scope.tree.tokenSlice(identifier.token); |
| 1602 | 1610 | ||
| ... | @@ -1694,7 +1702,7 @@ pub const Builder = struct { | ... | @@ -1694,7 +1702,7 @@ pub const Builder = struct { |
| 1694 | return result; | 1702 | return result; |
| 1695 | } | 1703 | } |
| 1696 | 1704 | ||
| 1697 | async fn genDefersForBlock( | 1705 | fn genDefersForBlock( |
| 1698 | irb: *Builder, | 1706 | irb: *Builder, |
| 1699 | inner_scope: *Scope, | 1707 | inner_scope: *Scope, |
| 1700 | outer_scope: *Scope, | 1708 | outer_scope: *Scope, |
| ... | @@ -1712,7 +1720,7 @@ pub const Builder = struct { | ... | @@ -1712,7 +1720,7 @@ pub const Builder = struct { |
| 1712 | }; | 1720 | }; |
| 1713 | if (generate) { | 1721 | if (generate) { |
| 1714 | const defer_expr_scope = defer_scope.defer_expr_scope; | 1722 | const defer_expr_scope = defer_scope.defer_expr_scope; |
| 1715 | const instruction = try irb.genNode( | 1723 | const instruction = try irb.genNodeRecursive( |
| 1716 | defer_expr_scope.expr_node, | 1724 | defer_expr_scope.expr_node, |
| 1717 | &defer_expr_scope.base, | 1725 | &defer_expr_scope.base, |
| 1718 | .None, | 1726 | .None, |
| ... | @@ -1797,7 +1805,7 @@ pub const Builder = struct { | ... | @@ -1797,7 +1805,7 @@ pub const Builder = struct { |
| 1797 | // Look at the params and ref() other instructions | 1805 | // Look at the params and ref() other instructions |
| 1798 | comptime var i = 0; | 1806 | comptime var i = 0; |
| 1799 | inline while (i < @memberCount(I.Params)) : (i += 1) { | 1807 | 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))); |
| 1801 | switch (FieldType) { | 1809 | switch (FieldType) { |
| 1802 | *Inst => @field(inst.params, @memberName(I.Params, i)).ref(self), | 1810 | *Inst => @field(inst.params, @memberName(I.Params, i)).ref(self), |
| 1803 | *BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self), | 1811 | *BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self), |
| ... | @@ -1909,7 +1917,7 @@ pub const Builder = struct { | ... | @@ -1909,7 +1917,7 @@ pub const Builder = struct { |
| 1909 | VarScope: *Scope.Var, | 1917 | VarScope: *Scope.Var, |
| 1910 | }; | 1918 | }; |
| 1911 | 1919 | ||
| 1912 | async fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident { | 1920 | fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident { |
| 1913 | var s = scope; | 1921 | var s = scope; |
| 1914 | while (true) { | 1922 | while (true) { |
| 1915 | switch (s.id) { | 1923 | switch (s.id) { |
| ... | @@ -2519,7 +2527,7 @@ const Analyze = struct { | ... | @@ -2519,7 +2527,7 @@ const Analyze = struct { |
| 2519 | } | 2527 | } |
| 2520 | }; | 2528 | }; |
| 2521 | 2529 | ||
| 2522 | pub async fn gen( | 2530 | pub fn gen( |
| 2523 | comp: *Compilation, | 2531 | comp: *Compilation, |
| 2524 | body_node: *ast.Node, | 2532 | body_node: *ast.Node, |
| 2525 | tree_scope: *Scope.AstTree, | 2533 | tree_scope: *Scope.AstTree, |
| ... | @@ -2541,7 +2549,7 @@ pub async fn gen( | ... | @@ -2541,7 +2549,7 @@ pub async fn gen( |
| 2541 | return irb.finish(); | 2549 | return irb.finish(); |
| 2542 | } | 2550 | } |
| 2543 | 2551 | ||
| 2544 | pub async fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code { | 2552 | pub fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code { |
| 2545 | const old_entry_bb = old_code.basic_block_list.at(0); | 2553 | const old_entry_bb = old_code.basic_block_list.at(0); |
| 2546 | 2554 | ||
| 2547 | var ira = try Analyze.init(comp, old_code.tree_scope, expected_type); | 2555 | 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 { | ... | @@ -143,7 +143,7 @@ pub const LibCInstallation = struct { |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | /// Finds the default, native libc. | 145 | /// Finds the default, native libc. |
| 146 | pub async fn findNative(self: *LibCInstallation, allocator: *Allocator) !void { | 146 | pub fn findNative(self: *LibCInstallation, allocator: *Allocator) !void { |
| 147 | self.initEmpty(); | 147 | self.initEmpty(); |
| 148 | var group = event.Group(FindError!void).init(allocator); | 148 | var group = event.Group(FindError!void).init(allocator); |
| 149 | errdefer group.wait() catch {}; | 149 | errdefer group.wait() catch {}; |
| ... | @@ -393,14 +393,14 @@ pub const LibCInstallation = struct { | ... | @@ -393,14 +393,14 @@ pub const LibCInstallation = struct { |
| 393 | }; | 393 | }; |
| 394 | 394 | ||
| 395 | /// caller owns returned memory | 395 | /// caller owns returned memory |
| 396 | async fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 { | 396 | fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 { |
| 397 | const cc_exe = std.os.getenv("CC") orelse "cc"; | 397 | const cc_exe = std.os.getenv("CC") orelse "cc"; |
| 398 | const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", o_file); | 398 | const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", o_file); |
| 399 | defer allocator.free(arg1); | 399 | defer allocator.free(arg1); |
| 400 | const argv = [_][]const u8{ cc_exe, arg1 }; | 400 | const argv = [_][]const u8{ cc_exe, arg1 }; |
| 401 | 401 | ||
| 402 | // TODO This simulates evented I/O for the child process exec | 402 | // TODO This simulates evented I/O for the child process exec |
| 403 | std.event.Loop.instance.?.yield(); | 403 | event.Loop.startCpuBoundOperation(); |
| 404 | const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); | 404 | const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); |
| 405 | const exec_result = if (std.debug.runtime_safety) blk: { | 405 | const exec_result = if (std.debug.runtime_safety) blk: { |
| 406 | break :blk errorable_result catch unreachable; | 406 | break :blk errorable_result catch unreachable; |
src-self-hosted/link.zig+33-35| ... | @@ -11,7 +11,7 @@ const util = @import("util.zig"); | ... | @@ -11,7 +11,7 @@ const util = @import("util.zig"); |
| 11 | const Context = struct { | 11 | const Context = struct { |
| 12 | comp: *Compilation, | 12 | comp: *Compilation, |
| 13 | arena: std.heap.ArenaAllocator, | 13 | arena: std.heap.ArenaAllocator, |
| 14 | args: std.ArrayList([*]const u8), | 14 | args: std.ArrayList([*:0]const u8), |
| 15 | link_in_crt: bool, | 15 | link_in_crt: bool, |
| 16 | 16 | ||
| 17 | link_err: error{OutOfMemory}!void, | 17 | link_err: error{OutOfMemory}!void, |
| ... | @@ -21,7 +21,7 @@ const Context = struct { | ... | @@ -21,7 +21,7 @@ const Context = struct { |
| 21 | out_file_path: std.Buffer, | 21 | out_file_path: std.Buffer, |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | pub async fn link(comp: *Compilation) !void { | 24 | pub fn link(comp: *Compilation) !void { |
| 25 | var ctx = Context{ | 25 | var ctx = Context{ |
| 26 | .comp = comp, | 26 | .comp = comp, |
| 27 | .arena = std.heap.ArenaAllocator.init(comp.gpa()), | 27 | .arena = std.heap.ArenaAllocator.init(comp.gpa()), |
| ... | @@ -33,7 +33,7 @@ pub async fn link(comp: *Compilation) !void { | ... | @@ -33,7 +33,7 @@ pub async fn link(comp: *Compilation) !void { |
| 33 | .out_file_path = undefined, | 33 | .out_file_path = undefined, |
| 34 | }; | 34 | }; |
| 35 | defer ctx.arena.deinit(); | 35 | 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); |
| 37 | ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator); | 37 | ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator); |
| 38 | 38 | ||
| 39 | if (comp.link_out_file) |out_file| { | 39 | if (comp.link_out_file) |out_file| { |
| ... | @@ -58,7 +58,8 @@ pub async fn link(comp: *Compilation) !void { | ... | @@ -58,7 +58,8 @@ pub async fn link(comp: *Compilation) !void { |
| 58 | try ctx.args.append("lld"); | 58 | try ctx.args.append("lld"); |
| 59 | 59 | ||
| 60 | if (comp.haveLibC()) { | 60 | 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: { | ||
| 62 | switch (comp.target) { | 63 | switch (comp.target) { |
| 63 | Target.Native => { | 64 | Target.Native => { |
| 64 | break :blk comp.zig_compiler.getNativeLibC() catch return error.LibCRequiredButNotProvidedOrFound; | 65 | break :blk comp.zig_compiler.getNativeLibC() catch return error.LibCRequiredButNotProvidedOrFound; |
| ... | @@ -66,6 +67,7 @@ pub async fn link(comp: *Compilation) !void { | ... | @@ -66,6 +67,7 @@ pub async fn link(comp: *Compilation) !void { |
| 66 | else => return error.LibCRequiredButNotProvidedOrFound, | 67 | else => return error.LibCRequiredButNotProvidedOrFound, |
| 67 | } | 68 | } |
| 68 | }; | 69 | }; |
| 70 | ctx.libc = libc; | ||
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | try constructLinkerArgs(&ctx); | 73 | try constructLinkerArgs(&ctx); |
| ... | @@ -171,7 +173,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { | ... | @@ -171,7 +173,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { |
| 171 | //} | 173 | //} |
| 172 | 174 | ||
| 173 | try ctx.args.append("-o"); | 175 | 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()); |
| 175 | 177 | ||
| 176 | if (ctx.link_in_crt) { | 178 | if (ctx.link_in_crt) { |
| 177 | const crt1o = if (ctx.comp.is_static) "crt1.o" else "Scrt1.o"; | 179 | const crt1o = if (ctx.comp.is_static) "crt1.o" else "Scrt1.o"; |
| ... | @@ -214,10 +216,11 @@ fn constructLinkerArgsElf(ctx: *Context) !void { | ... | @@ -214,10 +216,11 @@ fn constructLinkerArgsElf(ctx: *Context) !void { |
| 214 | 216 | ||
| 215 | if (ctx.comp.haveLibC()) { | 217 | if (ctx.comp.haveLibC()) { |
| 216 | try ctx.args.append("-L"); | 218 | 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)); | ||
| 218 | 221 | ||
| 219 | try ctx.args.append("-L"); | 222 | 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)); |
| 221 | 224 | ||
| 222 | if (!ctx.comp.is_static) { | 225 | if (!ctx.comp.is_static) { |
| 223 | const dl = blk: { | 226 | const dl = blk: { |
| ... | @@ -226,7 +229,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { | ... | @@ -226,7 +229,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { |
| 226 | return error.LibCMissingDynamicLinker; | 229 | return error.LibCMissingDynamicLinker; |
| 227 | }; | 230 | }; |
| 228 | try ctx.args.append("-dynamic-linker"); | 231 | 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)); |
| 230 | } | 233 | } |
| 231 | } | 234 | } |
| 232 | 235 | ||
| ... | @@ -238,7 +241,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { | ... | @@ -238,7 +241,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { |
| 238 | // .o files | 241 | // .o files |
| 239 | for (ctx.comp.link_objects) |link_object| { | 242 | for (ctx.comp.link_objects) |link_object| { |
| 240 | const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object); | 243 | 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)); |
| 242 | } | 245 | } |
| 243 | try addFnObjects(ctx); | 246 | try addFnObjects(ctx); |
| 244 | 247 | ||
| ... | @@ -313,7 +316,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { | ... | @@ -313,7 +316,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { |
| 313 | fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void { | 316 | fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void { |
| 314 | const full_path = try std.fs.path.join(&ctx.arena.allocator, [_][]const u8{ dirname, basename }); | 317 | const full_path = try std.fs.path.join(&ctx.arena.allocator, [_][]const u8{ dirname, basename }); |
| 315 | const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path); | 318 | 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)); |
| 317 | } | 320 | } |
| 318 | 321 | ||
| 319 | fn constructLinkerArgsCoff(ctx: *Context) !void { | 322 | fn constructLinkerArgsCoff(ctx: *Context) !void { |
| ... | @@ -339,12 +342,12 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { | ... | @@ -339,12 +342,12 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { |
| 339 | const is_library = ctx.comp.kind == .Lib; | 342 | const is_library = ctx.comp.kind == .Lib; |
| 340 | 343 | ||
| 341 | const out_arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-OUT:{}\x00", ctx.out_file_path.toSliceConst()); | 344 | 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)); |
| 343 | 346 | ||
| 344 | if (ctx.comp.haveLibC()) { | 347 | if (ctx.comp.haveLibC()) { |
| 345 | try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_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)); |
| 346 | try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_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)); |
| 347 | try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.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)); |
| 348 | } | 351 | } |
| 349 | 352 | ||
| 350 | if (ctx.link_in_crt) { | 353 | if (ctx.link_in_crt) { |
| ... | @@ -353,17 +356,17 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { | ... | @@ -353,17 +356,17 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { |
| 353 | 356 | ||
| 354 | if (ctx.comp.is_static) { | 357 | if (ctx.comp.is_static) { |
| 355 | const cmt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "libcmt{}.lib\x00", d_str); | 358 | 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)); |
| 357 | } else { | 360 | } else { |
| 358 | const msvcrt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "msvcrt{}.lib\x00", d_str); | 361 | 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)); |
| 360 | } | 363 | } |
| 361 | 364 | ||
| 362 | const vcruntime_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}vcruntime{}.lib\x00", lib_str, d_str); | 365 | 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)); |
| 364 | 367 | ||
| 365 | const crt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}ucrt{}.lib\x00", lib_str, d_str); | 368 | 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)); |
| 367 | 370 | ||
| 368 | // Visual C++ 2015 Conformance Changes | 371 | // Visual C++ 2015 Conformance Changes |
| 369 | // https://msdn.microsoft.com/en-us/library/bb531344.aspx | 372 | // https://msdn.microsoft.com/en-us/library/bb531344.aspx |
| ... | @@ -395,7 +398,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { | ... | @@ -395,7 +398,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { |
| 395 | 398 | ||
| 396 | for (ctx.comp.link_objects) |link_object| { | 399 | for (ctx.comp.link_objects) |link_object| { |
| 397 | const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object); | 400 | 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)); |
| 399 | } | 402 | } |
| 400 | try addFnObjects(ctx); | 403 | try addFnObjects(ctx); |
| 401 | 404 | ||
| ... | @@ -504,11 +507,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { | ... | @@ -504,11 +507,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { |
| 504 | //} | 507 | //} |
| 505 | 508 | ||
| 506 | try ctx.args.append("-arch"); | 509 | try ctx.args.append("-arch"); |
| 507 | const darwin_arch_str = try std.cstr.addNullByte( | 510 | try ctx.args.append(util.getDarwinArchString(ctx.comp.target)); |
| 508 | &ctx.arena.allocator, | ||
| 509 | ctx.comp.target.getDarwinArchString(), | ||
| 510 | ); | ||
| 511 | try ctx.args.append(darwin_arch_str.ptr); | ||
| 512 | 511 | ||
| 513 | const platform = try DarwinPlatform.get(ctx.comp); | 512 | const platform = try DarwinPlatform.get(ctx.comp); |
| 514 | switch (platform.kind) { | 513 | switch (platform.kind) { |
| ... | @@ -517,7 +516,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { | ... | @@ -517,7 +516,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { |
| 517 | .IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"), | 516 | .IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"), |
| 518 | } | 517 | } |
| 519 | const ver_str = try std.fmt.allocPrint(&ctx.arena.allocator, "{}.{}.{}\x00", platform.major, platform.minor, platform.micro); | 518 | 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)); |
| 521 | 520 | ||
| 522 | if (ctx.comp.kind == .Exe) { | 521 | if (ctx.comp.kind == .Exe) { |
| 523 | if (ctx.comp.is_static) { | 522 | if (ctx.comp.is_static) { |
| ... | @@ -528,7 +527,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { | ... | @@ -528,7 +527,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { |
| 528 | } | 527 | } |
| 529 | 528 | ||
| 530 | try ctx.args.append("-o"); | 529 | 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()); |
| 532 | 531 | ||
| 533 | //for (size_t i = 0; i < g->rpath_list.length; i += 1) { | 532 | //for (size_t i = 0; i < g->rpath_list.length; i += 1) { |
| 534 | // Buf *rpath = g->rpath_list.at(i); | 533 | // Buf *rpath = g->rpath_list.at(i); |
| ... | @@ -572,7 +571,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { | ... | @@ -572,7 +571,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { |
| 572 | 571 | ||
| 573 | for (ctx.comp.link_objects) |link_object| { | 572 | for (ctx.comp.link_objects) |link_object| { |
| 574 | const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object); | 573 | 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)); |
| 576 | } | 575 | } |
| 577 | try addFnObjects(ctx); | 576 | try addFnObjects(ctx); |
| 578 | 577 | ||
| ... | @@ -593,10 +592,10 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { | ... | @@ -593,10 +592,10 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { |
| 593 | } else { | 592 | } else { |
| 594 | if (mem.indexOfScalar(u8, lib.name, '/') == null) { | 593 | if (mem.indexOfScalar(u8, lib.name, '/') == null) { |
| 595 | const arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-l{}\x00", lib.name); | 594 | 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)); |
| 597 | } else { | 596 | } else { |
| 598 | const arg = try std.cstr.addNullByte(&ctx.arena.allocator, lib.name); | 597 | 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)); |
| 600 | } | 599 | } |
| 601 | } | 600 | } |
| 602 | } | 601 | } |
| ... | @@ -626,20 +625,19 @@ fn constructLinkerArgsWasm(ctx: *Context) void { | ... | @@ -626,20 +625,19 @@ fn constructLinkerArgsWasm(ctx: *Context) void { |
| 626 | } | 625 | } |
| 627 | 626 | ||
| 628 | fn addFnObjects(ctx: *Context) !void { | 627 | fn addFnObjects(ctx: *Context) !void { |
| 629 | // at this point it's guaranteed nobody else has this lock, so we circumvent it | 628 | const held = ctx.comp.fn_link_set.acquire(); |
| 630 | // and avoid having to be an async function | 629 | defer held.release(); |
| 631 | const fn_link_set = &ctx.comp.fn_link_set.private_data; | ||
| 632 | 630 | ||
| 633 | var it = fn_link_set.first; | 631 | var it = held.value.first; |
| 634 | while (it) |node| { | 632 | while (it) |node| { |
| 635 | const fn_val = node.data orelse { | 633 | const fn_val = node.data orelse { |
| 636 | // handle the tombstone. See Value.Fn.destroy. | 634 | // handle the tombstone. See Value.Fn.destroy. |
| 637 | it = node.next; | 635 | it = node.next; |
| 638 | fn_link_set.remove(node); | 636 | held.value.remove(node); |
| 639 | ctx.comp.gpa().destroy(node); | 637 | ctx.comp.gpa().destroy(node); |
| 640 | continue; | 638 | continue; |
| 641 | }; | 639 | }; |
| 642 | try ctx.args.append(fn_val.containing_object.ptr()); | 640 | try ctx.args.append(fn_val.containing_object.toSliceConst()); |
| 643 | it = node.next; | 641 | it = node.next; |
| 644 | } | 642 | } |
| 645 | } | 643 | } |
src-self-hosted/llvm.zig+1-1| ... | @@ -86,7 +86,7 @@ pub const AddGlobal = LLVMAddGlobal; | ... | @@ -86,7 +86,7 @@ pub const AddGlobal = LLVMAddGlobal; |
| 86 | extern fn LLVMAddGlobal(M: *Module, Ty: *Type, Name: [*:0]const u8) ?*Value; | 86 | extern fn LLVMAddGlobal(M: *Module, Ty: *Type, Name: [*:0]const u8) ?*Value; |
| 87 | 87 | ||
| 88 | pub const ConstStringInContext = LLVMConstStringInContext; | 88 | pub const ConstStringInContext = LLVMConstStringInContext; |
| 89 | extern fn LLVMConstStringInContext(C: *Context, Str: [*:0]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value; | 89 | extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value; |
| 90 | 90 | ||
| 91 | pub const ConstInt = LLVMConstInt; | 91 | pub const ConstInt = LLVMConstInt; |
| 92 | extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) ?*Value; | 92 | extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) ?*Value; |
src-self-hosted/main.zig+64-73| ... | @@ -49,14 +49,15 @@ const usage = | ... | @@ -49,14 +49,15 @@ const usage = |
| 49 | 49 | ||
| 50 | const Command = struct { | 50 | const Command = struct { |
| 51 | name: []const u8, | 51 | name: []const u8, |
| 52 | exec: fn (*Allocator, []const []const u8) anyerror!void, | 52 | exec: async fn (*Allocator, []const []const u8) anyerror!void, |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | pub fn main() !void { | 55 | pub fn main() !void { |
| 56 | // This allocator needs to be thread-safe because we use it for the event.Loop | 56 | // This allocator needs to be thread-safe because we use it for the event.Loop |
| 57 | // which multiplexes async functions onto kernel threads. | 57 | // which multiplexes async functions onto kernel threads. |
| 58 | // libc allocator is guaranteed to have this property. | 58 | // 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; | ||
| 60 | 61 | ||
| 61 | stdout = &std.io.getStdOut().outStream().stream; | 62 | stdout = &std.io.getStdOut().outStream().stream; |
| 62 | 63 | ||
| ... | @@ -118,14 +119,18 @@ pub fn main() !void { | ... | @@ -118,14 +119,18 @@ pub fn main() !void { |
| 118 | }, | 119 | }, |
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 121 | for (commands) |command| { | 122 | inline for (commands) |command| { |
| 122 | if (mem.eql(u8, command.name, args[1])) { | 123 | 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; | ||
| 124 | } | 128 | } |
| 125 | } | 129 | } |
| 126 | 130 | ||
| 127 | try stderr.print("unknown command: {}\n\n", args[1]); | 131 | try stderr.print("unknown command: {}\n\n", args[1]); |
| 128 | try stderr.write(usage); | 132 | try stderr.write(usage); |
| 133 | process.argsFree(allocator, args); | ||
| 129 | process.exit(1); | 134 | process.exit(1); |
| 130 | } | 135 | } |
| 131 | 136 | ||
| ... | @@ -461,13 +466,12 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co | ... | @@ -461,13 +466,12 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co |
| 461 | comp.link_objects = link_objects; | 466 | comp.link_objects = link_objects; |
| 462 | 467 | ||
| 463 | comp.start(); | 468 | comp.start(); |
| 464 | const frame = async processBuildEvents(comp, color); | 469 | processBuildEvents(comp, color); |
| 465 | } | 470 | } |
| 466 | 471 | ||
| 467 | async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void { | 472 | fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void { |
| 468 | var count: usize = 0; | 473 | var count: usize = 0; |
| 469 | while (true) { | 474 | while (!comp.cancelled) { |
| 470 | // TODO directly awaiting async should guarantee memory allocation elision | ||
| 471 | const build_event = comp.events.get(); | 475 | const build_event = comp.events.get(); |
| 472 | count += 1; | 476 | count += 1; |
| 473 | 477 | ||
| ... | @@ -545,7 +549,7 @@ fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_fil | ... | @@ -545,7 +549,7 @@ fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_fil |
| 545 | "Try running `zig libc` to see an example for the native target.\n", | 549 | "Try running `zig libc` to see an example for the native target.\n", |
| 546 | libc_paths_file, | 550 | libc_paths_file, |
| 547 | @errorName(err), | 551 | @errorName(err), |
| 548 | ) catch process.exit(1); | 552 | ) catch {}; |
| 549 | process.exit(1); | 553 | process.exit(1); |
| 550 | }; | 554 | }; |
| 551 | } | 555 | } |
| ... | @@ -567,12 +571,8 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -567,12 +571,8 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void { |
| 567 | var zig_compiler = try ZigCompiler.init(allocator); | 571 | var zig_compiler = try ZigCompiler.init(allocator); |
| 568 | defer zig_compiler.deinit(); | 572 | defer zig_compiler.deinit(); |
| 569 | 573 | ||
| 570 | const frame = async findLibCAsync(&zig_compiler); | ||
| 571 | } | ||
| 572 | |||
| 573 | async fn findLibCAsync(zig_compiler: *ZigCompiler) void { | ||
| 574 | const libc = zig_compiler.getNativeLibC() catch |err| { | 574 | 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 {}; |
| 576 | process.exit(1); | 576 | process.exit(1); |
| 577 | }; | 577 | }; |
| 578 | libc.render(stdout) catch process.exit(1); | 578 | libc.render(stdout) catch process.exit(1); |
| ... | @@ -644,11 +644,23 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -644,11 +644,23 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 644 | process.exit(1); | 644 | process.exit(1); |
| 645 | } | 645 | } |
| 646 | 646 | ||
| 647 | return asyncFmtMain( | 647 | var fmt = Fmt{ |
| 648 | allocator, | 648 | .allocator = allocator, |
| 649 | &flags, | 649 | .seen = event.Locked(Fmt.SeenMap).init(Fmt.SeenMap.init(allocator)), |
| 650 | color, | 650 | .any_error = false, |
| 651 | ); | 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 | } | ||
| 652 | } | 664 | } |
| 653 | 665 | ||
| 654 | const FmtError = error{ | 666 | const FmtError = error{ |
| ... | @@ -673,30 +685,6 @@ const FmtError = error{ | ... | @@ -673,30 +685,6 @@ const FmtError = error{ |
| 673 | CurrentWorkingDirectoryUnlinked, | 685 | CurrentWorkingDirectoryUnlinked, |
| 674 | } || fs.File.OpenError; | 686 | } || fs.File.OpenError; |
| 675 | 687 | ||
| 676 | async 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 | |||
| 700 | async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void { | 688 | async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void { |
| 701 | const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref); | 689 | const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref); |
| 702 | defer fmt.allocator.free(file_path); | 690 | defer fmt.allocator.free(file_path); |
| ... | @@ -708,33 +696,34 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro | ... | @@ -708,33 +696,34 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro |
| 708 | if (try held.value.put(file_path, {})) |_| return; | 696 | if (try held.value.put(file_path, {})) |_| return; |
| 709 | } | 697 | } |
| 710 | 698 | ||
| 711 | const source_code = ""; | 699 | const source_code = event.fs.readFile( |
| 712 | // const source_code = event.fs.readFile( | 700 | fmt.allocator, |
| 713 | // file_path, | 701 | file_path, |
| 714 | // max_src_size, | 702 | max_src_size, |
| 715 | // ) catch |err| switch (err) { | 703 | ) catch |err| switch (err) { |
| 716 | // error.IsDir, error.AccessDenied => { | 704 | error.IsDir, error.AccessDenied => { |
| 717 | // // TODO make event based (and dir.next()) | 705 | var dir = try fs.Dir.cwd().openDirList(file_path); |
| 718 | // var dir = try fs.Dir.cwd().openDirList(file_path); | 706 | defer dir.close(); |
| 719 | // defer dir.close(); | 707 | |
| 720 | 708 | var group = event.Group(FmtError!void).init(fmt.allocator); | |
| 721 | // var group = event.Group(FmtError!void).init(fmt.allocator); | 709 | var it = dir.iterate(); |
| 722 | // while (try dir.next()) |entry| { | 710 | while (try it.next()) |entry| { |
| 723 | // if (entry.kind == fs.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) { | 711 | if (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 }); | 712 | 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); | 713 | @panic("TODO https://github.com/ziglang/zig/issues/3777"); |
| 726 | // } | 714 | // try group.call(fmtPath, fmt, full_path, check_mode); |
| 727 | // } | 715 | } |
| 728 | // return group.wait(); | 716 | } |
| 729 | // }, | 717 | return group.wait(); |
| 730 | // else => { | 718 | }, |
| 731 | // // TODO lock stderr printing | 719 | else => { |
| 732 | // try stderr.print("unable to open '{}': {}\n", file_path, err); | 720 | // TODO lock stderr printing |
| 733 | // fmt.any_error = true; | 721 | try stderr.print("unable to open '{}': {}\n", file_path, err); |
| 734 | // return; | 722 | fmt.any_error = true; |
| 735 | // }, | 723 | return; |
| 736 | // }; | 724 | }, |
| 737 | // defer fmt.allocator.free(source_code); | 725 | }; |
| 726 | defer fmt.allocator.free(source_code); | ||
| 738 | 727 | ||
| 739 | const tree = std.zig.parse(fmt.allocator, source_code) catch |err| { | 728 | const tree = std.zig.parse(fmt.allocator, source_code) catch |err| { |
| 740 | try stderr.print("error parsing file '{}': {}\n", file_path, err); | 729 | try stderr.print("error parsing file '{}': {}\n", file_path, err); |
| ... | @@ -867,10 +856,12 @@ fn cmdInternal(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -867,10 +856,12 @@ fn cmdInternal(allocator: *Allocator, args: []const []const u8) !void { |
| 867 | .exec = cmdInternalBuildInfo, | 856 | .exec = cmdInternalBuildInfo, |
| 868 | }}; | 857 | }}; |
| 869 | 858 | ||
| 870 | for (sub_commands) |sub_command| { | 859 | inline for (sub_commands) |sub_command| { |
| 871 | if (mem.eql(u8, sub_command.name, args[0])) { | 860 | if (mem.eql(u8, sub_command.name, args[0])) { |
| 872 | try sub_command.exec(allocator, args[1..]); | 861 | var frame = try allocator.create(@Frame(sub_command.exec)); |
| 873 | return; | 862 | defer allocator.destroy(frame); |
| 863 | frame.* = async sub_command.exec(allocator, args[1..]); | ||
| 864 | return await frame; | ||
| 874 | } | 865 | } |
| 875 | } | 866 | } |
| 876 | 867 |
src-self-hosted/test.zig+11-13| ... | @@ -26,7 +26,8 @@ test "stage2" { | ... | @@ -26,7 +26,8 @@ test "stage2" { |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | const file1 = "1.zig"; | 28 | const file1 = "1.zig"; |
| 29 | const allocator = std.heap.c_allocator; | 29 | // TODO https://github.com/ziglang/zig/issues/3783 |
| 30 | const allocator = std.heap.page_allocator; | ||
| 30 | 31 | ||
| 31 | pub const TestContext = struct { | 32 | pub const TestContext = struct { |
| 32 | zig_compiler: ZigCompiler, | 33 | zig_compiler: ZigCompiler, |
| ... | @@ -94,8 +95,8 @@ pub const TestContext = struct { | ... | @@ -94,8 +95,8 @@ pub const TestContext = struct { |
| 94 | &self.zig_compiler, | 95 | &self.zig_compiler, |
| 95 | "test", | 96 | "test", |
| 96 | file1_path, | 97 | file1_path, |
| 97 | Target.Native, | 98 | .Native, |
| 98 | Compilation.Kind.Obj, | 99 | .Obj, |
| 99 | .Debug, | 100 | .Debug, |
| 100 | true, // is_static | 101 | true, // is_static |
| 101 | self.zig_lib_dir, | 102 | self.zig_lib_dir, |
| ... | @@ -116,7 +117,7 @@ pub const TestContext = struct { | ... | @@ -116,7 +117,7 @@ pub const TestContext = struct { |
| 116 | const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr()); | 117 | const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr()); |
| 117 | const file1_path = try std.fs.path.join(allocator, [_][]const u8{ tmp_dir_name, file_index, file1 }); | 118 | const file1_path = try std.fs.path.join(allocator, [_][]const u8{ tmp_dir_name, file_index, file1 }); |
| 118 | 119 | ||
| 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()); |
| 120 | if (std.fs.path.dirname(file1_path)) |dirname| { | 121 | if (std.fs.path.dirname(file1_path)) |dirname| { |
| 121 | try std.fs.makePath(allocator, dirname); | 122 | try std.fs.makePath(allocator, dirname); |
| 122 | } | 123 | } |
| ... | @@ -128,8 +129,8 @@ pub const TestContext = struct { | ... | @@ -128,8 +129,8 @@ pub const TestContext = struct { |
| 128 | &self.zig_compiler, | 129 | &self.zig_compiler, |
| 129 | "test", | 130 | "test", |
| 130 | file1_path, | 131 | file1_path, |
| 131 | Target.Native, | 132 | .Native, |
| 132 | Compilation.Kind.Exe, | 133 | .Exe, |
| 133 | .Debug, | 134 | .Debug, |
| 134 | false, | 135 | false, |
| 135 | self.zig_lib_dir, | 136 | self.zig_lib_dir, |
| ... | @@ -148,15 +149,12 @@ pub const TestContext = struct { | ... | @@ -148,15 +149,12 @@ pub const TestContext = struct { |
| 148 | exe_file: []const u8, | 149 | exe_file: []const u8, |
| 149 | expected_output: []const u8, | 150 | expected_output: []const u8, |
| 150 | ) anyerror!void { | 151 | ) anyerror!void { |
| 151 | // TODO this should not be necessary | ||
| 152 | const exe_file_2 = try std.mem.dupe(allocator, u8, exe_file); | ||
| 153 | |||
| 154 | defer comp.destroy(); | 152 | defer comp.destroy(); |
| 155 | const build_event = comp.events.get(); | 153 | const build_event = comp.events.get(); |
| 156 | 154 | ||
| 157 | switch (build_event) { | 155 | switch (build_event) { |
| 158 | .Ok => { | 156 | .Ok => { |
| 159 | const argv = [_][]const u8{exe_file_2}; | 157 | const argv = [_][]const u8{exe_file}; |
| 160 | // TODO use event loop | 158 | // TODO use event loop |
| 161 | const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); | 159 | const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); |
| 162 | switch (child.term) { | 160 | switch (child.term) { |
| ... | @@ -173,13 +171,13 @@ pub const TestContext = struct { | ... | @@ -173,13 +171,13 @@ pub const TestContext = struct { |
| 173 | return error.OutputMismatch; | 171 | return error.OutputMismatch; |
| 174 | } | 172 | } |
| 175 | }, | 173 | }, |
| 176 | Compilation.Event.Error => |err| return err, | 174 | .Error => @panic("Cannot return error: https://github.com/ziglang/zig/issues/3190"), // |err| return err, |
| 177 | Compilation.Event.Fail => |msgs| { | 175 | .Fail => |msgs| { |
| 178 | const stderr = std.io.getStdErr(); | 176 | const stderr = std.io.getStdErr(); |
| 179 | try stderr.write("build incorrectly failed:\n"); | 177 | try stderr.write("build incorrectly failed:\n"); |
| 180 | for (msgs) |msg| { | 178 | for (msgs) |msg| { |
| 181 | defer msg.destroy(); | 179 | defer msg.destroy(); |
| 182 | try msg.printToFile(stderr, errmsg.Color.Auto); | 180 | try msg.printToFile(stderr, .Auto); |
| 183 | } | 181 | } |
| 184 | }, | 182 | }, |
| 185 | } | 183 | } |
src-self-hosted/type.zig+14-12| ... | @@ -53,7 +53,7 @@ pub const Type = struct { | ... | @@ -53,7 +53,7 @@ pub const Type = struct { |
| 53 | base: *Type, | 53 | base: *Type, |
| 54 | allocator: *Allocator, | 54 | allocator: *Allocator, |
| 55 | llvm_context: *llvm.Context, | 55 | llvm_context: *llvm.Context, |
| 56 | ) (error{OutOfMemory}!*llvm.Type) { | 56 | ) error{OutOfMemory}!*llvm.Type { |
| 57 | switch (base.id) { | 57 | switch (base.id) { |
| 58 | .Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context), | 58 | .Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context), |
| 59 | .Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context), | 59 | .Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context), |
| ... | @@ -184,7 +184,7 @@ pub const Type = struct { | ... | @@ -184,7 +184,7 @@ pub const Type = struct { |
| 184 | 184 | ||
| 185 | /// If you happen to have an llvm context handy, use getAbiAlignmentInContext instead. | 185 | /// If you happen to have an llvm context handy, use getAbiAlignmentInContext instead. |
| 186 | /// Otherwise, this one will grab one from the pool and then release it. | 186 | /// 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 { |
| 188 | if (base.abi_alignment.start()) |ptr| return ptr.*; | 188 | if (base.abi_alignment.start()) |ptr| return ptr.*; |
| 189 | 189 | ||
| 190 | { | 190 | { |
| ... | @@ -200,7 +200,7 @@ pub const Type = struct { | ... | @@ -200,7 +200,7 @@ pub const Type = struct { |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | /// If you have an llvm conext handy, you can use it here. | 202 | /// 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 { |
| 204 | if (base.abi_alignment.start()) |ptr| return ptr.*; | 204 | if (base.abi_alignment.start()) |ptr| return ptr.*; |
| 205 | 205 | ||
| 206 | base.abi_alignment.data = base.resolveAbiAlignment(comp, llvm_context); | 206 | base.abi_alignment.data = base.resolveAbiAlignment(comp, llvm_context); |
| ... | @@ -209,7 +209,7 @@ pub const Type = struct { | ... | @@ -209,7 +209,7 @@ pub const Type = struct { |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | /// Lower level function that does the work. See getAbiAlignment. | 211 | /// 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 { |
| 213 | const llvm_type = try base.getLlvmType(comp.gpa(), llvm_context); | 213 | const llvm_type = try base.getLlvmType(comp.gpa(), llvm_context); |
| 214 | return @intCast(u32, llvm.ABIAlignmentOfType(comp.target_data_ref, llvm_type)); | 214 | return @intCast(u32, llvm.ABIAlignmentOfType(comp.target_data_ref, llvm_type)); |
| 215 | } | 215 | } |
| ... | @@ -367,7 +367,7 @@ pub const Type = struct { | ... | @@ -367,7 +367,7 @@ pub const Type = struct { |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | /// takes ownership of key.Normal.params on success | 369 | /// 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 { |
| 371 | { | 371 | { |
| 372 | const held = comp.fn_type_table.acquire(); | 372 | const held = comp.fn_type_table.acquire(); |
| 373 | defer held.release(); | 373 | defer held.release(); |
| ... | @@ -564,7 +564,7 @@ pub const Type = struct { | ... | @@ -564,7 +564,7 @@ pub const Type = struct { |
| 564 | return comp.u8_type; | 564 | return comp.u8_type; |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | pub async fn get(comp: *Compilation, key: Key) !*Int { | 567 | pub fn get(comp: *Compilation, key: Key) !*Int { |
| 568 | { | 568 | { |
| 569 | const held = comp.int_type_table.acquire(); | 569 | const held = comp.int_type_table.acquire(); |
| 570 | defer held.release(); | 570 | defer held.release(); |
| ... | @@ -606,7 +606,7 @@ pub const Type = struct { | ... | @@ -606,7 +606,7 @@ pub const Type = struct { |
| 606 | comp.registerGarbage(Int, &self.garbage_node); | 606 | comp.registerGarbage(Int, &self.garbage_node); |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | pub async fn gcDestroy(self: *Int, comp: *Compilation) void { | 609 | pub fn gcDestroy(self: *Int, comp: *Compilation) void { |
| 610 | { | 610 | { |
| 611 | const held = comp.int_type_table.acquire(); | 611 | const held = comp.int_type_table.acquire(); |
| 612 | defer held.release(); | 612 | defer held.release(); |
| ... | @@ -700,7 +700,7 @@ pub const Type = struct { | ... | @@ -700,7 +700,7 @@ pub const Type = struct { |
| 700 | comp.registerGarbage(Pointer, &self.garbage_node); | 700 | comp.registerGarbage(Pointer, &self.garbage_node); |
| 701 | } | 701 | } |
| 702 | 702 | ||
| 703 | pub async fn gcDestroy(self: *Pointer, comp: *Compilation) void { | 703 | pub fn gcDestroy(self: *Pointer, comp: *Compilation) void { |
| 704 | { | 704 | { |
| 705 | const held = comp.ptr_type_table.acquire(); | 705 | const held = comp.ptr_type_table.acquire(); |
| 706 | defer held.release(); | 706 | defer held.release(); |
| ... | @@ -711,14 +711,14 @@ pub const Type = struct { | ... | @@ -711,14 +711,14 @@ pub const Type = struct { |
| 711 | comp.gpa().destroy(self); | 711 | comp.gpa().destroy(self); |
| 712 | } | 712 | } |
| 713 | 713 | ||
| 714 | pub async fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 { | 714 | pub fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 { |
| 715 | switch (self.key.alignment) { | 715 | switch (self.key.alignment) { |
| 716 | .Abi => return self.key.child_type.getAbiAlignment(comp), | 716 | .Abi => return self.key.child_type.getAbiAlignment(comp), |
| 717 | .Override => |alignment| return alignment, | 717 | .Override => |alignment| return alignment, |
| 718 | } | 718 | } |
| 719 | } | 719 | } |
| 720 | 720 | ||
| 721 | pub async fn get( | 721 | pub fn get( |
| 722 | comp: *Compilation, | 722 | comp: *Compilation, |
| 723 | key: Key, | 723 | key: Key, |
| 724 | ) !*Pointer { | 724 | ) !*Pointer { |
| ... | @@ -726,8 +726,10 @@ pub const Type = struct { | ... | @@ -726,8 +726,10 @@ pub const Type = struct { |
| 726 | switch (key.alignment) { | 726 | switch (key.alignment) { |
| 727 | .Abi => {}, | 727 | .Abi => {}, |
| 728 | .Override => |alignment| { | 728 | .Override => |alignment| { |
| 729 | // TODO https://github.com/ziglang/zig/issues/3190 | ||
| 730 | var align_spill = alignment; | ||
| 729 | const abi_align = try key.child_type.getAbiAlignment(comp); | 731 | const abi_align = try key.child_type.getAbiAlignment(comp); |
| 730 | if (abi_align == alignment) { | 732 | if (abi_align == align_spill) { |
| 731 | normal_key.alignment = .Abi; | 733 | normal_key.alignment = .Abi; |
| 732 | } | 734 | } |
| 733 | }, | 735 | }, |
| ... | @@ -828,7 +830,7 @@ pub const Type = struct { | ... | @@ -828,7 +830,7 @@ pub const Type = struct { |
| 828 | comp.gpa().destroy(self); | 830 | comp.gpa().destroy(self); |
| 829 | } | 831 | } |
| 830 | 832 | ||
| 831 | pub async fn get(comp: *Compilation, key: Key) !*Array { | 833 | pub fn get(comp: *Compilation, key: Key) !*Array { |
| 832 | key.elem_type.base.ref(); | 834 | key.elem_type.base.ref(); |
| 833 | errdefer key.elem_type.base.deref(comp); | 835 | errdefer key.elem_type.base.deref(comp); |
| 834 | 836 |
src-self-hosted/util.zig+12-11| ... | @@ -32,21 +32,21 @@ pub fn getFloatAbi(self: Target) FloatAbi { | ... | @@ -32,21 +32,21 @@ pub fn getFloatAbi(self: Target) FloatAbi { |
| 32 | }; | 32 | }; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub fn getObjectFormat(self: Target) Target.ObjectFormat { | 35 | pub fn getObjectFormat(target: Target) Target.ObjectFormat { |
| 36 | return switch (self) { | 36 | switch (target) { |
| 37 | .Native => @import("builtin").object_format, | 37 | .Native => return @import("builtin").object_format, |
| 38 | .Cross => { | 38 | .Cross => blk: { |
| 39 | if (target.isWindows() or target.isUefi()) { | 39 | if (target.isWindows() or target.isUefi()) { |
| 40 | break .coff; | 40 | return .coff; |
| 41 | } else if (target.isDarwin()) { | 41 | } else if (target.isDarwin()) { |
| 42 | break .macho; | 42 | return .macho; |
| 43 | } | 43 | } |
| 44 | if (target.isWasm()) { | 44 | if (target.isWasm()) { |
| 45 | break .wasm; | 45 | return .wasm; |
| 46 | } | 46 | } |
| 47 | break .elf; | 47 | return .elf; |
| 48 | }, | 48 | }, |
| 49 | }; | 49 | } |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { | 52 | pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { |
| ... | @@ -156,7 +156,7 @@ pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { | ... | @@ -156,7 +156,7 @@ pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { |
| 156 | } | 156 | } |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | pub fn getDarwinArchString(self: Target) []const u8 { | 159 | pub fn getDarwinArchString(self: Target) [:0]const u8 { |
| 160 | const arch = self.getArch(); | 160 | const arch = self.getArch(); |
| 161 | switch (arch) { | 161 | switch (arch) { |
| 162 | .aarch64 => return "arm64", | 162 | .aarch64 => return "arm64", |
| ... | @@ -166,7 +166,8 @@ pub fn getDarwinArchString(self: Target) []const u8 { | ... | @@ -166,7 +166,8 @@ pub fn getDarwinArchString(self: Target) []const u8 { |
| 166 | .powerpc => return "ppc", | 166 | .powerpc => return "ppc", |
| 167 | .powerpc64 => return "ppc64", | 167 | .powerpc64 => return "ppc64", |
| 168 | .powerpc64le => return "ppc64le", | 168 | .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), | ||
| 170 | } | 171 | } |
| 171 | } | 172 | } |
| 172 | 173 |
src-self-hosted/value.zig+7-7| ... | @@ -156,7 +156,7 @@ pub const Value = struct { | ... | @@ -156,7 +156,7 @@ pub const Value = struct { |
| 156 | const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context); | 156 | const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context); |
| 157 | const llvm_fn = llvm.AddFunction( | 157 | const llvm_fn = llvm.AddFunction( |
| 158 | ofile.module, | 158 | ofile.module, |
| 159 | self.symbol_name.ptr(), | 159 | self.symbol_name.toSliceConst(), |
| 160 | llvm_fn_type, | 160 | llvm_fn_type, |
| 161 | ) orelse return error.OutOfMemory; | 161 | ) orelse return error.OutOfMemory; |
| 162 | 162 | ||
| ... | @@ -241,7 +241,7 @@ pub const Value = struct { | ... | @@ -241,7 +241,7 @@ pub const Value = struct { |
| 241 | const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context); | 241 | const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context); |
| 242 | const llvm_fn = llvm.AddFunction( | 242 | const llvm_fn = llvm.AddFunction( |
| 243 | ofile.module, | 243 | ofile.module, |
| 244 | self.symbol_name.ptr(), | 244 | self.symbol_name.toSliceConst(), |
| 245 | llvm_fn_type, | 245 | llvm_fn_type, |
| 246 | ) orelse return error.OutOfMemory; | 246 | ) orelse return error.OutOfMemory; |
| 247 | 247 | ||
| ... | @@ -334,7 +334,7 @@ pub const Value = struct { | ... | @@ -334,7 +334,7 @@ pub const Value = struct { |
| 334 | field_index: usize, | 334 | field_index: usize, |
| 335 | }; | 335 | }; |
| 336 | 336 | ||
| 337 | pub async fn createArrayElemPtr( | 337 | pub fn createArrayElemPtr( |
| 338 | comp: *Compilation, | 338 | comp: *Compilation, |
| 339 | array_val: *Array, | 339 | array_val: *Array, |
| 340 | mut: Type.Pointer.Mut, | 340 | mut: Type.Pointer.Mut, |
| ... | @@ -350,7 +350,7 @@ pub const Value = struct { | ... | @@ -350,7 +350,7 @@ pub const Value = struct { |
| 350 | .mut = mut, | 350 | .mut = mut, |
| 351 | .vol = Type.Pointer.Vol.Non, | 351 | .vol = Type.Pointer.Vol.Non, |
| 352 | .size = size, | 352 | .size = size, |
| 353 | .alignment = Type.Pointer.Align.Abi, | 353 | .alignment = .Abi, |
| 354 | }); | 354 | }); |
| 355 | var ptr_type_consumed = false; | 355 | var ptr_type_consumed = false; |
| 356 | errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp); | 356 | errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp); |
| ... | @@ -390,13 +390,13 @@ pub const Value = struct { | ... | @@ -390,13 +390,13 @@ pub const Value = struct { |
| 390 | const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?; | 390 | const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?; |
| 391 | const ptr_bit_count = ofile.comp.target_ptr_bits; | 391 | const ptr_bit_count = ofile.comp.target_ptr_bits; |
| 392 | const usize_llvm_type = llvm.IntTypeInContext(ofile.context, ptr_bit_count) orelse return error.OutOfMemory; | 392 | 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{ |
| 394 | llvm.ConstNull(usize_llvm_type) orelse return error.OutOfMemory, | 394 | llvm.ConstNull(usize_llvm_type) orelse return error.OutOfMemory, |
| 395 | llvm.ConstInt(usize_llvm_type, base_array.elem_index, 0) orelse return error.OutOfMemory, | 395 | llvm.ConstInt(usize_llvm_type, base_array.elem_index, 0) orelse return error.OutOfMemory, |
| 396 | }; | 396 | }; |
| 397 | return llvm.ConstInBoundsGEP( | 397 | return llvm.ConstInBoundsGEP( |
| 398 | array_llvm_value, | 398 | array_llvm_value, |
| 399 | &indices, | 399 | @ptrCast([*]*llvm.Value, &indices), |
| 400 | @intCast(c_uint, indices.len), | 400 | @intCast(c_uint, indices.len), |
| 401 | ) orelse return error.OutOfMemory; | 401 | ) orelse return error.OutOfMemory; |
| 402 | }, | 402 | }, |
| ... | @@ -423,7 +423,7 @@ pub const Value = struct { | ... | @@ -423,7 +423,7 @@ pub const Value = struct { |
| 423 | }; | 423 | }; |
| 424 | 424 | ||
| 425 | /// Takes ownership of buffer | 425 | /// Takes ownership of buffer |
| 426 | pub async fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array { | 426 | pub fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array { |
| 427 | const u8_type = Type.Int.get_u8(comp); | 427 | const u8_type = Type.Int.get_u8(comp); |
| 428 | defer u8_type.base.base.deref(comp); | 428 | defer u8_type.base.base.deref(comp); |
| 429 | 429 |