Handle labeled break and catch locals in ScriptTest
This commit is contained in:
parent
d6e1e74b48
commit
4b66454bf3
@ -712,7 +712,8 @@ class Compiler(
|
|||||||
private fun containsLoopControl(stmt: Statement, inLoop: Boolean = false): Boolean {
|
private fun containsLoopControl(stmt: Statement, inLoop: Boolean = false): Boolean {
|
||||||
val target = if (stmt is BytecodeStatement) stmt.original else stmt
|
val target = if (stmt is BytecodeStatement) stmt.original else stmt
|
||||||
return when (target) {
|
return when (target) {
|
||||||
is BreakStatement, is ContinueStatement -> !inLoop
|
is BreakStatement -> target.label != null || !inLoop
|
||||||
|
is ContinueStatement -> target.label != null || !inLoop
|
||||||
is IfStatement -> {
|
is IfStatement -> {
|
||||||
containsLoopControl(target.ifBody, inLoop) ||
|
containsLoopControl(target.ifBody, inLoop) ||
|
||||||
(target.elseBody?.let { containsLoopControl(it, inLoop) } ?: false)
|
(target.elseBody?.let { containsLoopControl(it, inLoop) } ?: false)
|
||||||
@ -2571,7 +2572,7 @@ class Compiler(
|
|||||||
val block = try {
|
val block = try {
|
||||||
resolutionSink?.enterScope(ScopeKind.BLOCK, catchVar.pos, null)
|
resolutionSink?.enterScope(ScopeKind.BLOCK, catchVar.pos, null)
|
||||||
resolutionSink?.declareSymbol(catchVar.value, SymbolKind.LOCAL, isMutable = false, pos = catchVar.pos)
|
resolutionSink?.declareSymbol(catchVar.value, SymbolKind.LOCAL, isMutable = false, pos = catchVar.pos)
|
||||||
withCatchSlot(unwrapBytecodeDeep(parseBlock()), catchVar.value)
|
withCatchSlot(unwrapBytecodeDeep(parseBlockWithPredeclared(listOf(catchVar.value to false))), catchVar.value)
|
||||||
} finally {
|
} finally {
|
||||||
resolutionSink?.exitScope(cc.currentPos())
|
resolutionSink?.exitScope(cc.currentPos())
|
||||||
}
|
}
|
||||||
@ -2585,7 +2586,10 @@ class Compiler(
|
|||||||
val block = try {
|
val block = try {
|
||||||
resolutionSink?.enterScope(ScopeKind.BLOCK, itToken.pos, null)
|
resolutionSink?.enterScope(ScopeKind.BLOCK, itToken.pos, null)
|
||||||
resolutionSink?.declareSymbol(itToken.value, SymbolKind.LOCAL, isMutable = false, pos = itToken.pos)
|
resolutionSink?.declareSymbol(itToken.value, SymbolKind.LOCAL, isMutable = false, pos = itToken.pos)
|
||||||
withCatchSlot(unwrapBytecodeDeep(parseBlock(true)), itToken.value)
|
withCatchSlot(
|
||||||
|
unwrapBytecodeDeep(parseBlockWithPredeclared(listOf(itToken.value to false), skipLeadingBrace = true)),
|
||||||
|
itToken.value
|
||||||
|
)
|
||||||
} finally {
|
} finally {
|
||||||
resolutionSink?.exitScope(cc.currentPos())
|
resolutionSink?.exitScope(cc.currentPos())
|
||||||
}
|
}
|
||||||
@ -3765,6 +3769,13 @@ class Compiler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun parseBlock(skipLeadingBrace: Boolean = false): Statement {
|
private suspend fun parseBlock(skipLeadingBrace: Boolean = false): Statement {
|
||||||
|
return parseBlockWithPredeclared(emptyList(), skipLeadingBrace)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun parseBlockWithPredeclared(
|
||||||
|
predeclared: List<Pair<String, Boolean>>,
|
||||||
|
skipLeadingBrace: Boolean = false
|
||||||
|
): Statement {
|
||||||
val startPos = cc.currentPos()
|
val startPos = cc.currentPos()
|
||||||
if (!skipLeadingBrace) {
|
if (!skipLeadingBrace) {
|
||||||
val t = cc.next()
|
val t = cc.next()
|
||||||
@ -3773,6 +3784,9 @@ class Compiler(
|
|||||||
}
|
}
|
||||||
resolutionSink?.enterScope(ScopeKind.BLOCK, startPos, null)
|
resolutionSink?.enterScope(ScopeKind.BLOCK, startPos, null)
|
||||||
val blockSlotPlan = SlotPlan(mutableMapOf(), 0, nextScopeId++)
|
val blockSlotPlan = SlotPlan(mutableMapOf(), 0, nextScopeId++)
|
||||||
|
for ((name, isMutable) in predeclared) {
|
||||||
|
declareSlotNameIn(blockSlotPlan, name, isMutable, isDelegated = false)
|
||||||
|
}
|
||||||
slotPlanStack.add(blockSlotPlan)
|
slotPlanStack.add(blockSlotPlan)
|
||||||
val capturePlan = CapturePlan(blockSlotPlan)
|
val capturePlan = CapturePlan(blockSlotPlan)
|
||||||
capturePlanStack.add(capturePlan)
|
capturePlanStack.add(capturePlan)
|
||||||
|
|||||||
@ -2942,7 +2942,13 @@ class BytecodeCompiler(
|
|||||||
|
|
||||||
private fun compileBreak(stmt: net.sergeych.lyng.BreakStatement): CompiledValue? {
|
private fun compileBreak(stmt: net.sergeych.lyng.BreakStatement): CompiledValue? {
|
||||||
val stack = loopStack.toList()
|
val stack = loopStack.toList()
|
||||||
val targetIndex = findLoopContextIndex(stmt.label) ?: return null
|
val targetIndex = findLoopContextIndex(stmt.label) ?: run {
|
||||||
|
val labels = stack.joinToString(prefix = "[", postfix = "]") { it.label ?: "<unlabeled>" }
|
||||||
|
throw BytecodeFallbackException(
|
||||||
|
"Bytecode fallback: break label '${stmt.label}' not found in $labels",
|
||||||
|
stmt.pos
|
||||||
|
)
|
||||||
|
}
|
||||||
val ctx = stack[targetIndex]
|
val ctx = stack[targetIndex]
|
||||||
val value = stmt.resultExpr?.let { compileStatementValueOrFallback(it) }
|
val value = stmt.resultExpr?.let { compileStatementValueOrFallback(it) }
|
||||||
if (ctx.resultSlot != null) {
|
if (ctx.resultSlot != null) {
|
||||||
|
|||||||
@ -2092,7 +2092,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLabelNreakTest() = runTest {
|
fun testForLabelNreakTest() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -2115,7 +2114,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testThrowExisting() = runTest {
|
fun testThrowExisting() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -2145,7 +2143,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testCatchShort1() = runTest {
|
fun testCatchShort1() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -2170,7 +2167,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testCatchShort2() = runTest {
|
fun testCatchShort2() = runTest {
|
||||||
eval(
|
eval(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user