PSI2IR KT-47450 prevent SOE when generating IR for deep expressions
This commit is contained in:
committed by
TeamCityServer
parent
c4d9945782
commit
560c269e05
+5
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
@@ -18,6 +19,10 @@ class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall) {
|
||||
expression.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase) {
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
typeTranslator.enterScope(declaration)
|
||||
|
||||
+24
-29
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.isTrivial
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -75,37 +74,33 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
|
||||
if (receiver is TransientReceiver) return TransientReceiverValue(irReceiverType)
|
||||
|
||||
return generateDelegatedValue(irReceiverType) {
|
||||
val receiverExpression: IrExpression = when (receiver) {
|
||||
is ImplicitClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||
else
|
||||
return object : ExpressionValue(irReceiverType) {
|
||||
override fun load(): IrExpression =
|
||||
when (receiver) {
|
||||
is ImplicitClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||
else
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
is ThisClassReceiver ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
is ExtensionReceiver ->
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||
defaultStartOffset, defaultStartOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
)
|
||||
else ->
|
||||
throw AssertionError("Unexpected receiver: ${receiver::class.java.simpleName}")
|
||||
}
|
||||
is ThisClassReceiver ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
is ExtensionReceiver ->
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultStartOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
)
|
||||
else ->
|
||||
TODO("Receiver: ${receiver::class.java.simpleName}")
|
||||
}
|
||||
|
||||
if (receiverExpression.isTrivial())
|
||||
RematerializableValue(receiverExpression.type, receiverExpression)
|
||||
else
|
||||
OnceExpressionValue(receiverExpression)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.util.withScope
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -37,6 +38,10 @@ class IrSyntheticDeclarationGenerator(context: GeneratorContext) : IrElementVisi
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall) {
|
||||
expression.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
private fun collectDescriptors(descriptor: ClassDescriptor): MutableList<DeclarationDescriptor> {
|
||||
val result = mutableListOf<DeclarationDescriptor>()
|
||||
result.addAll(DescriptorUtils.getAllDescriptors(descriptor.unsubstitutedMemberScope))
|
||||
|
||||
+20
-24
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
@@ -65,34 +66,28 @@ class StatementGenerator(
|
||||
fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun generateStatement(ktElement: KtElement): IrStatement =
|
||||
ktElement.genStmt()
|
||||
|
||||
fun generateStatements(ktStatements: List<KtExpression>, to: IrStatementContainer) =
|
||||
ktStatements.mapTo(to.statements) { generateStatement(it) }
|
||||
|
||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||
ktExpression.genExpr()
|
||||
|
||||
private fun KtElement.genStmt(): IrStatement =
|
||||
try {
|
||||
deparenthesize().accept(this@StatementGenerator, null)
|
||||
ktElement.deparenthesize().accept(this@StatementGenerator, null)
|
||||
} catch (e: BackendException) {
|
||||
throw e
|
||||
} catch (e: ErrorExpressionException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(ktElement, e)
|
||||
}
|
||||
|
||||
private fun KtElement.genExpr(): IrExpression =
|
||||
when (val irStatement = genStmt()) {
|
||||
fun generateStatements(ktStatements: List<KtExpression>, to: IrStatementContainer) =
|
||||
ktStatements.mapTo(to.statements) { generateStatement(it) }
|
||||
|
||||
fun generateExpression(ktElement: KtElement): IrExpression =
|
||||
when (val irStatement = generateStatement(ktElement)) {
|
||||
is IrExpression ->
|
||||
irStatement
|
||||
is IrDeclaration ->
|
||||
IrBlockImpl(
|
||||
irStatement.startOffset,
|
||||
irStatement.endOffset,
|
||||
this@StatementGenerator.context.irBuiltIns.unitType,
|
||||
context.irBuiltIns.unitType,
|
||||
null,
|
||||
listOf(irStatement)
|
||||
)
|
||||
@@ -122,7 +117,7 @@ class StatementGenerator(
|
||||
property.startOffsetSkippingComments, property.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor,
|
||||
variableDescriptor.type.toIrType(),
|
||||
property.initializer?.genExpr()
|
||||
property.initializer?.let { generateExpression(it) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -141,7 +136,7 @@ class StatementGenerator(
|
||||
context.irBuiltIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
val ktInitializer = multiDeclaration.initializer!!
|
||||
val containerValue = scope.createTemporaryVariableInBlock(context, ktInitializer.genExpr(), irBlock, "container")
|
||||
val containerValue = scope.createTemporaryVariableInBlock(context, generateExpression(ktInitializer), irBlock, "container")
|
||||
|
||||
declareComponentVariablesInBlock(multiDeclaration, irBlock, containerValue)
|
||||
|
||||
@@ -185,7 +180,7 @@ class StatementGenerator(
|
||||
val irBlock = IrBlockImpl(expression.startOffsetSkippingComments, expression.endOffset, returnType.toIrType())
|
||||
|
||||
expression.statements.forEach {
|
||||
irBlock.statements.add(it.genStmt())
|
||||
irBlock.statements.add(generateStatement(it))
|
||||
}
|
||||
|
||||
return irBlock
|
||||
@@ -193,10 +188,11 @@ class StatementGenerator(
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
||||
val returnTarget = getReturnExpressionTarget(expression)
|
||||
val irReturnedExpression = expression.returnedExpression?.genExpr() ?: IrGetObjectValueImpl(
|
||||
expression.startOffsetSkippingComments, expression.endOffset, context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
val irReturnedExpression = expression.returnedExpression?.let { generateExpression(it) }
|
||||
?: IrGetObjectValueImpl(
|
||||
expression.startOffsetSkippingComments, expression.endOffset, context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
return IrReturnImpl(
|
||||
expression.startOffsetSkippingComments, expression.endOffset, context.irBuiltIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression
|
||||
@@ -231,7 +227,7 @@ class StatementGenerator(
|
||||
expression.startOffsetSkippingComments,
|
||||
expression.endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
expression.thrownExpression!!.genExpr()
|
||||
generateExpression(expression.thrownExpression!!)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -254,7 +250,7 @@ class StatementGenerator(
|
||||
val endOffset = expression.endOffset
|
||||
|
||||
val resultType = getTypeInferredByFrontendOrFail(expression).toIrType()
|
||||
val entries = expression.entries.map { it.genExpr() }.postprocessStringTemplateEntries()
|
||||
val entries = expression.entries.map { generateExpression(it) }.postprocessStringTemplateEntries()
|
||||
|
||||
return when (entries.size) {
|
||||
0 -> IrConstImpl.string(startOffset, endOffset, resultType, "")
|
||||
@@ -311,7 +307,7 @@ class StatementGenerator(
|
||||
IrConstImpl.string(entry.startOffsetSkippingComments, entry.endOffset, context.irBuiltIns.stringType, entry.unescapedValue)
|
||||
|
||||
override fun visitStringTemplateEntryWithExpression(entry: KtStringTemplateEntryWithExpression, data: Nothing?): IrStatement =
|
||||
entry.expression!!.genExpr()
|
||||
generateExpression(entry.expression!!)
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
||||
val resolvedCall = getResolvedCall(expression)
|
||||
|
||||
-6
@@ -28,12 +28,6 @@ inline fun generateExpressionValue(type: IrType, crossinline generate: () -> IrE
|
||||
override fun load(): IrExpression = generate()
|
||||
}
|
||||
|
||||
inline fun generateDelegatedValue(type: IrType, crossinline generateValue: () -> IntermediateValue) =
|
||||
object : ExpressionValue(type) {
|
||||
val lazyDelegate by lazy { generateValue() }
|
||||
override fun load(): IrExpression = lazyDelegate.load()
|
||||
}
|
||||
|
||||
class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentReceiver {
|
||||
private var instantiated = false
|
||||
|
||||
|
||||
+5
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBasedDeclarationDescriptor
|
||||
@@ -110,6 +111,10 @@ internal class InsertImplicitCasts(
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall) {
|
||||
expression.acceptChildrenVoid(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user