Skip to content

fix: add libriscv Emscripten patches for 31-bit arena rebuild#9

Open
maceip wants to merge 1 commit intocursor/wasm-jit-optimizations-1523from
fix/libriscv-emscripten-patches
Open

fix: add libriscv Emscripten patches for 31-bit arena rebuild#9
maceip wants to merge 1 commit intocursor/wasm-jit-optimizations-1523from
fix/libriscv-emscripten-patches

Conversation

@maceip
Copy link
Owner

@maceip maceip commented Feb 15, 2026

Summary

  • Adds tools/libriscv-emscripten.patch containing 7 local patches to libriscv that are required for 31-bit arena to work under Emscripten/wasm32
  • Updates tools/pin_libriscv.sh to auto-apply the patch after checking out the pinned upstream commit

Root Cause

The 31-bit arena OOB crash in Machine constructor (wasm-function[55]) is caused by upstream libriscv using new PageData[n] where n * 4096 >= 2GB. Emscripten's C++ runtime operator new[] computes the allocation size using signed arithmetic, which overflows for 2GB+ → OOB trap.

The working prebuilt friscy.wasm was built from a locally-patched libriscv that uses malloc() instead. The pin_libriscv.sh script was overwriting these patches with a clean upstream checkout.

What the patch contains

File Fix
memory.cpp malloc+memset instead of new PageData[] under __EMSCRIPTEN__
machine_inline.hpp Syscall ring buffer tracing + -ENOSYS for unhandled syscalls
cpu_dispatch.cpp Optimized branch dispatch (stay in execute segment)
cpu_inaccurate_dispatch.cpp Same branch optimization
tailcall_dispatch.cpp Same branch optimization
threaded_rewriter.cpp Cross-segment branch handling (return base bytecode, not INVALID)
bytecode_impl.cpp Remove verbose jump logging, optimize JAL

Test plan

  • Run tools/pin_libriscv.sh — should checkout 396f8c2 + apply patch
  • Rebuild with tools/harness.sh — should produce working friscy.wasm
  • claude --version smoke 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 libriscv checkout 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.patch which (under __EMSCRIPTEN__) switches the unbounded arena allocation from new[] to malloc+memset with matching free, loosens the threaded rewriter to emit base bytecode (instead of INVALID) for cross-segment branches/jumps, and tweaks dispatch/bytecode handlers to better handle in-segment branches/jumps and reduce verbose logging. tools/pin_libriscv.sh now 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.

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>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

}
+ entry.result = (int64_t)cpu.reg(REG_ARG0);
+ g_syscall_ring_idx++;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant