Skip to content

Instantly share code, notes, and snippets.

@lbialy
Created October 27, 2023 12:24
Show Gist options
  • Save lbialy/168d8168414758d18c88ba4118693b98 to your computer and use it in GitHub Desktop.
Save lbialy/168d8168414758d18c88ba4118693b98 to your computer and use it in GitHub Desktop.
Decompiled Kotlin coroutine rendezvous from SML Blogpost
// AppKt.java
package hello;
import kotlin.Metadata;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.SourceDebugExtension;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.Job;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 9, 0},
k = 2,
d1 = {"\u0000$\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0010\t\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\b\u0003\u001a\u0019\u0010\u0000\u001a\u00020\u00012\f\u0010\u0002\u001a\b\u0012\u0004\u0012\u00020\u00040\u0003¢\u0006\u0002\u0010\u0005\u001a\u000e\u0010\u0006\u001a\u00020\u00072\u0006\u0010\b\u001a\u00020\u0007\u001a-\u0010\t\u001a\u0002H\n\"\u0004\b\u0000\u0010\n2\u0006\u0010\u000b\u001a\u00020\u00042\f\u0010\f\u001a\b\u0012\u0004\u0012\u0002H\n0\rH\u0086\bø\u0001\u0000¢\u0006\u0002\u0010\u000e\u001a\u0006\u0010\u000f\u001a\u00020\u0001\u0082\u0002\u0007\n\u0005\b\u009920\u0001¨\u0006\u0010"},
d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "sumUpTo", "", "n", "timed", "T", "label", "block", "Lkotlin/Function0;", "(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;", "usingCoroutines", "hello-world"}
)
@SourceDebugExtension({"SMAP\napp.kt\nKotlin\n*S Kotlin\n*F\n+ 1 app.kt\nhello/AppKt\n*L\n1#1,74:1\n58#1,6:75\n*S KotlinDebug\n*F\n+ 1 app.kt\nhello/AppKt\n*L\n11#1:75,6\n*E\n"})
public final class AppKt {
public static final void usingCoroutines() {
String label$iv = "coroutines";
int $i$f$timed = false;
long start$iv = System.currentTimeMillis();
int var4 = false;
Object result$iv = (Job)BuildersKt.runBlocking$default((CoroutineContext)null, (Function2)(new AppKt$usingCoroutines$1$1((Continuation)null)), 1, (Object)null);
long end$iv = System.currentTimeMillis();
long took$iv = end$iv - start$iv;
String var9 = label$iv + " Took " + took$iv + " ms";
System.out.println(var9);
}
public static final Object timed(@NotNull String label, @NotNull Function0 block) {
int $i$f$timed = 0;
Intrinsics.checkNotNullParameter(label, "label");
Intrinsics.checkNotNullParameter(block, "block");
long start = System.currentTimeMillis();
Object result = block.invoke();
long end = System.currentTimeMillis();
long took = end - start;
String var10 = label + " Took " + took + " ms";
System.out.println(var10);
return result;
}
public static final long sumUpTo(long n) {
return n * (n + 1L) / (long)2;
}
public static final void main(@NotNull String[] args) {
Intrinsics.checkNotNullParameter(args, "args");
int i = 1;
for(byte var2 = 10; i <= var2; ++i) {
String var3 = "Run " + i;
System.out.println(var3);
usingCoroutines();
}
}
}
// AppKt$usingCoroutines$1$1.java
package hello;
import java.util.concurrent.atomic.AtomicReference;
import kotlin.Metadata;
import kotlin.ResultKt;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.coroutines.intrinsics.IntrinsicsKt;
import kotlin.coroutines.jvm.internal.DebugMetadata;
import kotlin.coroutines.jvm.internal.SuspendLambda;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.Ref;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.CoroutineStart;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@DebugMetadata(
f = "app.kt",
l = {},
i = {},
s = {},
n = {},
m = "invokeSuspend",
c = "hello.AppKt$usingCoroutines$1$1"
)
@Metadata(
mv = {1, 9, 0},
k = 3,
d1 = {"\u0000\u000e\n\u0000\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\u00020\u0001*\u00020\u0002H\u008a@¢\u0006\u0004\b\u0003\u0010\u0004"},
d2 = {"<anonymous>", "Lkotlinx/coroutines/Job;", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}
)
final class AppKt$usingCoroutines$1$1 extends SuspendLambda implements Function2 {
// $FF: synthetic field
private Object L$0;
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object var1) {
Object var6 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch (this.label) {
case 0:
ResultKt.throwOnFailure(var1);
CoroutineScope $this$runBlocking = (CoroutineScope)this.L$0;
long max = 10000000L;
Ref.ObjectRef waiting = new Ref.ObjectRef();
waiting.element = new AtomicReference((Object)null);
BuildersKt.launch$default($this$runBlocking, (CoroutineContext)null, (CoroutineStart)null, (Function2)(new AppKt$usingCoroutines$1$1$1(max, waiting, (Continuation)null)), 3, (Object)null);
return BuildersKt.launch$default($this$runBlocking, (CoroutineContext)null, (CoroutineStart)null, (Function2)(new AppKt$usingCoroutines$1$1$2(max, waiting, (Continuation)null)), 3, (Object)null);
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
}
AppKt$usingCoroutines$1$1(Continuation var1) {
super(2, var1);
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
AppKt$usingCoroutines$1$1 var3 = new AppKt$usingCoroutines$1$1(completion);
var3.L$0 = value;
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((AppKt$usingCoroutines$1$1)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}
// AppKt$usingCoroutines$1$1$1.java
package hello;
import java.util.concurrent.atomic.AtomicReference;
import kotlin.Metadata;
import kotlin.Result;
import kotlin.ResultKt;
import kotlin.TuplesKt;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.SafeContinuation;
import kotlin.coroutines.intrinsics.IntrinsicsKt;
import kotlin.coroutines.jvm.internal.Boxing;
import kotlin.coroutines.jvm.internal.DebugMetadata;
import kotlin.coroutines.jvm.internal.DebugProbesKt;
import kotlin.coroutines.jvm.internal.SuspendLambda;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.Ref;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@DebugMetadata(
f = "app.kt",
l = {19},
i = {0},
s = {"J$0"},
n = {"i"},
m = "invokeSuspend",
c = "hello.AppKt$usingCoroutines$1$1$1"
)
@Metadata(
mv = {1, 9, 0},
k = 3,
d1 = {"\u0000\u000e\n\u0000\n\u0002\u0010\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\u00020\u0001*\u00020\u0002H\u008a@¢\u0006\u0004\b\u0003\u0010\u0004"},
d2 = {"<anonymous>", "", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}
)
final class AppKt$usingCoroutines$1$1$1 extends SuspendLambda implements Function2 {
long J$0;
long J$1;
Object L$0;
int label;
// $FF: synthetic field
final long $max;
// $FF: synthetic field
final Ref.ObjectRef $waiting;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var14 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
long i;
long var4;
switch (this.label) {
case 0:
ResultKt.throwOnFailure($result);
i = 1L;
var4 = this.$max;
if (i > var4) {
return Unit.INSTANCE;
}
break;
case 1:
var4 = this.J$1;
i = this.J$0;
AppKt$usingCoroutines$1$1$1 var6 = (AppKt$usingCoroutines$1$1$1)this.L$0;
ResultKt.throwOnFailure($result);
if (i == var4) {
return Unit.INSTANCE;
}
++i;
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
while(true) {
this.L$0 = this;
this.J$0 = i;
this.J$1 = var4;
this.label = 1;
Continuation var7 = (Continuation)this;
SafeContinuation var8 = new SafeContinuation(IntrinsicsKt.intercepted(var7));
Continuation ourContinuation = (Continuation)var8;
int var10 = false;
Object var10000;
if (!((AtomicReference)this.$waiting.element).compareAndSet((Object)null, TuplesKt.to(ourContinuation, Boxing.boxLong(i)))) {
var10000 = ((AtomicReference)this.$waiting.element).get();
if (var10000 == null) {
throw new NullPointerException("null cannot be cast to non-null type kotlin.coroutines.Continuation<kotlin.Long>");
}
Continuation theirContinuation = (Continuation)var10000;
((AtomicReference)this.$waiting.element).set((Object)null);
Long var13 = Boxing.boxLong(i);
Result.Companion var10001 = Result.Companion;
theirContinuation.resumeWith(Result.constructor-impl(var13));
Unit var15 = Unit.INSTANCE;
var10001 = Result.Companion;
ourContinuation.resumeWith(Result.constructor-impl(var15));
}
var10000 = var8.getOrThrow();
if (var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
DebugProbesKt.probeCoroutineSuspended((Continuation)this);
}
if (var10000 == var14) {
return var14;
}
if (i == var4) {
return Unit.INSTANCE;
}
++i;
}
}
AppKt$usingCoroutines$1$1$1(long var1, Ref.ObjectRef var3, Continuation var4) {
super(2, var4);
this.$max = var1;
this.$waiting = var3;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
AppKt$usingCoroutines$1$1$1 var3 = new AppKt$usingCoroutines$1$1$1(this.$max, this.$waiting, completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((AppKt$usingCoroutines$1$1$1)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}
// AppKt$usingCoroutines$1$1$2.java
package hello;
import java.util.concurrent.atomic.AtomicReference;
import kotlin.Metadata;
import kotlin.Pair;
import kotlin.Result;
import kotlin.ResultKt;
import kotlin.Unit;
import kotlin._Assertions;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.SafeContinuation;
import kotlin.coroutines.intrinsics.IntrinsicsKt;
import kotlin.coroutines.jvm.internal.DebugMetadata;
import kotlin.coroutines.jvm.internal.DebugProbesKt;
import kotlin.coroutines.jvm.internal.SuspendLambda;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.Ref;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@DebugMetadata(
f = "app.kt",
l = {38},
i = {0, 0},
s = {"J$0", "J$1"},
n = {"sum", "i"},
m = "invokeSuspend",
c = "hello.AppKt$usingCoroutines$1$1$2"
)
@Metadata(
mv = {1, 9, 0},
k = 3,
d1 = {"\u0000\u000e\n\u0000\n\u0002\u0010\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\u00020\u0001*\u00020\u0002H\u008a@¢\u0006\u0004\b\u0003\u0010\u0004"},
d2 = {"<anonymous>", "", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}
)
final class AppKt$usingCoroutines$1$1$2 extends SuspendLambda implements Function2 {
long J$0;
long J$1;
long J$2;
Object L$0;
int label;
// $FF: synthetic field
final long $max;
// $FF: synthetic field
final Ref.ObjectRef $waiting;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
long sum;
label54: {
Object var18 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
long i;
long var6;
long toAdd;
switch (this.label) {
case 0:
ResultKt.throwOnFailure($result);
sum = 0L;
i = 1L;
var6 = this.$max;
if (i > var6) {
break label54;
}
break;
case 1:
var6 = this.J$2;
i = this.J$1;
sum = this.J$0;
AppKt$usingCoroutines$1$1$2 var10 = (AppKt$usingCoroutines$1$1$2)this.L$0;
ResultKt.throwOnFailure($result);
toAdd = ((Number)$result).longValue();
sum += toAdd;
if (i == var6) {
break label54;
}
++i;
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
while(true) {
this.L$0 = this;
this.J$0 = sum;
this.J$1 = i;
this.J$2 = var6;
this.label = 1;
Continuation var11 = (Continuation)this;
SafeContinuation var12 = new SafeContinuation(IntrinsicsKt.intercepted(var11));
Continuation ourContinuation = (Continuation)var12;
int var14 = false;
Object var10000;
if (!((AtomicReference)this.$waiting.element).compareAndSet((Object)null, ourContinuation)) {
var10000 = ((AtomicReference)this.$waiting.element).get();
if (var10000 == null) {
throw new NullPointerException("null cannot be cast to non-null type kotlin.Pair<kotlin.coroutines.Continuation<kotlin.Unit>, kotlin.Long>");
}
Pair theirDataAndContinuation = (Pair)var10000;
((AtomicReference)this.$waiting.element).set((Object)null);
Continuation var16 = (Continuation)theirDataAndContinuation.getFirst();
Unit var17 = Unit.INSTANCE;
Result.Companion var10001 = Result.Companion;
var16.resumeWith(Result.constructor-impl(var17));
Object var20 = theirDataAndContinuation.getSecond();
var10001 = Result.Companion;
ourContinuation.resumeWith(Result.constructor-impl(var20));
}
var10000 = var12.getOrThrow();
if (var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
DebugProbesKt.probeCoroutineSuspended((Continuation)this);
}
if (var10000 == var18) {
return var18;
}
toAdd = ((Number)var10000).longValue();
sum += toAdd;
if (i == var6) {
break;
}
++i;
}
}
boolean var19 = sum == AppKt.sumUpTo(this.$max);
if (_Assertions.ENABLED && !var19) {
String var5 = "Assertion failed";
throw new AssertionError(var5);
} else {
return Unit.INSTANCE;
}
}
AppKt$usingCoroutines$1$1$2(long var1, Ref.ObjectRef var3, Continuation var4) {
super(2, var4);
this.$max = var1;
this.$waiting = var3;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
AppKt$usingCoroutines$1$1$2 var3 = new AppKt$usingCoroutines$1$1$2(this.$max, this.$waiting, completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((AppKt$usingCoroutines$1$1$2)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment