diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt index fba6b675eb5..2a135aef8a6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @@ -19,7 +19,8 @@ enum class ValueKind { METHOD_HANDLE_IN_DEFAULT, CAPTURED, DEFAULT_LAMBDA_CAPTURED_PARAMETER, - NON_INLINEABLE_CALLED_IN_SUSPEND + NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND, + NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER } interface CallGenerator { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index cf351f6078c..356a0a5ecc3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -134,7 +134,8 @@ class AnonymousObjectTransformer( inliningContext, classBuilder, methodsToTransform, - superClassName + superClassName, + additionalFakeParams ) for (next in methodsToTransform) { val deferringVisitor = diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 7a68d3837f2..300f23d0908 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.inline import com.intellij.psi.PsiElement import com.intellij.util.ArrayUtil import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive @@ -409,8 +410,11 @@ abstract class InlineCodegen( info.remapValue = remappedValue } else { info = invocationParamBuilder.addNextValueParameter(jvmType, false, remappedValue, parameterIndex) - if (kind == ValueKind.NON_INLINEABLE_CALLED_IN_SUSPEND) { - info.functionalArgument = CrossinlineLambdaInSuspendContextAsNoInline + info.functionalArgument = when (kind) { + ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND -> + NonInlineableArgumentForInlineableParameterCalledInSuspend(kotlinType?.isSuspendFunctionTypeOrSubtype == true) + ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER -> NonInlineableArgumentForInlineableSuspendParameter + else -> null } } @@ -804,15 +808,18 @@ class PsiInlineCodegen( } } else { val value = codegen.gen(argumentExpression) - putValueIfNeeded( - parameterType, - value, - if (isCallSiteIsSuspend(valueParameterDescriptor)) ValueKind.NON_INLINEABLE_CALLED_IN_SUSPEND else ValueKind.GENERAL, - parameterIndex - ) + val kind = when { + isCallSiteIsSuspend(valueParameterDescriptor) -> ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND + isInlineSuspendParameter(valueParameterDescriptor) -> ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER + else -> ValueKind.GENERAL + } + putValueIfNeeded(parameterType, value, kind, parameterIndex) } } + private fun isInlineSuspendParameter(descriptor: ValueParameterDescriptor): Boolean = + functionDescriptor.isInline && !descriptor.isNoinline && descriptor.type.isSuspendFunctionTypeOrSubtype + private fun isCallSiteIsSuspend(descriptor: ValueParameterDescriptor): Boolean = state.bindingContext[CodegenBinding.CALL_SITE_IS_SUSPEND_FOR_CROSSINLINE_LAMBDA, descriptor] == true diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt index 48dc1cb66d2..91cd3b1be69 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt @@ -79,7 +79,8 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu } } -object CrossinlineLambdaInSuspendContextAsNoInline : FunctionalArgument +class NonInlineableArgumentForInlineableParameterCalledInSuspend(val isSuspend: Boolean) : FunctionalArgument +object NonInlineableArgumentForInlineableSuspendParameter : FunctionalArgument class DefaultLambda( override val lambdaClassType: Type, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 29eec28e001..79e8f40fcaa 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -9,16 +9,14 @@ import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName -import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer +import org.jetbrains.kotlin.codegen.inline.coroutines.* import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer -import org.jetbrains.kotlin.codegen.optimization.common.ControlFlowGraph -import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence -import org.jetbrains.kotlin.codegen.optimization.common.asSequence -import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful +import org.jetbrains.kotlin.codegen.optimization.common.* import org.jetbrains.kotlin.codegen.optimization.fixStack.peek import org.jetbrains.kotlin.codegen.optimization.fixStack.top +import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor @@ -220,6 +218,9 @@ class MethodInliner( val info = invokeCall.functionalArgument if (info !is LambdaInfo) { + if (info == NonInlineableArgumentForInlineableSuspendParameter) { + super.visitMethodInsn(Opcodes.INVOKESTATIC, NOINLINE_CALL_MARKER, NOINLINE_CALL_MARKER, "()V", false) + } //noninlinable lambda super.visitMethodInsn(opcode, owner, name, desc, itf) return @@ -366,6 +367,8 @@ class MethodInliner( ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false)) ) { //we shouldn't process here content of inlining lambda it should be reified at external level except default lambdas + } else if (owner == NOINLINE_CALL_MARKER && name == NOINLINE_CALL_MARKER) { + // do not generate multiple markers on single invoke } else { super.visitMethodInsn(opcode, owner, name, desc, itf) } @@ -386,7 +389,21 @@ class MethodInliner( node.accept(lambdaInliner) - return resultNode + return surroundInvokesWithSuspendMarkersIfNeeded(resultNode) + } + + private fun surroundInvokesWithSuspendMarkersIfNeeded(node: MethodNode): MethodNode { + val markers = node.instructions.asSequence().filter { it.isNoinlineCallMarker() }.toList() + if (markers.isEmpty()) return node + val invokes = markers.map { it.next as MethodInsnNode } + node.instructions.removeAll(markers) + + val sourceFrames = MethodTransformer.analyze(inlineCallSiteInfo.ownerClassName, node, SourceInterpreter()) + val toSurround = invokes.mapNotNull { insn -> + findReceiverOfInvoke(sourceFrames[node.instructions.indexOf(insn)], insn)?.let { insn to it } + } + surroundInvokesWithSuspendMarkers(node, toSurround) + return node } private fun isDefaultLambdaWithReification(lambdaInfo: LambdaInfo) = diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt index ccb1f4503eb..ab5d5932a2c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt @@ -7,27 +7,34 @@ package org.jetbrains.kotlin.codegen.inline.coroutines import com.intellij.util.ArrayUtil import org.jetbrains.kotlin.codegen.ClassBuilder -import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor +import org.jetbrains.kotlin.codegen.TransformationMethodVisitor +import org.jetbrains.kotlin.codegen.coroutines.* import org.jetbrains.kotlin.codegen.coroutines.getLastParameterIndex -import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodName import org.jetbrains.kotlin.codegen.coroutines.replaceFakeContinuationsWithRealOnes import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.optimization.common.asSequence +import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull +import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.config.isReleaseCoroutines import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes -import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode -import org.jetbrains.org.objectweb.asm.tree.MethodNode -import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode +import org.jetbrains.org.objectweb.asm.tree.* +import org.jetbrains.org.objectweb.asm.tree.analysis.Frame +import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter +import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue + +const val NOINLINE_CALL_MARKER = "NOINLINE_CALL_MARKER" class CoroutineTransformer( private val inliningContext: InliningContext, private val classBuilder: ClassBuilder, private val methods: List, - private val superClassName: String + private val superClassName: String, + private val capturedParams: List ) { private val state = inliningContext.state @@ -94,22 +101,18 @@ class CoroutineTransformer( ArrayUtil.toStringArray(node.exceptions) ) ) { - CoroutineTransformerMethodVisitor( - classBuilder.newMethod( - JvmDeclarationOrigin.NO_ORIGIN, - node.access, - node.name, - node.desc, - node.signature, - ArrayUtil.toStringArray(node.exceptions) - ), node.access, node.name, node.desc, null, null, - obtainClassBuilderForCoroutineState = { classBuilder }, - element = element, - diagnostics = state.diagnostics, - languageVersionSettings = state.languageVersionSettings, - shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, - containingClassInternalName = classBuilder.thisName, - isForNamedFunction = false + surroundNoinlineCallsWithMarkersIfNeeded( + node, + CoroutineTransformerMethodVisitor( + createNewMethodFrom(node), node.access, node.name, node.desc, null, null, + obtainClassBuilderForCoroutineState = { classBuilder }, + element = element, + diagnostics = state.diagnostics, + languageVersionSettings = state.languageVersionSettings, + shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, + containingClassInternalName = classBuilder.thisName, + isForNamedFunction = false + ) ) } } @@ -123,24 +126,48 @@ class CoroutineTransformer( ArrayUtil.toStringArray(node.exceptions) ) ) { - CoroutineTransformerMethodVisitor( - classBuilder.newMethod( - JvmDeclarationOrigin.NO_ORIGIN, node.access, node.name, node.desc, node.signature, - ArrayUtil.toStringArray(node.exceptions) - ), node.access, node.name, node.desc, null, null, - obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! }, - element = element, - diagnostics = state.diagnostics, - languageVersionSettings = state.languageVersionSettings, - shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, - containingClassInternalName = classBuilder.thisName, - isForNamedFunction = true, - needDispatchReceiver = true, - internalNameForDispatchReceiver = classBuilder.thisName + surroundNoinlineCallsWithMarkersIfNeeded( + node, + CoroutineTransformerMethodVisitor( + createNewMethodFrom(node), node.access, node.name, node.desc, null, null, + obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! }, + element = element, + diagnostics = state.diagnostics, + languageVersionSettings = state.languageVersionSettings, + shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, + containingClassInternalName = classBuilder.thisName, + isForNamedFunction = true, + needDispatchReceiver = true, + internalNameForDispatchReceiver = classBuilder.thisName + ) ) } } + private fun surroundNoinlineCallsWithMarkersIfNeeded(node: MethodNode, delegate: MethodVisitor): MethodVisitor = + if (capturedParams.any { (it.functionalArgument as? NonInlineableArgumentForInlineableParameterCalledInSuspend)?.isSuspend == true }) + SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor( + delegate, + node.access, + node.name, + node.desc, + classBuilder.thisName, + capturedParams + ) + else + delegate + + private fun createNewMethodFrom(node: MethodNode): MethodVisitor { + return classBuilder.newMethod( + JvmDeclarationOrigin.NO_ORIGIN, + node.access, + node.name, + node.desc, + node.signature, + ArrayUtil.toStringArray(node.exceptions) + ) + } + fun replaceFakesWithReals(node: MethodNode) { findFakeContinuationConstructorClassName(node)?.let(::unregisterClassBuilder)?.let(ClassBuilder::done) replaceFakeContinuationsWithRealOnes( @@ -164,4 +191,68 @@ class CoroutineTransformer( return (new as TypeInsnNode).desc } } -} \ No newline at end of file +} + +private class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor( + delegate: MethodVisitor, + access: Int, + name: String, + desc: String, + val thisName: String, + val capturedParams: List +) : TransformationMethodVisitor(delegate, access, name, desc, null, null) { + override fun performTransformations(methodNode: MethodNode) { + fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this) + + val sourceFrames = MethodTransformer.analyze(thisName, methodNode, SourceInterpreter()) + + val noinlineInvokes = arrayListOf>() + + for (insn in methodNode.instructions.asSequence()) { + if (insn.opcode != Opcodes.INVOKEINTERFACE) continue + insn as MethodInsnNode + if (!isInvokeOnLambda(insn.owner, insn.name)) continue + val frame = sourceFrames[insn.index()] + val receiver = findReceiverOfInvoke(frame, insn).takeIf { it?.isNoinlineSuspendLambda(insn) == true } as? FieldInsnNode ?: continue + val aload = receiver.findPreviousOrNull { it.opcode != Opcodes.GETFIELD } ?: error("GETFIELD cannot be the first instruction") + assert(aload.opcode == Opcodes.ALOAD) { "Before GETFIELD there shall be ALOAD" } + noinlineInvokes.add(insn to aload) + } + + surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes) + } + + private fun AbstractInsnNode.isNoinlineSuspendLambda(invoke: MethodInsnNode): Boolean { + if (opcode != Opcodes.GETFIELD) return false + this as FieldInsnNode + if (owner != thisName || desc != "L${invoke.owner};") return false + val functionalArgument = capturedParams.find { it.newFieldName == name }?.functionalArgument ?: return false + return functionalArgument is NonInlineableArgumentForInlineableParameterCalledInSuspend && functionalArgument.isSuspend + } +} + +fun surroundInvokesWithSuspendMarkers( + methodNode: MethodNode, + noinlineInvokes: List> +) { + for ((invoke, aload) in noinlineInvokes) { + // Generate inline markers for stack transformation. It is required for local variables spilling. + methodNode.instructions.insertBefore(aload, withInstructionAdapter { + addInlineMarker(this, isStartNotEnd = true) + }) + methodNode.instructions.insertBefore(invoke, withInstructionAdapter { + addSuspendMarker(this, isStartNotEnd = true) + }) + methodNode.instructions.insert(invoke, withInstructionAdapter { + addSuspendMarker(this, isStartNotEnd = false) + addInlineMarker(this, isStartNotEnd = false) + }) + } +} + +// TODO: What to do if suddenly there are not exactly one receiver? +fun findReceiverOfInvoke(frame: Frame, insn: MethodInsnNode): AbstractInsnNode? = + frame.getStack(frame.stackSize - insn.owner.removePrefix(NUMBERED_FUNCTION_PREFIX).toInt() - 1)?.insns?.singleOrNull() + +fun AbstractInsnNode.isNoinlineCallMarker(): Boolean = + opcode == Opcodes.INVOKESTATIC && cast().let { it.owner == NOINLINE_CALL_MARKER && it.name == NOINLINE_CALL_MARKER } diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt new file mode 100644 index 00000000000..116fcd3c71e --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt @@ -0,0 +1,150 @@ +// IGNORE_BACKEND: JVM_IR +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// NO_CHECK_LAMBDA_INLINING +// CHECK_STATE_MACHINE + +// FILE: inline.kt + +import helpers.* + +interface SuspendRunnable { + suspend fun run() +} + +inline fun inlineMe1(crossinline c: suspend () -> Unit) = + object : SuspendRunnable { + override suspend fun run() { + c() + c() + } + } + +inline fun inlineMe2(crossinline c: suspend () -> Unit) = suspend { + c() + c() +} + +inline suspend fun inlineMe3(crossinline c: suspend () -> Unit) { + c() + c() +} + +inline suspend fun inlineMe4(c: suspend () -> Unit) { + c() + c() +} + +inline fun inlineMe5(noinline c: suspend () -> Unit) = + object : SuspendRunnable { + override suspend fun run() { + c() + c() + } + } + +inline fun inlineMe6(noinline c: suspend () -> Unit) = suspend { + c() + c() +} + +inline suspend fun inlineMe7(noinline c: suspend () -> Unit) { + c() + c() +} + +inline fun inlineMe11(crossinline c: suspend () -> Unit) = inlineMe1(c) +inline fun inlineMe12(crossinline c: suspend () -> Unit) = inlineMe2(c) +inline suspend fun inlineMe13(crossinline c: suspend () -> Unit) = inlineMe3(c) +inline suspend fun inlineMe14(crossinline c: suspend () -> Unit) = inlineMe4(c) + +// FILE: box.kt +// COMMON_COROUTINES_TEST + +import helpers.* +import COROUTINES_PACKAGE.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +fun box(): String { + val lambda = suspend { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + + builder { + val r = inlineMe1(lambda) + r.run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe2(lambda)() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe3(lambda) + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe4(lambda) + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + val r = inlineMe5(lambda) + r.run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe6(lambda)() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe7(lambda) + } + StateMachineChecker.check(numberOfSuspensions = 4) + + StateMachineChecker.reset() + builder { + val r = inlineMe11 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + r.run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe12 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + }() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe13 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + inlineMe14 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + } + StateMachineChecker.check(numberOfSuspensions = 4) + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index d0299257d43..a89e06c4cf7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -3936,6 +3936,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); } + @TestMetadata("passLambda.kt") + public void testPassLambda_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("passLambda.kt") + public void testPassLambda_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines"); + } + @TestMetadata("passParameterLambda.kt") public void testPassParameterLambda_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index c77c2a7d6dc..951b62ca464 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -3936,6 +3936,16 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); } + @TestMetadata("passLambda.kt") + public void testPassLambda_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("passLambda.kt") + public void testPassLambda_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines"); + } + @TestMetadata("passParameterLambda.kt") public void testPassParameterLambda_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index b76a203c7b6..21690c243a8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -3936,6 +3936,16 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); } + @TestMetadata("passLambda.kt") + public void testPassLambda_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("passLambda.kt") + public void testPassLambda_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines"); + } + @TestMetadata("passParameterLambda.kt") public void testPassParameterLambda_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines.experimental"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java index e41382dd0f8..901df93fd3e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java @@ -339,6 +339,11 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); } + @TestMetadata("passLambda.kt") + public void testPassLambda_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines"); + } + @TestMetadata("passParameterLambda.kt") public void testPassParameterLambda_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java index 928b4c463f9..523b0bda0c6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java @@ -549,6 +549,16 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); } + @TestMetadata("passLambda.kt") + public void testPassLambda_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("passLambda.kt") + public void testPassLambda_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines"); + } + @TestMetadata("passParameterLambda.kt") public void testPassParameterLambda_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines.experimental");