wasm: temporarily save curr file pointer before pwriting on Win

This is a temporary workaround to an unclear platform-dependence
behavior we have in libstd for `std.fs.File` abstraction. See
https://github.com/ziglang/zig/issues/12783 for more information.
This commit is contained in:
Jakub Konka 2022-09-08 14:29:51 +02:00
parent b98b3252be
commit 0ae2ea671b
3 changed files with 41 additions and 13 deletions

View File

@ -990,6 +990,8 @@ pub const File = struct {
return index;
}
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize {
if (is_windows) {
return windows.ReadFile(self.handle, buffer, offset, self.intended_io_mode);
@ -1004,6 +1006,8 @@ pub const File = struct {
/// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it
/// means the file reached the end. Reaching the end of a file is not an error condition.
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn preadAll(self: File, buffer: []u8, offset: u64) PReadError!usize {
var index: usize = 0;
while (index != buffer.len) {
@ -1058,6 +1062,8 @@ pub const File = struct {
}
/// See https://github.com/ziglang/zig/issues/7699
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn preadv(self: File, iovecs: []const os.iovec, offset: u64) PReadError!usize {
if (is_windows) {
// TODO improve this to use ReadFileScatter
@ -1079,6 +1085,8 @@ pub const File = struct {
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
/// order to handle partial reads from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
if (iovecs.len == 0) return 0;
@ -1122,6 +1130,8 @@ pub const File = struct {
}
}
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize {
if (is_windows) {
return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode);
@ -1134,6 +1144,8 @@ pub const File = struct {
}
}
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn pwriteAll(self: File, bytes: []const u8, offset: u64) PWriteError!void {
var index: usize = 0;
while (index < bytes.len) {
@ -1179,6 +1191,8 @@ pub const File = struct {
}
/// See https://github.com/ziglang/zig/issues/7699
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn pwritev(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!usize {
if (is_windows) {
// TODO improve this to use WriteFileScatter
@ -1197,6 +1211,8 @@ pub const File = struct {
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
/// order to handle partial writes from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
/// On Windows, this function currently does alter the file pointer.
/// https://github.com/ziglang/zig/issues/12783
pub fn pwritevAll(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!void {
if (iovecs.len == 0) return;

View File

@ -3055,14 +3055,26 @@ fn writeVecSectionHeader(file: fs.File, offset: u64, section: wasm.Section, size
buf[0] = @enumToInt(section);
leb.writeUnsignedFixed(5, buf[1..6], size);
leb.writeUnsignedFixed(5, buf[6..], items);
try file.pwriteAll(&buf, offset);
if (builtin.target.os.tag == .windows) {
// https://github.com/ziglang/zig/issues/12783
const curr_pos = try file.getPos();
try file.pwriteAll(&buf, offset);
try file.seekTo(curr_pos);
} else try file.pwriteAll(&buf, offset);
}
fn writeCustomSectionHeader(file: fs.File, offset: u64, size: u32) !void {
var buf: [1 + 5]u8 = undefined;
buf[0] = 0; // 0 = 'custom' section
leb.writeUnsignedFixed(5, buf[1..6], size);
try file.pwriteAll(&buf, offset);
if (builtin.target.os.tag == .windows) {
// https://github.com/ziglang/zig/issues/12783
const curr_pos = try file.getPos();
try file.pwriteAll(&buf, offset);
try file.seekTo(curr_pos);
} else try file.pwriteAll(&buf, offset);
}
fn emitLinkSection(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *std.AutoArrayHashMap(SymbolLoc, u32)) !void {

View File

@ -28,11 +28,22 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
}
fn addWasmCases(cases: *tests.StandaloneContext) void {
cases.addBuildFile("test/link/wasm/archive/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
});
cases.addBuildFile("test/link/wasm/bss/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
});
cases.addBuildFile("test/link/wasm/extern/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
.use_emulation = true,
});
cases.addBuildFile("test/link/wasm/segments/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
@ -47,17 +58,6 @@ fn addWasmCases(cases: *tests.StandaloneContext) void {
.build_modes = true,
.requires_stage2 = true,
});
cases.addBuildFile("test/link/wasm/archive/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
});
cases.addBuildFile("test/link/wasm/extern/build.zig", .{
.build_modes = true,
.requires_stage2 = true,
.use_emulation = true,
});
}
fn addMachOCases(cases: *tests.StandaloneContext) void {