From 7ea67d4816ff22c68eeae4485b47acb2d5043a3d Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 9 Feb 2026 00:52:44 +0300 Subject: [PATCH] Step 2: bytecode for implicit this refs --- bytecode_migration_plan.md | 41 +++++++------------ .../kotlin/net/sergeych/lyng/Compiler.kt | 6 +-- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/bytecode_migration_plan.md b/bytecode_migration_plan.md index ddb17dc..2a5bddf 100644 --- a/bytecode_migration_plan.md +++ b/bytecode_migration_plan.md @@ -1,32 +1,21 @@ # Bytecode Migration Plan -Goal: migrate :lynglib compiler/runtime so values live in frame slots and bytecode is the default execution path. +Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM tests green after each step. -## Step 1: Imports as module slots (done) -- [x] Seed module slot plans from import bindings (lazy, unused imports do not allocate). -- [x] Avoid mutating scopes during compile-time imports; bind slots at runtime instead. -- [x] Make runtime member access honor extensions (methods + properties). -- [x] Ensure class members (ObjClass instances) resolve by slot id in bytecode runtime. -- [x] Expose `Iterator` in root scope so stdlib externs bind at runtime. +## Steps -## Step 2: Class-scope member refs + qualified-this refs (pending) -- [ ] Bytecode-compile `ClassScopeMemberRef` (currently forced to AST in `Compiler.containsUnsupportedRef`). -- [ ] Bytecode-compile `QualifiedThisFieldSlotRef` / `QualifiedThisMethodSlotCallRef`. -- [ ] Ensure slot resolution uses class member ids, not scope lookup; no fallback opcodes. -- [ ] Add coverage for class static access + qualified-this access to keep JVM tests green. +- [x] Step 1: Module/import slots seeded into module frame; bytecode module resolution works across closures. +- [x] Step 2: Allow implicit/qualified `this` member refs to compile to bytecode. + - [x] Enable bytecode for `ImplicitThisMethodCallRef`, `QualifiedThisMethodSlotCallRef`, `QualifiedThisFieldSlotRef`. + - [x] Keep unsupported cases blocked: `ClassScopeMemberRef`, dynamic receivers, delegated members. + - [x] JVM tests must be green before commit. +- [ ] Step 3: Bytecode support for `try/catch/finally`. + - [ ] Implement bytecode emission for try/catch and finally blocks. + - [ ] Preserve existing error/stack semantics. + - [ ] JVM tests must be green before commit. -## Step 3: Expand bytecode coverage for control flow + literals (pending) -- [ ] Add bytecode support for `TryStatement` (catch/finally) in `Compiler.containsUnsupportedForBytecode` and `BytecodeCompiler`. -- [ ] Support `WhenStatement` conditions beyond the current limited set. -- [ ] Add map literal spread support (currently throws in `BytecodeCompiler`). -- [ ] Remove remaining `BytecodeCompileException` cases for common member access (missing id paths). +## Notes -## Known bytecode gaps (from current guards) -- [ ] `TryStatement` is always excluded by `Compiler.containsUnsupportedForBytecode`. -- [ ] `ClassScopeMemberRef` and qualified-this refs are excluded by `Compiler.containsUnsupportedRef`. -- [ ] `BytecodeCompiler` rejects map literal spreads and some argument expressions. -- [ ] Member access still fails when compile-time receiver class cannot be resolved. - -## Validation -- [ ] `./gradlew :lynglib:jvmTest` (full suite) after each step; if failures pre-exist, run targeted tests tied to the change and record the gap in this file. -- [ ] Baseline full suite: currently 46 failures on `:lynglib:jvmTest` (run 2026-02-08); keep targeted tests green until the baseline is addressed. +- Keep imports bound to module frame slots; no scope map writes for imports. +- Avoid inline suspend lambdas in compiler hot paths; use explicit `object : Statement()`. +- Do not reintroduce bytecode fallback opcodes; all symbol resolution remains compile-time only. diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt index a754ee4..b1588e9 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt @@ -1972,9 +1972,9 @@ class Compiler( if (!hasMember && !hasExtensionFor(receiverClass.className, ref.name)) return true containsUnsupportedRef(ref.receiver) || ref.args.any { containsUnsupportedForBytecode(it.value) } } - is ImplicitThisMethodCallRef -> true - is QualifiedThisMethodSlotCallRef -> true - is QualifiedThisFieldSlotRef -> true + is ImplicitThisMethodCallRef -> false + is QualifiedThisMethodSlotCallRef -> false + is QualifiedThisFieldSlotRef -> false is ClassScopeMemberRef -> true else -> false }