8000 Decompilation failure with kotlin `crossinline` lambdas crossinlined into a suspending context · Issue #470 · Vineflower/vineflower · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Decompilation failure with kotlin crossinline lambdas crossinlined into a suspending context #470
Open
@solonovamax

Description

@solonovamax

Vineflower version

1.11.1

Describe the bug

Vineflower cannot decompile kotlin crossinline lambdas when they are passed to a function which takes a suspending lambda.

Additional information

Here is some code which reproduces the issue. I have minimized it as much as possible, and have not been successful in minimizing it any further.

fun test() {
    return test2 { }
}

inline fun test2(crossinline fn: () -> Unit) {
    return runBlocking { fn() }
}

Here is the stack trace:

ERROR: Class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1 couldn't be fully decompiled.
java.lang.IllegalStateException: Couldn't find method <anonymous> (Lkotlinx/coroutines/CoroutineScope;)V in class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
	at org.vineflower.kotlin.struct.KFunction.parse(KFunction.java:112)
	at org.vineflower.kotlin.KotlinWriter.writeClass(KotlinWriter.java:221)
	at org.jetbrains.java.decompiler.main.ClassesProcessor.writeClass(ClassesProcessor.java:500)
	at org.jetbrains.java.decompiler.main.Fernflower.getClassContent(Fernflower.java:196)
	at org.jetbrains.java.decompiler.struct.ContextUnit.lambda$save$3(ContextUnit.java:195)
	at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1403)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)

If you run javap on the .class file, this is what it emits:

public final class ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1 extends kotlin.coroutines.jvm.internal.SuspendLambda implements kotlin.jvm.functions.Function2<kotlinx.coroutines.CoroutineScope, kotlin.coroutines.Continuation<? super kotlin.Unit>, java.lang.Object> {
  int label;

  public ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1(kotlin.coroutines.Continuation);
    Code:
       0: aload_0
       1: iconst_2
       2: aload_1
       3: invokespecial #19                 // Method kotlin/coroutines/jvm/internal/SuspendLambda."<init>":(ILkotlin/coroutines/Continuation;)V
       6: return

  public final java.lang.Object invokeSuspend(java.lang.Object);
    Code:
       0: invokestatic  #42                 // Method kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;
       3: pop
       4: aload_0
       5: getfield      #44                 // Field label:I
       8: tableswitch   { // 0 to 0
                     0: 28
               default: 39
          }
      28: aload_1
      29: invokestatic  #50                 // Method kotlin/ResultKt.throwOnFailure:(Ljava/lang/Object;)V
      32: iconst_0
      33: istore_2
      34: nop
      35: getstatic     #56                 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      38: areturn
      39: new           #58                 // class java/lang/IllegalStateException
      42: dup
      43: ldc           #60                 // String call to \'resume\' before \'invoke\' with coroutine
      45: invokespecial #63                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      48: athrow

  public final kotlin.coroutines.Continuation<kotlin.Unit> create(java.lang.Object, kotlin.coroutines.Continuation<?>);
    Code:
       0: new           #2                  // class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
       3: dup
       4: aload_2
       5: invokespecial #71                 // Method "<init>":(Lkotlin/coroutines/Continuation;)V
       8: checkcast     #73                 // class kotlin/coroutines/Continuation
      11: areturn

  public final java.lang.Object invoke(kotlinx.coroutines.CoroutineScope, kotlin.coroutines.Continuation<? super kotlin.Unit>);
    Code:
       0: aload_0
       1: aload_1
       2: aload_2
       3: invokevirtual #80                 // Method create:(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
       6: checkcast     #2                  // class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
       9: getstatic     #56                 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      12: invokevirtual #82                 // Method invokeSuspend:(Ljava/lang/Object;)Ljava/lang/Object;
      15: areturn

  public java.lang.Object invoke(java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #86                 // class kotlinx/coroutines/CoroutineScope
       5: aload_2
       6: checkcast     #73                 // class kotlin/coroutines/Continuation
       9: invokevirtual #88                 // Method invoke:(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
      12: areturn
}

and here are the kotlin annotations at the top of the class (decompiled with fernflower to get them):

@DebugMetadata(
   f = "test.kt",
   l = {},
   i = {},
   s = {},
   n = {},
   m = "invokeSuspend",
   c = "ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1"
)
@Metadata(
   mv = {1, 8, 0},
   k = 3,
   xi = 48,
   d1 = {"\u0000\f\n\u0000\n\u0002\u0010\u0002\n\u0002\u0018\u0002\n\u0000\u0010\u0000\u001a\u00020\u0001*\u00020\u0002H\u008a\u0006\u0003"},
   d2 = {"<anonymous>", "", "Lkotlinx/coroutines/CoroutineScope;", "ca/solostudios/nyx/plugin/compile/TestKt$test2$1"}
)
@SourceDebugExtension({"SMAP\ntest.kt\nKotlin\n*S Kotlin\n*F\n+ 1 test.kt\nca/solostudios/nyx/plugin/compile/TestKt$test2$1\n+ 2 test.kt\nca/solostudios/nyx/plugin/compile/TestKt\n*L\n1#1,37:1\n33#2:38\n*E\n"})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0