Step 26B: drop containsValueFnRef

This commit is contained in:
Sergey Chernov 2026-02-11 20:53:15 +03:00
parent bde32ca7b5
commit b9af80a1b2
2 changed files with 2 additions and 86 deletions

View File

@ -122,7 +122,8 @@ Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM te
- [x] Add JVM disasm coverage to ensure module init has no `CALL_SLOT` to `Callable@...` for declarations. - [x] Add JVM disasm coverage to ensure module init has no `CALL_SLOT` to `Callable@...` for declarations.
- [ ] Step 26: Bytecode-backed lambdas (remove `ValueFnRef` runtime execution). - [ ] Step 26: Bytecode-backed lambdas (remove `ValueFnRef` runtime execution).
- [x] Compile lambda bodies to bytecode and emit an opcode to create a callable from bytecode + capture plan. - [x] Compile lambda bodies to bytecode and emit an opcode to create a callable from bytecode + capture plan.
- [ ] Remove `containsValueFnRef`/`forceScopeSlots` workaround once lambdas are bytecode. - [x] Remove `containsValueFnRef` helper now that lambdas are bytecode-backed.
- [ ] Remove `forceScopeSlots` branches once no bytecode paths depend on scope slots.
- [x] Add JVM tests for captured locals and delegated locals inside lambdas on the bytecode path. - [x] Add JVM tests for captured locals and delegated locals inside lambdas on the bytecode path.
- [ ] Step 27: Remove interpreter opcodes and constants from bytecode runtime. - [ ] Step 27: Remove interpreter opcodes and constants from bytecode runtime.
- [ ] Delete `BytecodeConst.ValueFn`, `CmdMakeValueFn`, and `MAKE_VALUE_FN`. - [ ] Delete `BytecodeConst.ValueFn`, `CmdMakeValueFn`, and `MAKE_VALUE_FN`.

View File

@ -6860,91 +6860,6 @@ class BytecodeCompiler(
} }
} }
private fun containsValueFnRef(stmt: Statement): Boolean {
if (stmt is BytecodeStatement) return containsValueFnRef(stmt.original)
return when (stmt) {
is ExpressionStatement -> containsValueFnRef(stmt.ref)
is BlockStatement -> stmt.statements().any { containsValueFnRef(it) }
is VarDeclStatement -> stmt.initializer?.let { containsValueFnRef(it) } ?: false
is DestructuringVarDeclStatement -> {
containsValueFnRef(stmt.initializer) || containsValueFnRef(stmt.pattern)
}
is net.sergeych.lyng.ForInStatement -> {
containsValueFnRef(stmt.source) ||
containsValueFnRef(stmt.body) ||
(stmt.elseStatement?.let { containsValueFnRef(it) } ?: false)
}
is net.sergeych.lyng.WhileStatement -> {
containsValueFnRef(stmt.condition) ||
containsValueFnRef(stmt.body) ||
(stmt.elseStatement?.let { containsValueFnRef(it) } ?: false)
}
is net.sergeych.lyng.DoWhileStatement -> {
containsValueFnRef(stmt.body) ||
containsValueFnRef(stmt.condition) ||
(stmt.elseStatement?.let { containsValueFnRef(it) } ?: false)
}
is IfStatement -> {
containsValueFnRef(stmt.condition) ||
containsValueFnRef(stmt.ifBody) ||
(stmt.elseBody?.let { containsValueFnRef(it) } ?: false)
}
is net.sergeych.lyng.ReturnStatement -> {
stmt.resultExpr?.let { containsValueFnRef(it) } ?: false
}
is net.sergeych.lyng.ThrowStatement -> containsValueFnRef(stmt.throwExpr)
else -> false
}
}
private fun containsValueFnRef(ref: ObjRef): Boolean {
return when (ref) {
is ValueFnRef -> true
is BinaryOpRef -> containsValueFnRef(binaryLeft(ref)) || containsValueFnRef(binaryRight(ref))
is UnaryOpRef -> containsValueFnRef(unaryOperand(ref))
is CastRef -> containsValueFnRef(ref.castValueRef()) || containsValueFnRef(ref.castTypeRef())
is AssignRef -> {
val target = assignTarget(ref)
if (target != null) {
containsValueFnRef(target) || containsValueFnRef(assignValue(ref))
} else {
containsValueFnRef(ref.target) || containsValueFnRef(assignValue(ref))
}
}
is AssignOpRef -> containsValueFnRef(ref.target) || containsValueFnRef(ref.value)
is AssignIfNullRef -> containsValueFnRef(ref.target) || containsValueFnRef(ref.value)
is IncDecRef -> containsValueFnRef(ref.target)
is ConditionalRef -> {
containsValueFnRef(ref.condition) ||
containsValueFnRef(ref.ifTrue) ||
containsValueFnRef(ref.ifFalse)
}
is ElvisRef -> containsValueFnRef(ref.left) || containsValueFnRef(ref.right)
is FieldRef -> containsValueFnRef(ref.target)
is IndexRef -> containsValueFnRef(ref.targetRef) || containsValueFnRef(ref.indexRef)
is CallRef -> ref.tailBlock || containsValueFnRef(ref.target) || ref.args.any { arg ->
val stmt = arg.value
stmt is ExpressionStatement && containsValueFnRef(stmt.ref)
}
is MethodCallRef -> ref.tailBlock || containsValueFnRef(ref.receiver) || ref.args.any { arg ->
val stmt = arg.value
stmt is ExpressionStatement && containsValueFnRef(stmt.ref)
}
is ThisMethodSlotCallRef -> ref.hasTailBlock() || ref.arguments().any { arg ->
val stmt = arg.value
stmt is ExpressionStatement && containsValueFnRef(stmt.ref)
}
is ListLiteralRef -> ref.entries().any { entry ->
when (entry) {
is net.sergeych.lyng.ListEntry.Element -> containsValueFnRef(entry.ref)
is net.sergeych.lyng.ListEntry.Spread -> containsValueFnRef(entry.ref)
}
}
is StatementRef -> containsValueFnRef(ref.statement)
else -> false
}
}
private fun extractRangeRef(source: Statement): RangeRef? { private fun extractRangeRef(source: Statement): RangeRef? {
val target = if (source is BytecodeStatement) source.original else source val target = if (source is BytecodeStatement) source.original else source
val expr = target as? ExpressionStatement ?: return null val expr = target as? ExpressionStatement ?: return null