mentics
mentics

Reputation: 6999

ASM COMPUTE_MAXS not working for basic test case?

At the bottom of the post is the test case. It gives the following error. But I have set new ClassWriter(ClassWriter.COMPUTE_MAXS) so shouldn't it be automatically calculating the max stack and setting it properly?

Exception in thread "main" java.lang.RuntimeException: Error at instruction 2: Insufficient maximum stack size. testMethod()Ljava/lang/Object;
00000  :  :    L0
00001  :  :     LINENUMBER 22 L0
00002  :  :     ACONST_NULL
00003 ? :     ARETURN

Test case:

public static void main(String[] args) {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    CheckClassAdapter cv = new CheckClassAdapter(cw);
    cv.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "path/Cls", null, "java/lang/Object", null);
    {
        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + "path/Cls" + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        MethodVisitor mv = cv
                .visitMethod(ACC_PUBLIC + ACC_STATIC, "testMethod", "()Ljava/lang/Object;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(22, l0);
        mv.visitInsn(ACONST_NULL);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0); // Same error even if this is commented out
        mv.visitEnd();
    }

    byte[] byteArray = cw.toByteArray();
}

Upvotes: 0

Views: 1151

Answers (2)

Cephalopod
Cephalopod

Reputation: 15145

You can configure the CheckClassAdapter to not check the stack size:

CheckClassAdapter cv = new CheckClassAdapter(cw, false);

Upvotes: 0

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

The problem is not in ASM, but in your test. Basically the CheckClassAdapter is seeing bytecode before max stack and var values are calculated.

You can change code to something like this:

  ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
  cw.visit...

  byte[] byteArray = cw.toByteArray();
  ClassReader cr = new ClassReader(byteArray);
  cr.accept(new CheckClassAdapter(new ClassWriter(0)), 0);

Upvotes: 4

Related Questions