Closed bys1 closed 1 year ago
Thanks for reporting this; and especially for the simple example that triggers this bug.
I've been having some trouble reproducing the stacktrace:
rascal>decompile(|project://flybytes/target/classes/lang/flybytes/internal/Test.class|, "test2")
Method: method(
methodDesc(
integer(),
"test2",
[integer()]),
[var(
integer(),
"x")],
[return(const(
integer(),
5))],
modifiers={public()})
Perhaps its because my test class is nested in a package. going to try and move it to the root now.
So we're looking at the following code, and it does depend on some contextual parameters, namely whether or not javac
was called with the -debug
flag, and/or the -parameters
flag:
private IList formals(List<ParameterNode> parameters, List<LocalVariableNode> locals, IList types, boolean isStatic) {
IListWriter lw = VF.listWriter();
if (parameters != null && !parameters.isEmpty()) {
// only when class was compiled with javac -parameters
int i = 0;
for (IValue elem : types) {
lw.append(ast.Formal_var((IConstructor) elem, parameters.get(i++).name));
}
}
else if (locals != null && locals.size() >= types.length() - (isStatic?0:1)) {
// only when class was compiled with javac -debug
int i = 0;
for (IValue elem : types) {
// HERE the exception is thrown; `locals` does not have enough elements apparantly.
LocalVariableNode local = locals.get(i + (isStatic?0:1));
lw.append(ast.Formal_var((IConstructor) elem, local.name));
i++;
}
}
else {
// otherwise we "invent" the parameter names
int i = 0;
for (IValue elem : types) {
lw.append(ast.Formal_var((IConstructor) elem, "arg_" + i));
}
}
return lw.done();
}
This was after using javac Test.java
without the -g
and without -parameters
. With either of the parameters added, the bug does not trigger.
rascal>decompile(|project://flybytes/src/Test.class|)
)
|file:///Users/jurgenv/git/flybytes/src/lang/flybytes/Disassembler.rsc|(1465,237,<18,0>,<20,75>): Java("IndexOutOfBoundsException","Index 1 out of bounds for length 0")
at jdk.internal.util.Preconditions.outOfBounds(|unknown:///Preconditions.java|(0,0,<64,0>,<64,0>))
at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(|unknown:///Preconditions.java|(0,0,<70,0>,<70,0>))
at jdk.internal.util.Preconditions.checkIndex(|unknown:///Preconditions.java|(0,0,<248,0>,<248,0>))
at java.util.Objects.checkIndex(|unknown:///Objects.java|(0,0,<372,0>,<372,0>))
at java.util.ArrayList.get(|unknown:///ArrayList.java|(0,0,<459,0>,<459,0>))
at lang.flybytes.internal.ClassDisassembler.formals(|unknown:///ClassDisassembler.java|(0,0,<229,0>,<229,0>))
at lang.flybytes.internal.ClassDisassembler.method(|unknown:///ClassDisassembler.java|(0,0,<205,0>,<205,0>))
at lang.flybytes.internal.ClassDisassembler.methods(|unknown:///ClassDisassembler.java|(0,0,<178,0>,<178,0>))
at lang.flybytes.internal.ClassDisassembler.readClass(|unknown:///ClassDisassembler.java|(0,0,<105,0>,<105,0>))
at lang.flybytes.internal.ClassDisassembler.disassemble(|unknown:///ClassDisassembler.java|(0,0,<92,0>,<92,0>))
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
at disassemble(|file:///Users/jurgenv/git/flybytes/src/lang/flybytes/Disassembler.rsc|(1685,5,<20,58>,<20,63>))
at $shell$(|prompt:///|(0,57,<1,0>,<1,57>)ok
Ok the bug is fixed. However, it does show that the decompiler is depending on some of the debug information. You see that the constructor is not reduced to a super call anymore, but that the load instruction remains in an asm block. This is a different kind of bug though.
Need to figure out a better way to test this in the current project setup. We should have the same files compiled with different javac
settings and then decompiled to comparable ASTs.
I have compiled the following class with
javac
:When decompiling this using Flybytes (
decompile
fromlang::flybytes::Decompiler
), it throws an error:This happens whenever the class contains a method with exactly one argument. When I remove the method
test2
, or remove the argumentx
fromtest2
, the class decompiles fine. When I add another argument totest2
, such asint y
, it also decompiles without errors. However, with one argument, it throws the above error. Since I would expect Flybytes to be able to decompile such a simple Java class, I am assuming that this is a bug.