diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index f9a282b1eb9..ba8f5478c2b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -181,6 +181,8 @@ class JsIrBackendContext( val originalModuleIndex = ModuleIndex(irModuleFragment) + lateinit var moduleFragmentCopy: IrModuleFragment + fun getOperatorByName(name: Name, type: KotlinType) = operatorMap[name]?.get(type) override val ir = object : Ir(this, irModuleFragment) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index d795a7524cc..0a8cbbea5f5 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.ir.backend.js.lower.* import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering +import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering @@ -17,6 +18,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.patchDeclarationParents private fun DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable) = files.forEach { runOnFilePostfix(it) } @@ -79,6 +81,12 @@ private val expectDeclarationsRemovingPhase = makeJsModulePhase( description = "Remove expect declaration from module fragment" ) +private val coroutineIntrinsicLoweringPhase = makeJsModulePhase( + ::CoroutineIntrinsicLowering, + name = "CoroutineIntrinsicLowering", + description = "Replace common coroutine intrinsics with platform specific ones" +) + private val arrayInlineConstructorLoweringPhase = makeJsModulePhase( ::ArrayInlineConstructorLowering, name = "ArrayInlineConstructorLowering", @@ -91,6 +99,13 @@ private val lateinitLoweringPhase = makeJsModulePhase( description = "Insert checks for lateinit field references" ) +private val moduleCopyingPhase = makeCustomJsModulePhase( + { context, module -> context.moduleFragmentCopy = module.deepCopyWithSymbols() }, + name = "ModuleCopying", + description = " Copy current module to make it accessible from different one", + prerequisite = setOf(lateinitLoweringPhase) +) + private val functionInliningPhase = makeCustomJsModulePhase( { context, module -> FunctionInlining(context).inline(module) @@ -99,7 +114,7 @@ private val functionInliningPhase = makeCustomJsModulePhase( }, name = "FunctionInliningPhase", description = "Perform function inlining", - prerequisite = setOf(lateinitLoweringPhase, arrayInlineConstructorLoweringPhase) + prerequisite = setOf(moduleCopyingPhase, lateinitLoweringPhase, arrayInlineConstructorLoweringPhase, coroutineIntrinsicLoweringPhase) ) private val removeInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsModulePhase( @@ -182,7 +197,7 @@ private val suspendFunctionsLoweringPhase = makeJsModulePhase( ::SuspendFunctionsLowering, name = "SuspendFunctionsLowering", description = "Transform suspend functions into CoroutineImpl instance and build state machine", - prerequisite = setOf(unitMaterializationLoweringPhase) + prerequisite = setOf(unitMaterializationLoweringPhase, coroutineIntrinsicLoweringPhase) ) private val privateMembersLoweringPhase = makeJsModulePhase( @@ -338,8 +353,10 @@ val jsPhases = namedIrModulePhase( description = "IR module lowering", lower = moveBodilessDeclarationsToSeparatePlacePhase then expectDeclarationsRemovingPhase then + coroutineIntrinsicLoweringPhase then arrayInlineConstructorLoweringPhase then lateinitLoweringPhase then + moduleCopyingPhase then functionInliningPhase then removeInlineFunctionsWithReifiedTypeParametersLoweringPhase then throwableSuccessorsLoweringPhase then diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index d20e379e35e..34130d8655b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -82,16 +82,8 @@ fun compile( moduleType ) - // CoroutineIntrinsicLowering currently have to be applied to dependencies - // before running inline pass for current module. - // Therefore we run it here before producing ir for current module. - // TODO: Find a better way to implement coroutine intrinsics - val coroutineIntrinsicLowering = CoroutineIntrinsicLowering(context) - moduleFragment.files.forEach { file -> coroutineIntrinsicLowering.lower(file) } - // TODO: Split compilation into two steps: kt -> ir, ir -> js val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!! - var moduleFragmentCopy: IrModuleFragment? = null when (moduleType) { ModuleType.MAIN -> { val moduleDependencies: List = @@ -108,7 +100,6 @@ fun compile( } ModuleType.TEST_RUNTIME -> { - moduleFragmentCopy = moduleFragment.deepCopyWithSymbols() } } @@ -116,5 +107,5 @@ fun compile( val jsProgram = moduleFragment.accept(IrModuleToJsTransformer(context), null) - return CompiledModule(moduleName, jsProgram.toString(), moduleFragmentCopy, moduleType, dependencies) + return CompiledModule(moduleName, jsProgram.toString(), context.moduleFragmentCopy, moduleType, dependencies) }