rustc_codegen_jvm π
A custom Rust compiler backend that emits Java Virtual Machine bytecode.
Compile your Rust code into a runnable .jar on JVM 8+!
π Table of Contents
- Demos
- Features
- How It Works
- Prerequisites
- Installation & Build
- Usage
- Running Tests
- Project Structure
- Contributing
- License
π₯ Demos
All examples live in tests/binary and are compiled to JVM bytecode & run/tested on the CI on every commit. Some exciting demos made in pure-Rust include:
- RSA encryption/decryption
- Binary search algorithm
- Fibonacci sequence generator
- Collatz conjecture verifier
- Large prime generator
- Use of nested data structures: enums, structs, tuples, arrays, slices (enums, structs - both tests use arrays and tuples)
- Implementation blocks and traits (including dynamic dispatch!)
- β¦and more!
β¨ Features
- Minimal
no_std&no_coreprograms viajvm-unknown-unknown - Optimisations including constant folding and propogation, dead code elimination, and more to generate efficient JVM bytecode
- Basic
coresupport on host target for JVM output - Arithmetic (integers + floats, incl. checked ops)
- Comparisons, bitwise & logical ops
- Control flow:
if/else,match,for,while,loop - Type casting (
as), primitive types - Function calls (recursion supported)
- Arrays & slices with nested indexing
- Structs, tuples, enums (both Cβlike and Rustβstyle)
- Executable
.jargeneration for binary crates - Mutable borrowing, references, and dereferencing
- Implementations for ADTs, including using and returning
self,&self,&mut self - Traits, including dynamic dispatch (
&dyn Trait) - Integration tests for all features, in debug and release modes
π§ Next Milestone: Full support for the Rust core crate.
βοΈ How It Works
- Rustc Frontend β MIR
Standardrustcparses your code into Midβlevel IR (MIR). - MIR β OOMIR
Custom βObjectβOriented MIRβ simplifies MIR into OOPβstyle constructs.
(seesrc/lower1.rs) - OOMIR optimiser
Optimises OOMIR using constant folding, dead code elimination, and more.
(seesrc/optimise1.rs)- Constant Folding: Evaluates constant expressions at compile time.
- Constant Propagation: Replaces variables with their constant values.
- Dead Code Elimination: Removes unused code paths.
- Algebraic Simplification: Simplifies expressions using algebraic identities.
- OOMIR β JVM Classfile
Translate to.classfiles usingristretto_classfile.
(seesrc/lower2.rs) - R8 pass
r8adds stack map frames (neeeded to run on JVM 8+) and applies some further optimisations. - Link & Package
java-linkerbundles.classfiles into a runnable.jarwithMETA-INF/MANIFEST.MF.
π Prerequisites
- Rust Nightly (
rustup default nightly) - Gradle 8.5+ (
gradlein PATH) - JDK 8+ (
javain PATH, and theJAVA_HOMEenvironment variable set) - Python 3 (
python3in PATH)
π Installation & Build
# Clone & enter repo git clone https://github.com/IntegralPilot/rustc_codegen_jvm.git cd rustc_codegen_jvm # Build all components using the build script. # This single command handles all dependencies and recompiles only what's necessary. # On Linux or macOS: ./build.py all # On Windows, or if the above gives a "permission denied" error: python3 build.py all
This will intelligently build all necessary components in the correct order:
- The Kotlin library shim (
library/) - The shim metadata file (
core.json) - The
java-linkerexecutable - The
rustc_codegen_jvmbackend library - Configuration files (
config.toml,jvm-unknown-unknown.json) - Vendored dependencies like R8
The script uses timestamp checking, so subsequent runs of ./build.py will be very fast, only rebuilding parts of the project that have changed.
π Usage
-
Configure your project In your Rust project directory, create or update
.cargo/config.tomlby copying the generated template (it will be at the root of this repository after running the build script). Also, yourCargo.tomlneeds to contain the following (used to pass flags differentiating between debug and release builds to the linker):cargo-features = ["profile-rustflags"]
-
Build with Cargo
cargo build # debug cargo build --release # optimized
-
Run the
.jarjava -jar target/debug/deps/your_crate*.jar # debug java -jar target/release/deps/your_crate*.jar # release
π§ͺ Running Tests
Ensure the toolchain is built:
# On Linux/macOS: ./build.py all # On Windows: python3 build.py all
Then, run the test suite:
# Run tests in debug mode python3 Tester.py # Run tests in release mode python3 Tester.py --release
Look for β
All tests passed! or inspect .generated files on failure.
π Project Structure
.
βββ src/ # rustc_codegen_jvm backend
β βββ lib.rs
β βββ lower1.rs # MIR β OOMIR
β βββ lower2.rs # OOMIR β JVM bytecode
β βββ oomir.rs # OOMIR definitions
βββ java-linker/ # Bundles .class files into .jar
βββ tests/binary/ # Integration tests
βββ library/ # Kotlin shim for Rust core library
βββ shim-metadata-gen/ # Generates core.json metadata
βββ proguard/ # .pro rules used for r8
βββ build.py # Main build script (replaces Makefile)
βββ config.toml.template
βββ jvm-unknown-unknown.json.template
βββ Tester.py # Test runner script
βββ LICENSE, LICENSE-Apache
π€ Contributing
Contributions, issues & PRs welcome! :)
π License
Dualβlicensed under MIT OR Apache 2.0 at your option: https://opensource.org/licenses/MIT https://www.apache.org/licenses/LICENSE-2.0