JS IR: move inliner to common part; inline suspendCoroutineUninterceptedOrReturnJS
This commit is contained in:
@@ -179,6 +179,14 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
|||||||
|
|
||||||
abstract val getContinuation: IrSimpleFunctionSymbol
|
abstract val getContinuation: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
|
abstract val coroutineContextGetter: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
|
abstract val suspendCoroutineUninterceptedOrReturn: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
|
abstract val coroutineGetContext: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
|
abstract val returnIfSuspended: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>()
|
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>()
|
||||||
|
|
||||||
fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol {
|
fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol {
|
||||||
|
|||||||
+4
-4
@@ -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.
|
* 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.backend.common.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
internal class DeepCopyIrTreeWithSymbolsForInliner(
|
internal class DeepCopyIrTreeWithSymbolsForInliner(
|
||||||
val context: Context,
|
val context: CommonBackendContext,
|
||||||
val typeArguments: Map<IrTypeParameterSymbol, IrType?>?,
|
val typeArguments: Map<IrTypeParameterSymbol, IrType?>?,
|
||||||
val parent: IrDeclarationParent?
|
val parent: IrDeclarationParent?
|
||||||
) {
|
) {
|
||||||
+32
-52
@@ -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.
|
* 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.*
|
||||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createTemporaryVariableWithWrappedDescriptor
|
import org.jetbrains.kotlin.backend.common.ir.createTemporaryVariableWithWrappedDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.CoroutineIntrinsicLambdaOrigin
|
import org.jetbrains.kotlin.backend.common.lower.CoroutineIntrinsicLambdaOrigin
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
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.builders.irReturn
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
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
|
fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null)
|
||||||
internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() {
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
fun inline(irModule: IrModuleFragment): IrElement {
|
|
||||||
return irModule.accept(this, data = null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
val callee = when (expression) {
|
||||||
if (!(expression is IrCall || expression is IrConstructorCall) || !expression.symbol.owner.needsInlining)
|
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
|
return expression
|
||||||
|
|
||||||
val languageVersionSettings = context.configuration.languageVersionSettings
|
val actualCallee = getFunctionDeclaration(callee.symbol)
|
||||||
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 callee = getFunctionDeclaration(expression.symbol) // Get declaration of the function to be inlined.
|
actualCallee.transformChildrenVoid(this) // Process recursive inline.
|
||||||
callee.transformChildrenVoid(this) // Process recursive inline.
|
|
||||||
|
|
||||||
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
||||||
val inliner = Inliner(expression, callee, currentScope!!, parent, context)
|
val inliner = Inliner(expression, actualCallee, currentScope!!, parent, context)
|
||||||
return inliner.inline()
|
return inliner.inline()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
private fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
||||||
// val descriptor = symbol.descriptor.original
|
val descriptor = symbol.descriptor.original
|
||||||
// val languageVersionSettings = context.configuration.languageVersionSettings
|
val languageVersionSettings = context.configuration.languageVersionSettings
|
||||||
// // TODO: Remove these hacks when coroutine intrinsics are fixed.
|
// TODO: Remove these hacks when coroutine intrinsics are fixed.
|
||||||
// return when {
|
return when {
|
||||||
// descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||||
// error("Continuation.intercepted is not available with release coroutines")
|
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
|
|
||||||
// }
|
|
||||||
|
|
||||||
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)
|
private val IrFunction.needsInlining get() = (this.isInline && !this.isExternal)
|
||||||
@@ -94,7 +74,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
|
|||||||
val callee: IrFunction,
|
val callee: IrFunction,
|
||||||
val currentScope: ScopeWithIr,
|
val currentScope: ScopeWithIr,
|
||||||
val parent: IrDeclarationParent?,
|
val parent: IrDeclarationParent?,
|
||||||
val context: Context) {
|
val context: CommonBackendContext) {
|
||||||
|
|
||||||
val copyIrElement = run {
|
val copyIrElement = run {
|
||||||
val typeParameters =
|
val typeParameters =
|
||||||
@@ -159,7 +159,8 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
|
|
||||||
// Coroutines
|
// Coroutines
|
||||||
|
|
||||||
val jsCoroutineContext = context.symbolTable.referenceSimpleFunction(context.coroutineContextProperty.getter!!)
|
val jsCoroutineContext
|
||||||
|
get() = context.ir.symbols.coroutineContextGetter
|
||||||
|
|
||||||
val jsGetContinuation = getInternalFunction("getContinuation")
|
val jsGetContinuation = getInternalFunction("getContinuation")
|
||||||
val jsGetKClass = getInternalWithoutPackage("getKClass")
|
val jsGetKClass = getInternalWithoutPackage("getKClass")
|
||||||
|
|||||||
+12
-2
@@ -187,6 +187,14 @@ class JsIrBackendContext(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override val getContinuation = symbolTable.referenceSimpleFunction(getJsInternalFunction("getContinuation"))
|
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
|
override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true
|
||||||
@@ -213,7 +221,7 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
// Top-level functions forced to be loaded
|
// 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 coroutineSuspendGetter = ir.symbols.coroutineSuspendedGetter
|
||||||
val coroutineGetContext: IrSimpleFunctionSymbol
|
val coroutineGetContext: IrSimpleFunctionSymbol
|
||||||
get() {
|
get() {
|
||||||
@@ -223,7 +231,9 @@ class JsIrBackendContext(
|
|||||||
return contextGetter.symbol
|
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 coroutineEmptyContinuation = symbolTable.referenceField(getProperty(FqName.fromSegments(listOf("kotlin", "coroutines", "js", "internal", "EmptyContinuation"))))
|
||||||
|
|
||||||
val coroutineContextProperty: PropertyDescriptor
|
val coroutineContextProperty: PropertyDescriptor
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.ir.backend.js
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
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.backend.common.phaser.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
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.calls.CallsLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendFunctionsLowering
|
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.RemoveInlineFunctionsWithReifiedTypeParametersLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
|||||||
+5
@@ -155,6 +155,11 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
context.continuation
|
context.continuation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add(backendContext.ir.symbols.returnIfSuspended) { call, context ->
|
||||||
|
val args = translateCallArguments(call, context)
|
||||||
|
args[0]
|
||||||
|
}
|
||||||
|
|
||||||
add(intrinsics.jsCoroutineContext) { _, context: JsGenerationContext ->
|
add(intrinsics.jsCoroutineContext) { _, context: JsGenerationContext ->
|
||||||
val contextGetter = backendContext.coroutineGetContext
|
val contextGetter = backendContext.coroutineGetContext
|
||||||
val getterName = context.getNameForStaticFunction(contextGetter.owner)
|
val getterName = context.getNameForStaticFunction(contextGetter.owner)
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ class JvmSymbols(
|
|||||||
override val getContinuation: IrSimpleFunctionSymbol
|
override val getContinuation: IrSimpleFunctionSymbol
|
||||||
get() = TODO("not implemented")
|
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 =
|
val javaLangClass: IrClassSymbol =
|
||||||
if (firMode) createClass(FqName("java.lang.Class")) {}.symbol else context.getTopLevelClass(FqName("java.lang.Class"))
|
if (firMode) createClass(FqName("java.lang.Class")) {}.symbol else context.getTopLevelClass(FqName("java.lang.Class"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user