Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Suspending Lambda #7

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

poseidon-mysugr
Copy link

Given the following class:

class SuspendingLambda {
    private fun foo(suspendingLambda: suspend () -> Unit) {}
    fun bar() {
        foo {}
    }
}

the Kotlin 1.6.0 compiler generates an inner class SuspendingLambda.$bar.$1 with a function invokeSuspend with the following bytecode:

  public final java.lang.Object invokeSuspend(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
    Code:
      stack=3, locals=2, args_size=2
         0: invokestatic  #37                 // Method kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;
         3: pop
         4: aload_0
         5: getfield      #41                 // Field label:I
         8: tableswitch   { // 0 to 0
                       0: 28
                 default: 36
            }
        28: aload_1
        29: invokestatic  #47                 // Method kotlin/ResultKt.throwOnFailure:(Ljava/lang/Object;)V
        32: getstatic     #53                 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
        35: areturn
        36: new           #55                 // class java/lang/IllegalStateException
        39: dup
        40: ldc           #57                 // String call to \'resume\' before \'invoke\' with coroutine
        42: invokespecial #60                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
        45: athrow
      StackMapTable: number_of_entries = 2
        frame_type = 28 /* same */
        frame_type = 7 /* same */
      LineNumberTable:
        line 6: 3
        line 6: 32
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           32       4     0  this   Lcom/mysugr/SuspendingLambda$bar$1;
           32       4     1 $result   Ljava/lang/Object;
    RuntimeInvisibleAnnotations:
      0: #30()
        org.jetbrains.annotations.Nullable
    RuntimeInvisibleParameterAnnotations:
      parameter 0:
        0: #31()
          org.jetbrains.annotations.NotNull

The tableswitch instruction creates two branches, one of which (instructions 36 to 45) is impossible to cover in test cases, because the Kotlin compiler already takes care that this fault condition doesn't happen.

In this PR, a new filter is introduced to filter both the tableswitch instruction and the branch that throws the IllegalStateException.

Also, new functions nextIsLdc and nextIsLdcStartingWith are introduced to the AbstractMatcher to simplify a few cases where the cst property of the LdcInsnNode is checked against a String or a String prefix.

@poseidon-mysugr poseidon-mysugr force-pushed the feature/SuspendingLambda branch from 0ffc688 to 3a00398 Compare November 22, 2021 15:58
Copy link

@ChristopherKoellner ChristopherKoellner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have one question.
Other than that it looks good.

@poseidon-mysugr poseidon-mysugr force-pushed the feature/SuspendingLambda branch from 36ed729 to 7acfe7e Compare December 12, 2023 13:50
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants