JVM_IR: reorganize throw... functions in Symbols

This commit is contained in:
Georgy Bronnikov
2020-08-05 23:39:42 +03:00
parent 6a16d6a246
commit 7f4df19dd1
12 changed files with 94 additions and 82 deletions
@@ -28,7 +28,7 @@ interface CommonBackendContext : BackendContext, LoggingContext {
val scriptMode: Boolean val scriptMode: Boolean
fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression { fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression {
val throwErrorFunction = ir.symbols.ThrowUninitializedPropertyAccessException.owner val throwErrorFunction = ir.symbols.throwUninitializedPropertyAccessException.owner
return builder.irCall(throwErrorFunction).apply { return builder.irCall(throwErrorFunction).apply {
putValueArgument(0, builder.irString(name)) putValueArgument(0, builder.irString(name))
} }
@@ -274,13 +274,13 @@ open class BuiltinSymbolsBase(protected val irBuiltIns: IrBuiltIns, protected va
@Suppress("MemberVisibilityCanBePrivate", "PropertyName") @Suppress("MemberVisibilityCanBePrivate", "PropertyName")
abstract class Symbols<out T : CommonBackendContext>(val context: T, irBuiltIns: IrBuiltIns, symbolTable: SymbolTable) : abstract class Symbols<out T : CommonBackendContext>(val context: T, irBuiltIns: IrBuiltIns, symbolTable: SymbolTable) :
BuiltinSymbolsBase(irBuiltIns, context.builtIns, symbolTable) { BuiltinSymbolsBase(irBuiltIns, context.builtIns, symbolTable) {
abstract val ThrowNullPointerException: IrFunctionSymbol abstract val throwNullPointerException: IrSimpleFunctionSymbol
abstract val ThrowNoWhenBranchMatchedException: IrFunctionSymbol abstract val throwNoWhenBranchMatchedException: IrSimpleFunctionSymbol
abstract val ThrowTypeCastException: IrFunctionSymbol abstract val throwTypeCastException: IrSimpleFunctionSymbol
abstract val ThrowUninitializedPropertyAccessException: IrSimpleFunctionSymbol abstract val throwUninitializedPropertyAccessException: IrSimpleFunctionSymbol
abstract val ThrowKotlinNothingValueException: IrSimpleFunctionSymbol abstract val throwKotlinNothingValueException: IrSimpleFunctionSymbol
abstract val stringBuilder: IrClassSymbol abstract val stringBuilder: IrClassSymbol
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.types.isNothing
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -41,7 +40,7 @@ class KotlinNothingValueExceptionLowering(
backendContext.createIrBuilder(parent, expression.startOffset, expression.endOffset).run { backendContext.createIrBuilder(parent, expression.startOffset, expression.endOffset).run {
irBlock(expression, null, context.irBuiltIns.nothingType) { irBlock(expression, null, context.irBuiltIns.nothingType) {
+super.visitCall(expression) +super.visitCall(expression)
+irCall(backendContext.ir.symbols.ThrowKotlinNothingValueException) +irCall(backendContext.ir.symbols.throwKotlinNothingValueException)
} }
} }
} else { } else {
@@ -173,19 +173,19 @@ class JsIrBackendContext(
override val ir = object : Ir<JsIrBackendContext>(this, irModuleFragment) { override val ir = object : Ir<JsIrBackendContext>(this, irModuleFragment) {
override val symbols = object : Symbols<JsIrBackendContext>(this@JsIrBackendContext, irBuiltIns, symbolTable) { override val symbols = object : Symbols<JsIrBackendContext>(this@JsIrBackendContext, irBuiltIns, symbolTable) {
override val ThrowNullPointerException = override val throwNullPointerException =
symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_NPE"))).single()) symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_NPE"))).single())
override val ThrowNoWhenBranchMatchedException = override val throwNoWhenBranchMatchedException =
symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("noWhenBranchMatchedException"))).single()) symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("noWhenBranchMatchedException"))).single())
override val ThrowTypeCastException = override val throwTypeCastException =
symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_CCE"))).single()) symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_CCE"))).single())
override val ThrowUninitializedPropertyAccessException = override val throwUninitializedPropertyAccessException =
symbolTable.referenceSimpleFunction(getFunctions(FqName("kotlin.throwUninitializedPropertyAccessException")).single()) symbolTable.referenceSimpleFunction(getFunctions(FqName("kotlin.throwUninitializedPropertyAccessException")).single())
override val ThrowKotlinNothingValueException: IrSimpleFunctionSymbol = override val throwKotlinNothingValueException: IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(getFunctions(FqName("kotlin.throwKotlinNothingValueException")).single()) symbolTable.referenceSimpleFunction(getFunctions(FqName("kotlin.throwKotlinNothingValueException")).single())
override val defaultConstructorMarker = override val defaultConstructorMarker =
@@ -39,8 +39,8 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
private val devMode = context.devMode private val devMode = context.devMode
//NOTE: Should we define JS-own functions similar to current implementation? //NOTE: Should we define JS-own functions similar to current implementation?
private val throwCCE = context.ir.symbols.ThrowTypeCastException private val throwCCE = context.ir.symbols.throwTypeCastException
private val throwNPE = context.ir.symbols.ThrowNullPointerException private val throwNPE = context.ir.symbols.throwNullPointerException
private val eqeq = context.irBuiltIns.eqeqSymbol private val eqeq = context.irBuiltIns.eqeqSymbol
@@ -52,40 +52,6 @@ class JvmSymbols(
private val generateOptimizedCallableReferenceSuperClasses = context.state.generateOptimizedCallableReferenceSuperClasses private val generateOptimizedCallableReferenceSuperClasses = context.state.generateOptimizedCallableReferenceSuperClasses
private val nullPointerExceptionClass: IrClassSymbol =
createClass(FqName("java.lang.NullPointerException")) { klass ->
klass.addConstructor().apply {
addValueParameter("message", irBuiltIns.stringType)
}
}
override val ThrowNullPointerException: IrFunctionSymbol =
nullPointerExceptionClass.constructors.single()
override val ThrowNoWhenBranchMatchedException: IrSimpleFunctionSymbol
get() = error("Unused in JVM IR")
private val typeCastExceptionClass: IrClassSymbol =
createClass(FqName("kotlin.TypeCastException")) { klass ->
klass.addConstructor().apply {
addValueParameter("message", irBuiltIns.stringType)
}
}
override val ThrowTypeCastException: IrFunctionSymbol =
typeCastExceptionClass.constructors.single()
private val unsupportedOperationExceptionClass: IrClassSymbol =
createClass(FqName("java.lang.UnsupportedOperationException")) { klass ->
klass.addConstructor().apply {
addValueParameter("message", irBuiltIns.stringType.makeNullable())
}
}
val ThrowUnsupportOperationExceptionClass: IrFunctionSymbol =
unsupportedOperationExceptionClass.constructors.single()
private fun createPackage(fqName: FqName): IrPackageFragment = private fun createPackage(fqName: FqName): IrPackageFragment =
IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment(context.state.module, fqName) IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment(context.state.module, fqName)
@@ -119,9 +85,19 @@ class JvmSymbols(
private val intrinsicsClass: IrClassSymbol = createClass( private val intrinsicsClass: IrClassSymbol = createClass(
JvmClassName.byInternalName(IrIntrinsicMethods.INTRINSICS_CLASS_NAME).fqNameForTopLevelClassMaybeWithDollars JvmClassName.byInternalName(IrIntrinsicMethods.INTRINSICS_CLASS_NAME).fqNameForTopLevelClassMaybeWithDollars
) { klass -> ) { klass ->
klass.addFunction("throwNullPointerException", irBuiltIns.nothingType, isStatic = true).apply {
addValueParameter("message", irBuiltIns.stringType)
}
klass.addFunction("throwTypeCastException", irBuiltIns.nothingType, isStatic = true).apply {
addValueParameter("message", irBuiltIns.stringType)
}
klass.addFunction("throwUnsupportedOperationException", irBuiltIns.nothingType, isStatic = true).apply {
addValueParameter("message", irBuiltIns.stringType)
}
klass.addFunction("throwUninitializedPropertyAccessException", irBuiltIns.unitType, isStatic = true).apply { klass.addFunction("throwUninitializedPropertyAccessException", irBuiltIns.unitType, isStatic = true).apply {
addValueParameter("propertyName", irBuiltIns.stringType) addValueParameter("propertyName", irBuiltIns.stringType)
} }
klass.addFunction("throwKotlinNothingValueException", irBuiltIns.nothingType, isStatic = true)
klass.addFunction("checkExpressionValueIsNotNull", irBuiltIns.unitType, isStatic = true).apply { klass.addFunction("checkExpressionValueIsNotNull", irBuiltIns.unitType, isStatic = true).apply {
addValueParameter("value", irBuiltIns.anyNType) addValueParameter("value", irBuiltIns.anyNType)
addValueParameter("expression", irBuiltIns.stringType) addValueParameter("expression", irBuiltIns.stringType)
@@ -159,9 +135,24 @@ class JvmSymbols(
val throwNpe: IrSimpleFunctionSymbol = val throwNpe: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwNpe" } intrinsicsClass.functions.single { it.owner.name.asString() == "throwNpe" }
override val ThrowUninitializedPropertyAccessException: IrSimpleFunctionSymbol = override val throwNullPointerException: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwNullPointerException" }
override val throwNoWhenBranchMatchedException: IrSimpleFunctionSymbol
get() = error("Unused in JVM IR")
override val throwTypeCastException: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwTypeCastException" }
val throwUnsupportedOperationException: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwUnsupportedOperationException" }
override val throwUninitializedPropertyAccessException: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwUninitializedPropertyAccessException" } intrinsicsClass.functions.single { it.owner.name.asString() == "throwUninitializedPropertyAccessException" }
override val throwKotlinNothingValueException: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "throwKotlinNothingValueException" }
val intrinsicStringPlus: IrFunctionSymbol = val intrinsicStringPlus: IrFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "stringPlus" } intrinsicsClass.functions.single { it.owner.name.asString() == "stringPlus" }
@@ -744,15 +735,6 @@ class JvmSymbols(
val runSuspendFunction: IrSimpleFunctionSymbol = val runSuspendFunction: IrSimpleFunctionSymbol =
kotlinCoroutinesJvmInternalRunSuspendKt.functionByName("runSuspend") kotlinCoroutinesJvmInternalRunSuspendKt.functionByName("runSuspend")
override val ThrowKotlinNothingValueException: IrSimpleFunctionSymbol =
irFactory.buildFun {
name = Name.identifier("ThrowKotlinNothingValueException")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
returnType = irBuiltIns.nothingType
}.apply {
parent = kotlinJvmInternalPackage
}.symbol
} }
private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol = private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol =
@@ -113,7 +113,10 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce, symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce,
symbols.signatureStringIntrinsic.toKey()!! to SignatureString, symbols.signatureStringIntrinsic.toKey()!! to SignatureString,
symbols.reassignParameterIntrinsic.toKey()!! to ReassignParameter, symbols.reassignParameterIntrinsic.toKey()!! to ReassignParameter,
symbols.ThrowKotlinNothingValueException.toKey()!! to ThrowKotlinNothingValueException symbols.throwNullPointerException.toKey() to ThrowNullPointerException,
symbols.throwTypeCastException.toKey() to ThrowTypeCastException,
symbols.throwUnsupportedOperationException.toKey() to ThrowUnsupportedOperationException,
symbols.throwKotlinNothingValueException.toKey()!! to ThrowKotlinNothingValueException
) + ) +
numberConversionMethods() + numberConversionMethods() +
unaryFunForPrimitives("plus", UnaryPlus) + unaryFunForPrimitives("plus", UnaryPlus) +
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2020 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.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
abstract class ThrowException(val exceptionClass: Type) : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
with(codegen) {
mv.anew(exceptionClass)
mv.dup()
gen(expression.getValueArgument(0)!!, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType, data)
mv.invokespecial(exceptionClass.internalName, "<init>", "(Ljava/lang/String;)V", false)
mv.athrow()
return null
}
}
}
object ThrowNullPointerException : ThrowException(Type.getObjectType("java/lang/NullPointerException"))
object ThrowTypeCastException : ThrowException(Type.getObjectType("kotlin/TypeCastException"))
object ThrowUnsupportedOperationException : ThrowException(Type.getObjectType("java/lang/UnsupportedOperationException"))
@@ -83,13 +83,11 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
valueParameters = function.valueParameters.map { it.copyWithSubstitution(this, substitutionMap) } valueParameters = function.valueParameters.map { it.copyWithSubstitution(this, substitutionMap) }
// Function body consist only of throwing UnsupportedOperationException statement // Function body consist only of throwing UnsupportedOperationException statement
body = context.createIrBuilder(function.symbol).irBlockBody { body = context.createIrBuilder(function.symbol).irBlockBody {
+irThrow( +irCall(
irCall( this@CollectionStubMethodLowering.context.ir.symbols.throwUnsupportedOperationException
this@CollectionStubMethodLowering.context.ir.symbols.ThrowUnsupportOperationExceptionClass ).apply {
).apply { putValueArgument(0, irString("Operation is not supported for read-only collection"))
putValueArgument(0, irString("Operation is not supported for read-only collection")) }
}
)
} }
} }
} }
@@ -67,12 +67,12 @@ class JvmDefaultArgumentStubGenerator(override val context: JvmBackendContext) :
+irIfThen( +irIfThen(
context.irBuiltIns.unitType, context.irBuiltIns.unitType,
irNot(irEqualsNull(irGet(handlerDeclaration))), irNot(irEqualsNull(irGet(handlerDeclaration))),
irThrow(irCall(this@JvmDefaultArgumentStubGenerator.context.ir.symbols.ThrowUnsupportOperationExceptionClass).apply { irCall(this@JvmDefaultArgumentStubGenerator.context.ir.symbols.throwUnsupportedOperationException).apply {
putValueArgument( putValueArgument(
0, 0,
irString("Super calls with default arguments not supported in this target, function: ${irFunction.name.asString()}") irString("Super calls with default arguments not supported in this target, function: ${irFunction.name.asString()}")
) )
}) }
) )
} }
} }
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer
import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.at
import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.common.lower.irThrow
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
@@ -21,7 +20,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
@@ -81,9 +80,9 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
irIfNull( irIfNull(
type, type,
irGet(valueSymbol.owner), irGet(valueSymbol.owner),
irThrow(irCall(typeCastException).apply { irCall(throwTypeCastException).apply {
putValueArgument(0, irString("null cannot be cast to non-null type ${type.render()}")) putValueArgument(0, irString("null cannot be cast to non-null type ${type.render()}"))
}), },
lowerCast(irGet(valueSymbol.owner), type.makeNullable()) lowerCast(irGet(valueSymbol.owner), type.makeNullable())
) )
} }
@@ -183,13 +182,13 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
private fun sourceViewFor(declaration: IrDeclaration) = private fun sourceViewFor(declaration: IrDeclaration) =
context.psiSourceManager.getKtFile(declaration.fileParent)!!.viewProvider.contents context.psiSourceManager.getKtFile(declaration.fileParent)!!.viewProvider.contents
private val typeCastException: IrFunctionSymbol = private val throwTypeCastException: IrSimpleFunctionSymbol =
if (context.state.unifiedNullChecks) if (context.state.unifiedNullChecks)
context.ir.symbols.ThrowNullPointerException context.ir.symbols.throwNullPointerException
else else
context.ir.symbols.ThrowTypeCastException context.ir.symbols.throwTypeCastException
private val checkExpressionValueIsNotNull: IrFunctionSymbol = private val checkExpressionValueIsNotNull: IrSimpleFunctionSymbol =
if (context.state.unifiedNullChecks) if (context.state.unifiedNullChecks)
context.ir.symbols.checkNotNullExpressionValue context.ir.symbols.checkNotNullExpressionValue
else else
@@ -24,15 +24,15 @@ class WasmSymbols(
private val symbolTable: SymbolTable private val symbolTable: SymbolTable
) : Symbols<WasmBackendContext>(context, context.irBuiltIns, symbolTable) { ) : Symbols<WasmBackendContext>(context, context.irBuiltIns, symbolTable) {
override val ThrowNullPointerException override val throwNullPointerException
get() = TODO() get() = TODO()
override val ThrowNoWhenBranchMatchedException override val throwNoWhenBranchMatchedException
get() = TODO() get() = TODO()
override val ThrowTypeCastException override val throwTypeCastException
get() = TODO() get() = TODO()
override val ThrowUninitializedPropertyAccessException override val throwUninitializedPropertyAccessException
get() = TODO() get() = TODO()
override val ThrowKotlinNothingValueException: IrSimpleFunctionSymbol override val throwKotlinNothingValueException: IrSimpleFunctionSymbol
get() = TODO() get() = TODO()
override val defaultConstructorMarker override val defaultConstructorMarker
get() = TODO() get() = TODO()