aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-07-23 17:06:19 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-07-23 17:06:19 +0200
commit5533f77054acad376f2fce0d529569a7449e9949 (patch)
treeeba6945383fefa59a8858f7eec8beee3cfca7731 /lib/std
parent1beda818e1c10bde98b35759b3c131a864be58d9 (diff)
parente5b476209a1215a03164890d331e2013f20882a6 (diff)
downloadzig-5533f77054acad376f2fce0d529569a7449e9949.tar.gz
zig-5533f77054acad376f2fce0d529569a7449e9949.zip
Merge remote-tracking branch 'origin/master' into zld-incremental-2
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/crypto/25519/field.zig4
-rw-r--r--lib/std/os/bits/linux.zig10
-rw-r--r--lib/std/os/windows/user32.zig2
-rw-r--r--lib/std/target.zig100
-rw-r--r--lib/std/zig.zig40
-rw-r--r--lib/std/zig/c_translation.zig132
-rw-r--r--lib/std/zig/cross_target.zig4
7 files changed, 213 insertions, 79 deletions
diff --git a/lib/std/crypto/25519/field.zig b/lib/std/crypto/25519/field.zig
index 33ee36b816..1d67f0a902 100644
--- a/lib/std/crypto/25519/field.zig
+++ b/lib/std/crypto/25519/field.zig
@@ -93,7 +93,7 @@ pub const Fe = struct {
return s;
}
- /// Map a 64-bit big endian string into a field element
+ /// Map a 64 bytes big endian string into a field element
pub fn fromBytes64(s: [64]u8) Fe {
var fl: [32]u8 = undefined;
var gl: [32]u8 = undefined;
@@ -106,7 +106,7 @@ pub const Fe = struct {
gl[31] &= 0x7f;
var fe_f = fromBytes(fl);
const fe_g = fromBytes(gl);
- fe_f.limbs[0] += (s[32] >> 7) * 19;
+ fe_f.limbs[0] += (s[32] >> 7) * 19 + @as(u10, s[0] >> 7) * 722;
i = 0;
while (i < 5) : (i += 1) {
fe_f.limbs[i] += 38 * fe_g.limbs[i];
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig
index 69fdbc84fb..81bdfa6608 100644
--- a/lib/std/os/bits/linux.zig
+++ b/lib/std/os/bits/linux.zig
@@ -339,19 +339,19 @@ pub const O_RDWR = 0o2;
pub const kernel_rwf = u32;
/// high priority request, poll if possible
-pub const RWF_HIPRI = kernel_rwf(0x00000001);
+pub const RWF_HIPRI: kernel_rwf = 0x00000001;
/// per-IO O_DSYNC
-pub const RWF_DSYNC = kernel_rwf(0x00000002);
+pub const RWF_DSYNC: kernel_rwf = 0x00000002;
/// per-IO O_SYNC
-pub const RWF_SYNC = kernel_rwf(0x00000004);
+pub const RWF_SYNC: kernel_rwf = 0x00000004;
/// per-IO, return -EAGAIN if operation would block
-pub const RWF_NOWAIT = kernel_rwf(0x00000008);
+pub const RWF_NOWAIT: kernel_rwf = 0x00000008;
/// per-IO O_APPEND
-pub const RWF_APPEND = kernel_rwf(0x00000010);
+pub const RWF_APPEND: kernel_rwf = 0x00000010;
pub const SEEK_SET = 0;
pub const SEEK_CUR = 1;
diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig
index ee4ee87d88..d996a0f394 100644
--- a/lib/std/os/windows/user32.zig
+++ b/lib/std/os/windows/user32.zig
@@ -1336,7 +1336,7 @@ pub extern "user32" fn AdjustWindowRectEx(lpRect: *RECT, dwStyle: DWORD, bMenu:
pub fn adjustWindowRectEx(lpRect: *RECT, dwStyle: u32, bMenu: bool, dwExStyle: u32) !void {
assert(dwStyle & WS_OVERLAPPED == 0);
- if (AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle) == 0) {
+ if (AdjustWindowRectEx(lpRect, dwStyle, @boolToInt(bMenu), dwExStyle) == 0) {
switch (GetLastError()) {
.INVALID_PARAMETER => unreachable,
else => |err| return windows.unexpectedError(err),
diff --git a/lib/std/target.zig b/lib/std/target.zig
index 70626f5051..1b9f0084c8 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -549,16 +549,36 @@ pub const Target = struct {
};
pub const ObjectFormat = enum {
+ /// Common Object File Format (Windows)
coff,
- pe,
+ /// Executable and Linking Format
elf,
+ /// macOS relocatables
macho,
+ /// WebAssembly
wasm,
+ /// C source code
c,
+ /// Standard, Portable Intermediate Representation V
spirv,
+ /// Intel IHEX
hex,
+ /// Machine code with no metadata.
raw,
+ /// Plan 9 from Bell Labs
plan9,
+
+ pub fn fileExt(of: ObjectFormat, cpu_arch: Cpu.Arch) [:0]const u8 {
+ return switch (of) {
+ .coff => ".obj",
+ .elf, .macho, .wasm => ".o",
+ .c => ".c",
+ .spirv => ".spv",
+ .hex => ".ihex",
+ .raw => ".bin",
+ .plan9 => plan9Ext(cpu_arch),
+ };
+ }
};
pub const SubSystem = enum {
@@ -1290,30 +1310,16 @@ pub const Target = struct {
return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
}
- pub fn oFileExt_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 {
- if (abi == .msvc) {
- return ".obj";
- }
- switch (os_tag) {
- .windows, .uefi => return ".obj",
- else => return ".o",
- }
- }
-
- pub fn oFileExt(self: Target) [:0]const u8 {
- return oFileExt_os_abi(self.os.tag, self.abi);
- }
-
pub fn exeFileExtSimple(cpu_arch: Cpu.Arch, os_tag: Os.Tag) [:0]const u8 {
- switch (os_tag) {
- .windows => return ".exe",
- .uefi => return ".efi",
- else => if (cpu_arch.isWasm()) {
- return ".wasm";
- } else {
- return "";
+ return switch (os_tag) {
+ .windows => ".exe",
+ .uefi => ".efi",
+ .plan9 => plan9Ext(cpu_arch),
+ else => switch (cpu_arch) {
+ .wasm32, .wasm64 => ".wasm",
+ else => "",
},
- }
+ };
}
pub fn exeFileExt(self: Target) [:0]const u8 {
@@ -1353,20 +1359,16 @@ pub const Target = struct {
}
pub fn getObjectFormatSimple(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat {
- if (os_tag == .windows or os_tag == .uefi) {
- return .coff;
- } else if (os_tag.isDarwin()) {
- return .macho;
- }
- if (cpu_arch.isWasm()) {
- return .wasm;
- }
- if (cpu_arch.isSPIRV()) {
- return .spirv;
- }
- if (os_tag == .plan9)
- return .plan9;
- return .elf;
+ return switch (os_tag) {
+ .windows, .uefi => .coff,
+ .ios, .macos, .watchos, .tvos => .macho,
+ .plan9 => .plan9,
+ else => return switch (cpu_arch) {
+ .wasm32, .wasm64 => .wasm,
+ .spirv32, .spirv64 => .spirv,
+ else => .elf,
+ },
+ };
}
pub fn getObjectFormat(self: Target) ObjectFormat {
@@ -1677,6 +1679,30 @@ pub const Target = struct {
return false;
}
+
+ /// 0c spim little-endian MIPS 3000 family
+ /// 1c 68000 Motorola MC68000
+ /// 2c 68020 Motorola MC68020
+ /// 5c arm little-endian ARM
+ /// 6c amd64 AMD64 and compatibles (e.g., Intel EM64T)
+ /// 7c arm64 ARM64 (ARMv8)
+ /// 8c 386 Intel i386, i486, Pentium, etc.
+ /// kc sparc Sun SPARC
+ /// qc power Power PC
+ /// vc mips big-endian MIPS 3000 family
+ pub fn plan9Ext(cpu_arch: Cpu.Arch) [:0]const u8 {
+ return switch (cpu_arch) {
+ .arm => ".5",
+ .x86_64 => ".6",
+ .aarch64 => ".7",
+ .i386 => ".8",
+ .sparc => ".k",
+ .powerpc, .powerpcle => ".q",
+ .mips, .mipsel => ".v",
+ // ISAs without designated characters get 'X' for lack of a better option.
+ else => ".X",
+ };
+ }
};
test {
diff --git a/lib/std/zig.zig b/lib/std/zig.zig
index 595dce77c2..303c930b93 100644
--- a/lib/std/zig.zig
+++ b/lib/std/zig.zig
@@ -108,8 +108,9 @@ pub const BinNameOptions = struct {
pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
const root_name = options.root_name;
const target = options.target;
- switch (options.object_format orelse target.getObjectFormat()) {
- .coff, .pe => switch (options.output_mode) {
+ const ofmt = options.object_format orelse target.getObjectFormat();
+ switch (ofmt) {
+ .coff => switch (options.output_mode) {
.Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }),
.Lib => {
const suffix = switch (options.link_mode orelse .Static) {
@@ -118,7 +119,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
};
return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, suffix });
},
- .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),
+ .Obj => return std.fmt.allocPrint(allocator, "{s}.obj", .{root_name}),
},
.elf => switch (options.output_mode) {
.Exe => return allocator.dupe(u8, root_name),
@@ -140,7 +141,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
},
}
},
- .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),
+ .Obj => return std.fmt.allocPrint(allocator, "{s}.o", .{root_name}),
},
.macho => switch (options.output_mode) {
.Exe => return allocator.dupe(u8, root_name),
@@ -163,7 +164,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
}
return std.fmt.allocPrint(allocator, "{s}{s}{s}", .{ target.libPrefix(), root_name, suffix });
},
- .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),
+ .Obj => return std.fmt.allocPrint(allocator, "{s}.o", .{root_name}),
},
.wasm => switch (options.output_mode) {
.Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }),
@@ -175,36 +176,15 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
.Dynamic => return std.fmt.allocPrint(allocator, "{s}.wasm", .{root_name}),
}
},
- .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),
+ .Obj => return std.fmt.allocPrint(allocator, "{s}.o", .{root_name}),
},
.c => return std.fmt.allocPrint(allocator, "{s}.c", .{root_name}),
.spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}),
.hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}),
.raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
- .plan9 => {
- // copied from 2c(1)
- // 0c spim little-endian MIPS 3000 family
- // 1c 68000 Motorola MC68000
- // 2c 68020 Motorola MC68020
- // 5c arm little-endian ARM
- // 6c amd64 AMD64 and compatibles (e.g., Intel EM64T)
- // 7c arm64 ARM64 (ARMv8)
- // 8c 386 Intel i386, i486, Pentium, etc.
- // kc sparc Sun SPARC
- // qc power Power PC
- // vc mips big-endian MIPS 3000 family
- const char: u8 = switch (target.cpu.arch) {
- .arm => '5',
- .x86_64 => '6',
- .aarch64 => '7',
- .i386 => '8',
- .sparc => 'k',
- .powerpc, .powerpcle => 'q',
- .mips, .mipsel => 'v',
- else => 'X', // this arch does not have a char or maybe was not ported to plan9 so we just use X
- };
- return std.fmt.allocPrint(allocator, "{s}.{c}", .{ root_name, char });
- },
+ .plan9 => return std.fmt.allocPrint(allocator, "{s}{s}", .{
+ root_name, ofmt.fileExt(target.cpu.arch),
+ }),
}
}
diff --git a/lib/std/zig/c_translation.zig b/lib/std/zig/c_translation.zig
index 7851525bb7..bcf3b310ea 100644
--- a/lib/std/zig/c_translation.zig
+++ b/lib/std/zig/c_translation.zig
@@ -350,3 +350,135 @@ test "Flexible Array Type" {
try testing.expectEqual(FlexibleArrayType(*volatile Container, c_int), [*c]volatile c_int);
try testing.expectEqual(FlexibleArrayType(*const volatile Container, c_int), [*c]const volatile c_int);
}
+
+pub const Macros = struct {
+ pub fn U_SUFFIX(comptime n: comptime_int) @TypeOf(promoteIntLiteral(c_uint, n, .decimal)) {
+ return promoteIntLiteral(c_uint, n, .decimal);
+ }
+
+ fn L_SUFFIX_ReturnType(comptime number: anytype) type {
+ switch (@TypeOf(number)) {
+ comptime_int => return @TypeOf(promoteIntLiteral(c_long, number, .decimal)),
+ comptime_float => return c_longdouble,
+ else => @compileError("Invalid value for L suffix"),
+ }
+ }
+ pub fn L_SUFFIX(comptime number: anytype) L_SUFFIX_ReturnType(number) {
+ switch (@TypeOf(number)) {
+ comptime_int => return promoteIntLiteral(c_long, number, .decimal),
+ comptime_float => @compileError("TODO: c_longdouble initialization from comptime_float not supported"),
+ else => @compileError("Invalid value for L suffix"),
+ }
+ }
+
+ pub fn UL_SUFFIX(comptime n: comptime_int) @TypeOf(promoteIntLiteral(c_ulong, n, .decimal)) {
+ return promoteIntLiteral(c_ulong, n, .decimal);
+ }
+
+ pub fn LL_SUFFIX(comptime n: comptime_int) @TypeOf(promoteIntLiteral(c_longlong, n, .decimal)) {
+ return promoteIntLiteral(c_longlong, n, .decimal);
+ }
+
+ pub fn ULL_SUFFIX(comptime n: comptime_int) @TypeOf(promoteIntLiteral(c_ulonglong, n, .decimal)) {
+ return promoteIntLiteral(c_ulonglong, n, .decimal);
+ }
+
+ pub fn F_SUFFIX(comptime f: comptime_float) f32 {
+ return @as(f32, f);
+ }
+
+ pub fn WL_CONTAINER_OF(ptr: anytype, sample: anytype, comptime member: []const u8) @TypeOf(sample) {
+ return @fieldParentPtr(@TypeOf(sample.*), member, ptr);
+ }
+
+ /// A 2-argument function-like macro defined as #define FOO(A, B) (A)(B)
+ /// could be either: cast B to A, or call A with the value B.
+ pub fn CAST_OR_CALL(a: anytype, b: anytype) switch (@typeInfo(@TypeOf(a))) {
+ .Type => a,
+ .Fn => |fn_info| fn_info.return_type orelse void,
+ else => |info| @compileError("Unexpected argument type: " ++ @tagName(info)),
+ } {
+ switch (@typeInfo(@TypeOf(a))) {
+ .Type => return cast(a, b),
+ .Fn => return a(b),
+ else => unreachable, // return type will be a compile error otherwise
+ }
+ }
+};
+
+test "Macro suffix functions" {
+ try testing.expect(@TypeOf(Macros.F_SUFFIX(1)) == f32);
+
+ try testing.expect(@TypeOf(Macros.U_SUFFIX(1)) == c_uint);
+ if (math.maxInt(c_ulong) > math.maxInt(c_uint)) {
+ try testing.expect(@TypeOf(Macros.U_SUFFIX(math.maxInt(c_uint) + 1)) == c_ulong);
+ }
+ if (math.maxInt(c_ulonglong) > math.maxInt(c_ulong)) {
+ try testing.expect(@TypeOf(Macros.U_SUFFIX(math.maxInt(c_ulong) + 1)) == c_ulonglong);
+ }
+
+ try testing.expect(@TypeOf(Macros.L_SUFFIX(1)) == c_long);
+ if (math.maxInt(c_long) > math.maxInt(c_int)) {
+ try testing.expect(@TypeOf(Macros.L_SUFFIX(math.maxInt(c_int) + 1)) == c_long);
+ }
+ if (math.maxInt(c_longlong) > math.maxInt(c_long)) {
+ try testing.expect(@TypeOf(Macros.L_SUFFIX(math.maxInt(c_long) + 1)) == c_longlong);
+ }
+
+ try testing.expect(@TypeOf(Macros.UL_SUFFIX(1)) == c_ulong);
+ if (math.maxInt(c_ulonglong) > math.maxInt(c_ulong)) {
+ try testing.expect(@TypeOf(Macros.UL_SUFFIX(math.maxInt(c_ulong) + 1)) == c_ulonglong);
+ }
+
+ try testing.expect(@TypeOf(Macros.LL_SUFFIX(1)) == c_longlong);
+ try testing.expect(@TypeOf(Macros.ULL_SUFFIX(1)) == c_ulonglong);
+}
+
+test "WL_CONTAINER_OF" {
+ const S = struct {
+ a: u32 = 0,
+ b: u32 = 0,
+ };
+ var x = S{};
+ var y = S{};
+ var ptr = Macros.WL_CONTAINER_OF(&x.b, &y, "b");
+ try testing.expectEqual(&x, ptr);
+}
+
+test "CAST_OR_CALL casting" {
+ var arg = @as(c_int, 1000);
+ var casted = Macros.CAST_OR_CALL(u8, arg);
+ try testing.expectEqual(cast(u8, arg), casted);
+
+ const S = struct {
+ x: u32 = 0,
+ };
+ var s = S{};
+ var casted_ptr = Macros.CAST_OR_CALL(*u8, &s);
+ try testing.expectEqual(cast(*u8, &s), casted_ptr);
+}
+
+test "CAST_OR_CALL calling" {
+ const Helper = struct {
+ var last_val: bool = false;
+ fn returnsVoid(val: bool) void {
+ last_val = val;
+ }
+ fn returnsBool(f: f32) bool {
+ return f > 0;
+ }
+ fn identity(self: c_uint) c_uint {
+ return self;
+ }
+ };
+
+ Macros.CAST_OR_CALL(Helper.returnsVoid, true);
+ try testing.expectEqual(true, Helper.last_val);
+ Macros.CAST_OR_CALL(Helper.returnsVoid, false);
+ try testing.expectEqual(false, Helper.last_val);
+
+ try testing.expectEqual(Helper.returnsBool(1), Macros.CAST_OR_CALL(Helper.returnsBool, @as(f32, 1)));
+ try testing.expectEqual(Helper.returnsBool(-1), Macros.CAST_OR_CALL(Helper.returnsBool, @as(f32, -1)));
+
+ try testing.expectEqual(Helper.identity(@as(c_uint, 100)), Macros.CAST_OR_CALL(Helper.identity, @as(c_uint, 100)));
+}
diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig
index e6ca0a2baa..1058628633 100644
--- a/lib/std/zig/cross_target.zig
+++ b/lib/std/zig/cross_target.zig
@@ -473,10 +473,6 @@ pub const CrossTarget = struct {
return self.getOsTag() == .windows;
}
- pub fn oFileExt(self: CrossTarget) [:0]const u8 {
- return Target.oFileExt_os_abi(self.getOsTag(), self.getAbi());
- }
-
pub fn exeFileExt(self: CrossTarget) [:0]const u8 {
return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
}