The JIT that runs makepad apps from source: lexer, front end, type checker, lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and warm/cold caches keyed by compiler stamp, provided crates bound late, startup images, live patching. User-facing name is `makepad run` (binary `makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal library name. `makepad check` reports rustc-style diagnostics with rustc error codes and checks a whole workspace (`--workspace`). Runs on macOS, Linux, Windows and Android. makepad-remote: one tool schema for apps and the WM (app/1): grabs, captures, traces, frame profiles and tweaks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
59 lines
1.8 KiB
Rust
59 lines
1.8 KiB
Rust
// 3.1 / 3.3: patching a recursive fn while frames of it are on another thread's stack.
|
|
// Each run releases the thread the previous run left parked at the bottom of a 100-deep
|
|
// recursion and prints its result, then parks a new one. Frames on the stack across an edit
|
|
// finish in the code they started in; fresh calls run the new body.
|
|
// v0: level k adds k, v1: 2k, v2: 3k (1+..+100 = 5050)
|
|
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
|
use std::sync::Mutex;
|
|
|
|
static PARKED: AtomicBool = AtomicBool::new(false);
|
|
static GO: AtomicBool = AtomicBool::new(false);
|
|
static DONE: AtomicBool = AtomicBool::new(false);
|
|
static RESULT: AtomicU64 = AtomicU64::new(0);
|
|
static HAVE: Mutex<bool> = Mutex::new(false);
|
|
|
|
fn bottom(hold: bool) {
|
|
if hold {
|
|
PARKED.store(true, Ordering::SeqCst);
|
|
while !GO.load(Ordering::SeqCst) {
|
|
std::thread::sleep(std::time::Duration::from_millis(1));
|
|
}
|
|
}
|
|
}
|
|
|
|
fn rec(n: u64, hold: bool) -> u64 {
|
|
if n == 0 {
|
|
bottom(hold);
|
|
return 0;
|
|
}
|
|
rec(n - 1, hold) + 2 * n
|
|
}
|
|
|
|
fn park_one() {
|
|
PARKED.store(false, Ordering::SeqCst);
|
|
GO.store(false, Ordering::SeqCst);
|
|
DONE.store(false, Ordering::SeqCst);
|
|
std::thread::spawn(|| {
|
|
let r = rec(100, true);
|
|
RESULT.store(r, Ordering::SeqCst);
|
|
DONE.store(true, Ordering::SeqCst);
|
|
});
|
|
while !PARKED.load(Ordering::SeqCst) {
|
|
std::thread::sleep(std::time::Duration::from_millis(1));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn run() {
|
|
let mut have = HAVE.lock().unwrap();
|
|
if *have {
|
|
GO.store(true, Ordering::SeqCst);
|
|
while !DONE.load(Ordering::SeqCst) {
|
|
std::thread::sleep(std::time::Duration::from_millis(1));
|
|
}
|
|
println!("out stacked {}", RESULT.load(Ordering::SeqCst));
|
|
}
|
|
println!("out fresh {}", rec(100, false));
|
|
park_one();
|
|
*have = true;
|
|
}
|