Commit 41992c2
Session D: Interpreter ↔ codegen JIT dispatch wiring
End-to-end: parse OMC source → compile to bytecode → JIT eligible
fns in dual-band mode → register dispatch hook on Interpreter →
JIT-compiled native code runs in place of tree-walk for those fns.
The mechanism is proven via integration tests that drive the full
pipeline. The CLI-level `OMC_HBIT_JIT=1` env var is one small
follow-up away (extracting omnimcode-cli to a new package — see
deferred Session D.5 task; the workspace-cycle constraint prevents
adding codegen as a dep of core's existing binary).
Codegen API additions:
- `JitContext::jit_module(&Module) -> HashMap<String, JittedFn>`:
walks user fns, attempts dual-band lowering on each, returns
the successes as arity-tagged raw fn pointers. Failed fns are
silently skipped — and crucially, their partial LLVM IR is now
erased from the module so JIT finalization for the rest of the
module doesn't crash on broken IR (`function.delete()` after
the lowering errors).
- `JittedFn { arity, fn_ptr: *const () }` with `call(&[i64])`
dispatcher for arities 0..=4. Uses transmute to cast the raw
pointer to the right `unsafe extern "C" fn(...) -> i64`
signature based on arity.
- `extract_raw_fn_ptr` helper: typed `engine.get_function::<F>`
per arity, then `JitFunction::into_raw()` for storage.
(Discovered the bug: `engine.get_function_address` returned
garbage where the typed `get_function::<F>` produces correct
fn pointers — sticking with the typed path.)
Codegen lowerer fix (applies to BOTH scalar and dual-band):
- `bind_params_into_locals()` now runs at fn entry. The OMC
bytecode compiler emits `Op::LoadVar("x")` for parameter access
in fn bodies (treating params as already-bound locals); the
bytecode VM and tree-walk both pre-populate these bindings
before executing the body. Without this fix, the JIT was
reading uninitialized allocas — returning pointer-looking
garbage instead of the param value (the symptom that broke
the first integration test before it was diagnosed).
Interpreter additions:
- `JitDispatch = Rc<dyn Fn(&str, &[Value]) -> Option<Result<Value, String>>>`
type alias for the dispatch closure.
- `Interpreter::jit_dispatch: Option<JitDispatch>` field.
- `Interpreter::set_jit_dispatch(Some(hook))` setter (the
embedder API the future omnimcode-cli will call).
- `invoke_user_function_at` consults the hook BEFORE running the
tree-walk body. `Some(_)` return short-circuits tree-walk;
`None` falls through. Marshalling Value↔i64 happens in the
hook closure (decoupled from core).
Tests (5 new integration tests, all passing):
- jit_dispatch_routes_simple_int_fn: `double(21) == 42` via JIT
- jit_module_returns_callable_fn_directly: isolation — call JIT'd
fn without going through Interpreter (proves jit_module's
fn-ptr extraction)
- jit_dispatch_matches_tree_walk_factorial: factorial(10) == 3.6M,
matches tree-walk-only run
- jit_dispatch_matches_tree_walk_sum_loop: while loop with two
locals matches across both code paths
- jit_dispatch_falls_through_on_unsupported_fn: a string-using fn
silently skipped by JIT (delete() of partial IR), int fn still
routes through JIT, both produce correct outputs
Workspace state: 19/19 codegen tests green, 149/149 omnimcode-core
Rust unit tests green, 18/18 OMC harmonic-lib tests green.
Deferred to Session D.5: extract omnimcode-cli, wire OMC_HBIT_JIT
to populate set_jit_dispatch from inside main.rs.
Deferred to Session E: AVX-512 path (`<8 x i64>` carrier with
explicit LLVM intrinsics), benchmark harness measuring actual
speedup vs tree-walk and bytecode VM.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent e9f0fbc commit 41992c2
4 files changed
Lines changed: 429 additions & 0 deletions
File tree
- omnimcode-codegen
- src
- tests
- omnimcode-core/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
| 106 | + | |
106 | 107 | | |
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
110 | 141 | | |
111 | 142 | | |
112 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
59 | 124 | | |
60 | 125 | | |
61 | 126 | | |
| |||
107 | 172 | | |
108 | 173 | | |
109 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
110 | 257 | | |
111 | 258 | | |
112 | 259 | | |
| |||
187 | 334 | | |
188 | 335 | | |
189 | 336 | | |
| 337 | + | |
190 | 338 | | |
191 | 339 | | |
192 | 340 | | |
193 | 341 | | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
194 | 367 | | |
195 | 368 | | |
196 | 369 | | |
| |||
0 commit comments