I am the maintainer of grappa. This package generates parsers at runtime from Java code by using ASM to generate a class extending your parser class.
I have already migrated from ASM 4 to ASM 5, and from generating JVM 1.5 bytecode to generating JVM 1.6 bytecode, and now I have just succeeded in having it generate JVM 1.7 bytecode instead... except I have no idea why this works.
Basically, I did the following:
- Changing the argument to the ClassWriter constructors; prior to that it was
new ClassWriter(ClassWriter.COMPUTE_MAXS)
, and it is nownew ClassWriter(ClassWriter.COMPUTE_FRAMES)
- Changing the first argument of each call to the
.visit()
method fromOpcodes.V1_6
toOpcodes.V1_7
.
Now, why I don't understand why it works for two reasons:
I have several calls to
MethodVisitor
s which read:mv.visitMaxs(0, 0); // trigger automatic computing
Does that mean that these instructions can be removed?
At first I have only tried and added the
COMPUTE_FRAMES
argument to theClassWriter
constructors but it failed at one point for one of my tests in which I declare:static class TestJoinParser extends EventBusParser<Object> { protected final JoinMatcherBuilder builder = join('a').using('b'); }
And the error was:
java.lang.ClassFormatError: Arguments can't fit into locals
Given that it is an instance field I suppose it has to do with that particular argument being initialized in the constructor?
Anyway, all my tests now work, I am in the process of trying heavier tests etc... But as my goal is to go further, I'd like to understand at least a little as to why my modifications worked at all...