667 has an initializer like `a = b = new X()`. This broke the previous
version of the unscrambler, as it treated it as two separate
initializers: `a = b = new X()` and `b = new X()`. When the fields were
moved, the overlapping instructions were removed twice from the original
<clinit> method, making its size negative.
Even if this were fixed, it is still not safe to move the initializers,
as `new X()` would end up being executed twice, not once.
This commit fixes the problem by treating any simple initializer that
overlaps with any other simple initializer as a complex initializer.
Signed-off-by: Graham <gpe@openrs2.org>
This commit makes the following improvements:
- Converts the list of instructions in the entry and exit block to a
set, which makes checking for containment more efficient.
- Removes redundant excluded field filtering, which is already handled
by the unscramble() method.
- Treats fields written with PUTSTATIC outside the entry or exit block
as complex, instead of just fields read with GETSTATIC.
- Treats fields with multiple simple initializers as complex.
- Treats fields where we fail to extract a simple initializer as
complex. This fixes a bug where we accidentally thought those fields
had no initializer.
Signed-off-by: Graham <gpe@openrs2.org>
This is in preparation for adding a new deob module which invokes the
bytecode deobfuscator, decompiler and AST deobfuscator in turn.
Signed-off-by: Graham <gpe@openrs2.org>