Skip to content

Instantly share code, notes, and snippets.

@phiSgr
Last active February 18, 2023 22:33
Show Gist options
  • Save phiSgr/7045bccac80f267a66a93e23626cd427 to your computer and use it in GitHub Desktop.
Save phiSgr/7045bccac80f267a66a93e23626cd427 to your computer and use it in GitHub Desktop.
// git clone git@github.com:7045bccac80f267a66a93e23626cd427.git yinyang
// cd yinyang
// kotlinc yinyang.kt -include-runtime -d yinyang.jar && java -jar yinyang.jar; rm yinyang.jar
// Copied from https://github.com/arrow-kt/arrow/blob/0.10.1/modules/core/arrow-core-data/src/main/kotlin/arrow/typeclasses/ContinuationUtils.kt
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
private val coroutineImplClass by lazy { Class.forName("kotlin.coroutines.jvm.internal.BaseContinuationImpl") }
private val completionField by lazy { coroutineImplClass.getDeclaredField("completion").apply { isAccessible = true } }
private var <T> Continuation<T>.completion: Continuation<*>?
get() = completionField.get(this) as Continuation<*>
set(value) = completionField.set(this@completion, value)
var <T> Continuation<T>.stateStack: List<Map<String, *>>
get() {
if (!coroutineImplClass.isInstance(this)) return emptyList()
val resultForThis = (this.javaClass.declaredFields)
.associate { it.isAccessible = true; it.name to it.get(this@stateStack) }
.let(::listOf)
val resultForCompletion = completion?.stateStack
return resultForCompletion?.let { resultForThis + it } ?: resultForThis
}
set(value) {
if (!coroutineImplClass.isInstance(this)) return
val mapForThis = value.first()
(this.javaClass.declaredFields).forEach {
if (it.name in mapForThis) {
it.isAccessible = true
val fieldValue = mapForThis[it.name]
it.set(this@stateStack, fieldValue)
}
}
completion?.stateStack = value.subList(1, value.size)
}
// https://medium.com/@georgeleung_7777/the-yin-yang-puzzle-in-kotlin-bb1d5449d6f0
data class Cont(
val cont: Continuation<Cont>,
val stateStack: List<Map<String, *>>
) : (Cont) -> Unit {
override fun invoke(p1: Cont) {
cont.stateStack = stateStack
cont.resume(p1)
}
}
suspend fun captureCont(): Cont = suspendCoroutineUninterceptedOrReturn { c ->
Cont(c, stateStack = c.stateStack)
}
suspend fun main() {
val yin = captureCont()
println("@")
val yang = captureCont()
print("*")
yin(yang)
}
@phiSgr
Copy link
Author

phiSgr commented Feb 18, 2023

kotlinc-jvm 1.8.10

@
*@
**@
***@
****@
*****@
******@
*******@
********@
*********@
**********@
***********@
************@
*************@
**************@
***************@
****************@
*****************@
******************@
*******************@
********************@
*********************@
**********************@
***********************@
************************@
*************************@
**************************@
***************************@
****************************@
*****************************@
******************************@
*******************************@
********************************@
*********************************@
**********************************@
***********************************@
************************************@
*************************************@
**************************************@
***************************************@
****************************************@
*****************************************@
******************************************@
*******************************************@
********************************************@
*********************************************@
**********************************************@
***********************************************@
************************************************@
*************************************************@
**************************************************@
***************************************************@
****************************************************@
*****************************************************@
******************************************************@
***********************Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class kotlin.coroutines.ContinuationInterceptor
	at kotlin.coroutines.jvm.internal.ContinuationImpl.releaseIntercepted(ContinuationImpl.kt:118)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:39)
	at Cont.invoke(yinyang.kt:47)
	at YinyangKt.main(yinyang.kt:62)
	at YinyangKt$main$2.invoke(yinyang.kt)
	at YinyangKt$main$2.invoke(yinyang.kt)
	at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$1.invokeSuspend(IntrinsicsJvm.kt:205)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
	at kotlin.coroutines.jvm.internal.RunSuspendKt.runSuspend(RunSuspend.kt:19)
	at YinyangKt.main(yinyang.kt)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment