Files
hakorune/docs/development/roadmap/phases/phase-11.7_jit_complete/PLAN.md

82 lines
3.9 KiB
Markdown
Raw Normal View History

# Phase 11.7 JIT Complete Plan (Cranelift)
Goal
- Ship a complete JIT backend (Cranelift) for MIR Core15 with Semantics layer as the single source of truth, GC sync/async support, and full Box/Extern integration. Keep DX simple and crossplatform.
Milestones
1) Bootstrap (Infra + Skeleton)
- Add backend module: `src/backend/cranelift/{mod.rs,context.rs,lower.rs,jit.rs,object.rs}`
- Context: host ISA, FunctionBuilder, Module (JIT/Object) setup helpers
- Runner: `--backend cranelift` execution path; feature flag reuse (`cranelift-jit`)
- Minimal ops: Const i64/f64/bool/null/string → CLIF values; Return; straightline add/sub
- Smoke: `apps/tests/ny-echo-lite` returns 0 via JIT
2) Core MIR15 Lowering (Parity with VM)
- Control: Jump/Branch/Phi, Load/Store (alloca on entry; i1↔i64 widen/narrow)
- Unary/Binary/Compare: int/float/ptr eq/ne; logical and/or via to_bool
- TypeOp (when needed) + pointer/int casts (handle→i64/i8* via ABI helpers)
- Strings: concat via NyRT shims (`nyash.string.concat_*`)
- BoxCall (byid): fixed/tagged args (<=4) + vector path; handlefirst returns (i64/ptr)
- ExternCall: `env.console.*`, `env.debug.trace`, `console.readLine` via NyRT shims
- Smokes: array/map/vinvoke(size/ret), echo; compare outputs with VM
3) GC Cooperation
- Sync barriers: insert read/write barriers at Load/Store & NewBox as per VM semantics
- Async safepoints: at call sites/loop backedges; NyRT entry glue to yield if required
- Tests: targeted barrier smoke (array/map mutations) + perf sanity (no excessive barriers)
4) Parity + Stability
- UnsupportedLegacyInstruction: maintain strict mode; allow env override for debug
- Error reporting: source op prettyprint, MIR value ids in error messages
- Logging: `NYASH_CLI_VERBOSE=1` shows JIT compile stages + object sizes (optional)
- Doc/Doctor script: `tools/doctor.ps1`/`.sh` for quick env checks (optional nicetohave)
5) AOT (Optional within 11.7 if time)
- `cranelift-object` emit: `.o` for main; link with NyRT → exe (`tools/build_cl.*`)
- Windows: clang/lld link; Linux: cc link; parity with LLVMs scripts
Instruction Coverage (MIR Core15)
- Const, UnaryOp, BinOp, Compare, TypeOp
- Load, Store, Phi, Jump, Branch, Return
- Call, NewBox, BoxCall, ExternCall
ABI & Shims
- Handlefirst: receiver/values normalized to i64; ptr/int casts via helpers
- NyRT shims used: `nyash.console.*`, `nyash.debug.trace`, `nyash.console.readline`,
`nyash_string_new`, `nyash.string.concat_*`, `nyash_array_*_h`, `nyash.instance.*_h`,
plugin invoke (byid tagged, vector variants)
Semantics Integration (new in 11.7)
- Add `Semantics` trait as unified MIR semantics API.
- Provide `SemanticsVM` (exec) and `SemanticsClif` (lower) so the same MIR walks yield identical behavior across VM and JIT.
- Use `semantics::MirInterpreter` for parity tests; prefer zerocost abstractions with static dispatch.
Status Notes (20250901)
- LLVM AOT: closed for now due to Windows dependency weight; Cranelift is the mainline.
- VM: safepoint/barrier/scheduler wired and observable (CountingGc).
- JIT: `nyash.rt.checkpoint`/`nyash.gc.barrier_write` symbols are available via NyRT; LowerCore needs to emit safepoints and barriers; Await lowering pending.
Deliverables
- Code: Cranelift backend files + runner integration
- Tools: build/run scripts for JIT/AOT; updated smokes to exercise CL route
- Docs: this plan + CURRENT_TASK.md; brief README how to run JIT
Risks & Mitigations
- Pointer/int mismatch → normalize via i64/ptr helpers in one place; add asserts
- Barrier placement overhead → start with conservative placement; measure; trim if safe
- Windows toolchain variance → Cranelift avoids external LLVM; keep MSVC only
Timeline (indicative)
- Week 1: Milestone 1 + 2 (most ops) → basic smokes green
- Week 2: GC barriers + safepoints, full parity sweep; docs/tools polish
- Optional: AOT via clobject emit & link scripts