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