Port of Octoscript's re-entrancy and hardening items onto the new VM host contract.
- vm.rs: run_core no longer caches a raw pointer into the active body's opcode
vector across native calls. Each opcode is copied through a scoped
`bodies.borrow()` that ends before dispatch, so a native handler that
re-enters `eval` and replaces the body's parser cannot leave a dangling
pointer. Regression: reentrant_reload_of_the_active_body_does_not_keep_an_opcode_pointer.
- thread.rs: ScriptThreads::set_current validates the index before updating
the cached pointer (set_current_thread_id routes through it); update_ptr is
bounds-checked via get_mut; cur/cur_ref/trap use release-mode assert!.
Regressions: selecting_an_unknown_current_thread_panics_before_pointer_update,
empty_threads_reject_current_access_in_release_builds.
- handle.rs: ScriptHandleGc: Any; is/downcast_ref/downcast_mut compare
Any::type_id, removing the overridable ref_cast_type_id hook.
Regression: handle_downcasts_use_the_concrete_any_type.
- suggest.rs: value previews truncate at character boundaries.
Regression: preview_truncation_preserves_utf8_boundaries.
- libs/regex utf8.rs: iterator entry uses `self.range_stack.pop()?` instead of
a never-advancing `while let`, replacing upstream's #[allow(clippy::never_loop)].
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgSir4cQyaakzPju4h6smw
(cherry picked from commit ee7729e71c1408f61ec8f9083a79bdf9117d31a7)
(cherry picked from commit cdbc33e8ac1683fcdeb6e9dcb076e26ce5d23360)
Squash of 34 work commits (Sep 2–9):
cb97fc5 vj: the loop splat — a song sliced into per-stem, beat-quantized loops on the APC40 grid
5b309b3 vj: 32-bit usize constants no longer overflow on wasm32
441d604 vj: dropped or picked audio publishes into the connected store
6be1118 vj: the whole app on the web — site store for content, embedded store for local imports, native-only seams Unavailable
aa7345d vj: the whole app on the web — site store for content, embedded store for local imports, native-only seams Unavailable
511048c vj: no filesystem paths on the web startup path — the store is the disk there
78bfd5c vj: the web explorer shows the store's tracks — the listing reaches the rows
cc8ee5c vj: the web music browse fires when the store is ready, and startup never stalls the UI thread
53f0e96 vj: the DJ/VJ app exposes itself to the desktop assistant
ffd62da dj-pack + vj: the demo cache carries every per-track analysis — slices, beat grid, overviews — and the web app reads instead of computes
f35dd1d vj: effect thumbnails actually render and persist on the web
6fddf9e vj: loading a track onto a deck fetches and decodes its audio on the web
5c78ac0 vj: web effect thumbnails show the effect, not a black frame
21fce80 vj: stale-recipe thumbnails are swept from storage on startup
afdffd7 vj: clicking an effect tile puts it in a channel on the web vj: clicking an effect tile puts it in a channel on the web
cc1f256 vj: cached thumbnails appear within a second vj: cached thumbnails appear within a second and the pipeline never hangs
4f98c73 vj: a deck shows what it is loading — fetch, decode, stems — with real progress vj: a deck shows what it is loading — fetch, decode, stems — with real progress
66617cd vj: stem separation is a setting — hub by default, local only on purpose, never auto-started on the operator's machine
645de42 vj: a deck plays and draws while it decodes, and the stems swap in sample-aligned — one streaming path for native and web
c3d9314 vj: each deck's transport sits on two larger rows under its mixer — every button visible on both decks
b0ec2a4 vj: the audio engine owns the mix state — the UI sends commands over a wait-free ring and reads snapshots, no lock on either thread
acb8689 vj: the loop grid is built and refined on the web too — one pool + channel path for both targets
707d702 vj: every worker thread comes from the platform spawner — the loop ½ button no longer panics the web app
71c0e1e vj: a paused deck is never moved by sync or the loop grid, a loop cell plays exactly its bars with the view held, and the stems banner clears
35ac364 vj: the catalog runtime pump no longer logs every poll
5a9fa62 vj: no timed std waits on wasm workers — blocking channels, one tagged deck+background inbox for the stems/lyrics workers, a lost-wakeup fix in the thumb queue, native-only gates on the video decode loops; the DJ web app stops losing a worker at start-up
32bea89 vj: a playing slice keeps the big waveform of the whole sample — the active slot is an overlay on it (accent band, bracket edges, wrapped playhead, slot number) while the lane's viewport stays fixed; the grid cells are selectors only, their mini waveforms are gone
dd51a02 vj: a go-to-start transport button per deck — seeks to 0:00 through the normal seek path, keeps the playing state, leaves the loop alone; skip_start.svg icon; decks test
bf9418e vj: ironfish / synth rack, program mix, and a clean release check
28016ca vj: keep generated clips at the head of the grid
f45793a vj: batch live video publishes into grid rows
75b295c vj: synchronize decks and queue remote stem processing
ba662d2 Add responsive DJ and VJ modes with system and black-orange appearances
a18b2ee vj: route DREAM runs through the shared Flow engine
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>