// KOTLINRS — KOTLIN IN RUST

kotlinrs v0.1.6 · Kotlin on fusevm · lex/parse → AST → bytecode → Cranelift JIT · no JVM · a fusevm language host (with zshrs, stryke, awkrs, elisprs, rubylang, phplang, pythonrs, node-js) · MIT · in active development

Report Reference GitHub

>_KOTLINRS REFERENCE

A compiled Kotlin runtime written in Rust. Source is lexed and parsed to an AST, lowered to fusevm bytecode, and executed on the same language-agnostic VM + three-tier Cranelift JIT that hosts zshrs, stryke, awkrs, elisprs, rubylang, phplang, pythonrs, and node-js. No JVM, no kotlinc, no .class files. In active development.

What it is

kotlinrs runs Kotlin programs as ordinary compiled bytecode: it lexes and parses the source, lowers it to fusevm instructions, and lets the shared engine execute and JIT-compile them. There is no bespoke VM or tree-walker — arithmetic, comparison, control flow, locals, and calls lower to native fusevm ops so the Cranelift JIT can trace hot loops. A small runtime host (src/host.rs) supplies only the three Kotlin behaviours the universal ops cannot express: the Boolean/Double display form (true/false, 1.0) and truncating integer / and % with an ArithmeticException on a zero divisor.

It is another language hosted on fusevm, the shared bytecode VM and Cranelift JIT. kotlinrs carries no VM or JIT of its own.

Architecture

Kotlin source  →  lexer  →  parser (AST)  →  lower to fusevm bytecode  →  fusevm VM + Cranelift JIT
                                                    │
                                          KtHost extension handler (toString / idiv / imod)

fusevm-hosted

No local vm.rs / jit.rs. Kotlin is lowered to fusevm bytecode and executed on the shared three-tier Cranelift JIT.

Native ops

Arithmetic, comparison, if/while/for, locals, and calls compile to native fusevm ops (Add, NumLt, Call, …) — so the JIT can trace hot loops, not a bespoke interpreter.

Thin host

Only Kotlin display form and truncating integer //% are handled by the extension handler; everything else is language-agnostic bytecode.

Editor tooling

An LSP server (--lsp), a DAP debugger (--dap), inline Rust FFI (rust { … }), and bytecode disassembly (--disasm) ship in-tree.

Example

fun fib(n: Int): Int {
    if (n < 2) return n
    return fib(n - 1) + fib(n - 2)
}

fun main() {
    for (i in 0..10) {
        println("fib($i) = ${fib(i)}")
    }

    var total = 0
    for (x in 1..4) total += x
    println(total)          // => 10

    val half = 7 / 2        // truncating Int division => 3
    println(half)
}

Toolchain

--lsp

A Language Server Protocol server on stdio: parser-driven diagnostics, plus completion and hover over the whole 273-entry reference corpus — keywords, operators, types, builtins, throwables and every stdlib member — each with a signature, a description and an example (src/lsp.rs).

--dap

A Debug Adapter Protocol server on stdio: source-line breakpoints, step in/over/out, a stack frame, and live local values, with the debuggee's stdout streamed as output events (src/dap.rs).

rust { … } FFI

An inline rust { pub extern "C" fn … } block compiles to a cached cdylib whose exported functions are callable by name from Kotlin (src/rust_ffi.rs, fusevm::ffi).

Introspection

--dump-tokens, --dump-ast, and --disasm (a fusevm bytecode disassembly listing) print each stage and exit.

Status & roadmap

