反編譯后代碼分析
public final class ExampleUnitTest {
@Test
public final void addition_isCorrect() {
Assert.assertEquals(4L, 4L);
BuildersKt.launch$default((CoroutineScope)GlobalScope.INSTANCE, (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
ExampleUnitTest var10000;
String var2;
boolean var3;
Object var4;
//對應的標志位
label34: {
label33: {
var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch(this.label) {
case 0:
ResultKt.throwOnFailure($result);
var2 = "掛起點1開始";
var3 = false;
System.out.println(var2);
this.label = 1;
//根據返回值判斷是否為掛起函數,如果為掛起函數直接返回
// 掛起函數會持有Continuation,掛起函數執行后調用其resumeWith方法,之后就會回到invokeSuspend中
if (DelayKt.delay(1000L, this) ** var4) {
//協程退出
return var4;
}
break;
case 1:
//檢測上一步也就是delay是否發生異常或者失敗,接著執行-----》掛起點1結束
ResultKt.throwOnFailure($result);
break;
case 2:
//檢測上一步也就是hello是否發生異常或者失敗,接著執行-----》掛起點2結束
ResultKt.throwOnFailure($result);
break label33;
case 3:
//檢測上一步也就是delay是否發生異常或者失敗,接著執行-----》掛起點3結束
ResultKt.throwOnFailure($result);
break label34;
case 4:
ResultKt.throwOnFailure($result);
return Unit.INSTANCE;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
var2 = "掛起點1結束";
var3 = false;
//打印
System.out.println(var2);
var10000 = ExampleUnitTest.this;
//label增加,表示上一步執行完成,指向下一個該執行的函數體
this.label = 2;
//檢測hello是否為掛起函數
if (var10000.hello(this) ** var4) {
//協程退出
return var4;
}
}
//退出label33后執行的函數
var2 = "掛起點2結束";
var3 = false;
System.out.println(var2);
//再次更正
this.label = 3;
//檢測是否為掛起函數
if (DelayKt.delay(1000L, this) ** var4) {
//直接退出協程
return var4;
}
}
//退出label34后執行的函數
var2 = "掛起點3結束";
var3 = false;
System.out.println(var2);
var10000 = ExampleUnitTest.this;
this.label = 4;
//檢測是否為掛起函數
if (var10000.word(this) ** var4) {
return var4;
} else {
return Unit.INSTANCE;
}
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), 3, (Object)null);
}
}
「看完上面的反編譯解析會發現還差了兩個方法,沒錯,接下來就是自定的掛起函數的反編譯代碼,根據上面的分析請讀者親自分析下接下來的這兩個函數」
@Nullable
public final Object hello(@NotNull Continuation $completion) {
Object var10000 = BuildersKt.withContext((CoroutineContext)Dispatchers.getIO(), (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch(this.label) {
case 0:
ResultKt.throwOnFailure($result);
this.label = 1;
if (DelayKt.delay(1000L, this) ** var4) {
return var4;
}
break;
case 1:
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
String var2 = "hello";
boolean var3 = false;
System.out.println(var2);
return Unit.INSTANCE;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), $completion);
return var10000 ** IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}
@Nullable
public final Object word(@NotNull Continuation $completion) {
Object var10000 = BuildersKt.withContext((CoroutineContext)Dispatchers.getIO(), (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch(this.label) {
case 0:
ResultKt.throwOnFailure($result);
this.label = 1;
if (DelayKt.delay(1000L, this) ** var4) {
return var4;
}
break;
case 1:
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
String var2 = "word";
boolean var3 = false;
System.out.println(var2);
return Unit.INSTANCE;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), $completion);
return var10000 ** IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}
總而言之,言而總之。還是上一篇博客總結的道理,就是不斷的invokeSuspend標記標志位和掛起函數調用resumeWith。
文末致辭:
感謝東方月初提供的資料,和在分析協程原理時給予的支持。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
函數
+關注
關注
3文章
4333瀏覽量
62709 -
編譯器
+關注
關注
1文章
1634瀏覽量
49162 -
編譯
+關注
關注
0文章
659瀏覽量
32897
發布評論請先 登錄
相關推薦
一種用于反編譯代碼與源代碼的比較算法
現有反編譯器產生的代碼與對應的源代碼之間存在差異,找到并理解差異有助于改進并完善反編譯器的設計。該文給出一種適用于C 語言反編譯
發表于 03-21 15:08
?10次下載
C32asm國產靜態反編譯工具源代碼
C32asm國產靜態反編譯工具源代碼
[GLOBENOTE]LanguageChange=必須重新打開應用程序才能生效Done=完成OpenFileErr=打開 %s 文件遭遇錯誤
[GENERAL]ButtonOk=確定
發表于 02-24 14:12
?49次下載
FoxPro編程愛好者的反編譯工具源代碼
FoxPro編程愛好者的反編譯工具源代碼
UNFOXALL 2.1獻給廣大FoxPro編程愛好者的反編譯工具
&nb
發表于 02-26 16:13
?94次下載
8051 MCU反編譯開發方法記錄[
8051 MCU反編譯開發方法記錄1、項目背景2、開發環境3、開發步驟3.1 反編譯3.2 找出EEPROM的寫入地址3.3 找出EEPROM讀寫操作的代碼段3.4 找出EEPROM讀
發表于 11-29 17:51
?11次下載
java反編譯常用的保護技術
由于Java字節碼的抽象級別較高,因此它們較容易被反編譯。本節介紹了幾種常用的方法,用于保護Java字節碼不被反編譯。通常,這些方法不能夠絕對防止程序被反編譯,而是加大反編譯的難度而已
發表于 07-29 16:00
?714次閱讀
反編譯后代碼分析1
?協程掛起讓異步代碼可以像同步代碼一樣調用,但其本質還是同步,即協程體中的代碼其實是同步。
> ?因為協程也只是對線程池的封裝,所以需要了解些線程的一些知識。線程本身已經有的協程也會有,但是協程有的線程不一定有
>
ida反編譯出來代碼能直接用嗎
IDA反編譯出來的代碼通常 不能直接使用 ,這主要基于以下幾個方面的原因: 一、代碼的不完整性 IDA反編譯生成的代碼可能缺少原始源
java反編譯的代碼可以修改么
Java反編譯是一種將編譯后的Java字節碼(.class文件)轉換回源代碼的過程。反編譯后的代碼可以進行修改,但是需要注意,
java反編譯能拿到源碼嗎
Java反編譯是一種將編譯后的Java字節碼(.class文件)轉換回Java源代碼的過程。雖然反編譯可以幫助理解代碼的邏輯和結構,但它并不
評論