commit c9fa8e46df21cdf66b291fb3dfdcef1b6a1d3cab (tree)
parent 1bf29757d963b301c1fcfccb9b39b277381de115
Author: Carl Ã…stholm <carl@astholm.se>
Date: Fri, 7 Nov 2025 22:15:30 +0100
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.
Diffstat:
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git 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
@@ -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
@@ -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 {