Bug in code generation by asm.tree?
Yaroslav Kavenchuk <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Hi, All! This code is obtained by disassembling the java class without framesand debugging. "No tree" version compiles just fine. But "tree-version" is compiled with a bug in MethodWriter.visitMaxs - Frame.merge. ClassNode obtained by disassemblingcompiles fine, but I could not find differences in the debugger with built node. How can I continue to look for where the bug? -- WBR, Yaroslav Kavenchuk
NodeGenerationTest.java
(text/x-java-source, 8.3 KB)
import junit.framework.TestCase;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import static org.objectweb.asm.Opcodes.*;
import org.objectweb.asm.tree.*;
public class NodeGenerationTest extends TestCase implements Opcodes {
public void test() {
ClassNode cn1 = new ClassNode();
cn1.version = V1_7;
cn1.access = ACC_SUPER;
cn1.name = "xxlc/StandartIntegerRule";
cn1.superName = "java/lang/Object";
cn1.interfaces.add("xxlc/Parser$Rule");
InnerClassNode icn1 = new InnerClassNode(
"xxlc/Parser$Rule",
"xxlc/Parser",
"Rule",
ACC_PUBLIC + ACC_INTERFACE + ACC_ABSTRACT + ACC_STATIC);
cn1.innerClasses.add(icn1);
// fields
FieldNode fn1 = new FieldNode(
ACC_FINAL + ACC_PRIVATE + ACC_STATIC,
"inRegExFull",
"Ljava/lang/String;",
null,
"[-|+]?((\\p{Digit}+)|(0[xX](\\p{XDigit}+)))[L|l]?");
FieldNode fn2 = new FieldNode(
ACC_FINAL + ACC_PRIVATE + ACC_STATIC,
"ip",
"Ljava/util/regex/Pattern;",
null,
null);
cn1.fields.add(fn1);
cn1.fields.add(fn2);
// methods
MethodNode mn1 = new MethodNode(0,
"<init>", "()V", null, null);
InsnList il1 = mn1.instructions;
il1.add(new VarInsnNode(ALOAD, 0));
il1.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"));
il1.add(new InsnNode(RETURN));
mn1.maxLocals = 1;
mn1.maxStack = 1;
cn1.methods.add(mn1);
MethodNode mn2 = new MethodNode(ACC_PUBLIC,
"condition", "(Lxxlc/Token;Lxxlc/Parser;)Z", null, null);
InsnList il2 = mn2.instructions;
il2.add(new FieldInsnNode(GETSTATIC, "xxlc/StandartIntegerRule", "ip", "Ljava/util/regex/Pattern;"));
il2.add(new VarInsnNode(ALOAD, 1));
il2.add(new FieldInsnNode(GETFIELD, "xxlc/Token", "value", "Ljava/lang/String;"));
il2.add(new MethodInsnNode(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;"));
il2.add(new MethodInsnNode(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z"));
il2.add(new InsnNode(IRETURN));
mn2.maxLocals = 3;
mn2.maxStack = 2;
cn1.methods.add(mn2);
MethodNode mn3 = new MethodNode(ACC_PUBLIC,
"apply", "(Lxxlc/Token;Lxxlc/Parser;)Lxxlc/ast/Literal;", null, null);
InsnList il3 = mn3.instructions;
il3.add(new VarInsnNode(ALOAD, 1));
il3.add(new FieldInsnNode(GETFIELD, "xxlc/Token", "value", "Ljava/lang/String;"));
il3.add(new VarInsnNode(ASTORE, 3));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new LdcInsnNode("L"));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "endsWith", "(Ljava/lang/String;)Z"));
il3.add(new VarInsnNode(ISTORE, 4));
il3.add(new VarInsnNode(ILOAD, 4));
LabelNode l1 = new LabelNode();
il3.add(new JumpInsnNode(IFEQ, l1));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new InsnNode(ICONST_0));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "length", "()I"));
il3.add(new InsnNode(ICONST_1));
il3.add(new InsnNode(ISUB));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;"));
il3.add(new VarInsnNode(ASTORE, 3));
il3.add(l1);
il3.add(new InsnNode(ICONST_0));
il3.add(new VarInsnNode(ISTORE, 5));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new LdcInsnNode("0x"));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "contains", "(Ljava/lang/CharSequence;)Z"));
LabelNode l2 = new LabelNode();
il3.add(new JumpInsnNode(IFEQ, l2));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new LdcInsnNode("0x"));
il3.add(new LdcInsnNode(""));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
il3.add(new VarInsnNode(ASTORE, 3));
il3.add(new InsnNode(ICONST_1));
il3.add(new VarInsnNode(ISTORE, 5));
il3.add(l2);
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new LdcInsnNode("0X"));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "contains", "(Ljava/lang/CharSequence;)Z"));
LabelNode l3 = new LabelNode();
il3.add(new JumpInsnNode(IFEQ, l3));
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new LdcInsnNode("0X"));
il3.add(new LdcInsnNode(""));
il3.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
il3.add(new VarInsnNode(ASTORE, 3));
il3.add(new InsnNode(ICONST_1));
il3.add(new VarInsnNode(ISTORE, 5));
il3.add(l3);
il3.add(new VarInsnNode(ALOAD, 3));
il3.add(new VarInsnNode(ILOAD, 5));
LabelNode l4 = new LabelNode();
il3.add(new JumpInsnNode(IFEQ, l4));
il3.add(new IntInsnNode(BIPUSH, 16));
LabelNode l5 = new LabelNode();
il3.add(new JumpInsnNode(GOTO, l5));
il3.add(l4);
il3.add(new IntInsnNode(BIPUSH, 10));
il3.add(l5);
il3.add(new MethodInsnNode(INVOKESTATIC, "java/lang/Long", "parseLong", "(Ljava/lang/String;I)J"));
il3.add(new VarInsnNode(LSTORE, 6));
il3.add(new VarInsnNode(LLOAD, 6));
il3.add(new LdcInsnNode(2147483647));
il3.add(new InsnNode(LCMP));
LabelNode l6 = new LabelNode();
il3.add(new JumpInsnNode(IFGT, l6));
il3.add(new VarInsnNode(LLOAD, 6));
il3.add(new LdcInsnNode(-2147483648));
il3.add(new InsnNode(LCMP));
il3.add(new JumpInsnNode(IFLT, l6));
il3.add(new VarInsnNode(ILOAD, 4));
il3.add(new JumpInsnNode(IFNE, l6));
il3.add(new TypeInsnNode(NEW, "xxlc/ast/Literal"));
il3.add(new InsnNode(DUP));
il3.add(new VarInsnNode(ALOAD, 1));
il3.add(new VarInsnNode(LLOAD, 6));
il3.add(new InsnNode(L2I));
il3.add(new MethodInsnNode(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"));
il3.add(new FieldInsnNode(GETSTATIC, "xxlc/EType", "INT_TYPE", "Lxxlc/EType;"));
il3.add(new MethodInsnNode(INVOKESPECIAL, "xxlc/ast/Literal", "<init>", "(Lxxlc/Token;Ljava/lang/Object;Lxxlc/EType;)V"));
LabelNode l7 = new LabelNode();
il3.add(new JumpInsnNode(GOTO, l7));
il3.add(l6);
il3.add(new TypeInsnNode(NEW, "xxlc/ast/Literal"));
il3.add(new InsnNode(DUP));
il3.add(new VarInsnNode(ALOAD, 1));
il3.add(new VarInsnNode(LLOAD, 6));
il3.add(new MethodInsnNode(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"));
il3.add(new FieldInsnNode(GETSTATIC, "xxlc/EType", "LONG_TYPE", "Lxxlc/EType;"));
il3.add(new MethodInsnNode(INVOKESPECIAL, "xxlc/ast/Literal", "<init>", "(Lxxlc/Token;Ljava/lang/Object;Lxxlc/EType;)V"));
il3.add(l7);
il3.add(new VarInsnNode(ASTORE, 8));
il3.add(new VarInsnNode(ALOAD, 8));
il2.add(new InsnNode(ARETURN));
mn3.maxLocals = 9;
mn3.maxStack = 5;
cn1.methods.add(mn3);
MethodNode mn4 = new MethodNode(ACC_STATIC,
"<clinit>", "()V", null, null);
InsnList il4 = mn4.instructions;
il4.add(new LdcInsnNode("[-|+]?((\\p{Digit}+)|(0[xX](\\p{XDigit}+)))[L|l]?"));
il4.add(new MethodInsnNode(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;"));
il4.add(new FieldInsnNode(PUTSTATIC, "xxlc/StandartIntegerRule", "ip", "Ljava/util/regex/Pattern;"));
il4.add(new InsnNode(RETURN));
mn4.maxLocals = 0;
mn4.maxStack = 1;
cn1.methods.add(mn4);
ClassWriter cw1 = new ClassWriter(ClassWriter.COMPUTE_FRAMES+ClassWriter.COMPUTE_MAXS);
cn1.accept(cw1);
byte[] asmBytes1 = cw1.toByteArray();
}
}
ClassGenerationTest.java
(text/x-java-source, 7.9 KB)
import junit.framework.TestCase;
import org.objectweb.asm.*;
import static org.objectweb.asm.Opcodes.*;
public class ClassGenerationTest extends TestCase implements Opcodes {
public void test() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES+ClassWriter.COMPUTE_MAXS);
FieldVisitor fv;
MethodVisitor mv;
cw.visit(V1_7, ACC_SUPER, "xxlc/StandartIntegerRule", null, "java/lang/Object", new String[]{"xxlc/Parser$Rule"});
cw.visitInnerClass("xxlc/Parser$Rule", "xxlc/Parser", "Rule", ACC_PUBLIC + ACC_STATIC + ACC_ABSTRACT + ACC_INTERFACE);
{
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "inRegExFull", "Ljava/lang/String;", null, "[-|+]?((\\p{Digit}+)|(0[xX](\\p{XDigit}+)))[L|l]?");
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "ip", "Ljava/util/regex/Pattern;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(0, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "condition", "(Lxxlc/Token;Lxxlc/Parser;)Z", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "xxlc/StandartIntegerRule", "ip", "Ljava/util/regex/Pattern;");
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(GETFIELD, "xxlc/Token", "value", "Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z");
mv.visitInsn(IRETURN);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "apply", "(Lxxlc/Token;Lxxlc/Parser;)Lxxlc/ast/Literal;", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(GETFIELD, "xxlc/Token", "value", "Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 3);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("L");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "endsWith", "(Ljava/lang/String;)Z");
mv.visitVarInsn(ISTORE, 4);
mv.visitVarInsn(ILOAD, 4);
Label l0 = new Label();
mv.visitJumpInsn(IFEQ, l0);
mv.visitVarInsn(ALOAD, 3);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
mv.visitInsn(ICONST_1);
mv.visitInsn(ISUB);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 3);
mv.visitLabel(l0);
// mv.visitFrame(Opcodes.F_APPEND, 2, new Object[]{"java/lang/String", Opcodes.INTEGER}, 0, null);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 5);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("0x");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "contains", "(Ljava/lang/CharSequence;)Z");
Label l1 = new Label();
mv.visitJumpInsn(IFEQ, l1);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("0x");
mv.visitLdcInsn("");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 3);
mv.visitInsn(ICONST_1);
mv.visitVarInsn(ISTORE, 5);
mv.visitLabel(l1);
// mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{Opcodes.INTEGER}, 0, null);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("0X");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "contains", "(Ljava/lang/CharSequence;)Z");
Label l2 = new Label();
mv.visitJumpInsn(IFEQ, l2);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("0X");
mv.visitLdcInsn("");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 3);
mv.visitInsn(ICONST_1);
mv.visitVarInsn(ISTORE, 5);
mv.visitLabel(l2);
// mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ILOAD, 5);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitIntInsn(BIPUSH, 16);
Label l4 = new Label();
mv.visitJumpInsn(GOTO, l4);
mv.visitLabel(l3);
// mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/String"});
mv.visitIntInsn(BIPUSH, 10);
mv.visitLabel(l4);
// mv.visitFrame(Opcodes.F_FULL, 6, new Object[]{"xxlc/StandartIntegerRule", "xxlc/Token", "xxlc/Parser", "java/lang/String", Opcodes.INTEGER, Opcodes.INTEGER}, 2, new Object[]{"java/lang/String", Opcodes.INTEGER});
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "parseLong", "(Ljava/lang/String;I)J");
mv.visitVarInsn(LSTORE, 6);
mv.visitVarInsn(LLOAD, 6);
mv.visitLdcInsn(new Long(2147483647L));
mv.visitInsn(LCMP);
Label l5 = new Label();
mv.visitJumpInsn(IFGT, l5);
mv.visitVarInsn(LLOAD, 6);
mv.visitLdcInsn(new Long(-2147483648L));
mv.visitInsn(LCMP);
mv.visitJumpInsn(IFLT, l5);
mv.visitVarInsn(ILOAD, 4);
mv.visitJumpInsn(IFNE, l5);
mv.visitTypeInsn(NEW, "xxlc/ast/Literal");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(LLOAD, 6);
mv.visitInsn(L2I);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
mv.visitFieldInsn(GETSTATIC, "xxlc/EType", "INT_TYPE", "Lxxlc/EType;");
mv.visitMethodInsn(INVOKESPECIAL, "xxlc/ast/Literal", "<init>", "(Lxxlc/Token;Ljava/lang/Object;Lxxlc/EType;)V");
Label l6 = new Label();
mv.visitJumpInsn(GOTO, l6);
mv.visitLabel(l5);
// mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{Opcodes.LONG}, 0, null);
mv.visitTypeInsn(NEW, "xxlc/ast/Literal");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(LLOAD, 6);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
mv.visitFieldInsn(GETSTATIC, "xxlc/EType", "LONG_TYPE", "Lxxlc/EType;");
mv.visitMethodInsn(INVOKESPECIAL, "xxlc/ast/Literal", "<init>", "(Lxxlc/Token;Ljava/lang/Object;Lxxlc/EType;)V");
mv.visitLabel(l6);
// mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"xxlc/ast/Literal"});
mv.visitVarInsn(ASTORE, 8);
mv.visitVarInsn(ALOAD, 8);
mv.visitInsn(ARETURN);
mv.visitMaxs(5, 9);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
mv.visitLdcInsn("[-|+]?((\\p{Digit}+)|(0[xX](\\p{XDigit}+)))[L|l]?");
mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;");
mv.visitFieldInsn(PUTSTATIC, "xxlc/StandartIntegerRule", "ip", "Ljava/util/regex/Pattern;");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
cw.visitEnd();
byte[] code = cw.toByteArray();
}
}
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws