diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt index 6d6b3af5e33..af8b8240831 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt @@ -179,6 +179,14 @@ abstract class Symbols(val context: T, private val abstract val getContinuation: IrSimpleFunctionSymbol + abstract val coroutineContextGetter: IrSimpleFunctionSymbol + + abstract val suspendCoroutineUninterceptedOrReturn: IrSimpleFunctionSymbol + + abstract val coroutineGetContext: IrSimpleFunctionSymbol + + abstract val returnIfSuspended: IrSimpleFunctionSymbol + private val binaryOperatorCache = mutableMapOf, IrSimpleFunctionSymbol>() fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt similarity index 97% rename from compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt rename to compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt index 6b320dcc3cf..50eb8eae606 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt @@ -1,15 +1,15 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package org.jetbrains.kotlin.ir.backend.js.lower.inline +package org.jetbrains.kotlin.backend.common.lower.inline +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.Name internal class DeepCopyIrTreeWithSymbolsForInliner( - val context: Context, + val context: CommonBackendContext, val typeArguments: Map?, val parent: IrDeclarationParent? ) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt similarity index 85% rename from compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/FunctionInlining.kt rename to compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index dbdde9eb3cd..b77802ac6d5 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -1,24 +1,19 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -@file:Suppress("FoldInitializerAndIfToElvis") +package org.jetbrains.kotlin.backend.common.lower.inline -package org.jetbrains.kotlin.ir.backend.js.lower.inline -import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext -import org.jetbrains.kotlin.backend.common.ScopeWithIr -import org.jetbrains.kotlin.backend.common.ir.Symbols +import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.ir.createTemporaryVariableWithWrappedDescriptor -import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted -import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn +import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.lower.CoroutineIntrinsicLambdaOrigin import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* @@ -30,62 +25,47 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.util.OperatorNameConventions -typealias Context = JsIrBackendContext +class FunctionInlining(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() { -// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt -internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() { - //-------------------------------------------------------------------------// - - fun inline(irModule: IrModuleFragment): IrElement { - return irModule.accept(this, data = null) - } + fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null) override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression { expression.transformChildrenVoid(this) - - if (!(expression is IrCall || expression is IrConstructorCall) || !expression.symbol.owner.needsInlining) + val callee = when (expression) { + is IrCall -> expression.symbol.owner + is IrConstructorCall -> expression.symbol.owner + else -> return expression + } + if (!callee.needsInlining) + return expression + if (Symbols.isLateinitIsInitializedPropertyGetter(callee.symbol)) return expression - val languageVersionSettings = context.configuration.languageVersionSettings - when { - Symbols.isLateinitIsInitializedPropertyGetter(expression.symbol) -> - return expression - // Handle coroutine intrinsics - // TODO These should actually be inlined. - expression.descriptor.isBuiltInIntercepted(languageVersionSettings) -> - error("Continuation.intercepted is not available with release coroutines") - expression.symbol.descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) -> - return irCall(expression, context.coroutineSuspendOrReturn) - expression.symbol == context.intrinsics.jsCoroutineContext -> - return irCall(expression, context.coroutineGetContextJs) - } + val actualCallee = getFunctionDeclaration(callee.symbol) - val callee = getFunctionDeclaration(expression.symbol) // Get declaration of the function to be inlined. - callee.transformChildrenVoid(this) // Process recursive inline. + actualCallee.transformChildrenVoid(this) // Process recursive inline. val parent = allScopes.map { it.irElement }.filterIsInstance().lastOrNull() - val inliner = Inliner(expression, callee, currentScope!!, parent, context) + val inliner = Inliner(expression, actualCallee, currentScope!!, parent, context) return inliner.inline() } private fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { -// val descriptor = symbol.descriptor.original -// val languageVersionSettings = context.configuration.languageVersionSettings -// // TODO: Remove these hacks when coroutine intrinsics are fixed. -// return when { -// descriptor.isBuiltInIntercepted(languageVersionSettings) -> -// error("Continuation.intercepted is not available with release coroutines") -// -// descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) -> -// context.ir.symbols.konanSuspendCoroutineUninterceptedOrReturn.owner -// -// descriptor == context.ir.symbols.coroutineContextGetter -> -// context.ir.symbols.konanCoroutineContextGetter.owner -// -// else -> (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner -// } + val descriptor = symbol.descriptor.original + val languageVersionSettings = context.configuration.languageVersionSettings + // TODO: Remove these hacks when coroutine intrinsics are fixed. + return when { + descriptor.isBuiltInIntercepted(languageVersionSettings) -> + error("Continuation.intercepted is not available with release coroutines") - return (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner + descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) -> + context.ir.symbols.suspendCoroutineUninterceptedOrReturn.owner + + symbol == context.ir.symbols.coroutineContextGetter -> + context.ir.symbols.coroutineGetContext.owner + + else -> (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner + } } private val IrFunction.needsInlining get() = (this.isInline && !this.isExternal) @@ -94,7 +74,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW val callee: IrFunction, val currentScope: ScopeWithIr, val parent: IrDeclarationParent?, - val context: Context) { + val context: CommonBackendContext) { val copyIrElement = run { val typeParameters = diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index 76ad4b97a56..85cc44d4ec9 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -159,7 +159,8 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC // Coroutines - val jsCoroutineContext = context.symbolTable.referenceSimpleFunction(context.coroutineContextProperty.getter!!) + val jsCoroutineContext + get() = context.ir.symbols.coroutineContextGetter val jsGetContinuation = getInternalFunction("getContinuation") val jsGetKClass = getInternalWithoutPackage("getKClass") 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 c78b763baa8..213a1c60f6e 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 @@ -187,6 +187,14 @@ class JsIrBackendContext( ) override val getContinuation = symbolTable.referenceSimpleFunction(getJsInternalFunction("getContinuation")) + + override val coroutineContextGetter = symbolTable.referenceSimpleFunction(context.coroutineContextProperty.getter!!) + + override val suspendCoroutineUninterceptedOrReturn = symbolTable.referenceSimpleFunction(getJsInternalFunction(COROUTINE_SUSPEND_OR_RETURN_JS_NAME)) + + override val coroutineGetContext = symbolTable.referenceSimpleFunction(getJsInternalFunction(GET_COROUTINE_CONTEXT_NAME)) + + override val returnIfSuspended = symbolTable.referenceSimpleFunction(getJsInternalFunction("returnIfSuspended")) } override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true @@ -213,7 +221,7 @@ class JsIrBackendContext( // Top-level functions forced to be loaded - val coroutineSuspendOrReturn = symbolTable.referenceSimpleFunction(getJsInternalFunction(COROUTINE_SUSPEND_OR_RETURN_JS_NAME)) + val coroutineSuspendOrReturn = ir.symbols.suspendCoroutineUninterceptedOrReturn val coroutineSuspendGetter = ir.symbols.coroutineSuspendedGetter val coroutineGetContext: IrSimpleFunctionSymbol get() { @@ -223,7 +231,9 @@ class JsIrBackendContext( return contextGetter.symbol } - val coroutineGetContextJs = symbolTable.referenceSimpleFunction(getJsInternalFunction(GET_COROUTINE_CONTEXT_NAME)) + val coroutineGetContextJs + get() = ir.symbols.coroutineGetContext + val coroutineEmptyContinuation = symbolTable.referenceField(getProperty(FqName.fromSegments(listOf("kotlin", "coroutines", "js", "internal", "EmptyContinuation")))) val coroutineContextProperty: PropertyDescriptor 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 3cd4fa20428..7bf969ac220 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 @@ -7,11 +7,11 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.lower.* +import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining 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.JsSuspendFunctionsLowering -import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering import org.jetbrains.kotlin.ir.declarations.IrFile diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/IrUnboundSymbolReplacer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/IrUnboundSymbolReplacer.kt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index db9ac92f582..ac0211eb33f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -155,6 +155,11 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { context.continuation } + add(backendContext.ir.symbols.returnIfSuspended) { call, context -> + val args = translateCallArguments(call, context) + args[0] + } + add(intrinsics.jsCoroutineContext) { _, context: JsGenerationContext -> val contextGetter = backendContext.coroutineGetContext val getterName = context.getNameForStaticFunction(contextGetter.owner) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 015c309f46e..6e6b9a9099b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -96,6 +96,18 @@ class JvmSymbols( override val getContinuation: IrSimpleFunctionSymbol get() = TODO("not implemented") + override val coroutineContextGetter: IrSimpleFunctionSymbol + get() = TODO("not implemented") + + override val suspendCoroutineUninterceptedOrReturn: IrSimpleFunctionSymbol + get() = TODO("not implemented") + + override val coroutineGetContext: IrSimpleFunctionSymbol + get() = TODO("not implemented") + + override val returnIfSuspended: IrSimpleFunctionSymbol + get() = TODO("not implemented") + val javaLangClass: IrClassSymbol = if (firMode) createClass(FqName("java.lang.Class")) {}.symbol else context.getTopLevelClass(FqName("java.lang.Class"))