I am working on a small java bytecode instrumentation tool.
The general idea is to have all of a class methods renamed with a _CONGU suffix, creating then proxy methods with the original method names that will call their _CONGU counterparts.
For instance, if a class C contains a int m() { return 1; } method, the instrumented C class will have a int m_CONGU() { return 1; } method and a int m() { return m_CONGU(); } method.
Later on I’ll add some extra logic on int m() that will do some checks before calling m_CONGU().
At the moment, I am in the process of instrumenting all constructor invocation calls to a method of mine with the _CONGU suffix.
Bellow you can see both the instrumented and non-instrumented versions of the inverse() method of a Fraction class.

When trying to run this code
Fraction fraction = new Fraction(4, 1);
I get the following exception which is puzzling me for the last couple of hours:
Exception in thread “main” java.lang.VerifyError: (class:
jorgeTestes/system/fraction/Fraction, method: inverse_CONGU signature:
()LjorgeTestes/system/fraction/Fraction;) Expecting to find
object/array on stack at
jorgeTestes.system.fraction.XyzTest.main(XyzTest.java:9)
I guess this must be a dead obvious mistake, but I can’t get what the problem might be. It looks to be in some way related to having the wrong number of data in the stack, but it looks to me that the number of elements in the stack is the same both on the original and instrumented code (at least that’s what should be happening). Any ideas?
Some more info:
1) here are the descriptors of both <init> and Fraction_CONGU(which are the same, as one would expect!):

2) I’m wondering if the color of [0] Code being different in Bytecode Viewer could mean there’s some other problem with my instrumented code? Maybe there is some metadata that’s being broken in the process, so that could be the reason the code looks alright and there’s still a problem when trying to run the code?
It looks like the code on the first screenshot is fundamentally broken. Object construction in JVM bytecode can be split into two phass: allocating memory on the heap and calling a constructor (with optional parameters) against that allocated memory:
What you are basically doing is: allocate some raw (probably zeroed) memory on the heap and invoke virtual method
Fraction_conguagainst that memory block. You haven’t yet called the constructor!Also there should be
invokevirtual, I guess this generated methods areprivate.UPDATE: I assume you want to transform the following class:
Into:
As you can see it is perfectly possible (if I get your idea correctly). Just compile this Java code and see how compiler implemented this.
Which begs a question: can’t you just use AspectJ with compile time-weaving?