authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-08 14:29:51+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-08 14:29:54+02:00
log0ae2ea671b867e5ecd0bc779405c175f33316559
treebe04082be44611973aa36b4d4ebaa260f310d6d9
parentb98b3252beea98522c25b88eb29b5e2d8a65adfe

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.

3 files changed, 37 insertions(+), 9 deletions(-)

lib/std/fs/file.zig+16
......@@ -990,6 +990,8 @@ pub const File = struct {
990990 return index;
991991 }
992992
993 /// On Windows, this function currently does alter the file pointer.
994 /// https://github.com/ziglang/zig/issues/12783
993995 pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize {
994996 if (is_windows) {
995997 return windows.ReadFile(self.handle, buffer, offset, self.intended_io_mode);
......@@ -1004,6 +1006,8 @@ pub const File = struct {
10041006
10051007 /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it
10061008 /// means the file reached the end. Reaching the end of a file is not an error condition.
1009 /// On Windows, this function currently does alter the file pointer.
1010 /// https://github.com/ziglang/zig/issues/12783
10071011 pub fn preadAll(self: File, buffer: []u8, offset: u64) PReadError!usize {
10081012 var index: usize = 0;
10091013 while (index != buffer.len) {
......@@ -1058,6 +1062,8 @@ pub const File = struct {
10581062 }
10591063
10601064 /// See https://github.com/ziglang/zig/issues/7699
1065 /// On Windows, this function currently does alter the file pointer.
1066 /// https://github.com/ziglang/zig/issues/12783
10611067 pub fn preadv(self: File, iovecs: []const os.iovec, offset: u64) PReadError!usize {
10621068 if (is_windows) {
10631069 // TODO improve this to use ReadFileScatter
......@@ -1079,6 +1085,8 @@ pub const File = struct {
10791085 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
10801086 /// order to handle partial reads from the underlying OS layer.
10811087 /// See https://github.com/ziglang/zig/issues/7699
1088 /// On Windows, this function currently does alter the file pointer.
1089 /// https://github.com/ziglang/zig/issues/12783
10821090 pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
10831091 if (iovecs.len == 0) return 0;
10841092
......@@ -1122,6 +1130,8 @@ pub const File = struct {
11221130 }
11231131 }
11241132
1133 /// On Windows, this function currently does alter the file pointer.
1134 /// https://github.com/ziglang/zig/issues/12783
11251135 pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize {
11261136 if (is_windows) {
11271137 return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode);
......@@ -1134,6 +1144,8 @@ pub const File = struct {
11341144 }
11351145 }
11361146
1147 /// On Windows, this function currently does alter the file pointer.
1148 /// https://github.com/ziglang/zig/issues/12783
11371149 pub fn pwriteAll(self: File, bytes: []const u8, offset: u64) PWriteError!void {
11381150 var index: usize = 0;
11391151 while (index < bytes.len) {
......@@ -1179,6 +1191,8 @@ pub const File = struct {
11791191 }
11801192
11811193 /// See https://github.com/ziglang/zig/issues/7699
1194 /// On Windows, this function currently does alter the file pointer.
1195 /// https://github.com/ziglang/zig/issues/12783
11821196 pub fn pwritev(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!usize {
11831197 if (is_windows) {
11841198 // TODO improve this to use WriteFileScatter
......@@ -1197,6 +1211,8 @@ pub const File = struct {
11971211 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
11981212 /// order to handle partial writes from the underlying OS layer.
11991213 /// See https://github.com/ziglang/zig/issues/7699
1214 /// On Windows, this function currently does alter the file pointer.
1215 /// https://github.com/ziglang/zig/issues/12783
12001216 pub fn pwritevAll(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!void {
12011217 if (iovecs.len == 0) return;
12021218
src/link/Wasm.zig+14-2
......@@ -3055,14 +3055,26 @@ fn writeVecSectionHeader(file: fs.File, offset: u64, section: wasm.Section, size
30553055 buf[0] = @enumToInt(section);
30563056 leb.writeUnsignedFixed(5, buf[1..6], size);
30573057 leb.writeUnsignedFixed(5, buf[6..], items);
3058 try file.pwriteAll(&buf, offset);
3058
3059 if (builtin.target.os.tag == .windows) {
3060 // https://github.com/ziglang/zig/issues/12783
3061 const curr_pos = try file.getPos();
3062 try file.pwriteAll(&buf, offset);
3063 try file.seekTo(curr_pos);
3064 } else try file.pwriteAll(&buf, offset);
30593065}
30603066
30613067fn writeCustomSectionHeader(file: fs.File, offset: u64, size: u32) !void {
30623068 var buf: [1 + 5]u8 = undefined;
30633069 buf[0] = 0; // 0 = 'custom' section
30643070 leb.writeUnsignedFixed(5, buf[1..6], size);
3065 try file.pwriteAll(&buf, offset);
3071
3072 if (builtin.target.os.tag == .windows) {
3073 // https://github.com/ziglang/zig/issues/12783
3074 const curr_pos = try file.getPos();
3075 try file.pwriteAll(&buf, offset);
3076 try file.seekTo(curr_pos);
3077 } else try file.pwriteAll(&buf, offset);
30663078}
30673079
30683080fn emitLinkSection(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *std.AutoArrayHashMap(SymbolLoc, u32)) !void {
test/link.zig+7-7
......@@ -28,35 +28,35 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
2828}
2929
3030fn addWasmCases(cases: *tests.StandaloneContext) void {
31 cases.addBuildFile("test/link/wasm/bss/build.zig", .{
31 cases.addBuildFile("test/link/wasm/archive/build.zig", .{
3232 .build_modes = true,
3333 .requires_stage2 = true,
3434 });
3535
36 cases.addBuildFile("test/link/wasm/segments/build.zig", .{
36 cases.addBuildFile("test/link/wasm/bss/build.zig", .{
3737 .build_modes = true,
3838 .requires_stage2 = true,
3939 });
4040
41 cases.addBuildFile("test/link/wasm/stack_pointer/build.zig", .{
41 cases.addBuildFile("test/link/wasm/extern/build.zig", .{
4242 .build_modes = true,
4343 .requires_stage2 = true,
44 .use_emulation = true,
4445 });
4546
46 cases.addBuildFile("test/link/wasm/type/build.zig", .{
47 cases.addBuildFile("test/link/wasm/segments/build.zig", .{
4748 .build_modes = true,
4849 .requires_stage2 = true,
4950 });
5051
51 cases.addBuildFile("test/link/wasm/archive/build.zig", .{
52 cases.addBuildFile("test/link/wasm/stack_pointer/build.zig", .{
5253 .build_modes = true,
5354 .requires_stage2 = true,
5455 });
5556
56 cases.addBuildFile("test/link/wasm/extern/build.zig", .{
57 cases.addBuildFile("test/link/wasm/type/build.zig", .{
5758 .build_modes = true,
5859 .requires_stage2 = true,
59 .use_emulation = true,
6060 });
6161}
6262