Fix escaping immutable closure captures
This commit is contained in:
parent
0f5343fa17
commit
14214e91e1
@ -2204,8 +2204,8 @@ class CmdAssignOpObj(
|
|||||||
}
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
val name = (frame.fn.constants.getOrNull(nameId) as? BytecodeConst.StringVal)?.value
|
val name = (frame.fn.constants.getOrNull(nameId) as? BytecodeConst.StringVal)?.value
|
||||||
if (name != null) frame.ensureScope().raiseIllegalAssignment("symbol is readonly: $name")
|
if (name != null) frame.ensureScope().raiseIllegalAssignment("can't reassign val $name")
|
||||||
frame.ensureScope().raiseIllegalAssignment("symbol is readonly")
|
frame.ensureScope().raiseIllegalAssignment("can't reassign val")
|
||||||
}
|
}
|
||||||
frame.storeObjResult(dst, result)
|
frame.storeObjResult(dst, result)
|
||||||
return
|
return
|
||||||
@ -4552,7 +4552,7 @@ class CmdFrame(
|
|||||||
type = inherited.type
|
type = inherited.type
|
||||||
)
|
)
|
||||||
copied.delegate = inherited.delegate
|
copied.delegate = inherited.delegate
|
||||||
return@mapIndexed copied
|
return@mapIndexed freezeImmutableCaptureRecord(copied)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val isMutable = fn.localSlotMutables.getOrNull(localIndex) ?: false
|
val isMutable = fn.localSlotMutables.getOrNull(localIndex) ?: false
|
||||||
@ -4576,11 +4576,13 @@ class CmdFrame(
|
|||||||
val record = findNamedExistingRecord(scope, name)
|
val record = findNamedExistingRecord(scope, name)
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
val value = record.value
|
val value = record.value
|
||||||
return@mapIndexed when (value) {
|
return@mapIndexed freezeImmutableCaptureRecord(
|
||||||
|
when (value) {
|
||||||
is FrameSlotRef -> ObjRecord(value, isMutable)
|
is FrameSlotRef -> ObjRecord(value, isMutable)
|
||||||
is RecordSlotRef -> ObjRecord(value, isMutable)
|
is RecordSlotRef -> ObjRecord(value, isMutable)
|
||||||
else -> ObjRecord(value, isMutable)
|
else -> ObjRecord(value, isMutable)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (hasNamedScopeBinding(scope, name)) {
|
if (hasNamedScopeBinding(scope, name)) {
|
||||||
throw ScriptError(
|
throw ScriptError(
|
||||||
@ -4589,11 +4591,13 @@ class CmdFrame(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
freezeImmutableCaptureRecord(
|
||||||
when (raw) {
|
when (raw) {
|
||||||
is FrameSlotRef -> ObjRecord(raw, isMutable)
|
is FrameSlotRef -> ObjRecord(raw, isMutable)
|
||||||
is RecordSlotRef -> ObjRecord(raw, isMutable)
|
is RecordSlotRef -> ObjRecord(raw, isMutable)
|
||||||
else -> ObjRecord(FrameSlotRef(frame, localIndex), isMutable)
|
else -> ObjRecord(FrameSlotRef(frame, localIndex), isMutable)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,4 +90,48 @@ class OptTest {
|
|||||||
}
|
}
|
||||||
assertContains(ex.errorMessage, "can't reassign val a")
|
assertContains(ex.errorMessage, "can't reassign val a")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAssignOpErrorMessageFromExample() = runTest {
|
||||||
|
val source = Source(
|
||||||
|
"examples/error1.lyng",
|
||||||
|
"""
|
||||||
|
val a = 1
|
||||||
|
a += 2
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val ex = assertFailsWith<ScriptError> {
|
||||||
|
Script.newScope().eval(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertContains(ex.errorMessage, "can't reassign val a")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testClosuresInLaunchPool() = runTest {
|
||||||
|
eval($$"""
|
||||||
|
val result = Set()
|
||||||
|
val mu = Mutex()
|
||||||
|
fn doSomething(value) {
|
||||||
|
delay(100)
|
||||||
|
println(value)
|
||||||
|
mu.withLock {
|
||||||
|
result += value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val lp = LaunchPool(4, 1000)
|
||||||
|
for (i in 1 .. 10) {
|
||||||
|
val ii: Int = i
|
||||||
|
lp.launch {
|
||||||
|
doSomething( ii )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("all tasks were placed into lauchpool")
|
||||||
|
lp.closeAndJoin()
|
||||||
|
println("ALL DONE: $result")
|
||||||
|
assertEquals((1..10).toSet(), result)
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user