# Rava
A Java interpreter written in C99. Fast. Beats Python.
Author: retoor <retoor@molodetz.nl>
## Introduction
Rava is a complete Java interpreter. Lexer, parser, semantic analyzer, IR generator, and runtime VM. All in C.
What it does:
- Tokenizes Java source code
- Builds an AST
- Type checks everything
- Generates bytecode
- Executes on a stack-based VM
What it supports:
- Primitives: int, long, double, boolean, char
- Arrays and strings
- Objects and instance methods
- Inheritance
- Control flow: if/else, while, for, break, continue
- File I/O
- Recursion
Compiles with zero warnings. No memory leaks.
## Installation
```bash
make
```
Done.
## Usage
Example Rava source:
```java
public class Fibonacci {
public static int fib(int n) {
if (n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
public static int main() {
System.out.println(fib(30));
return 0;
}
}
```
Run the benchmark:
```bash
make benchmark
./test_benchmark
```
## Performance
Rava beats Python on all benchmarks.
| Benchmark | Rava | Python | Speedup |
|---------------|--------|--------|--------------|
| Fibonacci(30) | 257ms | 291ms | 1.13x faster |
| Primes(100k) | 273ms | 416ms | 1.52x faster |
| Sum(10M) | 666ms | 1104ms | 1.66x faster |
All three benchmarks. Rava wins.
The optimiziii took 9 phases. Started at 1402ms for Fibonacci. Now 257ms. That is 5.5x faster.
## Structure
```
rava/
├── lexer/
│ ├── lexer.h
│ ├── lexer_tokenizer.c
│ ├── lexer_keywords.c
│ └── lexer_literals.c
├── parser/
│ ├── parser.h
│ ├── parser.c
│ ├── parser_expressions.c
│ ├── parser_statements.c
│ ├── parser_declarations.c
│ └── parser_printer.c
├── types/
│ ├── types.h
│ └── types.c
├── semantic/
│ ├── semantic.h
│ ├── semantic.c
│ ├── symbol_table.h
│ └── symbol_table.c
├── ir/
│ ├── ir.h
│ ├── ir.c
│ ├── ir_gen.h
│ └── ir_gen.c
├── runtime/
│ ├── runtime.h
│ ├── runtime.c
│ ├── nanbox.h
│ ├── fastframe.h
│ ├── fastframe.c
│ ├── labeltable.h
│ ├── labeltable.c
│ ├── methodcache.h
│ ├── methodcache.c
│ ├── superinst.h
│ └── superinst.c
├── tests/
│ └── *.c
├── examples/
│ └── *.java
├── docs/
│ └── *.md
└── Makefile
```
## Optimization
Rava implements proven interpreter optimization techniques. Same stuff V8, LuaJIT, and CPython use.
### NaN Boxing
64-bit value representation. Packs all types into 8 bytes instead of 16. Half the memory. Faster stack ops.
Location: `runtime/nanbox.h`
### Fast Frames
Pre-allocated frame pool. No heap allocation per function call. Stack discipline. Eliminates thousands of mallocs.
Location: `runtime/fastframe.h`, `runtime/fastframe.c`
### Label Table
O(1) jump resolution. Pre-computes label to PC mapping. Replaces O(n) linear search. Loops go 5-10x fastiii.
Location: `runtime/labeltable.h`, `runtime/labeltable.c`
### Method Cache
Hash-based method lookup. O(1) instead of O(n*m). Caches class+method pairs.
Location: `runtime/methodcache.h`, `runtime/methodcache.c`
### Superinstructions
Combines common opcode sequences into single instructions:
- INC_LOCAL: load + const 1 + add + store combined
- DEC_LOCAL: load + const 1 + sub + store combined
- ADD_LOCAL_TO_LOCAL: fused accumulator pattern
- LOAD_LOCAL_CONST_LT_JUMPFALSE: fused loop condition
Location: `runtime/superinst.h`, `runtime/superinst.c`
### Computed Goto
GCC extension for faster dispatch. Jump table instead of switch.
### PGO Build
Profile-guided optimization targets in Makefile. Run benchmarks, collect profile, rebuild.
```bash
make pgo
```
## References
- Dataset library: https://dataset.readthedocs.io/en/latest/index.html