[JS IR BE] Make coroutine compile separately from stdlib
* use accessors instead of direct field access
This commit is contained in:
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
private fun IrClassSymbol.getPropertyDeclaration(name: String) =
|
||||
fun IrClassSymbol.getPropertyDeclaration(name: String) =
|
||||
this.owner.declarations.filterIsInstance<IrProperty>()
|
||||
.atMostOne { it.descriptor.name == Name.identifier(name) }
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ReflectionTypes
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
@@ -22,10 +23,7 @@ import org.jetbrains.kotlin.ir.SourceRangeInfo
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ModuleIndex
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
@@ -86,6 +84,7 @@ class JsIrBackendContext(
|
||||
|
||||
// TODO: what is more clear way reference this getter?
|
||||
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 coroutineIntrinsicsPackageName = coroutinePackageName.child(INTRINSICS_PACKAGE_NAME)
|
||||
@@ -103,7 +102,9 @@ class JsIrBackendContext(
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
) as ClassDescriptor
|
||||
)
|
||||
val contextGetter = continuation.owner.declarations.single { it.descriptor.name == CONTINUATION_CONTEXT_GETTER_NAME } as IrFunction
|
||||
val contextGetter =
|
||||
continuation.owner.declarations.filterIsInstance<IrFunction>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_GETTER_NAME }
|
||||
?: continuation.owner.declarations.filterIsInstance<IrProperty>().atMostOne { it.descriptor.name == CONTINUATION_CONTEXT_PROPERTY_NAME }?.getter!!
|
||||
return contextGetter.symbol
|
||||
}
|
||||
|
||||
|
||||
+33
-32
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
@@ -55,9 +56,9 @@ class StateMachineBuilder(
|
||||
val context: JsIrBackendContext,
|
||||
val function: IrFunctionSymbol,
|
||||
private val rootLoop: IrLoop,
|
||||
private val exceptionSymbol: IrFieldSymbol,
|
||||
private val exStateSymbol: IrFieldSymbol,
|
||||
private val stateSymbol: IrFieldSymbol,
|
||||
private val exceptionSymbol: IrProperty,
|
||||
private val exStateSymbol: IrProperty,
|
||||
private val stateSymbol: IrProperty,
|
||||
thisSymbol: IrValueParameterSymbol,
|
||||
private val suspendResult: IrVariableSymbol
|
||||
) : IrElementVisitorVoid {
|
||||
@@ -75,7 +76,7 @@ class StateMachineBuilder(
|
||||
|
||||
val entryState = SuspendState(unit)
|
||||
val rootExceptionTrap = buildExceptionTrapState()
|
||||
private val globalExceptionVar = JsIrBuilder.buildVar(exceptionSymbol.owner.type, function.owner, "e")
|
||||
private val globalExceptionVar = JsIrBuilder.buildVar(exceptionSymbol.getter!!.returnType, function.owner, "e")
|
||||
lateinit var globalCatch: IrCatch
|
||||
|
||||
fun finalizeStateMachine() {
|
||||
@@ -109,18 +110,14 @@ class StateMachineBuilder(
|
||||
)
|
||||
|
||||
// TODO: exception table
|
||||
elseBlock.statements += JsIrBuilder.buildSetField(
|
||||
stateSymbol,
|
||||
thisReceiver,
|
||||
exceptionState(),
|
||||
unit
|
||||
)
|
||||
elseBlock.statements += JsIrBuilder.buildSetField(
|
||||
exceptionSymbol,
|
||||
thisReceiver,
|
||||
JsIrBuilder.buildGetValue(globalExceptionSymbol),
|
||||
unit
|
||||
)
|
||||
elseBlock.statements += JsIrBuilder.buildCall(stateSymbol.setter!!.symbol, unit).apply {
|
||||
dispatchReceiver = thisReceiver
|
||||
putValueArgument(0, exceptionState())
|
||||
}
|
||||
elseBlock.statements += JsIrBuilder.buildCall(exceptionSymbol.setter!!.symbol, unit).apply {
|
||||
dispatchReceiver = thisReceiver
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(globalExceptionSymbol))
|
||||
}
|
||||
} else {
|
||||
block.statements += JsIrBuilder.buildThrow(
|
||||
nothing,
|
||||
@@ -175,7 +172,10 @@ class StateMachineBuilder(
|
||||
private fun doDispatchImpl(target: SuspendState, block: IrContainerExpression, andContinue: Boolean) {
|
||||
val irDispatch = IrDispatchPoint(target)
|
||||
currentState.successors.add(target)
|
||||
block.addStatement(JsIrBuilder.buildSetField(stateSymbol, thisReceiver, irDispatch, unit))
|
||||
block.addStatement(JsIrBuilder.buildCall(stateSymbol.setter!!.symbol, unit).apply {
|
||||
dispatchReceiver = thisReceiver
|
||||
putValueArgument(0, irDispatch)
|
||||
})
|
||||
if (andContinue) doContinue(block)
|
||||
}
|
||||
|
||||
@@ -288,7 +288,12 @@ class StateMachineBuilder(
|
||||
|
||||
currentState.successors += continueState
|
||||
|
||||
transformLastExpression { JsIrBuilder.buildSetField(stateSymbol, thisReceiver, dispatch, unit) }
|
||||
transformLastExpression {
|
||||
JsIrBuilder.buildCall(stateSymbol.setter!!.symbol, unit).apply {
|
||||
dispatchReceiver = thisReceiver
|
||||
putValueArgument(0, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
addStatement(JsIrBuilder.buildSetVariable(suspendResult, result, unit))
|
||||
|
||||
@@ -661,14 +666,10 @@ class StateMachineBuilder(
|
||||
aTry.finallyExpression?.acceptVoid(this)
|
||||
currentState.successors += listOf(throwExitState, exitState)
|
||||
addStatement(
|
||||
JsIrBuilder.buildSetField(
|
||||
stateSymbol,
|
||||
thisReceiver,
|
||||
JsIrBuilder.buildGetValue(
|
||||
finallyStateVar.symbol
|
||||
),
|
||||
unit
|
||||
)
|
||||
JsIrBuilder.buildCall(stateSymbol.setter!!.symbol, unit).also {
|
||||
it.dispatchReceiver = thisReceiver
|
||||
it.putValueArgument(0, JsIrBuilder.buildGetValue(finallyStateVar.symbol))
|
||||
}
|
||||
)
|
||||
doContinue()
|
||||
|
||||
@@ -685,15 +686,15 @@ class StateMachineBuilder(
|
||||
|
||||
private fun setupExceptionState(target: SuspendState) {
|
||||
addStatement(
|
||||
JsIrBuilder.buildSetField(
|
||||
exStateSymbol, thisReceiver,
|
||||
IrDispatchPoint(target), unit
|
||||
)
|
||||
JsIrBuilder.buildCall(exStateSymbol.setter!!.symbol, unit).apply {
|
||||
dispatchReceiver = thisReceiver
|
||||
putValueArgument(0, IrDispatchPoint(target))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun exceptionState() = JsIrBuilder.buildGetField(exStateSymbol, thisReceiver)
|
||||
private fun pendingException() = JsIrBuilder.buildGetField(exceptionSymbol, thisReceiver)
|
||||
private fun exceptionState() = JsIrBuilder.buildCall(exStateSymbol.getter!!.symbol).also { it.dispatchReceiver = thisReceiver }
|
||||
private fun pendingException() = JsIrBuilder.buildCall(exceptionSymbol.getter!!.symbol).also { it.dispatchReceiver = thisReceiver }
|
||||
|
||||
private fun buildTryState(aTry: IrTry) =
|
||||
TryState(
|
||||
|
||||
+14
-9
@@ -280,9 +280,9 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
|
||||
private val create1CompletionParameter = create1Function.valueParameters[0]
|
||||
|
||||
private val coroutineImplLabelFieldSymbol = coroutineImplSymbol.getPropertyField("label")!!
|
||||
private val coroutineImplExceptionFieldSymbol = coroutineImplSymbol.getPropertyField("pendingException")!!
|
||||
private val coroutineImplExceptionStateFieldSymbol = coroutineImplSymbol.getPropertyField("exceptionState")!!
|
||||
private val coroutineImplLabelProperty = coroutineImplSymbol.getPropertyDeclaration("label")!!
|
||||
private val coroutineImplExceptionProperty = coroutineImplSymbol.getPropertyDeclaration("pendingException")!!
|
||||
private val coroutineImplExceptionStateProperty = coroutineImplSymbol.getPropertyDeclaration("exceptionState")!!
|
||||
|
||||
private val coroutineConstructors = mutableListOf<IrConstructor>()
|
||||
private var exceptionTrapId = -1
|
||||
@@ -797,7 +797,7 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
initializer = JsIrBuilder.buildGetValue(dataArgument.symbol)
|
||||
)
|
||||
|
||||
suspendState = JsIrBuilder.buildVar(coroutineImplLabelFieldSymbol.owner.type, function, "suspendState", true)
|
||||
suspendState = JsIrBuilder.buildVar(coroutineImplLabelProperty.getter!!.returnType, function, "suspendState", true)
|
||||
|
||||
val body =
|
||||
(originalBody as IrBlockBody).run {
|
||||
@@ -821,7 +821,10 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
(it.body as? IrBlockBody)?.run {
|
||||
val receiver = JsIrBuilder.buildGetValue(coroutineClassThis.symbol)
|
||||
val id = JsIrBuilder.buildInt(context.irBuiltIns.intType, exceptionTrapId)
|
||||
statements += JsIrBuilder.buildSetField(coroutineImplExceptionStateFieldSymbol, receiver, id, context.irBuiltIns.unitType)
|
||||
statements += JsIrBuilder.buildCall(coroutineImplExceptionStateProperty.setter!!.symbol).also { call ->
|
||||
call.dispatchReceiver = receiver
|
||||
call.putValueArgument(0, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -850,9 +853,9 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
context,
|
||||
function.symbol,
|
||||
rootLoop,
|
||||
coroutineImplExceptionFieldSymbol,
|
||||
coroutineImplExceptionStateFieldSymbol,
|
||||
coroutineImplLabelFieldSymbol,
|
||||
coroutineImplExceptionProperty,
|
||||
coroutineImplExceptionStateProperty,
|
||||
coroutineImplLabelProperty,
|
||||
thisReceiver,
|
||||
suspendResult.symbol
|
||||
)
|
||||
@@ -877,7 +880,9 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
|
||||
for (state in sortedStates) {
|
||||
val condition = JsIrBuilder.buildCall(eqeqeqInt).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetField(coroutineImplLabelFieldSymbol, JsIrBuilder.buildGetValue(thisReceiver)))
|
||||
putValueArgument(0, JsIrBuilder.buildCall(coroutineImplLabelProperty.getter!!.symbol).also {
|
||||
it.dispatchReceiver = JsIrBuilder.buildGetValue(thisReceiver)
|
||||
})
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, state.id))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user