fix: add libriscv Emscripten patches for 31-bit arena rebuild#9
fix: add libriscv Emscripten patches for 31-bit arena rebuild#9maceip wants to merge 1 commit intocursor/wasm-jit-optimizations-1523from
Conversation
The 31-bit arena OOB crash in Machine constructor is caused by upstream libriscv using `new PageData[]` which triggers signed overflow in Emscripten's wasm32 C++ runtime for 2GB+ allocations. This adds: - tools/libriscv-emscripten.patch: 7 local patches including the critical malloc fix in memory.cpp, dispatch optimizations, syscall tracing, and threaded_rewriter cross-segment branch fixes - Updated pin_libriscv.sh to auto-apply patches after checkout The patch is verified to apply cleanly against the pinned upstream commit (396f8c2). With this fix, `pin_libriscv.sh` produces the same patched libriscv tree that built the working friscy.wasm. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This is the final PR Bugbot will review for you during this billing cycle
Your free Bugbot reviews will reset on March 15
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| else | ||
| git -C "$TARGET_DIR" apply "$PATCH_FILE" | ||
| echo "[pin-libriscv] Patches applied successfully" | ||
| fi |
There was a problem hiding this comment.
Patch conflicts silently skip required fixes
High Severity
pin_libriscv.sh treats any git apply --check failure as “already applied or conflict” and then skips applying. If the patch no longer applies cleanly due to upstream drift, the script continues with an unpatched libriscv, reintroducing the Emscripten 31-bit arena crash the PR intends to prevent.
| } | ||
| + entry.result = (int64_t)cpu.reg(REG_ARG0); | ||
| + g_syscall_ring_idx++; | ||
| } |
There was a problem hiding this comment.
Global syscall trace causes cross-machine races
Medium Severity
The patch introduces g_syscall_ring and g_syscall_ring_idx as header-level globals shared by all Machine<W> instances. Multiple machines (or threads) calling Machine<W>::system_call concurrently can race on these globals and mix traces across instances, producing misleading diagnostics and potential undefined behavior from data races.


Summary
tools/libriscv-emscripten.patchcontaining 7 local patches to libriscv that are required for 31-bit arena to work under Emscripten/wasm32tools/pin_libriscv.shto auto-apply the patch after checking out the pinned upstream commitRoot Cause
The 31-bit arena OOB crash in Machine constructor (
wasm-function[55]) is caused by upstream libriscv usingnew PageData[n]wheren * 4096 >= 2GB. Emscripten's C++ runtimeoperator new[]computes the allocation size using signed arithmetic, which overflows for 2GB+ → OOB trap.The working prebuilt
friscy.wasmwas built from a locally-patched libriscv that usesmalloc()instead. Thepin_libriscv.shscript was overwriting these patches with a clean upstream checkout.What the patch contains
memory.cppmalloc+memsetinstead ofnew PageData[]under__EMSCRIPTEN__machine_inline.hpp-ENOSYSfor unhandled syscallscpu_dispatch.cppcpu_inaccurate_dispatch.cpptailcall_dispatch.cppthreaded_rewriter.cppbytecode_impl.cppTest plan
tools/pin_libriscv.sh— should checkout 396f8c2 + apply patchtools/harness.sh— should produce working friscy.wasmclaude --versionsmoke test passes with rebuilt artifacts🤖 Generated with Claude Code
Note
Medium Risk
Patches modify core VM execution and memory allocation paths (branch/jump dispatch, bytecode rewriting, syscall handling), which could introduce subtle correctness or performance regressions despite being targeted at Emscripten stability.
Overview
Ensures the vendored
libriscvcheckout is automatically patched for Emscripten/wasm32 builds, preventing 31-bit arena allocation failures and aligning local builds with the previously working patched artifact.Adds
tools/libriscv-emscripten.patchwhich (under__EMSCRIPTEN__) switches the unbounded arena allocation fromnew[]tomalloc+memsetwith matchingfree, loosens the threaded rewriter to emit base bytecode (instead ofINVALID) for cross-segment branches/jumps, and tweaks dispatch/bytecode handlers to better handle in-segment branches/jumps and reduce verbose logging.tools/pin_libriscv.shnow applies this patch after checking out the pinned upstream commit (skipping if already applied or conflicting).Written by Cursor Bugbot for commit 0a6c962. This will update automatically on new commits. Configure here.