kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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:
Msrc/arch/wasm/emit.c | 16++++++++--------
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;