From f9fe3d1186f77f9a9abb17f9c9146036c8b86e03 Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 9 Feb 2026 01:39:00 +0300 Subject: [PATCH] Step 4: allow bytecode for destructuring/extension decls --- bytecode_migration_plan.md | 18 ++++++++++++++++++ .../kotlin/net/sergeych/lyng/Compiler.kt | 3 +++ 2 files changed, 21 insertions(+) diff --git a/bytecode_migration_plan.md b/bytecode_migration_plan.md index e5ab69b..7502a7d 100644 --- a/bytecode_migration_plan.md +++ b/bytecode_migration_plan.md @@ -14,6 +14,24 @@ Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM te - [x] Preserve existing error/stack semantics. - [x] JVM tests must be green before commit. +## Remaining Migration (prioritized) + +- [x] Step 4: Allow bytecode wrapping for supported declaration statements. + - [x] Enable `DestructuringVarDeclStatement` and `ExtensionPropertyDeclStatement` in `containsUnsupportedForBytecode`. + - [x] Keep JVM tests green before commit. +- [ ] Step 5: Enable bytecode for delegated var declarations. + - [ ] Revisit `containsDelegatedRefs` guard for `DelegatedVarDeclStatement`. + - [ ] Ensure delegate binding uses explicit `Statement` objects (no inline suspend lambdas). +- [ ] Step 6: Map literal spread in bytecode. + - [ ] Replace `MapLiteralEntry.Spread` bytecode exception with runtime `putAll`/merge logic. +- [ ] Step 7: Class-scope member refs in bytecode. + - [ ] Support `ClassScopeMemberRef` without scope-map fallback. +- [ ] Step 8: ObjDynamic member access in bytecode. + - [ ] Allow dynamic receiver field/method lookup without falling back to interpreter. +- [ ] Step 9: Module-level bytecode execution. + - [ ] Compile `Script` bodies to bytecode instead of interpreting at module scope. + - [ ] Keep import/module slot seeding in frame-only flow. + ## Notes - Keep imports bound to module frame slots; no scope map writes for imports. diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt index 63e9c9c..d6aa3db 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt @@ -1893,10 +1893,12 @@ class Compiler( is BlockStatement -> target.statements().any { containsUnsupportedForBytecode(it) } is InlineBlockStatement -> target.statements().any { containsUnsupportedForBytecode(it) } is VarDeclStatement -> target.initializer?.let { containsUnsupportedForBytecode(it) } ?: false + is DestructuringVarDeclStatement -> containsUnsupportedForBytecode(target.initializer) is BreakStatement -> target.resultExpr?.let { containsUnsupportedForBytecode(it) } ?: false is ContinueStatement -> false is ReturnStatement -> target.resultExpr?.let { containsUnsupportedForBytecode(it) } ?: false is ThrowStatement -> containsUnsupportedForBytecode(target.throwExpr) + is ExtensionPropertyDeclStatement -> false is TryStatement -> { containsUnsupportedForBytecode(target.body) || target.catches.any { containsUnsupportedForBytecode(it.block) } || @@ -1928,6 +1930,7 @@ class Compiler( is CastRef -> containsUnsupportedRef(ref.castValueRef()) || containsUnsupportedRef(ref.castTypeRef()) is net.sergeych.lyng.obj.TypeDeclRef -> false is AssignRef -> { + if (ref.target is ListLiteralRef) return true val target = ref.target as? LocalSlotRef (target?.isDelegated == true) || containsUnsupportedRef(ref.value) }