How integralpilot/rustc_codegen_jvm works
Purpose and entry points
rustc_codegen_jvm is a Rust compiler backend that emits JVM Java 8+ class files from Rust crates, then packages runnable/self-contained JARs. The backend is loaded by rustc through the root crate (Cargo.toml, src/lib.rs). User-facing orchestration is the Cargo subcommand in cargo-jvm/src/main.rs; JAR assembly is a separate CLI in java-linker/src/main.rs.
Compilation boundary: rustc MIR to OOMIR
Rustc owns parsing, type checking, borrow checking, drop elaboration, and MIR production. The backend receives MIR and lowers it into Object-Oriented MIR (OOMIR), a JVM-oriented intermediate representation. Core definitions and interpretation support are in src/oomir.rs and src/oomir/interpret.rs; the backend integration and instrumentation are in src/lib.rs and src/instrumentation.rs.
Stage 1: MIR lowering
lower1 translates Rust constructs into Java-compatible classes, interfaces, methods, fields, and control flow while preserving Rust semantics. It contains the critical representation decisions for types, operands/places, statics, closures, trait objects, naming, and checked operations:
src/lower1.rs, src/lower1/types.rs, src/lower1/control_flow.rs.
This is the principal semantic boundary where Rust ABI/data-model features become OOMIR/JVM constructs.
Stage 2: OOMIR optimization
The first optimization layer transforms OOMIR before bytecode emission, including dataflow, copy propagation, reachability, and reorganization:
src/optimise1.rs, src/optimise1/dataflow.rs, src/optimise1/copyprop.rs.
Its output remains JVM-independent enough to be reasoned about as OOMIR, but is tailored to make bytecode generation tractable and efficient.
Stage 3: JVM bytecode generation
lower2 turns optimized OOMIR into class-file structures and serialized .class artifacts. It manages constant pools, JVM instruction generation, translation, large-method handling, second-pass optimization, and verifier-required stack-map frames:
src/lower2.rs, src/lower2/jvm_gen.rs, src/lower2/stackmaps.rs.
This is the hard JVM verification boundary: generated code must satisfy JVM operand-stack, control-flow, and class-file constraints.
Packaging and developer workflow
cargo-jvm wraps Cargo using the pinned nightly and JVM target, supports build/run/test/package workflows, invokes Java tooling, and locates generated artifacts. Relevant implementation paths are cargo-jvm/src/main.rs, cargo-jvm/src/lib.rs, and cargo-jvm/build.rs. java-linker packages generated classes with runtime classes and manifest metadata into JARs (java-linker/src/main.rs). Material external requirements are rustup/pinned nightly, Cargo/rustc internals, Python 3 for repository automation, Git, and a JDK with java, javac, and jar.
Runtime and standard-library adaptation
Generated code depends on a Java runtime library implementing Rust-specific behavior: pointer virtualization, numeric types, intrinsics, deterministic drop dispatch, panic/unwind support, threading, files, and networking. Key boundary paths are runtime/src/Pointer.java, runtime/src/RuntimeSupport.java, and runtime/src/PanicSupport.java. The virtual-MMU pointer layer permits raw pointers, transmute, unions, and atomic operations without violating GC or bytecode verification.
Rust std support is supplied by patches plus JVM platform overlays rather than a native OS layer: std/patches/0001-jvm-bootstrap.patch, std/overlay/std/src/sys/fs/jvm.rs, and std/overlay/std/src/sys/net/connection/jvm.rs. These bridge Rust APIs to the Java runtime/NIO and JVM services.
Execution model and interop
The output runs inside a JVM, with HotSpot JIT responsible for much runtime optimization. Rust structs map to Java classes, traits to interfaces, enums to base/subclass families, closures/function types to single-method interfaces, and trait-object dispatch to interface references. Java-facing integration examples establish the intended direct interop boundary: tests/integration/lambda_callbacks/Main.java, tests/integration/trait_implementors/Main.java, and tests/integration/cdylib/Main.java.
Main entry points: RuntimeSupport.java Java runtime support · main.rs java-linker · lower2.rs OOMIR → class files · lower1.rs MIR → OOMIR lowering
Components 17
Developer workflow
- cargo-jvm · Builds, runs, tests, and packages JVM-targeted Rust crates.
cargo-jvm/src/main.rs - Pinned rustc toolchain · Provides Rust analysis and MIR through rustc internals.
- java-linker · Combines generated classes, runtime classes, and manifest metadata.
java-linker/src/main.rs
Compiler backend
- rustc codegen backend · Loaded by rustc to compile crate MIR into JVM artifacts.
src/lib.rs - Rust MIR · Typed and elaborated control-flow input owned by rustc.
- MIR → OOMIR lowering · Maps Rust data-model and ABI semantics to JVM-oriented constructs.
src/lower1.rs - OOMIR · Object-oriented MIR with interpretation support.
src/oomir.rs - OOMIR optimization · Performs dataflow, copy propagation, reachability, and reorganization.
src/optimise1.rs - OOMIR → class files · Builds constant pools, JVM instructions, and serialized class artifacts.
src/lower2.rs - Verifier stack maps · Emits verifier-required operand-stack frames.
src/lower2/stackmaps.rs - Generated .class files
JVM runtime and std
- Java runtime support · Implements pointer virtualization, intrinsics, drops, panics, and platform services.
runtime/src/RuntimeSupport.java - Virtual-MMU pointers · Supports raw-pointer features while preserving GC and bytecode safety.
runtime/src/Pointer.java - Rust std JVM overlay · Bridges Rust filesystem and networking APIs to Java and NIO.
std/overlay/std/src/sys/fs/jvm.rs
JVM execution
- Runnable JAR · Self-contained application package.
- JVM / HotSpot · Verifies classes and JIT-optimizes execution.
- Java callers · Java code can directly use generated classes, interfaces, and callbacks.
tests/integration/lambda_callbacks/Main.java
Connections 20
- cargo-jvm → Pinned rustc toolchain: invokes
- Pinned rustc toolchain → Rust MIR: produces
- Pinned rustc toolchain → rustc codegen backend: loads
- Rust MIR → MIR → OOMIR lowering: lowers
- rustc codegen backend → MIR → OOMIR lowering: orchestrates
- MIR → OOMIR lowering → OOMIR: emits
- OOMIR → OOMIR optimization: optimizes
- OOMIR optimization → OOMIR → class files: optimized OOMIR
- OOMIR → class files → Verifier stack maps: computes
- Verifier stack maps → Generated .class files: verifies emission
- OOMIR → class files → Generated .class files: serializes
- cargo-jvm → java-linker: packages through
- Generated .class files → java-linker: packages
- Java runtime support → java-linker: bundles
- Virtual-MMU pointers → Java runtime support: provides memory model
- Rust std JVM overlay → Java runtime support: uses Java services
- java-linker → Runnable JAR: assembles
- Runnable JAR → JVM / HotSpot: runs on
- Java runtime support → JVM / HotSpot: executes within
- Java callers → Runnable JAR: uses generated API