[JS IR BE] Get rid of parameters in doResume method. Make its signature similar for both 1.2 and 1.3 coroutines
This commit is contained in:
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.getPropertyDeclaration
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -74,7 +75,8 @@ class JsIrBackendContext(
|
||||
private val internalPackage = module.getPackage(internalPackageName)
|
||||
|
||||
// TODO: replace it with appropriate package name once we migrate to 1.3 coroutines
|
||||
private val coroutinePackageNameSrting = "kotlin.coroutines.experimental"
|
||||
private val coroutinePackageNameSrting_12 = "kotlin.coroutines.experimental"
|
||||
private val coroutinePackageNameSrting_13 = "kotlin.coroutines"
|
||||
|
||||
private val INTRINSICS_PACKAGE_NAME = Name.identifier("intrinsics")
|
||||
private val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED")
|
||||
@@ -86,7 +88,7 @@ class JsIrBackendContext(
|
||||
private val CONTINUATION_CONTEXT_GETTER_NAME = Name.special("<get-context>")
|
||||
private val CONTINUATION_CONTEXT_PROPERTY_NAME = Name.identifier("context")
|
||||
|
||||
private val coroutinePackageName = FqName(coroutinePackageNameSrting)
|
||||
private val coroutinePackageName = FqName(coroutinePackageNameSrting_12)
|
||||
private val coroutineIntrinsicsPackageName = coroutinePackageName.child(INTRINSICS_PACKAGE_NAME)
|
||||
|
||||
private val coroutinePackage = module.getPackage(coroutinePackageName)
|
||||
@@ -193,6 +195,11 @@ class JsIrBackendContext(
|
||||
override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true
|
||||
}
|
||||
|
||||
val coroutineImplLabelProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("label")!! }
|
||||
val coroutineImplResultSymbol by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("result")!! }
|
||||
val coroutineImplExceptionProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exception")!! }
|
||||
val coroutineImplExceptionStateProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exceptionState")!! }
|
||||
|
||||
private fun referenceOperators() = OperatorNames.ALL.map { name ->
|
||||
// TODO to replace KotlinType with IrType we need right equals on IrType
|
||||
name to irBuiltIns.primitiveTypes.fold(mutableMapOf<KotlinType, IrFunctionSymbol>()) { m, t ->
|
||||
|
||||
+56
-38
@@ -227,24 +227,34 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
builtCoroutines[irFunction] = coroutine
|
||||
|
||||
if (functionReference == null) {
|
||||
val resultSetter = context.coroutineImplResultSymbol.setter!!
|
||||
val exceptionSetter = context.coroutineImplExceptionProperty.setter!!
|
||||
// It is not a lambda - replace original function with a call to constructor of the built coroutine.
|
||||
val irBuilder = context.createIrBuilder(irFunction.symbol, irFunction.startOffset, irFunction.endOffset)
|
||||
irFunction.body = irBuilder.irBlockBody(irFunction) {
|
||||
+irReturn(
|
||||
irCall(coroutine.doResumeFunction.symbol).apply {
|
||||
dispatchReceiver = irCall(coroutine.coroutineConstructor.symbol).apply {
|
||||
val functionParameters = irFunction.explicitParameters
|
||||
functionParameters.forEachIndexed { index, argument ->
|
||||
putValueArgument(index, irGet(argument))
|
||||
}
|
||||
putValueArgument(
|
||||
functionParameters.size,
|
||||
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(irFunction.returnType))
|
||||
)
|
||||
}
|
||||
putValueArgument(0, irGetObject(unit)) // value
|
||||
putValueArgument(1, irNull()) // exception
|
||||
})
|
||||
val dispatchReceiverCall = irCall(coroutine.coroutineConstructor.symbol).apply {
|
||||
val functionParameters = irFunction.explicitParameters
|
||||
functionParameters.forEachIndexed { index, argument ->
|
||||
putValueArgument(index, irGet(argument))
|
||||
}
|
||||
putValueArgument(
|
||||
functionParameters.size,
|
||||
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(irFunction.returnType))
|
||||
)
|
||||
}
|
||||
val dispatchReceiverVar = JsIrBuilder.buildVar(dispatchReceiverCall.type, irFunction, initializer = dispatchReceiverCall)
|
||||
+dispatchReceiverVar
|
||||
+irCall(resultSetter).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
putValueArgument(0, irGetObject(unit))
|
||||
}
|
||||
+irCall(exceptionSetter).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
putValueArgument(0, irNull())
|
||||
}
|
||||
+irReturn(irCall(coroutine.doResumeFunction.symbol).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,8 +277,6 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
|
||||
private lateinit var suspendResult: IrVariable
|
||||
private lateinit var suspendState: IrVariable
|
||||
private lateinit var dataArgument: IrValueParameter
|
||||
private lateinit var exceptionArgument: IrValueParameter
|
||||
private lateinit var coroutineClass: IrClassImpl
|
||||
private lateinit var coroutineClassThis: IrValueParameter
|
||||
private lateinit var argumentToPropertiesMap: Map<IrValueParameter, IrField>
|
||||
@@ -280,9 +288,10 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
|
||||
private val create1CompletionParameter = create1Function.valueParameters[0]
|
||||
|
||||
private val coroutineImplLabelProperty = coroutineImplSymbol.getPropertyDeclaration("label")!!
|
||||
private val coroutineImplExceptionProperty = coroutineImplSymbol.getPropertyDeclaration("pendingException")!!
|
||||
private val coroutineImplExceptionStateProperty = coroutineImplSymbol.getPropertyDeclaration("exceptionState")!!
|
||||
private val coroutineImplLabelProperty = context.coroutineImplLabelProperty
|
||||
private val coroutineImplResultSymbol = context.coroutineImplResultSymbol
|
||||
private val coroutineImplExceptionProperty = context.coroutineImplExceptionProperty
|
||||
private val coroutineImplExceptionStateProperty = context.coroutineImplExceptionStateProperty
|
||||
|
||||
private val coroutineConstructors = mutableListOf<IrConstructor>()
|
||||
private var exceptionTrapId = -1
|
||||
@@ -710,25 +719,35 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
JsIrBuilder.buildValueParameter(p.name, p.index, p.type, p.origin).also { it.parent = declaration }
|
||||
}
|
||||
|
||||
val resultSetter = context.coroutineImplResultSymbol.setter!!
|
||||
val exceptionSetter = context.coroutineImplExceptionProperty.setter!!
|
||||
|
||||
val thisReceiver = coroutineClassThis
|
||||
val irBuilder = context.createIrBuilder(symbol, irFunction.startOffset, irFunction.endOffset)
|
||||
declaration.body = irBuilder.irBlockBody(irFunction.startOffset, irFunction.endOffset) {
|
||||
+irReturn(
|
||||
irCall(doResumeFunction).apply {
|
||||
dispatchReceiver = irCall(createFunction).apply {
|
||||
dispatchReceiver = irGet(thisReceiver)
|
||||
declaration.valueParameters.forEachIndexed { index, parameter ->
|
||||
putValueArgument(index, irGet(parameter))
|
||||
}
|
||||
putValueArgument(
|
||||
declaration.valueParameters.size,
|
||||
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(declaration.returnType))
|
||||
)
|
||||
}
|
||||
putValueArgument(0, irGetObject(symbols.unit)) // value
|
||||
putValueArgument(1, irNull()) // exception
|
||||
val dispatchReceiverCall = irCall(createFunction).apply {
|
||||
dispatchReceiver = irGet(thisReceiver)
|
||||
declaration.valueParameters.forEachIndexed { index, parameter ->
|
||||
putValueArgument(index, irGet(parameter))
|
||||
}
|
||||
)
|
||||
putValueArgument(
|
||||
declaration.valueParameters.size,
|
||||
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(declaration.returnType))
|
||||
)
|
||||
}
|
||||
val dispatchReceiverVar = JsIrBuilder.buildVar(dispatchReceiverCall.type, irFunction, initializer = dispatchReceiverCall)
|
||||
+dispatchReceiverVar
|
||||
+irCall(resultSetter).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
putValueArgument(0, irGetObject(unit))
|
||||
}
|
||||
+irCall(exceptionSetter).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
putValueArgument(0, irNull())
|
||||
}
|
||||
+irReturn(irCall(doResumeFunction).apply {
|
||||
dispatchReceiver = irGet(dispatchReceiverVar)
|
||||
})
|
||||
}
|
||||
|
||||
return declaration
|
||||
@@ -787,14 +806,13 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
JsIrBuilder.buildValueParameter(it.name, it.index, it.type, it.origin).also { p -> p.parent = function }
|
||||
}
|
||||
|
||||
dataArgument = function.valueParameters[0]
|
||||
exceptionArgument = function.valueParameters[1]
|
||||
val thisReceiver = JsIrBuilder.buildGetValue(coroutineClassThis.symbol)
|
||||
suspendResult = JsIrBuilder.buildVar(
|
||||
context.irBuiltIns.anyNType,
|
||||
function,
|
||||
"suspendResult",
|
||||
true,
|
||||
initializer = JsIrBuilder.buildGetValue(dataArgument.symbol)
|
||||
initializer = JsIrBuilder.buildCall(coroutineImplResultSymbol.getter!!.symbol).apply { dispatchReceiver = thisReceiver }
|
||||
)
|
||||
|
||||
suspendState = JsIrBuilder.buildVar(coroutineImplLabelProperty.getter!!.returnType, function, "suspendState", true)
|
||||
|
||||
@@ -34,7 +34,8 @@ internal abstract class CoroutineImpl(private val completion: Continuation<Any?>
|
||||
protected var exceptionState = 0
|
||||
protected var label: Int = 0
|
||||
|
||||
protected var pendingException: dynamic = null
|
||||
protected var exception: dynamic = null
|
||||
protected var result: dynamic = null
|
||||
|
||||
public override val context: CoroutineContext get() = completion?.context
|
||||
|
||||
@@ -44,21 +45,22 @@ internal abstract class CoroutineImpl(private val completion: Continuation<Any?>
|
||||
}
|
||||
|
||||
override fun resume(value: Any?) {
|
||||
doResumeWrapper(value, null)
|
||||
this.result = value
|
||||
doResumeWrapper()
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
// TODO: once we have arrays working refact it with exception table
|
||||
label = exceptionState
|
||||
pendingException = exception
|
||||
doResumeWrapper(null, exception)
|
||||
this.label = exceptionState
|
||||
this.exception = exception
|
||||
doResumeWrapper()
|
||||
}
|
||||
|
||||
protected fun doResumeWrapper(data: Any?, exception: Throwable?) {
|
||||
processBareContinuationResume(completion) { doResume(data, exception) }
|
||||
protected fun doResumeWrapper() {
|
||||
processBareContinuationResume(completion) { doResume() }
|
||||
}
|
||||
|
||||
protected abstract fun doResume(data: Any?, exception: Throwable?): Any?
|
||||
protected abstract fun doResume(): Any?
|
||||
|
||||
open fun create(completion: Continuation<*>): Continuation<Unit> {
|
||||
throw IllegalStateException("create(Continuation) has not been overridden")
|
||||
|
||||
Reference in New Issue
Block a user