Fix for-loop real widening coercions
This commit is contained in:
parent
fd2da1efd3
commit
a8f6aa31f1
@ -6002,6 +6002,11 @@ class BytecodeCompiler(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val needsBreakFlag = stmt.canBreak || stmt.elseStatement != null
|
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()
|
val breakFlagSlot = allocSlot()
|
||||||
if (range == null && rangeRef == null && typedRangeLocal == null) {
|
if (range == null && rangeRef == null && typedRangeLocal == null) {
|
||||||
val sourceValue = compileStatementValueOrFallback(stmt.source) ?: return null
|
val sourceValue = compileStatementValueOrFallback(stmt.source) ?: return null
|
||||||
@ -6075,12 +6080,18 @@ class BytecodeCompiler(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||||
|
if (hasRealWiden) {
|
||||||
|
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||||
|
}
|
||||||
loopStack.removeLast()
|
loopStack.removeLast()
|
||||||
if (wantResult) {
|
if (wantResult) {
|
||||||
val bodyObj = ensureObjSlot(bodyValue)
|
val bodyObj = ensureObjSlot(bodyValue)
|
||||||
builder.emit(Opcode.MOVE_OBJ, bodyObj.slot, resultSlot!!)
|
builder.emit(Opcode.MOVE_OBJ, bodyObj.slot, resultSlot!!)
|
||||||
}
|
}
|
||||||
builder.mark(continueLabel)
|
builder.mark(continueLabel)
|
||||||
|
if (hasRealWiden) {
|
||||||
|
emitLoopRealCoercions(realWidenSlots)
|
||||||
|
}
|
||||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||||
|
|
||||||
builder.mark(endLabel)
|
builder.mark(endLabel)
|
||||||
@ -6188,6 +6199,9 @@ class BytecodeCompiler(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||||
|
if (hasRealWiden) {
|
||||||
|
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||||
|
}
|
||||||
loopStack.removeLast()
|
loopStack.removeLast()
|
||||||
if (wantResult) {
|
if (wantResult) {
|
||||||
val bodyObj = ensureObjSlot(bodyValue)
|
val bodyObj = ensureObjSlot(bodyValue)
|
||||||
@ -6195,6 +6209,9 @@ class BytecodeCompiler(
|
|||||||
}
|
}
|
||||||
builder.mark(continueLabel)
|
builder.mark(continueLabel)
|
||||||
builder.emit(Opcode.INC_INT, iSlot)
|
builder.emit(Opcode.INC_INT, iSlot)
|
||||||
|
if (hasRealWiden) {
|
||||||
|
emitLoopRealCoercions(realWidenSlots)
|
||||||
|
}
|
||||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||||
|
|
||||||
builder.mark(endLabel)
|
builder.mark(endLabel)
|
||||||
@ -6265,6 +6282,9 @@ class BytecodeCompiler(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||||
|
if (hasRealWiden) {
|
||||||
|
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||||
|
}
|
||||||
loopStack.removeLast()
|
loopStack.removeLast()
|
||||||
if (wantResult) {
|
if (wantResult) {
|
||||||
val bodyObj = ensureObjSlot(bodyValue)
|
val bodyObj = ensureObjSlot(bodyValue)
|
||||||
@ -6272,6 +6292,9 @@ class BytecodeCompiler(
|
|||||||
}
|
}
|
||||||
builder.mark(continueLabel)
|
builder.mark(continueLabel)
|
||||||
builder.emit(Opcode.INC_INT, iSlot)
|
builder.emit(Opcode.INC_INT, iSlot)
|
||||||
|
if (hasRealWiden) {
|
||||||
|
emitLoopRealCoercions(realWidenSlots)
|
||||||
|
}
|
||||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(loopLabel)))
|
||||||
|
|
||||||
builder.mark(endLabel)
|
builder.mark(endLabel)
|
||||||
@ -6331,6 +6354,9 @@ class BytecodeCompiler(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
val bodyValue = compileLoopBody(stmt.body, wantResult) ?: return null
|
||||||
|
if (hasRealWiden) {
|
||||||
|
applySlotTypes(realWidenSlots, SlotType.UNKNOWN)
|
||||||
|
}
|
||||||
loopStack.removeLast()
|
loopStack.removeLast()
|
||||||
if (wantResult) {
|
if (wantResult) {
|
||||||
val bodyObj = ensureObjSlot(bodyValue)
|
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
|
@Test
|
||||||
fun testIntClosedRangeInclusive() = runTest {
|
fun testIntClosedRangeInclusive() = runTest {
|
||||||
eval(
|
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