Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • asm asm
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 4
    • Issues 4
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • asm
  • asmasm
  • Issues
  • #317827
Closed
Open
Created Apr 30, 2018 by Vootele Rõtov@vooteler

Computing maximum stack size does not work correctly with dead code present

Commenting in the ACONST_NULL and POP instructions should mean that the maximum stack size is at least one, but zero is computed.

Tested with 6.1.2-SNAPSHOT built from source, containing fix to #317823 (closed).

As in #317823 (closed), the issue does not reproduce on 6.0 if methodVisitor.visitMaxs(2, 0); is used.

With mv.visitMaxs(0, 0), the class verification fails with both versions

The test case is inspired by org/eclipse/ui/texteditor/StatusTextEditor from the newest version of Eclipse Oxygen.

import java.util.Arrays;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class TestCase implements Opcodes {

  public static void main(String[] args) {
    byte[] bytes = dumpBytes();
    Class test = new ClassLoader() {
      public Class<?> defineClass(String name, byte[] bytes) {
        return defineClass(name, bytes, 0, bytes.length, null);
      }
    }.defineClass("test.Test", bytes);
    System.out.println(Arrays.toString(test.getDeclaredMethods()));
  }

  public static byte[] dumpBytes() {

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    MethodVisitor methodVisitor;

    cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, "test/Test", null, "java/lang/Object", null);

    {
      methodVisitor = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "test", "()V", null, null);
      methodVisitor.visitCode();
      methodVisitor.visitInsn(RETURN);

      Label label0 = new Label();
      methodVisitor.visitLabel(label0);
      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

      {
        //methodVisitor.visitInsn(ACONST_NULL);
        //methodVisitor.visitInsn(POP);
      }
      methodVisitor.visitInsn(RETURN);

      //methodVisitor.visitMaxs(0, 0);
      methodVisitor.visitMaxs(2, 0);
      methodVisitor.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
  }

}
Assignee
Assign to
Time tracking