Guidance for coding agents working in this repository.
qjs4jis a pure Java reimplementation of QuickJS (JDK 17+, zero runtime dependencies).- Migration work is tracked in
docs/migration/(TODO.md,FEATURES.md,MIGRATION_STATUS.md). - QuickJS reference source:
../quickjs(especiallyquickjs.candquickjs-opcode.h). - Test262 conformance suite:
../test262. - Goal: preserve QuickJS semantics while staying consistent with existing qjs4j architecture.
- Confirm behavior from QuickJS source.
- Validate with
../quickjs/qjsor../quickjs/qjs -mwhen useful. - Port semantics, not just syntax.
- If qjs4j diverges from QuickJS, prefer fixing qjs4j.
- Do not introduce new opcodes unless explicitly required; use the existing 262-opcode set.
com.caoccao.qjs4j/
├── compilation/ ← Frontend pipeline
│ ├── ast/ Records implementing sealed interfaces (Expression, Statement, etc.)
│ ├── compiler/ Compiler (entry), BytecodeCompiler, CompilerDelegates, EmitHelpers
│ ├── lexer/ Lexer, LexerTemplateScanner
│ └── parser/ Parser, ParserDelegates, Expression*Parser, StatementParser
├── core/ ← JSContext, JSRuntime, JSGlobalObject, JSValue hierarchy
├── vm/ ← VirtualMachine, Opcode (262 opcodes), StackFrame, CallStack
├── builtins/ ← Constructor + Prototype pairs (ArrayConstructor/ArrayPrototype, etc.)
├── exceptions/ ← JSCompilerException, JSSyntaxErrorException, JSTypeErrorException,
│ JSRangeErrorException, JSVirtualMachineException, JSErrorException
├── memory/ ← GarbageCollector, HeapManager, MemoryPool, ReferenceCounter
├── regexp/ ← RegExp engine
├── unicode/ ← Unicode data and normalization
├── utils/ ← AtomTable, DtoaConverter, Float16
└── cli/ ← QuickJSInterpreter (main class), REPL
Key entry points:
| Component | Path |
|---|---|
| Compiler entry | src/main/java/com/caoccao/qjs4j/compilation/compiler/Compiler.java |
| Lexer | src/main/java/com/caoccao/qjs4j/compilation/lexer/Lexer.java |
| Parser | src/main/java/com/caoccao/qjs4j/compilation/parser/Parser.java |
| BytecodeCompiler | src/main/java/com/caoccao/qjs4j/compilation/compiler/BytecodeCompiler.java |
| VirtualMachine | src/main/java/com/caoccao/qjs4j/vm/VirtualMachine.java |
| Opcode | src/main/java/com/caoccao/qjs4j/vm/Opcode.java |
| JSContext | src/main/java/com/caoccao/qjs4j/core/JSContext.java |
- Apache 2.0 license header (
Copyright (c) 2025-2026. caoccao.com Sam Cao) onsrc/main/files. - 4-space indentation, no tabs. Prefer
finalclasses where the project does. - AST nodes are records with
SourceLocation locationimplementing sealed interfaces — seeIdentifier.javaorForOfStatement.java. - Document stack shapes (
Stack: ...) in compiler/VM code. - Use project exception types:
JSSyntaxErrorException,JSTypeErrorException,JSRangeErrorException,JSCompilerException,JSVirtualMachineException.
./gradlew test # All tests (excludes @Tag("performance"))
./gradlew test --tests "com.caoccao.qjs4j.compilation.ast.ClassCompilerTest" # Single class
./gradlew test --tests "*.ForOfStatementTest.testArrayForOf" # Single method
./gradlew compileJava # Compile only (fast check)
./gradlew compileTestJava # Compile tests
./gradlew test262Quick # Quick Test262 subset
./gradlew test262 # Full Test262 (requires ../test262, -Xmx2g)
./gradlew performanceTest # JMH benchmarks (@Tag("performance"))JDK 17+. Test stack: JUnit 6 + AssertJ + Javet (V8 parity).
Prefer BaseJavetTest for behavioral tests — runs code in both V8 and qjs4j, auto-tests strict mode:
public class MyFeatureTest extends BaseJavetTest {
@Test void testFeature() {
assertStringWithJavet("'hello'.toUpperCase()");
}
}Methods: assertStringWithJavet(), assertIntegerWithJavet(), assertBooleanWithJavet(), assertDoubleWithJavet(), assertErrorWithJavet(), assertUndefinedWithJavet(), assertObjectWithJavet(). Set moduleMode = true for ES module tests.
Use BaseTest for internal assertions not needing V8 parity. Provides assertError(), assertSyntaxError(), assertTypeError(), awaitPromise().
Test locations: compilation/ast/ (compiler), builtins/ (built-ins), core/ (runtime), vm/ (opcodes), regexp/ (regex).
- Read
docs/migration/TODO.mdand related docs. - Confirm QuickJS behavior (source + executable).
- Implement in parser/compiler/vm/core.
- Add/adjust tests.
- Run targeted tests, then
./gradlew test. - Update
docs/migration/TODO.mdandFEATURES.md.
- QuickJS behavior checked for the changed feature.
- Parser/compiler/vm changes are internally consistent.
- Tests added or updated under the relevant package.
-
./gradlew testpasses. - Migration docs updated to reflect the new status.