代码之家  ›  专栏  ›  技术社区  ›  rahat

挂起函数/方法在kotlin的引擎盖下是如何工作的?

  •  0
  • rahat  · 技术社区  · 2 年前

    这个问题的目的是了解悬挂方法是如何在引擎盖下工作的,以及 IntrinsicsKt.getCOROUTINE_SUSPENDED(); ?

    在下面的字节码中,您将看到一段代码

    if (var10000.resultingBlockingOp-IoAF18A((Continuation)$continuation) == var4) {
                   return var4;
                }
    

    其中var4是

    Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
    

    如果函数返回,那么协程将如何执行?

    invokeSuspend 方法,这是否意味着挂起方法在后台通过递归工作?

    
    class CoroutineExplanatoryUseCase {
        private val coroutineExplanatoryRepo: CoroutineExplanatoryRepo = CoroutineExplanatoryRepo()
    
        suspend fun simpleOp() {
            coroutineExplanatoryRepo.simpleBlockingOp()
        }
    
        suspend fun resultingBlockingOp() {
            coroutineExplanatoryRepo.resultingBlockingOp()
        }
    
    }
    

    生成的字节码

    public final class CoroutineExplanatoryUseCase {
       private final CoroutineExplanatoryRepo coroutineExplanatoryRepo = new CoroutineExplanatoryRepo();
    
       @Nullable
       public final Object simpleOp(@NotNull Continuation $completion) {
          Object var10000 = this.coroutineExplanatoryRepo.simpleBlockingOp($completion);
          return var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
       }
    
       @Nullable
       public final Object resultingBlockingOp(@NotNull Continuation var1) {
          Object $continuation;
          label20: {
             if (var1 instanceof <undefinedtype>) {
                $continuation = (<undefinedtype>)var1;
                if ((((<undefinedtype>)$continuation).label & Integer.MIN_VALUE) != 0) {
                   ((<undefinedtype>)$continuation).label -= Integer.MIN_VALUE;
                   break label20;
                }
             }
    
             $continuation = new ContinuationImpl(var1) {
                // $FF: synthetic field
                Object result;
                int label;
    
                @Nullable
                public final Object invokeSuspend(@NotNull Object $result) {
                   this.result = $result;
                   this.label |= Integer.MIN_VALUE;
                   return CoroutineExplanatoryUseCase.this.resultingBlockingOp(this);
                }
             };
          }
    
          Object $result = ((<undefinedtype>)$continuation).result;
          Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
          switch (((<undefinedtype>)$continuation).label) {
             case 0:
                ResultKt.throwOnFailure($result);
                CoroutineExplanatoryRepo var10000 = this.coroutineExplanatoryRepo;
                ((<undefinedtype>)$continuation).label = 1;
                if (var10000.resultingBlockingOp-IoAF18A((Continuation)$continuation) == var4) {
                   return var4;
                }
                break;
             case 1:
                ResultKt.throwOnFailure($result);
                ((Result)$result).unbox-impl();
                break;
             default:
                throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
          }
    
          return Unit.INSTANCE;
       }
    }
    
    0 回复  |  直到 2 年前