authorgravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2025-11-07 22:15:30+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-02 16:55:11-08:00
logc9fa8e46df21cdf66b291fb3dfdcef1b6a1d3cab
treebe1ef792bffa9d7f6eb6fa186d9100d31181a8db
parent1bf29757d963b301c1fcfccb9b39b277381de115

Use `mmap` `std.heap.page_allocator` impl when compiling for Wasm + libc

When linking libc, it should be the libc that manages the heap. The main Wasm memory might have been configured as non-growable, which makes `WasmAllocator` a poor default and causes the common `DebugAllocator` use case fail with OOM errors unless the user uses `std_options` to override the default page allocator. Additionally, on Emscripten, growing Wasm memory without notifying the JS glue code will cause array buffers to get detached and lead to spurious crashes.

3 files changed, 14 insertions(+), 12 deletions(-)

lib/std/c.zig+13-2
...@@ -1885,7 +1885,16 @@ pub const POLL = switch (native_os) {...@@ -1885,7 +1885,16 @@ pub const POLL = switch (native_os) {
1885/// Basic memory protection flags1885/// Basic memory protection flags
1886pub const PROT = switch (native_os) {1886pub const PROT = switch (native_os) {
1887 .linux => linux.PROT,1887 .linux => linux.PROT,
1888 .emscripten => emscripten.PROT,1888 // https://github.com/emscripten-core/emscripten/blob/08e2de1031913e4ba7963b1c56f35f036a7d4d56/system/lib/libc/musl/include/sys/mman.h#L57-L62
1889 // lib/libc/include/wasm-wasi-musl/sys/mman.h
1890 .emscripten, .wasi => struct {
1891 pub const NONE = 0;
1892 pub const READ = 1;
1893 pub const WRITE = 2;
1894 pub const EXEC = 4;
1895 pub const GROWSDOWN = 0x01000000;
1896 pub const GROWSUP = 0x02000000;
1897 },
1889 // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L311898 // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31
1890 .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => struct {1899 .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => struct {
1891 /// page can not be accessed1900 /// page can not be accessed
...@@ -8640,7 +8649,9 @@ pub const O = switch (native_os) {...@@ -8640,7 +8649,9 @@ pub const O = switch (native_os) {
86408649
8641pub const MAP = switch (native_os) {8650pub const MAP = switch (native_os) {
8642 .linux => linux.MAP,8651 .linux => linux.MAP,
8643 .emscripten => packed struct(u32) {8652 // https://github.com/emscripten-core/emscripten/blob/08e2de1031913e4ba7963b1c56f35f036a7d4d56/system/lib/libc/musl/include/sys/mman.h#L21-L39
8653 // lib/libc/include/wasm-wasi-musl/sys/mman.h
8654 .emscripten, .wasi => packed struct(u32) {
8644 TYPE: enum(u4) {8655 TYPE: enum(u4) {
8645 SHARED = 0x01,8656 SHARED = 0x01,
8646 PRIVATE = 0x02,8657 PRIVATE = 0x02,
lib/std/heap.zig+1-1
...@@ -352,7 +352,7 @@ pub const page_allocator: Allocator = if (@hasDecl(root, "os") and...@@ -352,7 +352,7 @@ pub const page_allocator: Allocator = if (@hasDecl(root, "os") and
352 @hasDecl(root.os, "heap") and352 @hasDecl(root.os, "heap") and
353 @hasDecl(root.os.heap, "page_allocator"))353 @hasDecl(root.os.heap, "page_allocator"))
354 root.os.heap.page_allocator354 root.os.heap.page_allocator
355else if (builtin.target.cpu.arch.isWasm()) .{355else if (builtin.target.cpu.arch.isWasm() and !builtin.link_libc) .{
356 .ptr = undefined,356 .ptr = undefined,
357 .vtable = &WasmAllocator.vtable,357 .vtable = &WasmAllocator.vtable,
358} else if (builtin.target.os.tag == .plan9) .{358} else if (builtin.target.os.tag == .plan9) .{
lib/std/os/emscripten.zig-9
...@@ -331,15 +331,6 @@ pub const POLL = struct {...@@ -331,15 +331,6 @@ pub const POLL = struct {
331 pub const RDBAND = 0x080;331 pub const RDBAND = 0x080;
332};332};
333333
334pub const PROT = struct {
335 pub const NONE = 0x0;
336 pub const READ = 0x1;
337 pub const WRITE = 0x2;
338 pub const EXEC = 0x4;
339 pub const GROWSDOWN = 0x01000000;
340 pub const GROWSUP = 0x02000000;
341};
342
343pub const rlim_t = u64;334pub const rlim_t = u64;
344335
345pub const RLIM = struct {336pub const RLIM = struct {