public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
}
这是一个可挂起的内联函数,编译后,该函数不存在,函数体已被内联至调用处。
这个函数的目的很简单,就是给 block: (Continuation<T>) -> Any? 传递协程块里的隐藏的 continuation(Continuation<T>) 参数并执行:
Object result = block(continuation)
参见 compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt:
fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSettings: LanguageVersionSettings): MethodNode {
val node =
MethodNode(
Opcodes.API_VERSION,
Opcodes.ACC_STATIC,
"fake",
Type.getMethodDescriptor(OBJECT_TYPE, AsmTypes.FUNCTION1, languageVersionSettings.continuationAsmType()),
null, null
)
with(InstructionAdapter(node)) {
load(0, OBJECT_TYPE) // block
load(1, OBJECT_TYPE) // continuation
// block.invoke(continuation)
invokeinterface(
AsmTypes.FUNCTION1.internalName,
OperatorNameConventions.INVOKE.identifier,
"($OBJECT_TYPE)$OBJECT_TYPE"
)
if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) {
val elseLabel = Label()
// if (result === COROUTINE_SUSPENDED) {
dup()
loadCoroutineSuspendedMarker(languageVersionSettings)
ifacmpne(elseLabel)
// DebugProbesKt.probeCoroutineSuspended(continuation)
load(1, OBJECT_TYPE) // continuation
checkcast(languageVersionSettings.continuationAsmType())
invokestatic(
languageVersionSettings.coroutinesJvmInternalPackageFqName().child(Name.identifier("DebugProbesKt"))
.topLevelClassAsmType().internalName,
"probeCoroutineSuspended",
"(${languageVersionSettings.continuationAsmType()})V",
false
)
// }
mark(elseLabel)
}
}
node.visitInsn(Opcodes.ARETURN)
node.visitMaxs(3, 2)
return node
}