Closed agaricusb closed 11 years ago
SpecialSource's use of ASM rewrites the constant pool therefore reordering local variables causing patch discrepancies when compared to RetroGuard.
Example comparing SpecialSource to RetroGuard (as used in MCP):
diff -ur src/minecraft/net/minecraft/server/MinecraftServer.java src-/minecraft/net/minecraft/server/MinecraftServer.java --- src/minecraft/net/minecraft/server/MinecraftServer.java 2013-03-10 18:51:56.000000000 -0700 +++ src-/minecraft/net/minecraft/server/MinecraftServer.java 2013-03-10 18:50:08.000000000 -0700 @@ -137,17 +137,17 @@ (near "menu.loadingLevel") this.field_71305_c = new WorldServer[3]; this.field_71312_k = new long[this.field_71305_c.length][100]; ISaveHandler var7 = this.field_71310_m.func_75804_a(p_71247_1_, true); - WorldInfo var9 = var7.func_75757_d(); - WorldSettings var8; - if(var9 == null) { - var8 = new WorldSettings(p_71247_3_, this.func_71265_f(), this.func_71225_e(), this.func_71199_h(), p_71247_5_); - var8.func_82750_a(p_71247_6_); + WorldInfo var8 = var7.func_75757_d(); + WorldSettings var9; + if(var8 == null) { + var9 = new WorldSettings(p_71247_3_, this.func_71265_f(), this.func_71225_e(), this.func_71199_h(), p_71247_5_); + var9.func_82750_a(p_71247_6_); } else { - var8 = new WorldSettings(var9); + var9 = new WorldSettings(var8); }
more at https://gist.github.com/agaricusb/5131683 - but this difference is pervasive throughout the decompile
The vanilla (unremapped) code is as follows:
ajz var7 = this.l.a(var1, true); ajp var9 = var7.d(); aac var8;
7, 9, 8 is vanilla/RG but SS reorders to 7, 8, 9.
vanilla disassembly with javap:
6: ldc #55 // String menu.loadingLevel 8: invokevirtual #335 // Method c:(Ljava/lang/String;)V 11: aload_0 12: iconst_3 13: anewarray #112 // class iz 16: putfield #185 // Field b:[Liz; 19: aload_0 20: aload_0 21: getfield #185 // Field b:[Liz; 24: arraylength 25: bipush 100 27: multianewarray #80, 2 // class "[[J" 31: putfield #193 // Field j:[[J 34: aload_0 35: getfield #195 // Field l:Lakc; 38: aload_1 39: iconst_1 40: invokeinterface #366, 3 // InterfaceMethod akc.a:(Ljava/lang/String;Z)Lajz; 45: astore 7 47: aload 7 49: invokeinterface #363, 1 // InterfaceMethod ajz.d:()Lajp; 54: astore 9 56: aload 9 58: ifnonnull 96 61: new #82 // class aac
RetroGuard:
6: ldc #55 // String menu.loadingLevel 8: invokevirtual #335 // Method func_71192_d:(Ljava/lang/String;)V 11: aload_0 12: iconst_3 13: anewarray #112 // class net/minecraft/src/WorldServer 16: putfield #185 // Field field_71305_c:[Lnet/minecraft/src/WorldServer; 19: aload_0 20: aload_0 21: getfield #185 // Field field_71305_c:[Lnet/minecraft/src/WorldServer; 24: arraylength 25: bipush 100 27: multianewarray #80, 2 // class "[[J" 31: putfield #193 // Field field_71312_k:[[J 34: aload_0 35: getfield #195 // Field field_71310_m:Lnet/minecraft/src/ISaveFormat; 38: aload_1 39: iconst_1 40: invokeinterface #366, 3 // InterfaceMethod net/minecraft/src/ISaveFormat.func_75804_a:(Ljava/lang/String;Z)Lnet/minecraft/src/ISaveHandler; 45: astore 7 47: aload 7 49: invokeinterface #363, 1 // InterfaceMethod net/minecraft/src/ISaveHandler.func_75757_d:()Lnet/minecraft/src/WorldInfo; 54: astore 9 56: aload 9 58: ifnonnull 96 61: new #82 // class net/minecraft/src/WorldSettings
SS:
6: ldc #192 // String menu.loadingLevel 8: invokevirtual #173 // Method func_71192_d:(Ljava/lang/String;)V 11: aload_0 12: iconst_3 13: anewarray #194 // class net/minecraft/src/WorldServer 16: putfield #196 // Field field_71305_c:[Lnet/minecraft/src/WorldServer; 19: aload_0 20: aload_0 21: getfield #196 // Field field_71305_c:[Lnet/minecraft/src/WorldServer; 24: arraylength 25: bipush 100 27: multianewarray #197, 2 // class "[[J" 31: putfield #199 // Field field_71312_k:[[J 34: aload_0 35: getfield #135 // Field field_71310_m:Lnet/minecraft/src/ISaveFormat; 38: aload_1 39: iconst_1 40: invokeinterface #203, 3 // InterfaceMethod net/minecraft/src/ISaveFormat.func_75804_a:(Ljava/lang/String;Z)Lnet/minecraft/src/ISaveHandler; 45: astore 7 47: aload 7 49: invokeinterface #209, 1 // InterfaceMethod net/minecraft/src/ISaveHandler.func_75757_d:()Lnet/minecraft/src/WorldInfo; 54: astore 8 56: aload 8 58: ifnonnull 96 61: new #211 // class net/minecraft/src/WorldSettings
All of the constant references are shifted, but only local variables create a discrepancy for fernflower decompilation.
edit: actually its the local variable slots - astore 8 vs astore 9 on line 54
There is an option to not compute this stuff in asm - might be what is causing it.
https://github.com/md-5/SpecialSource/commit/04069fb8b9c6699e21293b3fd01a62dd0d122796
SpecialSource's use of ASM rewrites the constant pool therefore reordering local variables causing patch discrepancies when compared to RetroGuard.
Example comparing SpecialSource to RetroGuard (as used in MCP):
more at https://gist.github.com/agaricusb/5131683 - but this difference is pervasive throughout the decompile
The vanilla (unremapped) code is as follows:
7, 9, 8 is vanilla/RG but SS reorders to 7, 8, 9.
vanilla disassembly with javap:
RetroGuard:
SS:
All of the constant references are shifted, but only local variables create a discrepancy for fernflower decompilation.
edit: actually its the local variable slots - astore 8 vs astore 9 on line 54