I'm trying to compile an AST to a java classfile, using ASM to create the class itself. I ran into a problem when I try to add local variables to functions (functions are created correctly).
F.e., a simple function like this:
public void test() {
int a = 10;
int b = 11;
int c = 12;
int d = 1;
}
Becomes this, once instrumented (decompiled with JD-GUI):
public void test() {
int i = 10;
int j = 11;
int k = 12;
int m = 4;
}
The bytecode for this looks like this:
public test() { //()V
bipush 10
istore1
bipush 11
istore2
bipush 12
istore3
iconst_4
istore4
return
}
I'm creating the local variables like this:
methodVisitor.visitVarInsn(Opcodes.BIPUSH, symbol.value);
methodVisitor.visitVarInsn(Opcodes.ISTORE, position);
symbol
is the current local variable, and position
its index, 1-based. F.e. a
would be on position 1
and d
would be on position 4
.
My problem is the correct use of the Opcodes
for different values. I tried Opcodes
like Opcodes.LDC
, but then the generated class doesn't have any local variables in its methods, but all the globally defined variables and functions are in there twice.
What's the correct way of adding variables of arbitrary type and with an arbitrary value to a method?
edit:
As per the comments I tried to incorporate the other questions answer like so:
MethodVisitor methodVisitor = cw.visitMethod(
access,
methodName,
typeDescriptors,
null,
null
);
LocalVariablesSorter mv = new LocalVariablesSorter(access, typeDescriptors, methodVisitor);
I then use the LocalVariablesSorter
to add a local variable like this:
// type is net.bytebuddy.jar.asm.Type.INT_TYPE
net.bytebuddy.jar.asm.Type type = getType(symbol.type);
int id = mv.newLocal(type);
mv.visitVarInsn(Opcodes.ISTORE, id);
which decompiles to:
/* Error */
public void test()
{
// Byte code:
// 0: istore_2
// 1: istore 4
// 3: istore 6
// 5: istore 8
// 7: return
}
resulting in this bytecode:
public test() { //()V
istore2
istore4
istore6
istore8
return
}
What am I missing here?