[JS IR] Fix offsets and add new test
[JS IR] Use TypeSubstitutor for full substitution of types - adding new tests [JS IR] Commonize context and use in wasm [JS IR] Add test with receiver with callable reference [JS IR] Add prerequisites around inlining and callable references [JS IR] Review fixes - Add test with bounded type parameter - Remove redundant casts - Use offsets for synth function - Correct traversing [JS IR] Not use origin for not inlined function reference [JS IR] Move util into common place [JS IR] Fix offsets [JS IR] Add type parameter argument and using value in test [JS IR] Wrap inlined callable references with reified parameters [JS IR] Add test on callable reference inlined fun Merge-request: KT-MR-4722
This commit is contained in:
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.cleanup.CleanupLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendArityStoreLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendFunctionsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.CopyInlineFunctionBodyLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineDeclarationsWithReifiedTypeParametersLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.SyntheticAccessorLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.jsRecordExtractedLocalClasses
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
|
||||
@@ -245,6 +242,12 @@ private val syntheticAccessorLoweringPhase = makeBodyLoweringPhase(
|
||||
description = "Wrap top level inline function to access through them from inline functions"
|
||||
)
|
||||
|
||||
private val wrapInlineDeclarationsWithReifiedTypeParametersLowering = makeBodyLoweringPhase(
|
||||
::WrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
||||
name = "WrapInlineDeclarationsWithReifiedTypeParametersLowering",
|
||||
description = "Wrap inline declarations with reified type parameters"
|
||||
)
|
||||
|
||||
private val functionInliningPhase = makeBodyLoweringPhase(
|
||||
::FunctionInlining,
|
||||
name = "FunctionInliningPhase",
|
||||
@@ -252,7 +255,7 @@ private val functionInliningPhase = makeBodyLoweringPhase(
|
||||
prerequisite = setOf(
|
||||
expectDeclarationsRemovingPhase, sharedVariablesLoweringPhase,
|
||||
localClassesInInlineLambdasPhase, localClassesExtractionFromInlineFunctionsPhase,
|
||||
syntheticAccessorLoweringPhase
|
||||
syntheticAccessorLoweringPhase, wrapInlineDeclarationsWithReifiedTypeParametersLowering
|
||||
)
|
||||
)
|
||||
|
||||
@@ -359,7 +362,8 @@ private val enumEntryRemovalLoweringPhase = makeDeclarationTransformerPhase(
|
||||
private val callableReferenceLowering = makeBodyLoweringPhase(
|
||||
::CallableReferenceLowering,
|
||||
name = "CallableReferenceLowering",
|
||||
description = "Build a lambda/callable reference class"
|
||||
description = "Build a lambda/callable reference class",
|
||||
prerequisite = setOf(functionInliningPhase, wrapInlineDeclarationsWithReifiedTypeParametersLowering)
|
||||
)
|
||||
|
||||
private val returnableBlockLoweringPhase = makeBodyLoweringPhase(
|
||||
@@ -767,6 +771,7 @@ private val loweringList = listOf<Lowering>(
|
||||
localClassesInInlineFunctionsPhase,
|
||||
localClassesExtractionFromInlineFunctionsPhase,
|
||||
syntheticAccessorLoweringPhase,
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
||||
functionInliningPhase,
|
||||
copyInlineFunctionBodyLoweringPhase,
|
||||
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase,
|
||||
|
||||
+1
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isInlineFunWithReifiedParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
@@ -17,8 +18,6 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
class RemoveInlineDeclarationsWithReifiedTypeParametersLowering: DeclarationTransformer {
|
||||
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
fun IrFunction.isInlineFunWithReifiedParameter() = isInline && typeParameters.any { it.isReified }
|
||||
|
||||
if (declaration is IrFunction && declaration.isInlineFunWithReifiedParameter() ||
|
||||
declaration is IrProperty && declaration.getter?.isInlineFunWithReifiedParameter() == true
|
||||
) {
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2010-2021 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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isInlineFunWithReifiedParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSubstitutor
|
||||
import org.jetbrains.kotlin.ir.util.typeSubstitutionMap
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
// Replace callable reference on inline function with reified parameter
|
||||
// with callable reference on new non inline function with substituted types
|
||||
class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: BackendContext) : BodyLoweringPass {
|
||||
private val irFactory
|
||||
get() = context.irFactory
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
|
||||
val owner = expression.symbol.owner as? IrSimpleFunction
|
||||
?: return expression
|
||||
|
||||
if (!owner.isInlineFunWithReifiedParameter()) {
|
||||
return expression
|
||||
}
|
||||
val substitutionMap = expression.typeSubstitutionMap
|
||||
.entries
|
||||
.map { (key, value) ->
|
||||
key to (value as IrTypeArgument)
|
||||
}
|
||||
val typeSubstitutor = IrTypeSubstitutor(
|
||||
substitutionMap.map { it.first },
|
||||
substitutionMap.map { it.second },
|
||||
context.irBuiltIns
|
||||
)
|
||||
|
||||
val function = irFactory.addFunction(container.parent as IrDeclarationContainer) {
|
||||
name = Name.identifier("${owner.name}${"$"}wrap")
|
||||
returnType = owner.returnType
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
origin = JsIrBuilder.SYNTHESIZED_DECLARATION
|
||||
}.also { function ->
|
||||
owner.valueParameters.forEach { valueParameter ->
|
||||
function.addValueParameter(
|
||||
valueParameter.name,
|
||||
typeSubstitutor.substitute(valueParameter.type)
|
||||
)
|
||||
}
|
||||
function.body = irFactory.createBlockBody(
|
||||
expression.startOffset,
|
||||
expression.endOffset
|
||||
) {
|
||||
statements.add(
|
||||
JsIrBuilder.buildReturn(
|
||||
function.symbol,
|
||||
JsIrBuilder.buildCall(owner.symbol).also { call ->
|
||||
call.dispatchReceiver = expression.dispatchReceiver
|
||||
call.extensionReceiver = expression.extensionReceiver
|
||||
function.valueParameters.forEachIndexed { index, valueParameter ->
|
||||
call.putValueArgument(index, JsIrBuilder.buildGetValue(valueParameter.symbol))
|
||||
}
|
||||
for (i in 0 until expression.typeArgumentsCount) {
|
||||
call.putTypeArgument(i, expression.getTypeArgument(i))
|
||||
}
|
||||
},
|
||||
owner.returnType
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return IrFunctionReferenceImpl.fromSymbolOwner(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.type,
|
||||
function.symbol,
|
||||
function.typeParameters.size,
|
||||
expression.reflectionTarget
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -129,4 +129,6 @@ fun invokeFunForLambda(call: IrCall) =
|
||||
.getClass()!!
|
||||
.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.single { it.name.asString() == "invoke" }
|
||||
.single { it.name.asString() == "invoke" }
|
||||
|
||||
fun IrFunction.isInlineFunWithReifiedParameter() = isInline && typeParameters.any { it.isReified }
|
||||
+12
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineDeclarationsWithReifiedTypeParametersLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.WrapInlineDeclarationsWithReifiedTypeParametersLowering
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
|
||||
@@ -87,6 +88,12 @@ private val provisionalFunctionExpressionPhase = makeWasmModulePhase(
|
||||
description = "Transform IrFunctionExpression to a local function reference"
|
||||
)
|
||||
|
||||
private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModulePhase(
|
||||
::WrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
||||
name = "WrapInlineDeclarationsWithReifiedTypeParametersPhase",
|
||||
description = "Wrap inline declarations with reified type parameters"
|
||||
)
|
||||
|
||||
private val functionInliningPhase = makeCustomWasmModulePhase(
|
||||
{ context, module ->
|
||||
FunctionInlining(context).inline(module)
|
||||
@@ -94,7 +101,10 @@ private val functionInliningPhase = makeCustomWasmModulePhase(
|
||||
},
|
||||
name = "FunctionInliningPhase",
|
||||
description = "Perform function inlining",
|
||||
prerequisite = setOf(expectDeclarationsRemovingPhase)
|
||||
prerequisite = setOf(
|
||||
expectDeclarationsRemovingPhase,
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase
|
||||
)
|
||||
)
|
||||
|
||||
private val removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase = makeWasmModulePhase(
|
||||
@@ -448,6 +458,7 @@ val wasmPhases = NamedCompilerPhase(
|
||||
|
||||
// TODO: Need some helpers from stdlib
|
||||
// arrayConstructorPhase then
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
||||
|
||||
functionInliningPhase then
|
||||
provisionalFunctionExpressionPhase then
|
||||
|
||||
Reference in New Issue
Block a user