Fix for-loop real widening coercions
This commit is contained in:
parent
fd2da1efd3
commit
a8f6aa31f1
@ -6002,6 +6002,11 @@ class BytecodeCompiler(
|
||||
|
||||
try {
|
||||
val needsBreakFlag = stmt.canBreak || stmt.elseStatement != null
|
||||
val realWidenSlots = collectLoopRealWidenSlots(stmt.body)
|
||||
val hasRealWiden = realWidenSlots.isNotEmpty()
|
||||
if (hasRealWiden) {
|
||||
applySlotTypes(realWidenSlots, SlotType.REAL)
|
||||
}
|
||||
val breakFlagSlot = allocSlot()
|
||||
if (range == null && rangeRef == null && typedRangeLocal == null) {
|
||||
val sourceValue = compileStatementValueOrFallback(stmt.source) ?: return null
|
||||
@ -6075,12 +6080,18 @@ class BytecodeCompiler(
|
||||
)
|
||||
)
|
||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||
if (hasRealWiden) {
|
||||
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||
}
|
||||
loopStack.removeLast()
|
||||
if (wantResult) {
|
||||
val bodyObj = ensureObjSlot(bodyValue)
|
||||
builder.emit(Opcode.MOVE_OBJ, bodyObj.slot, resultSlot!!)
|
||||
}
|
||||
builder.mark(continueLabel)
|
||||
if (hasRealWiden) {
|
||||
emitLoopRealCoercions(realWidenSlots)
|
||||
}
|
||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||
|
||||
builder.mark(endLabel)
|
||||
@ -6188,6 +6199,9 @@ class BytecodeCompiler(
|
||||
)
|
||||
)
|
||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||
if (hasRealWiden) {
|
||||
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||
}
|
||||
loopStack.removeLast()
|
||||
if (wantResult) {
|
||||
val bodyObj = ensureObjSlot(bodyValue)
|
||||
@ -6195,6 +6209,9 @@ class BytecodeCompiler(
|
||||
}
|
||||
builder.mark(continueLabel)
|
||||
builder.emit(Opcode.INC_INT, iSlot)
|
||||
if (hasRealWiden) {
|
||||
emitLoopRealCoercions(realWidenSlots)
|
||||
}
|
||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||
|
||||
builder.mark(endLabel)
|
||||
@ -6265,6 +6282,9 @@ class BytecodeCompiler(
|
||||
)
|
||||
)
|
||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||
if (hasRealWiden) {
|
||||
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||
}
|
||||
loopStack.removeLast()
|
||||
if (wantResult) {
|
||||
val bodyObj = ensureObjSlot(bodyValue)
|
||||
@ -6272,6 +6292,9 @@ class BytecodeCompiler(
|
||||
}
|
||||
builder.mark(continueLabel)
|
||||
builder.emit(Opcode.INC_INT, iSlot)
|
||||
if (hasRealWiden) {
|
||||
emitLoopRealCoercions(realWidenSlots)
|
||||
}
|
||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||
|
||||
builder.mark(endLabel)
|
||||
@ -6331,6 +6354,9 @@ class BytecodeCompiler(
|
||||
)
|
||||
)
|
||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||
if (hasRealWiden) {
|
||||
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||
}
|
||||
loopStack.removeLast()
|
||||
if (wantResult) {
|
||||
val bodyObj = ensureObjSlot(bodyValue)
|
||||
|
||||
@ -1258,6 +1258,28 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testForLoopRealWidenDisasm() = runTest {
|
||||
val scope = Script.newScope()
|
||||
scope.eval(
|
||||
"""
|
||||
fun widenFor() {
|
||||
var acc = 0
|
||||
for(i in 0..3) {
|
||||
if (i == 1) acc = 0.5
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
val disasm = scope.disassembleSymbol("widenFor")
|
||||
println("[DEBUG_LOG] widenFor disasm:\n$disasm")
|
||||
val incIndex = disasm.indexOf("INC_INT")
|
||||
assertTrue(incIndex >= 0, "expected INC_INT in for-loop disasm")
|
||||
val convIndex = disasm.indexOf("INT_TO_REAL")
|
||||
assertTrue(convIndex >= 0, "expected INT_TO_REAL in for-loop disasm")
|
||||
assertTrue(convIndex > incIndex, "INT_TO_REAL should appear after INC_INT")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIntClosedRangeInclusive() = runTest {
|
||||
eval(
|
||||
|
||||
9
notes/nested_range_baseline.md
Normal file
9
notes/nested_range_baseline.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Nested Range Benchmark Baseline
|
||||
|
||||
Date: 2026-02-16
|
||||
|
||||
Command:
|
||||
`BENCHMARKS=true timeout 20s ./gradlew :lynglib:jvmTest --tests NestedRangeBenchmarkTest --rerun-tasks`
|
||||
|
||||
Result:
|
||||
- nested-happy elapsed=56 ms
|
||||
Loading…
x
Reference in New Issue
Block a user