Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SuspendingLambda #1258

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

Conversation

poseidon-mysugr
Copy link
Contributor

@poseidon-mysugr poseidon-mysugr commented Nov 22, 2021

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.

@Godin Godin added this to Awaiting triage in Filtering via automation Nov 22, 2021
@Godin Godin self-requested a review December 22, 2021 00:59
@Godin Godin moved this from Awaiting triage to To Do in Filtering Dec 22, 2021
@Godin Godin added this to Implementation in Current work items via automation Dec 22, 2021
@Godin Godin moved this from Implementation to Review in Current work items Dec 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Filtering
  
To Do
Development

Successfully merging this pull request may close these issues.

None yet

2 participants