commit 8d3bb285e71aed150d99db5019df5876c1f245a0
parent 3a93557bc838c194609de1e670e7f831f74fb61e
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 4 Jun 2026 02:24:24 -0700
wasm: tighten shared-memory max to min pages so atomics modules load
ensure_shared_memory promotes the module memory to shared (required for
wasm atomic ops) with a provisional 4 GiB cap (65536 pages). The comment
claimed wasm_materialize_data tightens that to the real size, but the code
only ever raised min toward max -- never lowered max -- so atomics modules
shipped a 4 GiB declared maximum. `kit run` reserves the declared maximum
and caps total linear memory at 1 GiB, so every such module was rejected at
load ("wasm linear memory reservation exceeds 1073741824 bytes").
Tighten max_pages down to min_pages for shared memory once the final layout
is known. The backend never emits memory.grow, so a fixed shared memory is
correct, and embedders now reserve a snug arena. Fixes the 8 toy atomics
cases on lane W (124/17/22/59/73/74/75/77) and lets the C-frontend wasm
atomics cases run instead of failing at load.
Diffstat:
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/arch/wasm/emit.c b/src/arch/wasm/emit.c
@@ -4533,15 +4533,15 @@ static void wasm_materialize_data(WTarget* t) {
t->data_end = image;
u32 stack_top = (u32)align_to_u32(image + stack_size, 16u);
t->module->memories[0].min_pages = (stack_top + 65535u) / 65536u;
- /* Shared memory requires has_max and max >= min. We provisionally set max
- * to the wasm32 cap in ensure_shared_memory; raise min, not max, if min
- * grew larger here (shouldn't happen for a 4 GiB cap, but stays correct). */
+ /* Shared memory requires has_max and max >= min. ensure_shared_memory set a
+ * provisional wasm32-ceiling cap (65536 pages = 4 GiB); now that the final
+ * layout is known, tighten max down to min so the module declares a snug,
+ * fixed shared memory. The backend never emits memory.grow, so the memory is
+ * non-growable regardless, and a 4 GiB declared max would otherwise force an
+ * embedder (e.g. `kit run`) to reserve the full ceiling up front. */
if (t->module->memories[0].shared) {
- if (!t->module->memories[0].has_max ||
- t->module->memories[0].max_pages < t->module->memories[0].min_pages) {
- t->module->memories[0].has_max = 1;
- t->module->memories[0].max_pages = t->module->memories[0].min_pages;
- }
+ t->module->memories[0].has_max = 1;
+ t->module->memories[0].max_pages = t->module->memories[0].min_pages;
}
if (t->has_stack_pointer && t->stack_pointer_global < t->module->nglobals) {
t->module->globals[t->stack_pointer_global].init.imm = stack_top;