Refine dispatching convention
Dispatching happens only via `suspendWithCurrentContinuation` calls instead of each `resume` call #KT-15657 Fixed
This commit is contained in:
@@ -60,6 +60,9 @@ const val COROUTINE_LABEL_FIELD_NAME = "label"
|
||||
const val SUSPEND_FUNCTION_CREATE_METHOD_NAME = "create"
|
||||
const val DO_RESUME_METHOD_NAME = "doResume"
|
||||
|
||||
private val INTERNAL_COROUTINE_INTRINSICS_OWNER = "kotlin/jvm/internal/CoroutineIntrinsics"
|
||||
private val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation"
|
||||
|
||||
data class ResolvedCallWithRealDescriptor(val resolvedCall: ResolvedCall<*>, val fakeContinuationExpression: KtExpression)
|
||||
|
||||
@JvmField
|
||||
@@ -207,6 +210,15 @@ fun createMethodNodeForSuspendCoroutineOrReturn(
|
||||
|
||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||
node.visitVarInsn(Opcodes.ALOAD, 1)
|
||||
|
||||
node.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
INTERNAL_COROUTINE_INTRINSICS_OWNER,
|
||||
NORMALIZE_CONTINUATION_METHOD_NAME,
|
||||
Type.getMethodDescriptor(AsmTypes.CONTINUATION, AsmTypes.CONTINUATION),
|
||||
false
|
||||
)
|
||||
|
||||
node.visitMethodInsn(
|
||||
Opcodes.INVOKEINTERFACE,
|
||||
typeMapper.mapType(functionDescriptor.valueParameters[0]).internalName,
|
||||
|
||||
@@ -53,7 +53,7 @@ fun box(): String {
|
||||
val k = suspendWithValue("K")
|
||||
log += "$o$k;"
|
||||
}
|
||||
if (result != "before 0;suspend(O);before 1;suspend(K);before 2;OK;after 2;after 1;after 0;") return "fail1: $result"
|
||||
if (result != "suspend(O);before 0;suspend(K);before 1;OK;after 1;after 0;") return "fail1: $result"
|
||||
|
||||
result = test {
|
||||
try {
|
||||
@@ -64,7 +64,7 @@ fun box(): String {
|
||||
log += "${e.message};"
|
||||
}
|
||||
}
|
||||
if (result != "before 0;error(OK);before 1;OK;after 1;after 0;") return "fail2: $result"
|
||||
if (result != "error(OK);before 0;OK;after 0;") return "fail2: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+2
-2
@@ -71,12 +71,12 @@ fun box(): String {
|
||||
var result = test {
|
||||
test1()
|
||||
}
|
||||
if (result != "before 0;suspend();before 1;suspend(O);before 2;before 3;suspend(K);before 4;OK;before 5;after 5;after 4;after 3;after 2;after 1;after 0;") return "fail1: $result"
|
||||
if (result != "suspend();before 0;suspend(O);before 1;suspend(K);before 2;OK;after 2;after 1;after 0;") return "fail1: $result"
|
||||
|
||||
result = test {
|
||||
test2()
|
||||
}
|
||||
if (result != "before 0;suspend();before 1;suspend(O);before 2;before 3;error(OK);before 4;OK;before 5;after 5;after 4;after 3;after 2;after 1;after 0;") return "fail2: $result"
|
||||
if (result != "suspend();before 0;suspend(O);before 1;error(OK);before 2;OK;after 2;after 1;after 0;") return "fail2: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user