| author | |
| committer | |
| log | fbd6c883213ae9fce9734e2702cd6d3ef7691694 |
| tree | 54b3178757d827e2756165e123d4526332bc3a3a |
| parent | f59bd2be539ce736d2ef04d16f48980d9c02a3ab |
| parent | 6fc9f6c5f6a067475f97cd16cb265332c8b7c6f3 |
4 files changed, 140 insertions(+), 87 deletions(-)
lib/std/Thread.zig+2-1| ... | ... | @@ -513,7 +513,8 @@ const WindowsThreadImpl = struct { |
| 513 | 513 | errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0); |
| 514 | 514 | |
| 515 | 515 | const instance_bytes = @ptrCast([*]u8, alloc_ptr)[0..alloc_bytes]; |
| 516 | const instance = std.heap.FixedBufferAllocator.init(instance_bytes).allocator().create(Instance) catch unreachable; | |
| 516 | var fba = std.heap.FixedBufferAllocator.init(instance_bytes); | |
| 517 | const instance = fba.allocator().create(Instance) catch unreachable; | |
| 517 | 518 | instance.* = .{ |
| 518 | 519 | .fn_args = args, |
| 519 | 520 | .thread = .{ |
src/Sema.zig+35-26| ... | ... | @@ -5736,6 +5736,7 @@ fn instantiateGenericCall( |
| 5736 | 5736 | const arg_src = call_src; // TODO better source location |
| 5737 | 5737 | const arg_ty = sema.typeOf(uncasted_args[i]); |
| 5738 | 5738 | const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]); |
| 5739 | try sema.resolveLazyValue(block, arg_src, arg_val); | |
| 5739 | 5740 | arg_val.hash(arg_ty, &hasher, mod); |
| 5740 | 5741 | if (is_anytype) { |
| 5741 | 5742 | arg_ty.hashWithHasher(&hasher, mod); |
| ... | ... | @@ -26079,12 +26080,12 @@ fn intFitsInType( |
| 26079 | 26080 | sema: *Sema, |
| 26080 | 26081 | block: *Block, |
| 26081 | 26082 | src: LazySrcLoc, |
| 26082 | self: Value, | |
| 26083 | val: Value, | |
| 26083 | 26084 | ty: Type, |
| 26084 | 26085 | vector_index: ?*usize, |
| 26085 | 26086 | ) CompileError!bool { |
| 26086 | 26087 | const target = sema.mod.getTarget(); |
| 26087 | switch (self.tag()) { | |
| 26088 | switch (val.tag()) { | |
| 26088 | 26089 | .zero, |
| 26089 | 26090 | .undef, |
| 26090 | 26091 | .bool_false, |
| ... | ... | @@ -26104,30 +26105,38 @@ fn intFitsInType( |
| 26104 | 26105 | else => unreachable, |
| 26105 | 26106 | }, |
| 26106 | 26107 | |
| 26107 | .lazy_align => { | |
| 26108 | const info = ty.intInfo(target); | |
| 26109 | const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); | |
| 26110 | // If it is u16 or bigger we know the alignment fits without resolving it. | |
| 26111 | if (info.bits >= max_needed_bits) return true; | |
| 26112 | const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data); | |
| 26113 | if (x == 0) return true; | |
| 26114 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); | |
| 26115 | return info.bits >= actual_needed_bits; | |
| 26108 | .lazy_align => switch (ty.zigTypeTag()) { | |
| 26109 | .Int => { | |
| 26110 | const info = ty.intInfo(target); | |
| 26111 | const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); | |
| 26112 | // If it is u16 or bigger we know the alignment fits without resolving it. | |
| 26113 | if (info.bits >= max_needed_bits) return true; | |
| 26114 | const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data); | |
| 26115 | if (x == 0) return true; | |
| 26116 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); | |
| 26117 | return info.bits >= actual_needed_bits; | |
| 26118 | }, | |
| 26119 | .ComptimeInt => return true, | |
| 26120 | else => unreachable, | |
| 26116 | 26121 | }, |
| 26117 | .lazy_size => { | |
| 26118 | const info = ty.intInfo(target); | |
| 26119 | const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); | |
| 26120 | // If it is u64 or bigger we know the size fits without resolving it. | |
| 26121 | if (info.bits >= max_needed_bits) return true; | |
| 26122 | const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data); | |
| 26123 | if (x == 0) return true; | |
| 26124 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); | |
| 26125 | return info.bits >= actual_needed_bits; | |
| 26122 | .lazy_size => switch (ty.zigTypeTag()) { | |
| 26123 | .Int => { | |
| 26124 | const info = ty.intInfo(target); | |
| 26125 | const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); | |
| 26126 | // If it is u64 or bigger we know the size fits without resolving it. | |
| 26127 | if (info.bits >= max_needed_bits) return true; | |
| 26128 | const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data); | |
| 26129 | if (x == 0) return true; | |
| 26130 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); | |
| 26131 | return info.bits >= actual_needed_bits; | |
| 26132 | }, | |
| 26133 | .ComptimeInt => return true, | |
| 26134 | else => unreachable, | |
| 26126 | 26135 | }, |
| 26127 | 26136 | |
| 26128 | 26137 | .int_u64 => switch (ty.zigTypeTag()) { |
| 26129 | 26138 | .Int => { |
| 26130 | const x = self.castTag(.int_u64).?.data; | |
| 26139 | const x = val.castTag(.int_u64).?.data; | |
| 26131 | 26140 | if (x == 0) return true; |
| 26132 | 26141 | const info = ty.intInfo(target); |
| 26133 | 26142 | const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); |
| ... | ... | @@ -26138,13 +26147,13 @@ fn intFitsInType( |
| 26138 | 26147 | }, |
| 26139 | 26148 | .int_i64 => switch (ty.zigTypeTag()) { |
| 26140 | 26149 | .Int => { |
| 26141 | const x = self.castTag(.int_i64).?.data; | |
| 26150 | const x = val.castTag(.int_i64).?.data; | |
| 26142 | 26151 | if (x == 0) return true; |
| 26143 | 26152 | const info = ty.intInfo(target); |
| 26144 | 26153 | if (info.signedness == .unsigned and x < 0) |
| 26145 | 26154 | return false; |
| 26146 | 26155 | var buffer: Value.BigIntSpace = undefined; |
| 26147 | return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); | |
| 26156 | return (try val.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); | |
| 26148 | 26157 | }, |
| 26149 | 26158 | .ComptimeInt => return true, |
| 26150 | 26159 | else => unreachable, |
| ... | ... | @@ -26152,7 +26161,7 @@ fn intFitsInType( |
| 26152 | 26161 | .int_big_positive => switch (ty.zigTypeTag()) { |
| 26153 | 26162 | .Int => { |
| 26154 | 26163 | const info = ty.intInfo(target); |
| 26155 | return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); | |
| 26164 | return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); | |
| 26156 | 26165 | }, |
| 26157 | 26166 | .ComptimeInt => return true, |
| 26158 | 26167 | else => unreachable, |
| ... | ... | @@ -26160,7 +26169,7 @@ fn intFitsInType( |
| 26160 | 26169 | .int_big_negative => switch (ty.zigTypeTag()) { |
| 26161 | 26170 | .Int => { |
| 26162 | 26171 | const info = ty.intInfo(target); |
| 26163 | return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); | |
| 26172 | return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); | |
| 26164 | 26173 | }, |
| 26165 | 26174 | .ComptimeInt => return true, |
| 26166 | 26175 | else => unreachable, |
| ... | ... | @@ -26191,7 +26200,7 @@ fn intFitsInType( |
| 26191 | 26200 | |
| 26192 | 26201 | .aggregate => { |
| 26193 | 26202 | assert(ty.zigTypeTag() == .Vector); |
| 26194 | for (self.castTag(.aggregate).?.data) |elem, i| { | |
| 26203 | for (val.castTag(.aggregate).?.data) |elem, i| { | |
| 26195 | 26204 | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) { |
| 26196 | 26205 | if (vector_index) |some| some.* = i; |
| 26197 | 26206 | return false; |
src/codegen/spirv/Section.zig+10| ... | ... | @@ -328,6 +328,8 @@ fn extendedUnionSize(comptime Operand: type, operand: Operand) usize { |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | 330 | test "SPIR-V Section emit() - no operands" { |
| 331 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 332 | ||
| 331 | 333 | var section = Section{}; |
| 332 | 334 | defer section.deinit(std.testing.allocator); |
| 333 | 335 | |
| ... | ... | @@ -337,6 +339,8 @@ test "SPIR-V Section emit() - no operands" { |
| 337 | 339 | } |
| 338 | 340 | |
| 339 | 341 | test "SPIR-V Section emit() - simple" { |
| 342 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 343 | ||
| 340 | 344 | var section = Section{}; |
| 341 | 345 | defer section.deinit(std.testing.allocator); |
| 342 | 346 | |
| ... | ... | @@ -353,6 +357,8 @@ test "SPIR-V Section emit() - simple" { |
| 353 | 357 | } |
| 354 | 358 | |
| 355 | 359 | test "SPIR-V Section emit() - string" { |
| 360 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 361 | ||
| 356 | 362 | var section = Section{}; |
| 357 | 363 | defer section.deinit(std.testing.allocator); |
| 358 | 364 | |
| ... | ... | @@ -378,6 +384,8 @@ test "SPIR-V Section emit() - string" { |
| 378 | 384 | } |
| 379 | 385 | |
| 380 | 386 | test "SPIR-V Section emit()- extended mask" { |
| 387 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 388 | ||
| 381 | 389 | var section = Section{}; |
| 382 | 390 | defer section.deinit(std.testing.allocator); |
| 383 | 391 | |
| ... | ... | @@ -402,6 +410,8 @@ test "SPIR-V Section emit()- extended mask" { |
| 402 | 410 | } |
| 403 | 411 | |
| 404 | 412 | test "SPIR-V Section emit() - extended union" { |
| 413 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 414 | ||
| 405 | 415 | var section = Section{}; |
| 406 | 416 | defer section.deinit(std.testing.allocator); |
| 407 | 417 |
src/link/Coff.zig+93-60| ... | ... | @@ -809,6 +809,36 @@ pub fn updateDeclExports( |
| 809 | 809 | if (build_options.skip_non_native and builtin.object_format != .coff) { |
| 810 | 810 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 811 | 811 | } |
| 812 | ||
| 813 | // Even in the case of LLVM, we need to notice certain exported symbols in order to | |
| 814 | // detect the default subsystem. | |
| 815 | for (exports) |exp| { | |
| 816 | const exported_decl = module.declPtr(exp.exported_decl); | |
| 817 | if (exported_decl.getFunction() == null) continue; | |
| 818 | const winapi_cc = switch (self.base.options.target.cpu.arch) { | |
| 819 | .i386 => std.builtin.CallingConvention.Stdcall, | |
| 820 | else => std.builtin.CallingConvention.C, | |
| 821 | }; | |
| 822 | const decl_cc = exported_decl.ty.fnCallingConvention(); | |
| 823 | if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and | |
| 824 | self.base.options.link_libc) | |
| 825 | { | |
| 826 | module.stage1_flags.have_c_main = true; | |
| 827 | } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { | |
| 828 | if (mem.eql(u8, exp.options.name, "WinMain")) { | |
| 829 | module.stage1_flags.have_winmain = true; | |
| 830 | } else if (mem.eql(u8, exp.options.name, "wWinMain")) { | |
| 831 | module.stage1_flags.have_wwinmain = true; | |
| 832 | } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) { | |
| 833 | module.stage1_flags.have_winmain_crt_startup = true; | |
| 834 | } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) { | |
| 835 | module.stage1_flags.have_wwinmain_crt_startup = true; | |
| 836 | } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) { | |
| 837 | module.stage1_flags.have_dllmain_crt_startup = true; | |
| 838 | } | |
| 839 | } | |
| 840 | } | |
| 841 | ||
| 812 | 842 | if (build_options.have_llvm) { |
| 813 | 843 | if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports); |
| 814 | 844 | } |
| ... | ... | @@ -1114,17 +1144,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 1114 | 1144 | try argv.append("-dynamicbase"); |
| 1115 | 1145 | } |
| 1116 | 1146 | |
| 1117 | const subsystem_suffix = ss: { | |
| 1118 | if (self.base.options.major_subsystem_version) |major| { | |
| 1119 | if (self.base.options.minor_subsystem_version) |minor| { | |
| 1120 | break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); | |
| 1121 | } else { | |
| 1122 | break :ss try allocPrint(arena, ",{d}", .{major}); | |
| 1123 | } | |
| 1124 | } | |
| 1125 | break :ss ""; | |
| 1126 | }; | |
| 1127 | ||
| 1128 | 1147 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 1129 | 1148 | |
| 1130 | 1149 | if (self.base.options.implib_emit) |emit| { |
| ... | ... | @@ -1186,57 +1205,71 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 1186 | 1205 | } |
| 1187 | 1206 | break :blk null; |
| 1188 | 1207 | }; |
| 1208 | ||
| 1189 | 1209 | const Mode = enum { uefi, win32 }; |
| 1190 | 1210 | const mode: Mode = mode: { |
| 1191 | if (resolved_subsystem) |subsystem| switch (subsystem) { | |
| 1192 | .Console => { | |
| 1193 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{ | |
| 1194 | subsystem_suffix, | |
| 1195 | })); | |
| 1196 | break :mode .win32; | |
| 1197 | }, | |
| 1198 | .EfiApplication => { | |
| 1199 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{ | |
| 1200 | subsystem_suffix, | |
| 1201 | })); | |
| 1202 | break :mode .uefi; | |
| 1203 | }, | |
| 1204 | .EfiBootServiceDriver => { | |
| 1205 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{ | |
| 1206 | subsystem_suffix, | |
| 1207 | })); | |
| 1208 | break :mode .uefi; | |
| 1209 | }, | |
| 1210 | .EfiRom => { | |
| 1211 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{ | |
| 1212 | subsystem_suffix, | |
| 1213 | })); | |
| 1214 | break :mode .uefi; | |
| 1215 | }, | |
| 1216 | .EfiRuntimeDriver => { | |
| 1217 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{ | |
| 1218 | subsystem_suffix, | |
| 1219 | })); | |
| 1220 | break :mode .uefi; | |
| 1221 | }, | |
| 1222 | .Native => { | |
| 1223 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{ | |
| 1224 | subsystem_suffix, | |
| 1225 | })); | |
| 1226 | break :mode .win32; | |
| 1227 | }, | |
| 1228 | .Posix => { | |
| 1229 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{ | |
| 1230 | subsystem_suffix, | |
| 1231 | })); | |
| 1232 | break :mode .win32; | |
| 1233 | }, | |
| 1234 | .Windows => { | |
| 1235 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{ | |
| 1236 | subsystem_suffix, | |
| 1237 | })); | |
| 1238 | break :mode .win32; | |
| 1239 | }, | |
| 1211 | if (resolved_subsystem) |subsystem| { | |
| 1212 | const subsystem_suffix = ss: { | |
| 1213 | if (self.base.options.major_subsystem_version) |major| { | |
| 1214 | if (self.base.options.minor_subsystem_version) |minor| { | |
| 1215 | break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); | |
| 1216 | } else { | |
| 1217 | break :ss try allocPrint(arena, ",{d}", .{major}); | |
| 1218 | } | |
| 1219 | } | |
| 1220 | break :ss ""; | |
| 1221 | }; | |
| 1222 | ||
| 1223 | switch (subsystem) { | |
| 1224 | .Console => { | |
| 1225 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{ | |
| 1226 | subsystem_suffix, | |
| 1227 | })); | |
| 1228 | break :mode .win32; | |
| 1229 | }, | |
| 1230 | .EfiApplication => { | |
| 1231 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{ | |
| 1232 | subsystem_suffix, | |
| 1233 | })); | |
| 1234 | break :mode .uefi; | |
| 1235 | }, | |
| 1236 | .EfiBootServiceDriver => { | |
| 1237 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{ | |
| 1238 | subsystem_suffix, | |
| 1239 | })); | |
| 1240 | break :mode .uefi; | |
| 1241 | }, | |
| 1242 | .EfiRom => { | |
| 1243 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{ | |
| 1244 | subsystem_suffix, | |
| 1245 | })); | |
| 1246 | break :mode .uefi; | |
| 1247 | }, | |
| 1248 | .EfiRuntimeDriver => { | |
| 1249 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{ | |
| 1250 | subsystem_suffix, | |
| 1251 | })); | |
| 1252 | break :mode .uefi; | |
| 1253 | }, | |
| 1254 | .Native => { | |
| 1255 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{ | |
| 1256 | subsystem_suffix, | |
| 1257 | })); | |
| 1258 | break :mode .win32; | |
| 1259 | }, | |
| 1260 | .Posix => { | |
| 1261 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{ | |
| 1262 | subsystem_suffix, | |
| 1263 | })); | |
| 1264 | break :mode .win32; | |
| 1265 | }, | |
| 1266 | .Windows => { | |
| 1267 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{ | |
| 1268 | subsystem_suffix, | |
| 1269 | })); | |
| 1270 | break :mode .win32; | |
| 1271 | }, | |
| 1272 | } | |
| 1240 | 1273 | } else if (target.os.tag == .uefi) { |
| 1241 | 1274 | break :mode .uefi; |
| 1242 | 1275 | } else { |