$ show mozilla/rhino
Mozilla Rhino is a complete JavaScript engine implemented entirely in Java, designed for embedding script execution into Java applications. It provides a full ECMAScript runtime, including ES6+ features (BigInt, Promises, typed arrays, classes, modules), E4X (XML) support, LiveConnect (Java-JS interop), and a JSR-223 ScriptEngine implementation. The architecture is modular, with separate modules for the core engine, tools (shell, debugger, compiler), XML support, and Kotlin integration. The engine supports multiple execution modes: an interpreted bytecode (interpreter v1 and v2), a just-in-time compiler via the optimizer (using jdk.dynalink), and a classfile-based compiler. Key entry points include the `Context` class for script execution, `RhinoScriptEngine` for Java scripting API, and the `Main` shell tool. The project is well-tested with thousands of regression tests, test262 conformance, and JMH benchmarks. It is actively maintained, with recent releases and CI pipelines for Gradle and Bazel, targeting Java 17+ and Android.
The LLM identified 5 files worth highlighting for reuse:
Defines the SlotMap interface and its implementations (ThreadSafeImmutableSmallSlotMap, LockAwareSlotMap, HashSlotMap, etc.) for storing JavaScript object properties. The pattern is reusable for any Java system needing a thread-safe, small-object-optimized property map with lazy expansion. The ImmutableSmallSlotMap uses a copy-on-write strategy for small numbers of properties, and the LockAwareSlotMap provides fine-grained locking. This is a non-obvious optimization for performance-critical property storage.
Represents a single instruction in the interpreter v2 bytecode. It pushes constant values (undefined, null, booleans, numbers, strings) onto the operand stack. The instruction is a self-contained object with methods for interpretation, stack change calculation, debug string, and known type inference. This pattern demonstrates a clean separation of instruction semantics from execution logic, and can be reused in any bytecode interpreter design.
Implements ModuleScriptProvider with a soft-reference-based cache for script modules. It caches compiled scripts to avoid re-compilation, using soft references to allow garbage collection under memory pressure. This is a reusable pattern for resource-constrained module systems, with fallback to a strong cache variant. The design is decoupled from the module source retrieval via the ModuleSourceProvider SPI.
An interface and its implementations (EagerSourceCodeProvider, LazySourceCodeProvider, BuiltInSourceCodeProvider, NullSourceCodeProvider) for providing JavaScript source code to the compiler. This abstraction decouples source retrieval from compilation, allowing lazy loading, embedded sources, or null providers. The pattern is reusable for any system that needs to provide code to a compiler from various sources without tight coupling.
Provides a factory for creating TypeInfo objects that describe Java types (classes, arrays, generics, wildcards, etc.) for LiveConnect interop. It includes caching strategies (ClassValueCacheFactory, WeakReference cache) to avoid repeated reflection. This is a reusable pattern for any Java-to-foreign-type bridge that needs efficient type introspection with generics support.