Fix block capture sync for bytecode locals
This commit is contained in:
parent
89cf2c1612
commit
ecf64dcbc3
@ -2116,6 +2116,7 @@ class BytecodeCompiler(
|
|||||||
compileRefWithFallback(ref, null, target.pos)
|
compileRefWithFallback(ref, null, target.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is VarDeclStatement -> emitVarDecl(target)
|
||||||
is IfStatement -> compileIfStatement(target)
|
is IfStatement -> compileIfStatement(target)
|
||||||
is net.sergeych.lyng.ForInStatement -> {
|
is net.sergeych.lyng.ForInStatement -> {
|
||||||
val resultSlot = emitForIn(target, false) ?: return null
|
val resultSlot = emitForIn(target, false) ?: return null
|
||||||
|
|||||||
@ -1522,6 +1522,19 @@ class CmdFrame(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shouldSyncLocalCaptures(captures: List<String>): Boolean {
|
||||||
|
if (captures.isEmpty()) return false
|
||||||
|
val localNames = fn.localSlotNames
|
||||||
|
if (localNames.isEmpty()) return false
|
||||||
|
for (capture in captures) {
|
||||||
|
for (local in localNames) {
|
||||||
|
if (local == null) continue
|
||||||
|
if (local == capture) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveModuleScope(scope: Scope): Scope {
|
private fun resolveModuleScope(scope: Scope): Scope {
|
||||||
var current: Scope? = scope
|
var current: Scope? = scope
|
||||||
var last: Scope = scope
|
var last: Scope = scope
|
||||||
@ -1545,7 +1558,7 @@ class CmdFrame(
|
|||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
if (captures.isNotEmpty() && fn.localSlotNames.isNotEmpty()) {
|
if (shouldSyncLocalCaptures(captures)) {
|
||||||
syncFrameToScope()
|
syncFrameToScope()
|
||||||
}
|
}
|
||||||
if (scope.skipScopeCreation) {
|
if (scope.skipScopeCreation) {
|
||||||
@ -1584,8 +1597,8 @@ class CmdFrame(
|
|||||||
?: error("Scope stack underflow in POP_SCOPE")
|
?: error("Scope stack underflow in POP_SCOPE")
|
||||||
val captures = captureStack.removeLastOrNull() ?: emptyList()
|
val captures = captureStack.removeLastOrNull() ?: emptyList()
|
||||||
scopeDepth -= 1
|
scopeDepth -= 1
|
||||||
if (captures.isNotEmpty() && fn.localSlotNames.isNotEmpty()) {
|
if (shouldSyncLocalCaptures(captures)) {
|
||||||
syncScopeToFrame()
|
syncFrameToScope()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,6 @@ class ScriptTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Helpers to test iterator cancellation semantics ---
|
// --- Helpers to test iterator cancellation semantics ---
|
||||||
@Ignore
|
|
||||||
class ObjTestIterable : Obj() {
|
class ObjTestIterable : Obj() {
|
||||||
|
|
||||||
var cancelCount: Int = 0
|
var cancelCount: Int = 0
|
||||||
@ -148,7 +147,6 @@ class ScriptTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
class ObjTestIterator(private val owner: ObjTestIterable) : Obj() {
|
class ObjTestIterator(private val owner: ObjTestIterable) : Obj() {
|
||||||
override val objClass: ObjClass = type
|
override val objClass: ObjClass = type
|
||||||
private var i = 0
|
private var i = 0
|
||||||
@ -171,7 +169,6 @@ class ScriptTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Scope.eval should seed compile-time symbols from current scope")
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopDoesNotCancelOnNaturalCompletion() = runTest {
|
fun testForLoopDoesNotCancelOnNaturalCompletion() = runTest {
|
||||||
val scope = Script.newScope()
|
val scope = Script.newScope()
|
||||||
@ -189,7 +186,6 @@ class ScriptTest {
|
|||||||
assertEquals(0, ti.cancelCount)
|
assertEquals(0, ti.cancelCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopCancelsOnBreak() = runTest {
|
fun testForLoopCancelsOnBreak() = runTest {
|
||||||
val scope = Script.newScope()
|
val scope = Script.newScope()
|
||||||
@ -205,7 +201,6 @@ class ScriptTest {
|
|||||||
assertEquals(1, ti.cancelCount)
|
assertEquals(1, ti.cancelCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopCancelsOnException() = runTest {
|
fun testForLoopCancelsOnException() = runTest {
|
||||||
val scope = Script.newScope()
|
val scope = Script.newScope()
|
||||||
@ -384,7 +379,6 @@ class ScriptTest {
|
|||||||
assertTrue(eval("sin(π)").toDouble() - 1 < 0.000001)
|
assertTrue(eval("sin(π)").toDouble() - 1 < 0.000001)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Scope.eval should seed compile-time symbols from current scope")
|
|
||||||
@Test
|
@Test
|
||||||
fun varsAndConstsTest() = runTest {
|
fun varsAndConstsTest() = runTest {
|
||||||
val scope = Scope(pos = Pos.builtIn)
|
val scope = Scope(pos = Pos.builtIn)
|
||||||
@ -406,7 +400,6 @@ class ScriptTest {
|
|||||||
assertEquals(5, scope.eval("b").toInt())
|
assertEquals(5, scope.eval("b").toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun functionTest() = runTest {
|
fun functionTest() = runTest {
|
||||||
val scope = Scope(pos = Pos.builtIn)
|
val scope = Scope(pos = Pos.builtIn)
|
||||||
@ -433,7 +426,6 @@ class ScriptTest {
|
|||||||
assertEquals(14, scope.eval("bar(3)").toInt())
|
assertEquals(14, scope.eval("bar(3)").toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun simpleClosureTest() = runTest {
|
fun simpleClosureTest() = runTest {
|
||||||
val scope = Scope(pos = Pos.builtIn)
|
val scope = Scope(pos = Pos.builtIn)
|
||||||
@ -559,7 +551,6 @@ class ScriptTest {
|
|||||||
assertFalse { eval("4 <= 3").toBool() }
|
assertFalse { eval("4 <= 3").toBool() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun ifTest() = runTest {
|
fun ifTest() = runTest {
|
||||||
// if - single line
|
// if - single line
|
||||||
@ -759,7 +750,6 @@ class ScriptTest {
|
|||||||
assertEquals(ObjInt(5), c["c"]?.value)
|
assertEquals(ObjInt(5), c["c"]?.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Scope.eval should seed compile-time symbols from current scope")
|
|
||||||
@Test
|
@Test
|
||||||
fun testAssignArgumentsEndEllipsis() = runTest {
|
fun testAssignArgumentsEndEllipsis() = runTest {
|
||||||
// equal args,
|
// equal args,
|
||||||
@ -787,7 +777,6 @@ class ScriptTest {
|
|||||||
c.eval("assert( b == [] )")
|
c.eval("assert( b == [] )")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testAssignArgumentsStartEllipsis() = runTest {
|
fun testAssignArgumentsStartEllipsis() = runTest {
|
||||||
val ttEnd = Token.Type.RBRACE
|
val ttEnd = Token.Type.RBRACE
|
||||||
@ -822,7 +811,6 @@ class ScriptTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("incremental enable")
|
|
||||||
@Test
|
@Test
|
||||||
fun testAssignArgumentsMiddleEllipsis() = runTest {
|
fun testAssignArgumentsMiddleEllipsis() = runTest {
|
||||||
val ttEnd = Token.Type.RBRACE
|
val ttEnd = Token.Type.RBRACE
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user