Home Technology Minikotlin
Technology

Minikotlin

Key Points

struct.new Every class becomes a GC struct type; properties are real struct fields. Allocation is struct.new , not a hand-rolled heap of bytes. minikotlin is written from scratch in C and emits WebAssembly GC bytecode by hand — no JVM, no LLVM, no Binaryen, no Gradle.

class instance → struct.new Every class becomes a GC struct type; properties are real struct fields. Allocation is struct.new , not a hand-rolled heap of bytes. minikotlin is written from scratch in C and emits WebAssembly GC bytecode by hand — no JVM, no LLVM, no Binaryen, no Gradle. The compiler is itself compiled to WASM, so .kt source goes in and a running .wasm module comes out, entirely in the tab. // Main.kt + Greeter.kt compile as one unit fun main() { val g = Greeter("WebAssembly") println(g.greet()) (1..3).forEach { println("tick $it") } } No intermediate VM, no external backend. The frontend — lexer, parser, semantic analysis (it’s called mkf) — hands off to two of its own IRs before writing WASM-GC by hand. .kt files, compiled as one unit so they can see each other.The compiler ships as WASM itself, so it runs where your code runs — no toolchain to install. Not a token subset. These are lowered properly onto the WASM-GC type system — each one has end-to-end tests behind it. open /override ), interfaces with default methods, data class with generated equals /hashCode /copy , enum , and named, companion & anonymous object expressions.sealed hierarchies with exhaustive when , is checks compiled to ref.test , and flow-sensitive smart-casting that holds across branches.?. safe calls, ?: elvis and !! assertions — including nullable primitives, boxed through Any .fun id(x: T): T — lowered over a boxed Any representation.plus , get , …) dispatched to the LHS class, extension functions in their own namespace, and custom accessors with a backing field .launch , delay and coroutineScope — real suspension compiled as CPS over closures, with no Asyncify, no JSPI and no threads.String /Char operations, list higher-order functions (map /filter /forEach …), kotlin.math , and the scope functions let /apply /run /also /with .The lowering is the interesting part of any compiler. Four real ones — each maps a language construct onto a concrete WASM-GC mechanism, written by hand. Every class becomes a GC struct type; properties are real struct fields. Allocation is struct.new , not a hand-rolled heap of bytes. Open and overridden methods go through a per-class vtable. A virtual call is a function-reference load followed by call_ref — true dynamic dispatch. An is check and a when (x) { is T -> } arm compile to ref.test , and the narrowed value is reused through a ref.cast — smart-casting for free. A suspension point splits the function at the seam and captures the rest as a continuation. A bare delay hands a token to the host and resumes from setTimeout — genuinely off the stack. Everything below is supported Kotlin. The Studio highlights it with the compiler’s own lexer, then runs the resulting WASM in place. import kotlinx.coroutines.* sealed class Lane(val id: Int) class Fast : Lane(1) class Slow : Lane(2) fun Lane.pace(): Long = when (this) { is Fast -> 120 is Slow -> 300 } fun main() = runBlocking { val lanes = listOf(Fast(), Slow()) coroutineScope { lanes.forEach { lane -> launch { delay(lane.pace()) println("lane ${lane.id} in") } } } println("race over") } Each launch suspends at its delay and yields. The faster lane resumes first; coroutineScope waits for both children before the last line runs. No blocking and no Asyncify — the suspension is compiled into continuation closures. The sealed Lane , the when (this) { is … } dispatch and the Lane.pace() extension are all lowered for real, not interpreted. Make a project, write a few .kt files that compile as one unit so they can see each other, hit Run, and read the output — all in the tab, nothing installed.
GC (ORG) minikotlin (PERSON) WebAssembly GC (ORG) Binaryen (LOCATION) WASM (ORG) { val g = Greeter("WebAssembly (PERSON) VM (ORG) IRs (ORG) WASM-GC (ORG) LHS (ORG) CPS (ORG) Asyncify (ORG) setTimeout (ORG) Kotlin (PERSON) Lane(val (PERSON)
Originally published by Hacker News Read original →