Fix loop scoping in bytecode and unignore ScriptTests
This commit is contained in:
parent
d363501081
commit
8f60a84e3b
@ -101,11 +101,16 @@ class Compiler(
|
||||
|
||||
private fun moduleSlotPlan(): SlotPlan? = slotPlanStack.firstOrNull()
|
||||
|
||||
private fun seedSlotPlanFromScope(scope: Scope) {
|
||||
private fun seedSlotPlanFromScope(scope: Scope, includeParents: Boolean = false) {
|
||||
val plan = moduleSlotPlan() ?: return
|
||||
for ((name, record) in scope.objects) {
|
||||
if (!record.visibility.isPublic) continue
|
||||
declareSlotNameIn(plan, name, record.isMutable, record.type == ObjRecord.Type.Delegated)
|
||||
var current: Scope? = scope
|
||||
while (current != null) {
|
||||
for ((name, record) in current.objects) {
|
||||
if (!record.visibility.isPublic) continue
|
||||
declareSlotNameIn(plan, name, record.isMutable, record.type == ObjRecord.Type.Delegated)
|
||||
}
|
||||
if (!includeParents) return
|
||||
current = current.parent
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,6 +404,9 @@ class Compiler(
|
||||
return LocalVarRef(name, pos)
|
||||
}
|
||||
resolutionSink?.reference(name, pos)
|
||||
seedScope?.chainLookupIgnoreClosure(name)?.let {
|
||||
return LocalVarRef(name, pos)
|
||||
}
|
||||
if (allowUnresolvedRefs || (name.isNotEmpty() && name[0].isUpperCase())) {
|
||||
return LocalVarRef(name, pos)
|
||||
}
|
||||
|
||||
@ -2575,6 +2575,12 @@ class BytecodeCompiler(
|
||||
rangeRef = extractRangeFromLocal(stmt.source)
|
||||
}
|
||||
val typedRangeLocal = if (range == null && rangeRef == null) extractTypedRangeLocal(stmt.source) else null
|
||||
val useLoopScope = stmt.loopSlotPlan.isNotEmpty()
|
||||
val planId = if (useLoopScope) {
|
||||
builder.addConst(BytecodeConst.SlotPlan(stmt.loopSlotPlan, emptyList()))
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
val loopLocalIndex = localSlotIndexByName[stmt.loopVarName]
|
||||
var usedOverride = false
|
||||
val loopSlotId = when {
|
||||
@ -2631,6 +2637,10 @@ class BytecodeCompiler(
|
||||
val loopLabel = builder.label()
|
||||
val continueLabel = builder.label()
|
||||
val endLabel = builder.label()
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.PUSH_SCOPE, planId)
|
||||
resetAddrCache()
|
||||
}
|
||||
builder.mark(loopLabel)
|
||||
|
||||
val hasNextSlot = allocSlot()
|
||||
@ -2694,6 +2704,10 @@ class BytecodeCompiler(
|
||||
}
|
||||
builder.mark(afterElse)
|
||||
}
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.POP_SCOPE)
|
||||
resetAddrCache()
|
||||
}
|
||||
return resultSlot
|
||||
}
|
||||
|
||||
@ -2739,6 +2753,10 @@ class BytecodeCompiler(
|
||||
val continueLabel = builder.label()
|
||||
val endLabel = builder.label()
|
||||
val doneLabel = builder.label()
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.PUSH_SCOPE, planId)
|
||||
resetAddrCache()
|
||||
}
|
||||
builder.mark(loopLabel)
|
||||
val cmpSlot = allocSlot()
|
||||
builder.emit(Opcode.CMP_GTE_INT, iSlot, endSlot, cmpSlot)
|
||||
@ -2786,6 +2804,10 @@ class BytecodeCompiler(
|
||||
}
|
||||
builder.mark(afterElse)
|
||||
}
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.POP_SCOPE)
|
||||
resetAddrCache()
|
||||
}
|
||||
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(doneLabel)))
|
||||
builder.mark(badRangeLabel)
|
||||
val msgId = builder.addConst(BytecodeConst.StringVal("expected Int range"))
|
||||
@ -2808,6 +2830,10 @@ class BytecodeCompiler(
|
||||
val loopLabel = builder.label()
|
||||
val continueLabel = builder.label()
|
||||
val endLabel = builder.label()
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.PUSH_SCOPE, planId)
|
||||
resetAddrCache()
|
||||
}
|
||||
builder.mark(loopLabel)
|
||||
val cmpSlot = allocSlot()
|
||||
builder.emit(Opcode.CMP_GTE_INT, iSlot, endSlot, cmpSlot)
|
||||
@ -2855,6 +2881,10 @@ class BytecodeCompiler(
|
||||
}
|
||||
builder.mark(afterElse)
|
||||
}
|
||||
if (useLoopScope) {
|
||||
builder.emit(Opcode.POP_SCOPE)
|
||||
resetAddrCache()
|
||||
}
|
||||
return resultSlot
|
||||
} finally {
|
||||
if (usedOverride) {
|
||||
|
||||
@ -905,7 +905,6 @@ class ScriptTest {
|
||||
eval(code)
|
||||
}
|
||||
|
||||
@Ignore("bytecode fallback in labeled break")
|
||||
@Test
|
||||
fun whileNonLocalBreakTest() = runTest {
|
||||
assertEquals(
|
||||
@ -3752,7 +3751,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable: closure capture in acc?.let { acc + f(x) } mis-evaluates")
|
||||
@Test
|
||||
fun testThisInClosure() = runTest {
|
||||
eval(
|
||||
@ -4428,7 +4426,6 @@ class ScriptTest {
|
||||
println(r)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable: parent scope capture for child eval not wired")
|
||||
@Test
|
||||
fun testScopeShortCircuit() = runTest() {
|
||||
val baseScope = Script.newScope()
|
||||
@ -4862,7 +4859,6 @@ class ScriptTest {
|
||||
assertContains(x1.message!!, "tc2")
|
||||
}
|
||||
|
||||
@Ignore("incremental enable: filtered stack trace missing source frame")
|
||||
@Test
|
||||
fun testFilterStackTrace() = runTest {
|
||||
var x = try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user