ComponentStateNotes
Lexer / parser → ASTImplementedKotlin subset: fun, val/var, if/while/for, ranges, string interpolation (src/lexer.rs, src/parser.rs).
AST → fusevm bytecode loweringImplementedNative arithmetic / comparison / control flow; no local VM (src/compiler.rs).
Kotlin runtime hostImplementedtoString() display form, truncating integer //%, zero-divisor ArithmeticException, plus the object heap behind classes / collections / lambdas / throwables (src/host.rs).
Exceptions (try/catch/finally/throw)Implementedtry as an expression; the JVM throwable hierarchy in catch; host faults (/ 0, !!, bad index) catchable. fusevm has no unwind opcode, so an in-flight exception is a host pending slot plus per-statement unwind checks — emitted only in programs that use exceptions.
Standalone kotlin binaryImplementedRun .kt files and -e one-liners (src/main.rs).
LSP server (--lsp)ImplementedParser diagnostics, keyword/type/builtin completion and hover (src/lsp.rs).
DAP adapter (--dap)ImplementedLine breakpoints, step in/over/out, stack + live locals, streamed stdout (src/dap.rs).
Inline Rust FFI (rust { … })ImplementedCached cdylib, exported functions callable by name (src/rust_ffi.rs, fusevm::ffi).
Bytecode disassembly (--disasm)ImplementedShared fusevm::Chunk::disassemble listing.
Classes, data class, collections, lambdasImplementedConstructor and body properties, companion object, inheritance (open/abstract/sealed/interface, virtual dispatch), generated toString/equals/copy/componentN, List/Map/Set/Pair/Triple, arrays, ranges, first-class lambdas and the higher-order collection functions.
Extensions, scope functions, parametersImplementedExtension functions dispatched by the receiver's static type; both scope-function families (let/also/takeIf/takeUnless and run/apply/with); default, named and vararg arguments; local funs that recurse; as/as? casts; top-level properties and by lazy; runCatching/Result; and a var a lambda writes to, boxed so the write reaches the enclosing frame.
Constructors, delegation, invocation, String collectionsImplementedSecondary constructors with Kotlin's initialization ORDER (property initializers and init blocks interleaved in declaration order; a secondary's body after the constructor it delegates to); interface delegation (class C(x: I) : I by x), forwarding I's defaulted members too, so a default method calls the delegate's implementation rather than the delegating class's override; property delegation through a custom operator fun getValue/setValue; invoking the result of a call (f()(), lst[0](7), { x: Int -> x }(9), operator fun invoke); and the collection functions on a String receiver, whose result type follows kotlin.text"abc".map { … } is a List<Char> but "abc".filter { … } is a String.
Type arguments, inferred and written downImplementedA type variable takes its width from the use site: the argument for fun <T> id(x: T): T, the receiver's type argument for a member of a generic class (stored, var, body and computed properties and method results; nested instantiations and several type parameters resolve per position; a call selecting a SECONDARY constructor reads its own parameters), and the argument written down in SOURCE — a function result (fun mk(): Box<Int>), a parameter, a property of another class, a supertype (class Sub : Box<Int>()), a top-level or local val annotation, and a cast. Unresolved stays untyped, which narrows nothing, so a String or Double argument never reaches the 32-bit wrap.
Variance, secondary-constructor super, wider stdlibPlannedVariance and bounds are parsed and discarded (a type test against a NON-reified type parameter is rejected rather than answered; a reified one is compiled); a supertype argument is substituted for a DIRECT parent only; an explicit : super(args) from a secondary constructor and the rest of the standard-library surface are pending.

Building from source

kotlinrs builds as a standalone Rust crate (it is not a workspace member of the meta repo):

# clone
git clone https://github.com/MenkeTechnologies/kotlinrs
cd kotlinrs

# build (produces target/debug/kotlin)
cargo build

# run a script or a one-liner
./target/debug/kotlin examples/fib.kt
./target/debug/kotlin -e 'println(6 * 7)'

# editor tooling
./target/debug/kotlin --lsp        # Language Server Protocol on stdio
./target/debug/kotlin --dap        # Debug Adapter Protocol on stdio
./target/debug/kotlin --disasm examples/hello.kt

# run tests
cargo test

fusevm is pulled from crates.io with the jit and ffi features.

License

kotlinrs is MIT licensed — free and open source. See LICENSE.

Repository & links

  • Engineering reportreport.html (architecture, fusevm hosting, roadmap, dependency posture)
  • Language referencereference.html (keywords, operators, types, builtins, throwables, stdlib members)
  • Sourcegithub.com/MenkeTechnologies/kotlinrs
  • The shared VMfusevm (also behind zshrs, stryke, awkrs, elisprs, rubylang, phplang, pythonrs, node-js)