Skip to content
This repository has been archived by the owner on Apr 2, 2021. It is now read-only.

Support unpicking of locals #2

Open
ChloeDawn opened this issue Jun 12, 2019 · 1 comment
Open

Support unpicking of locals #2

ChloeDawn opened this issue Jun 12, 2019 · 1 comment

Comments

@ChloeDawn
Copy link

ChloeDawn commented Jun 12, 2019

When a local is known to be constant, the compiler will inline it.
Take, for example, this code:

// in
public int pad(final int foo) {
	final int bar = 10;
	return foo + bar;
}

When compiled, bar is known to be constant, as it is a constant value in a final local. The compiler will then inline it, and the decompiled code would look roughly like this:

// out
public int pad(int foo) {
	int bar = 10;
	return foo + 10;
}

The compile does not strip the local, so theoretically unpick could support it. In the context of Minecraft code, it can be seen that the tool ProGuard also does not strip these locals (likely as at the time of stripping they are not seen as unused, or simply because ProGuard does not wish to modify the LVT for such a small optimization).
Unfortunately, there are cases where unpicking is not possible (to my knowledge), wherein the compiler can inline math operations of known constants, as shown in the example below:

// in
public int foo() {
	final int bar = 10;
	return 20 + bar;
}
// out
public int foo() {
	final int bar = 10;
	return 30;
}

In most cases, operations involving inlined locals load other locals or fields that cannot be inlined, however, so the case of this inlining scenario is rare, and still justifies support for unpicking of locals, IMO.

@ChloeDawn
Copy link
Author

Full example with bytecode representation:

public int pad(final int foo) {
  final int bar = 10;
  return foo + bar;
}

public int foo() {
  final int bar = 10;
  return 20 + bar;
}
// access flags 0x1
public pad(I)I
 L0
  LINENUMBER 19 L0
  BIPUSH 10
  ISTORE 2
 L1
  LINENUMBER 20 L1
  ILOAD 1
  BIPUSH 10
  IADD
  IRETURN
 L2
  LOCALVARIABLE this LFooBar; L0 L2 0
  LOCALVARIABLE foo I L0 L2 1
  LOCALVARIABLE bar I L1 L2 2
  MAXSTACK = 2
  MAXLOCALS = 3

// access flags 0x1
public foo()I
 L0
  LINENUMBER 24 L0
  BIPUSH 10
  ISTORE 1
 L1
  LINENUMBER 25 L1
  BIPUSH 30
  IRETURN
 L2
  LOCALVARIABLE this LFooBar; L0 L2 0
  LOCALVARIABLE bar I L1 L2 1
  MAXSTACK = 1
  MAXLOCALS = 2

Earthcomputer added a commit to Earthcomputer/unpick that referenced this issue Mar 27, 2021
…onstants (WeaveMC#2)

* Better analysis

* Fix ASM stuff

* Add Minecraft to classpath
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant