JVM: do not use crossinline flag when inlining assertions
Crossinline lambdas *can* be inlined into objects, but don't *have* to; the correct place should be determined from the context, not from the parameter.
This commit is contained in:
@@ -1264,7 +1264,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
// Thus, do not generate it. Otherwise, it leads to VerifyError on run-time.
|
||||
boolean isCrossinlineLambda = (callGenerator instanceof PsiInlineCodegen) &&
|
||||
Objects.requireNonNull(((PsiInlineCodegen) callGenerator).getActiveLambda(),
|
||||
"no active lambda found").isCrossInline;
|
||||
"no active lambda found").isCrossInline();
|
||||
if (!isCrossinlineLambda) {
|
||||
v.aconst(null);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
|
||||
interface FunctionalArgument
|
||||
|
||||
abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgument {
|
||||
|
||||
abstract class LambdaInfo : FunctionalArgument {
|
||||
abstract val isBoundCallableReference: Boolean
|
||||
|
||||
abstract val isSuspend: Boolean
|
||||
@@ -66,7 +65,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
object NonInlineableArgumentForInlineableParameterCalledInSuspend : FunctionalArgument
|
||||
object NonInlineableArgumentForInlineableSuspendParameter : FunctionalArgument
|
||||
|
||||
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||
abstract class ExpressionLambda : LambdaInfo() {
|
||||
fun generateLambdaBody(sourceCompiler: SourceCompilerForInline) {
|
||||
node = sourceCompiler.generateLambdaBody(this, reifiedTypeParametersUsages)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
@@ -76,11 +75,10 @@ abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInli
|
||||
abstract class DefaultLambda(
|
||||
final override val lambdaClassType: Type,
|
||||
capturedArgs: Array<Type>,
|
||||
isCrossinline: Boolean,
|
||||
val offset: Int,
|
||||
val needReification: Boolean,
|
||||
sourceCompiler: SourceCompilerForInline
|
||||
) : LambdaInfo(isCrossinline) {
|
||||
) : LambdaInfo() {
|
||||
final override val isSuspend
|
||||
get() = false // TODO: it should probably be true sometimes, but it never was
|
||||
final override val isBoundCallableReference: Boolean
|
||||
|
||||
@@ -558,21 +558,17 @@ class MethodInliner(
|
||||
)
|
||||
} else if (fieldInsnNode.isCheckAssertionsStatus()) {
|
||||
fieldInsnNode.owner = inlineCallSiteInfo.ownerClassName
|
||||
if (inliningContext.isInliningLambda) {
|
||||
if (inliningContext.lambdaInfo!!.isCrossInline) {
|
||||
assert(inliningContext.parent?.parent is RegeneratedClassContext) {
|
||||
"$inliningContext grandparent shall be RegeneratedClassContext but got ${inliningContext.parent?.parent}"
|
||||
}
|
||||
inliningContext.parent!!.parent!!.generateAssertField = true
|
||||
} else {
|
||||
assert(inliningContext.parent != null) {
|
||||
"$inliningContext parent shall not be null"
|
||||
}
|
||||
inliningContext.parent!!.generateAssertField = true
|
||||
}
|
||||
} else {
|
||||
inliningContext.generateAssertField = true
|
||||
}
|
||||
when {
|
||||
// In inline function itself:
|
||||
inliningContext.parent == null -> inliningContext
|
||||
// In method of regenerated object - field should already exist:
|
||||
inliningContext.parent is RegeneratedClassContext -> inliningContext.parent
|
||||
// In lambda inlined into the root function:
|
||||
inliningContext.parent.parent == null -> inliningContext.parent
|
||||
// In lambda inlined into a method of a regenerated object:
|
||||
else -> inliningContext.parent.parent as? RegeneratedClassContext
|
||||
?: throw AssertionError("couldn't find class for \$assertionsDisabled (context = $inliningContext)")
|
||||
}.generateAssertField = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ class PsiInlineCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
var activeLambda: LambdaInfo? = null
|
||||
var activeLambda: PsiExpressionLambda? = null
|
||||
private set
|
||||
|
||||
private fun putClosureParametersOnStack(next: PsiExpressionLambda, receiverValue: StackValue?) {
|
||||
@@ -210,9 +210,9 @@ private val FunctionDescriptor.explicitParameters
|
||||
class PsiExpressionLambda(
|
||||
expression: KtExpression,
|
||||
private val state: GenerationState,
|
||||
isCrossInline: Boolean,
|
||||
val isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean
|
||||
) : ExpressionLambda(isCrossInline) {
|
||||
) : ExpressionLambda() {
|
||||
override val lambdaClassType: Type
|
||||
|
||||
override val invokeMethod: Method
|
||||
@@ -308,7 +308,7 @@ class PsiDefaultLambda(
|
||||
offset: Int,
|
||||
needReification: Boolean,
|
||||
sourceCompiler: SourceCompilerForInline
|
||||
) : DefaultLambda(lambdaClassType, capturedArgs, parameterDescriptor.isCrossinline, offset, needReification, sourceCompiler) {
|
||||
) : DefaultLambda(lambdaClassType, capturedArgs, offset, needReification, sourceCompiler) {
|
||||
private val invokeMethodDescriptor: FunctionDescriptor
|
||||
|
||||
override val invokeMethodParameters: List<KotlinType?>
|
||||
|
||||
Reference in New Issue
Block a user