From c9fa8e46df21cdf66b291fb3dfdcef1b6a1d3cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20=C3=85stholm?= Date: Fri, 7 Nov 2025 22:15:30 +0100 Subject: [PATCH] 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. --- lib/std/c.zig | 15 +++++++++++++-- lib/std/heap.zig | 2 +- lib/std/os/emscripten.zig | 9 --------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/std/c.zig b/lib/std/c.zig index e9810aeb0912015c015dd68f1259cde477b1a60a..77ea235f53761c59d699905e607ce7fd54ba112a 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -1885,7 +1885,16 @@ pub const POLL = switch (native_os) { /// Basic memory protection flags pub const PROT = switch (native_os) { .linux => linux.PROT, - .emscripten => emscripten.PROT, + // https://github.com/emscripten-core/emscripten/blob/08e2de1031913e4ba7963b1c56f35f036a7d4d56/system/lib/libc/musl/include/sys/mman.h#L57-L62 + // lib/libc/include/wasm-wasi-musl/sys/mman.h + .emscripten, .wasi => struct { + pub const NONE = 0; + pub const READ = 1; + pub const WRITE = 2; + pub const EXEC = 4; + pub const GROWSDOWN = 0x01000000; + pub const GROWSUP = 0x02000000; + }, // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31 .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => struct { /// page can not be accessed @@ -8640,7 +8649,9 @@ pub const O = switch (native_os) { pub const MAP = switch (native_os) { .linux => linux.MAP, - .emscripten => packed struct(u32) { + // https://github.com/emscripten-core/emscripten/blob/08e2de1031913e4ba7963b1c56f35f036a7d4d56/system/lib/libc/musl/include/sys/mman.h#L21-L39 + // lib/libc/include/wasm-wasi-musl/sys/mman.h + .emscripten, .wasi => packed struct(u32) { TYPE: enum(u4) { SHARED = 0x01, PRIVATE = 0x02, diff --git a/lib/std/heap.zig b/lib/std/heap.zig index f584e3f72e46241728ba1448ae2c7a766401b348..3da8a063ed762ee01bd89c8b825db401d358902d 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -352,7 +352,7 @@ pub const page_allocator: Allocator = if (@hasDecl(root, "os") and @hasDecl(root.os, "heap") and @hasDecl(root.os.heap, "page_allocator")) root.os.heap.page_allocator -else if (builtin.target.cpu.arch.isWasm()) .{ +else if (builtin.target.cpu.arch.isWasm() and !builtin.link_libc) .{ .ptr = undefined, .vtable = &WasmAllocator.vtable, } else if (builtin.target.os.tag == .plan9) .{ diff --git a/lib/std/os/emscripten.zig b/lib/std/os/emscripten.zig index cb444b360dd00e0375a6e02e0d95936fce90b2b5..8dbf90dad9bcebb118b130b55e2e6023b63a6b85 100644 --- a/lib/std/os/emscripten.zig +++ b/lib/std/os/emscripten.zig @@ -331,15 +331,6 @@ pub const POLL = struct { pub const RDBAND = 0x080; }; -pub const PROT = struct { - pub const NONE = 0x0; - pub const READ = 0x1; - pub const WRITE = 0x2; - pub const EXEC = 0x4; - pub const GROWSDOWN = 0x01000000; - pub const GROWSUP = 0x02000000; -}; - pub const rlim_t = u64; pub const RLIM = struct { -- 2.54.0