[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:
Roman Artemev
2018-09-04 14:08:05 +03:00
committed by romanart
parent e66f3fa59e
commit 6bb77ba51d
3 changed files with 75 additions and 48 deletions
@@ -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 ->
@@ -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")