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 com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
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.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
@@ -41,21 +39,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
protected var maskStartIndex = -1
|
protected var maskStartIndex = -1
|
||||||
protected var methodHandleInDefaultMethodIndex = -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) {
|
protected fun generateStub(text: String, codegen: BaseExpressionCodegen) {
|
||||||
leaveTemps()
|
leaveTemps()
|
||||||
AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", "Call is part of inline cycle: $text")
|
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) {
|
} catch (e: CompilationException) {
|
||||||
throw e
|
throw e
|
||||||
} catch (e: InlineException) {
|
} 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) {
|
} 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
|
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) {
|
protected fun rememberClosure(parameterType: Type, index: Int, lambdaInfo: LambdaInfo) {
|
||||||
val closureInfo = invocationParamBuilder.addNextValueParameter(parameterType, true, null, index)
|
val closureInfo = invocationParamBuilder.addNextValueParameter(parameterType, true, null, index)
|
||||||
closureInfo.functionalArgument = lambdaInfo
|
closureInfo.functionalArgument = lambdaInfo
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
||||||
import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
|
import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
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.markNoinlineLambdaIfSuspend
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkersIfNeeded
|
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkersIfNeeded
|
||||||
import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer
|
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.codegen.pseudoInsns.PseudoInsn
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
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
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
@@ -230,7 +228,7 @@ class MethodInliner(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val nullableAnyType = inliningContext.root.sourceCompilerForInline.compilationContextDescriptor.builtIns.nullableAnyType
|
val nullableAnyType = inliningContext.state.module.builtIns.nullableAnyType
|
||||||
val expectedParameters = info.invokeMethod.argumentTypes
|
val expectedParameters = info.invokeMethod.argumentTypes
|
||||||
val expectedKotlinParameters = info.invokeMethodParameters
|
val expectedKotlinParameters = info.invokeMethodParameters
|
||||||
val argumentCount = Type.getArgumentTypes(desc).size.let {
|
val argumentCount = Type.getArgumentTypes(desc).size.let {
|
||||||
@@ -825,7 +823,7 @@ class MethodInliner(
|
|||||||
getFunctionalArgumentIfExists((insnNode as VarInsnNode).`var`)
|
getFunctionalArgumentIfExists((insnNode as VarInsnNode).`var`)
|
||||||
insnNode is FieldInsnNode && insnNode.name.startsWith(CAPTURED_FIELD_FOLD_PREFIX) ->
|
insnNode is FieldInsnNode && insnNode.name.startsWith(CAPTURED_FIELD_FOLD_PREFIX) ->
|
||||||
findCapturedField(insnNode, nodeRemapper).functionalArgument
|
findCapturedField(insnNode, nodeRemapper).functionalArgument
|
||||||
insnNode is FieldInsnNode && insnNode.isSuspendLambdaCapturedByOuterObjectOrLambda(inliningContext) ->
|
insnNode is FieldInsnNode && inliningContext.root.sourceCompilerForInline.isSuspendLambdaCapturedByOuterObjectOrLambda(insnNode.name) ->
|
||||||
NonInlineableArgumentForInlineableParameterCalledInSuspend
|
NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||||
else ->
|
else ->
|
||||||
null
|
null
|
||||||
|
|||||||
+33
-7
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.codegen.inline
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.context.*
|
import org.jetbrains.kotlin.codegen.context.*
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
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.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
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.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault
|
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
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.ExpressionTypingUtils
|
||||||
import org.jetbrains.kotlin.types.expressions.LabelResolver
|
import org.jetbrains.kotlin.types.expressions.LabelResolver
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
@@ -76,8 +80,8 @@ class PsiSourceCompilerForInline(
|
|||||||
parentCodegen.className,
|
parentCodegen.className,
|
||||||
signature.asmMethod.name,
|
signature.asmMethod.name,
|
||||||
signature.asmMethod.descriptor,
|
signature.asmMethod.descriptor,
|
||||||
compilationContextFunctionDescriptor.isInlineOrInsideInline(),
|
context.functionDescriptor.isInlineOrInsideInline(),
|
||||||
compilationContextFunctionDescriptor.isSuspend,
|
context.functionDescriptor.isSuspend,
|
||||||
CodegenUtil.getLineNumberForElement(callElement, false) ?: 0
|
CodegenUtil.getLineNumberForElement(callElement, false) ?: 0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -314,11 +318,33 @@ class PsiSourceCompilerForInline(
|
|||||||
override val isFinallyMarkerRequired: Boolean
|
override val isFinallyMarkerRequired: Boolean
|
||||||
get() = isFinallyMarkerRequired(codegen.getContext())
|
get() = isFinallyMarkerRequired(codegen.getContext())
|
||||||
|
|
||||||
override val compilationContextDescriptor
|
override fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean {
|
||||||
get() = codegen.getContext().contextDescriptor
|
// 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:
|
||||||
override val compilationContextFunctionDescriptor
|
// inline fun inlineMe(crossinline c: suspend() -> Unit) = suspend { c() }
|
||||||
get() = codegen.getContext().functionDescriptor
|
// 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?> {
|
override fun getContextLabels(): Map<String, Label?> {
|
||||||
val context = codegen.getContext()
|
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.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
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.LocationInfo
|
||||||
import org.jetbrains.kotlin.incremental.components.Position
|
import org.jetbrains.kotlin.incremental.components.Position
|
||||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
@@ -54,9 +53,7 @@ interface SourceCompilerForInline {
|
|||||||
|
|
||||||
val isFinallyMarkerRequired: Boolean
|
val isFinallyMarkerRequired: Boolean
|
||||||
|
|
||||||
val compilationContextDescriptor: DeclarationDescriptor
|
fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean
|
||||||
|
|
||||||
val compilationContextFunctionDescriptor: FunctionDescriptor
|
|
||||||
|
|
||||||
fun getContextLabels(): Map<String, Label?>
|
fun getContextLabels(): Map<String, Label?>
|
||||||
|
|
||||||
|
|||||||
-34
@@ -6,18 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||||
import org.jetbrains.kotlin.codegen.inline.*
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
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.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
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
|
// Interpreter, that keeps track of captured functional arguments
|
||||||
private class PossibleLambdaLoad(val insn: AbstractInsnNode) : BasicValue(AsmTypes.OBJECT_TYPE)
|
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.BaseExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.inline.*
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
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.diagnostics.DiagnosticUtils
|
||||||
import org.jetbrains.kotlin.incremental.components.LocationInfo
|
import org.jetbrains.kotlin.incremental.components.LocationInfo
|
||||||
import org.jetbrains.kotlin.incremental.components.Position
|
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.psi.doNotAnalyze
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -122,11 +121,8 @@ class IrSourceCompilerForInline(
|
|||||||
override val isFinallyMarkerRequired: Boolean
|
override val isFinallyMarkerRequired: Boolean
|
||||||
get() = codegen.isFinallyMarkerRequired
|
get() = codegen.isFinallyMarkerRequired
|
||||||
|
|
||||||
override val compilationContextDescriptor: DeclarationDescriptor
|
override fun isSuspendLambdaCapturedByOuterObjectOrLambda(name: String): Boolean =
|
||||||
get() = compilationContextFunctionDescriptor
|
false // IR does not capture variables through outer this
|
||||||
|
|
||||||
override val compilationContextFunctionDescriptor: FunctionDescriptor
|
|
||||||
get() = generateSequence(codegen) { it.inlinedInto }.last().irFunction.toIrBasedDescriptor()
|
|
||||||
|
|
||||||
override fun getContextLabels(): Map<String, Label?> {
|
override fun getContextLabels(): Map<String, Label?> {
|
||||||
val result = mutableMapOf<String, Label?>(codegen.irFunction.name.asString() to null)
|
val result = mutableMapOf<String, Label?>(codegen.irFunction.name.asString() to null)
|
||||||
|
|||||||
Reference in New Issue
Block a user