diff --git a/bytecode_migration_plan.md b/bytecode_migration_plan.md index 5f4a718..d84c924 100644 --- a/bytecode_migration_plan.md +++ b/bytecode_migration_plan.md @@ -43,6 +43,16 @@ Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM te - [x] Fix post-inc return value for object slots stored in scope frames. - [x] Handle optional receivers for member assign-ops and inc/dec without evaluating operands on null. - [x] Support class-scope and index optional inc/dec paths in bytecode. +- [x] Step 13: Qualified `this` value refs in bytecode. + - [x] Compile `QualifiedThisRef` (`this@Type`) via `LOAD_THIS_VARIANT`. + - [x] Add a JVM test that evaluates `this@Type` as a value inside nested classes. +- [ ] Step 14: Fast local ref reads in bytecode. + - [ ] Support `FastLocalVarRef` reads with the same slot resolution as `LocalVarRef`. + - [ ] If `BoundLocalVarRef` is still emitted, map it to a direct slot read instead of failing. + - [ ] Add a JVM test that exercises fast-local reads in a bytecode-compiled function. +- [ ] Step 15: Class-scope `?=` in bytecode. + - [ ] Handle `C.x ?= v` and `C?.x ?= v` for class-scope members without falling back. + - [ ] Add a JVM test for class-scope `?=` on static vars. ## Notes diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt index 31685d6..a7ddcee 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt @@ -397,6 +397,7 @@ class BytecodeCompiler( is ImplicitThisMethodCallRef -> compileImplicitThisMethodCall(ref) is QualifiedThisMethodSlotCallRef -> compileQualifiedThisMethodSlotCall(ref) is IndexRef -> compileIndexRef(ref) + is QualifiedThisRef -> compileThisVariantRef(ref.typeName) else -> null } } @@ -5422,6 +5423,7 @@ class BytecodeCompiler( } ?: nameObjClass[ref.name] ?: resolveTypeNameClass(ref.name) } + is QualifiedThisRef -> resolveTypeNameClass(ref.typeName) is ListLiteralRef -> ObjList.type is MapLiteralRef -> ObjMap.type is RangeRef -> ObjRange.type @@ -5487,6 +5489,7 @@ class BytecodeCompiler( return when (ref) { is LocalSlotRef -> nameObjClass[ref.name] ?: resolveTypeNameClass(ref.name) is LocalVarRef -> nameObjClass[ref.name] ?: resolveTypeNameClass(ref.name) + is QualifiedThisRef -> resolveTypeNameClass(ref.typeName) is ListLiteralRef -> ObjList.type is MapLiteralRef -> ObjMap.type is RangeRef -> ObjRange.type diff --git a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt index d14052d..d69b14f 100644 --- a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt +++ b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt @@ -140,4 +140,18 @@ class BytecodeRecentOpsTest { """.trimIndent() ) } + + @Test + fun qualifiedThisValueRef() = runTest { + eval( + """ + class T(val v) { + fun get() { + this@T.v + } + } + assertEquals(7, T(7).get()) + """.trimIndent() + ) + } }