JVM: remove descriptors from SourceCompilerForInline
Printing the call site source on errors isn't really useful anyway - the old backend points to a specific PsiElement, and JVM_IR wraps the exception in FunctionCodegen (and printing the source never worked with JVM_IR anyway).
This commit is contained in:
@@ -8,11 +8,9 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -41,21 +39,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
protected var maskStartIndex = -1
|
||||
protected var methodHandleInDefaultMethodIndex = -1
|
||||
|
||||
protected fun throwCompilationException(
|
||||
nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean
|
||||
): CompilationException {
|
||||
val contextDescriptor = sourceCompiler.compilationContextDescriptor
|
||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor)
|
||||
val node = nodeAndSmap?.node
|
||||
throw CompilationException(
|
||||
"Couldn't inline method call '${jvmSignature.asmMethod}' into\n" +
|
||||
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
||||
(element?.text ?: "<no source>") +
|
||||
if (generateNodeText) "\nCause: " + node.nodeText else "",
|
||||
e, sourceCompiler.callElement as? PsiElement
|
||||
)
|
||||
}
|
||||
|
||||
protected fun generateStub(text: String, codegen: BaseExpressionCodegen) {
|
||||
leaveTemps()
|
||||
AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", "Call is part of inline cycle: $text")
|
||||
@@ -75,9 +58,15 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
} catch (e: CompilationException) {
|
||||
throw e
|
||||
} catch (e: InlineException) {
|
||||
throw throwCompilationException(nodeAndSmap, e, false)
|
||||
throw CompilationException(
|
||||
"Couldn't inline method call: ${sourceCompiler.callElementText}",
|
||||
e, sourceCompiler.callElement as? PsiElement
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
throw throwCompilationException(nodeAndSmap, e, true)
|
||||
throw CompilationException(
|
||||
"Couldn't inline method call: ${sourceCompiler.callElementText}\nMethod: ${nodeAndSmap?.node?.nodeText}",
|
||||
e, sourceCompiler.callElement as? PsiElement
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,21 +108,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
return true
|
||||
}
|
||||
|
||||
private fun continuationValue(): StackValue {
|
||||
assert(codegen is ExpressionCodegen) { "Expected ExpressionCodegen in coroutineContext inlining" }
|
||||
codegen as ExpressionCodegen
|
||||
|
||||
val parentContext = codegen.context.parentContext
|
||||
return if (parentContext is ClosureContext) {
|
||||
val originalSuspendLambdaDescriptor =
|
||||
parentContext.originalSuspendLambdaDescriptor ?: error("No original lambda descriptor found")
|
||||
codegen.genCoroutineInstanceForSuspendLambda(originalSuspendLambdaDescriptor)
|
||||
?: error("No stack value for coroutine instance of lambda found")
|
||||
} else
|
||||
codegen.getContinuationParameterFromEnclosingSuspendFunctionDescriptor(codegen.context.functionDescriptor)
|
||||
?: error("No stack value for continuation parameter of suspend function")
|
||||
}
|
||||
|
||||
protected fun rememberClosure(parameterType: Type, index: Int, lambdaInfo: LambdaInfo) {
|
||||
val closureInfo = invocationParamBuilder.addNextValueParameter(parameterType, true, null, index)
|
||||
closureInfo.functionalArgument = lambdaInfo
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
||||
import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.isSuspendLambdaCapturedByOuterObjectOrLambda
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.markNoinlineLambdaIfSuspend
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkersIfNeeded
|
||||
import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer
|
||||
@@ -24,7 +23,6 @@ import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNot
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
@@ -230,7 +228,7 @@ class MethodInliner(
|
||||
return
|
||||
}
|
||||
|
||||
val nullableAnyType = inliningContext.root.sourceCompilerForInline.compilationContextDescriptor.builtIns.nullableAnyType
|
||||
val nullableAnyType = inliningContext.state.module.builtIns.nullableAnyType
|
||||
val expectedParameters = info.invokeMethod.argumentTypes
|
||||
val expectedKotlinParameters = info.invokeMethodParameters
|
||||
val argumentCount = Type.getArgumentTypes(desc).size.let {
|
||||
@@ -825,7 +823,7 @@ class MethodInliner(
|
||||
getFunctionalArgumentIfExists((insnNode as VarInsnNode).`var`)
|
||||
insnNode is FieldInsnNode && insnNode.name.startsWith(CAPTURED_FIELD_FOLD_PREFIX) ->
|
||||
findCapturedField(insnNode, nodeRemapper).functionalArgument
|
||||
insnNode is FieldInsnNode && insnNode.isSuspendLambdaCapturedByOuterObjectOrLambda(inliningContext) ->
|
||||
insnNode is FieldInsnNode && inliningContext.root.sourceCompilerForInline.isSuspendLambdaCapturedByOuterObjectOrLambda(insnNode.name) ->
|
||||
NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
else ->
|
||||
null
|
||||
|
||||
+33
-7
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -21,11 +23,13 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.types.expressions.LabelResolver
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -76,8 +80,8 @@ class PsiSourceCompilerForInline(
|
||||
parentCodegen.className,
|
||||
signature.asmMethod.name,
|
||||
signature.asmMethod.descriptor,
|
||||
compilationContextFunctionDescriptor.isInlineOrInsideInline(),
|
||||
compilationContextFunctionDescriptor.isSuspend,
|
||||
context.functionDescriptor.isInlineOrInsideInline(),
|
||||
context.functionDescriptor.isSuspend,
|
||||
CodegenUtil.getLineNumberForElement(callElement, false) ?: 0
|
||||
)
|
||||
}
|
||||
@@ -314,11 +318,33 @@ class PsiSourceCompilerForInline(
|
||||
override val isFinallyMarkerRequired: Boolean
|
||||
get() = isFinallyMarkerRequired(codegen.getContext())
|
||||
|
||||
override val compilationContextDescriptor
|
||||
get() = codegen.getContext().contextDescriptor
|
||||
|
||||
override val compilationContextFunctionDescriptor
|
||||
get() = codegen.getContext().functionDescriptor
|
||||
override fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean {
|
||||
// We cannot find the lambda in captured parameters: it came from object outside of the our reach:
|
||||
// this can happen when the lambda capture by non-transformed closure:
|
||||
// inline fun inlineMe(crossinline c: suspend() -> Unit) = suspend { c() }
|
||||
// inline fun inlineMe2(crossinline c: suspend() -> Unit) = suspend { inlineMe { c() }() }
|
||||
// Suppose, we inline inlineMe into inlineMe2: the only knowledge we have about inlineMe$1 is captured receiver (this$0)
|
||||
// Thus, transformed lambda from inlineMe, inlineMe3$$inlined$inlineMe2$1 contains the following bytecode
|
||||
// ALOAD 0
|
||||
// GETFIELD inlineMe2$1$invokeSuspend$$inlined$inlineMe$1.this$0 : LScratchKt$inlineMe2$1;
|
||||
// GETFIELD inlineMe2$1.$c : Lkotlin/jvm/functions/Function1;
|
||||
// Since inlineMe2's lambda is outside of reach of the inliner, find crossinline parameter from compilation context:
|
||||
var container: DeclarationDescriptor = codegen.getContext().functionDescriptor
|
||||
while (container !is ClassDescriptor) {
|
||||
container = container.containingDeclaration ?: return false
|
||||
}
|
||||
var classDescriptor: ClassDescriptor? = container
|
||||
while (classDescriptor != null) {
|
||||
val closure = state.bindingContext[CodegenBinding.CLOSURE, classDescriptor] ?: return false
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param is ValueParameterDescriptor && value.fieldName == name) {
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
}
|
||||
classDescriptor = closure.capturedOuterClassDescriptor
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getContextLabels(): Map<String, Label?> {
|
||||
val context = codegen.getContext()
|
||||
|
||||
@@ -11,14 +11,13 @@ import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LocationInfo
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
@@ -54,9 +53,7 @@ interface SourceCompilerForInline {
|
||||
|
||||
val isFinallyMarkerRequired: Boolean
|
||||
|
||||
val compilationContextDescriptor: DeclarationDescriptor
|
||||
|
||||
val compilationContextFunctionDescriptor: FunctionDescriptor
|
||||
fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean
|
||||
|
||||
fun getContextLabels(): Map<String, Label?>
|
||||
|
||||
|
||||
-34
@@ -6,18 +6,13 @@
|
||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -238,35 +233,6 @@ fun surroundInvokesWithSuspendMarkersIfNeeded(node: MethodNode) {
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot find the lambda in captured parameters: it came from object outside of the our reach:
|
||||
// this can happen when the lambda capture by non-transformed closure:
|
||||
// inline fun inlineMe(crossinline c: suspend() -> Unit) = suspend { c() }
|
||||
// inline fun inlineMe2(crossinline c: suspend() -> Unit) = suspend { inlineMe { c() }() }
|
||||
// Suppose, we inline inlineMe into inlineMe2: the only knowledge we have about inlineMe$1 is captured receiver (this$0)
|
||||
// Thus, transformed lambda from inlineMe, inlineMe3$$inlined$inlineMe2$1 contains the following bytecode
|
||||
// ALOAD 0
|
||||
// GETFIELD inlineMe2$1$invokeSuspend$$inlined$inlineMe$1.this$0 : LScratchKt$inlineMe2$1;
|
||||
// GETFIELD inlineMe2$1.$c : Lkotlin/jvm/functions/Function1;
|
||||
// Since inlineMe2's lambda is outside of reach of the inliner, find crossinline parameter from compilation context:
|
||||
fun FieldInsnNode.isSuspendLambdaCapturedByOuterObjectOrLambda(inliningContext: InliningContext): Boolean {
|
||||
var container: DeclarationDescriptor = inliningContext.root.sourceCompilerForInline.compilationContextFunctionDescriptor
|
||||
while (container !is ClassDescriptor) {
|
||||
container = container.containingDeclaration ?: return false
|
||||
}
|
||||
val bindingContext = inliningContext.state.bindingContext
|
||||
var classDescriptor: ClassDescriptor? = container
|
||||
while (classDescriptor != null) {
|
||||
val closure = bindingContext[CodegenBinding.CLOSURE, classDescriptor] ?: return false
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param is ValueParameterDescriptor && value.fieldName == name) {
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
}
|
||||
classDescriptor = closure.capturedOuterClassDescriptor
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Interpreter, that keeps track of captured functional arguments
|
||||
private class PossibleLambdaLoad(val insn: AbstractInsnNode) : BasicValue(AsmTypes.OBJECT_TYPE)
|
||||
|
||||
|
||||
+3
-7
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledReturnType
|
||||
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.incremental.components.LocationInfo
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
@@ -32,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.doNotAnalyze
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -122,11 +121,8 @@ class IrSourceCompilerForInline(
|
||||
override val isFinallyMarkerRequired: Boolean
|
||||
get() = codegen.isFinallyMarkerRequired
|
||||
|
||||
override val compilationContextDescriptor: DeclarationDescriptor
|
||||
get() = compilationContextFunctionDescriptor
|
||||
|
||||
override val compilationContextFunctionDescriptor: FunctionDescriptor
|
||||
get() = generateSequence(codegen) { it.inlinedInto }.last().irFunction.toIrBasedDescriptor()
|
||||
override fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean =
|
||||
false // IR does not capture variables through outer this
|
||||
|
||||
override fun getContextLabels(): Map<String, Label?> {
|
||||
val result = mutableMapOf<String, Label?>(codegen.irFunction.name.asString() to null)
|
||||
|
||||
Reference in New Issue
Block a user