Revert "Add a common JVM/JS lowering for Array(size, function)"

This reverts commit 4a29e3cfcf.
This commit is contained in:
max-kammerer
2019-05-09 11:48:58 +02:00
parent 856a1649c6
commit e74e0ea013
14 changed files with 287 additions and 228 deletions
@@ -84,12 +84,6 @@ private val lateinitLoweringPhase = makeJsModulePhase(
description = "Insert checks for lateinit field references"
)
private val arrayConstructorPhase = makeJsModulePhase(
::ArrayConstructorLowering,
name = "ArrayConstructor",
description = "Transform `Array(size) { index -> value }` into a loop"
)
private val functionInliningPhase = makeCustomJsModulePhase(
{ context, module ->
FunctionInlining(context).inline(module)
@@ -357,7 +351,6 @@ val jsPhases = namedIrModulePhase(
description = "IR module lowering",
lower = testGenerationPhase then
expectDeclarationsRemovingPhase then
arrayConstructorPhase then
functionInliningPhase then
lateinitLoweringPhase then
tailrecLoweringPhase then
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2018 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
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.util.irCall
// Replace array inline constructors with stdlib function invocations
class ArrayConstructorTransformer(
val context: JsIrBackendContext
) {
// Inline constructor for CharArray is implemented in runtime
private val primitiveArrayInlineToSizeConstructorMap =
context.intrinsics.primitiveArrays.filter { it.value != PrimitiveType.CHAR }.keys.associate {
it.inlineConstructor to it.sizeConstructor
}
fun transformConstructorCall(expression: IrConstructorCall): IrFunctionAccessExpression {
if (expression.symbol == context.intrinsics.array.inlineConstructor) {
return irCall(expression, context.intrinsics.jsArray).apply {
copyTypeArgumentsFrom(expression)
}
} else {
primitiveArrayInlineToSizeConstructorMap[expression.symbol]?.let { sizeConstructor ->
return IrCallImpl(
expression.startOffset,
expression.endOffset,
expression.type,
context.intrinsics.jsFillArray
).apply {
putValueArgument(0, IrConstructorCallImpl.fromSymbolOwner(
expression.startOffset,
expression.endOffset,
expression.type,
sizeConstructor
).apply {
putValueArgument(0, expression.getValueArgument(0))
})
putValueArgument(1, expression.getValueArgument(1))
}
}
}
return expression
}
}
// TODO it.isInline doesn't work =(
private val IrClassSymbol.inlineConstructor
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 2 }.symbol
private val IrClassSymbol.sizeConstructor
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 1 }.symbol
@@ -19,6 +19,7 @@ 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.backend.js.lower.ArrayConstructorTransformer
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.*
@@ -42,31 +43,38 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
return irModule.accept(this, data = null)
}
private val arrayConstructorTransformer = ArrayConstructorTransformer(context)
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
expression.transformChildrenVoid(this)
if (!(expression is IrCall || expression is IrConstructorCall) || !expression.symbol.owner.needsInlining)
return expression
val callSite = when (expression) {
is IrCall -> expression
is IrConstructorCall -> arrayConstructorTransformer.transformConstructorCall(expression)
else -> return expression
}
if (!callSite.symbol.owner.needsInlining)
return callSite
val languageVersionSettings = context.configuration.languageVersionSettings
when {
Symbols.isLateinitIsInitializedPropertyGetter(expression.symbol) ->
return expression
Symbols.isLateinitIsInitializedPropertyGetter(callSite.symbol) ->
return callSite
// Handle coroutine intrinsics
// TODO These should actually be inlined.
expression.descriptor.isBuiltInIntercepted(languageVersionSettings) ->
callSite.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)
callSite.symbol.descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
return irCall(callSite, context.coroutineSuspendOrReturn)
callSite.symbol == context.intrinsics.jsCoroutineContext ->
return irCall(callSite, context.coroutineGetContextJs)
}
val callee = getFunctionDeclaration(expression.symbol) // Get declaration of the function to be inlined.
val callee = getFunctionDeclaration(callSite.symbol) // Get declaration of the function to be inlined.
callee.transformChildrenVoid(this) // Process recursive inline.
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
val inliner = Inliner(expression, callee, currentScope!!, parent, context)
val inliner = Inliner(callSite, callee, currentScope!!, parent, context)
return inliner.inline()
}