feat(compile): Phase 2 — native ops + direct calls (fib30 50s -> 0.076s, ~660x)
Two changes unlock native Janet speed in compile mode:
- Hot numeric primitives (+ - * < > <= >=) emit as native Janet SYMBOLS rather
than the variadic core fns, so Janet's compiler uses its arithmetic/compare
opcodes. = / not= / quot / rem / mod / division stay as core fns (their
semantics differ from Janet's). Trade-off: the strict non-number checks are
relaxed under compilation (documented perf-mode divergence).
- emit-invoke emits a DIRECT call (f arg...) when the callee is a function
reference (core/local/symbol/fn), instead of wrapping every call in jolt-call.
jolt-call is kept only for keyword/collection literals in call position
((:k m), ({:a 1} :a)) so IFn dispatch still works.
compiled fib(30): 3.4s -> 0.076s (native ceiling), faster than jank's 0.8s.
Updated compiler-test string assertions (core-+ -> +); compile-mode-test gains
native-op + IFn-dispatch cases; README documents compile mode. jpm test green.
This commit is contained in:
parent
f74af5dbc5
commit
3cf303578e
4 changed files with 59 additions and 16 deletions
12
README.md
12
README.md
|
|
@ -51,6 +51,18 @@ hello 42
|
|||
|
||||
`(init)` returns a context with `clojure.core` loaded. Each context is isolated; use separate contexts for separate environments.
|
||||
|
||||
### Compilation
|
||||
|
||||
By default Jolt tree-walks the interpreter. Passing `:compile?` compiles each form to Janet — `def`/`defn` persist in a per-context Janet environment and resolve across forms, hot numeric primitives (`+ - * < > <= >=`) emit native Janet ops, and function calls compile to direct calls (keyword/map/set still dispatch as IFn). For compute-heavy code this is dramatically faster — recursive `fib(30)` runs in ~0.08 s compiled vs ~50 s interpreted (≈600×), at native Janet speed:
|
||||
|
||||
```janet
|
||||
(def ctx (init {:compile? true}))
|
||||
(eval-string ctx "(defn fib [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))")
|
||||
(eval-string ctx "(fib 30)") ; → 832040, fast
|
||||
```
|
||||
|
||||
Compile mode is opt-in and still maturing: context-modifying forms (`ns`/`defmacro`/`deftype`/multimethods/…) always interpret, and the numeric-op inlining relaxes the strict non-number checks (e.g. `(< nil 1)`). Constructs the compiler doesn't yet handle fall back to errors rather than the interpreter (a hybrid fallback is planned).
|
||||
|
||||
## Host interop
|
||||
|
||||
Jolt exposes CLJS-style host interop through `.` on any Janet table or struct — a field holding a function is called with the receiver as the first argument:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue