bump version to 1.0.7-SNAPSHOT; fix potential infinite loops in Scope traversal
This commit is contained in:
parent
55caa65f97
commit
c0fab3d60e
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "1.0.6-SNAPSHOT"
|
version = "1.0.7-SNAPSHOT"
|
||||||
|
|
||||||
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
||||||
|
|
||||||
|
|||||||
@ -1351,15 +1351,21 @@ class FastLocalVarRef(
|
|||||||
if (owner.frameId != cachedOwnerFrameId) return false
|
if (owner.frameId != cachedOwnerFrameId) return false
|
||||||
// Ensure owner is an ancestor (or same) of current
|
// Ensure owner is an ancestor (or same) of current
|
||||||
var s: Scope? = current
|
var s: Scope? = current
|
||||||
|
var guard = 0
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
if (s === owner) return true
|
if (s === owner) return true
|
||||||
s = s.parent
|
val next = s.parent
|
||||||
|
// Defensive: break on self-parent or pathological cycles
|
||||||
|
if (next === s) return false
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveSlotInAncestry(scope: Scope): Int {
|
private fun resolveSlotInAncestry(scope: Scope): Int {
|
||||||
var s: Scope? = scope
|
var s: Scope? = scope
|
||||||
|
var guard = 0
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
val idx = s.getSlotIndexOf(name)
|
val idx = s.getSlotIndexOf(name)
|
||||||
if (idx != null) {
|
if (idx != null) {
|
||||||
@ -1368,7 +1374,10 @@ class FastLocalVarRef(
|
|||||||
cachedSlot = idx
|
cachedSlot = idx
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
s = s.parent
|
val next = s.parent
|
||||||
|
if (next === s) return -1
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) return -1
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
@ -1387,16 +1396,26 @@ class FastLocalVarRef(
|
|||||||
// Try per-frame local binding maps in the ancestry first (locals declared in frames)
|
// Try per-frame local binding maps in the ancestry first (locals declared in frames)
|
||||||
run {
|
run {
|
||||||
var s: Scope? = scope
|
var s: Scope? = scope
|
||||||
|
var guard = 0
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
s.localBindings[name]?.let { return it }
|
s.localBindings[name]?.let { return it }
|
||||||
s = s.parent
|
val next = s.parent
|
||||||
|
if (next === s) break
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try to find a direct local binding in the current ancestry (without invoking name resolution that may prefer fields)
|
// Try to find a direct local binding in the current ancestry (without invoking name resolution that may prefer fields)
|
||||||
var s: Scope? = scope
|
run {
|
||||||
while (s != null) {
|
var s: Scope? = scope
|
||||||
s.objects[name]?.let { return it }
|
var guard = 0
|
||||||
s = s.parent
|
while (s != null) {
|
||||||
|
s.objects[name]?.let { return it }
|
||||||
|
val next = s.parent
|
||||||
|
if (next === s) break
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Fallback to standard name lookup (locals or closure chain) if the slot owner changed across suspension
|
// Fallback to standard name lookup (locals or closure chain) if the slot owner changed across suspension
|
||||||
scope[name]?.let { return it }
|
scope[name]?.let { return it }
|
||||||
@ -1413,16 +1432,26 @@ class FastLocalVarRef(
|
|||||||
// Try per-frame local binding maps in the ancestry first
|
// Try per-frame local binding maps in the ancestry first
|
||||||
run {
|
run {
|
||||||
var s: Scope? = scope
|
var s: Scope? = scope
|
||||||
|
var guard = 0
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
s.localBindings[name]?.let { return it.value }
|
s.localBindings[name]?.let { return it.value }
|
||||||
s = s.parent
|
val next = s.parent
|
||||||
|
if (next === s) break
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try to find a direct local binding in the current ancestry first
|
// Try to find a direct local binding in the current ancestry first
|
||||||
var s: Scope? = scope
|
run {
|
||||||
while (s != null) {
|
var s: Scope? = scope
|
||||||
s.objects[name]?.let { return it.value }
|
var guard = 0
|
||||||
s = s.parent
|
while (s != null) {
|
||||||
|
s.objects[name]?.let { return it.value }
|
||||||
|
val next = s.parent
|
||||||
|
if (next === s) break
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Fallback to standard name lookup (locals or closure chain)
|
// Fallback to standard name lookup (locals or closure chain)
|
||||||
scope[name]?.let { return it.value }
|
scope[name]?.let { return it.value }
|
||||||
@ -1443,6 +1472,7 @@ class FastLocalVarRef(
|
|||||||
// Try per-frame local binding maps in the ancestry first
|
// Try per-frame local binding maps in the ancestry first
|
||||||
run {
|
run {
|
||||||
var s: Scope? = scope
|
var s: Scope? = scope
|
||||||
|
var guard = 0
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
val rec = s.localBindings[name]
|
val rec = s.localBindings[name]
|
||||||
if (rec != null) {
|
if (rec != null) {
|
||||||
@ -1450,7 +1480,10 @@ class FastLocalVarRef(
|
|||||||
rec.value = newValue
|
rec.value = newValue
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s = s.parent
|
val next = s.parent
|
||||||
|
if (next === s) break
|
||||||
|
s = next
|
||||||
|
if (++guard > 4096) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fallback to standard name lookup
|
// Fallback to standard name lookup
|
||||||
|
|||||||
@ -4056,4 +4056,18 @@ class ScriptTest {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testHangOnPrintlnInMethods() = runTest {
|
||||||
|
eval("""
|
||||||
|
class T(someList) {
|
||||||
|
fun f() {
|
||||||
|
val x = [...someList]
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
T([1,2]).f()
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user