This directory contains architecture documentation for the PerlOnJava compiler and runtime.
PerlOnJava is a Perl 5 implementation that compiles Perl source code to JVM bytecode. The system consists of:
-
Frontend (
org.perlonjava.frontend)- Lexer: Tokenizes Perl source code
- Parser: Builds Abstract Syntax Tree (AST)
- Semantic analysis: Variable resolution, scope handling
-
Backend (
org.perlonjava.backend)- JVM backend: Emits JVM bytecode using ASM library
- Bytecode interpreter: Interprets a subset of operations for eval STRING
-
Runtime (
org.perlonjava.runtime)- Runtime types: RuntimeScalar, RuntimeArray, RuntimeHash, RuntimeList, RuntimeCode, RuntimeGlob, RuntimeIO
- Operators: Arithmetic, string, comparison, I/O
- Perl modules: Built-in implementations of core modules
-
Application (
org.perlonjava.app)- CLI entry point (Main, ArgumentParser, CompilerOptions)
- JSR-223 ScriptEngine integration
| Document | Description |
|---|---|
| dynamic-scope.md | Dynamic scoping via local and DynamicVariableManager |
| weaken-destroy.md | Cooperative reference counting, DESTROY, and weak references |
| lexical-pragmas.md | Lexical warnings, strict, and features |
| control-flow.md | Control flow implementation (die/eval, last/next/redo, block dispatchers) |
| block-dispatcher-optimization.md | Block-level shared dispatchers for control flow |
| large-code-refactoring.md | Large code handling: proactive block refactoring and interpreter fallback |
| ../design/inline-cache.md | Inline caching design (runtime global cache implemented; per-site variant planned) |
| ../design/method-call-optimization.md | Method call optimization plan (Phase 1 done; Phases 2-3 not yet implemented) |
| ../design/interpreter.md | Bytecode interpreter design |
| ../design/variables_and_values.md | Runtime value representation |
Perl Source
│
▼
┌─────────┐
│ Lexer │ Tokenizes source into LexerToken instances
└────┬────┘
│
▼
┌─────────┐
│ Parser │ Builds AST (AbstractNode tree)
└────┬────┘
│
▼
┌─────────────┐
│ Visitors │ Analysis passes (variable resolution, etc.)
└─────┬───────┘
│
▼
┌───────────────┐
│ JVM Emitter │ Generates bytecode via ASM
└───────┬───────┘
│
▼
JVM Bytecode
┌────────────────────────────────────────────────┐
│ Perl Code │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ Runtime Types │
│ RuntimeScalar, RuntimeArray, RuntimeHash │
│ RuntimeList, RuntimeCode, RuntimeGlob, RuntimeIO │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ Global State │
│ GlobalVariable (package variables) │
│ DynamicVariableManager (local scoping) │
│ CallerStack (call frame tracking) │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ JVM │
└────────────────────────────────────────────────┘
-
Direct JVM Bytecode: We emit bytecode directly rather than generating Java source, enabling better optimization and avoiding Java language limitations.
-
Dual Backend: JVM bytecode for compiled code, bytecode interpreter for
eval STRINGto avoid runtime class generation overhead. -
Dynamic Scoping: Implemented via
DynamicVariableManagerwhich maintains a stack of saved values, restored on scope exit. -
Lexical Pragmas: Warnings and strict are tracked in the symbol table at compile time and propagate via
CompilerFlagNode.
- AGENTS.md - Development guidelines
- dev/design/ - Detailed design documents