Uploaded image for project: 'Commons Sandbox'
  1. Commons Sandbox
  2. SANDBOX-318

AsmClassTransformer generates wrong bytecode when constructor invocation exist

VotersWatch issueWatchersLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • None
    • None
    • Javaflow
    • None
    • Sun JDK 1.6.0_16, Windows XP SP3 32bit, ObjectWeb ASM 3.1 and 3.2

    Description

      AsmClassTransformer generates wrong bytecode for the method with Continuation.suspend code when there are constructor invocation instructions ("new SomeClass()") exist in code.

      The actual errors may be different, but all of them are VerifierErrors.
      Here is an example java.lang.Runnable implementation that explains the problem:
      //=========
      package sampleFlow;

      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;

      import org.apache.commons.javaflow.Continuation;

      public class Runner implements Runnable {
      final Object d = new Date();

      public void run()

      { // No problem for fields System.out.println(d); // No problem for primitives for (int i = 0; i < 3; i++) System.out.println(i); // No problem for "externalized" constructor call //final Map<String, String> map = newMap(); // But direct constructor invocation always causes an error final Map<String, String> map = new HashMap<String, String>(); map.put("A", "B"); System.out.println(map); Continuation.suspend(); System.out.println("RESUMED, YES!"); }

      protected Map<String, String> newMap()

      { return new HashMap<String, String>(); }

      }
      //=========

      Please see comments inside method run() – when we have direct invocation "new HashMap<String, String>()" we got a verifier error:

      org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 30: Cannot pop operand off an empty stack.
      at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source)
      at org.apache.commons.javaflow.bytecode.transformation.asm.ContinuationMethodAnalyzer$2.analyze(ContinuationMethodAnalyzer.java:124)
      at org.apache.commons.javaflow.bytecode.transformation.asm.ContinuationMethodAnalyzer.visitEnd(ContinuationMethodAnalyzer.java:135)
      at org.objectweb.asm.ClassReader.accept(Unknown Source)
      at org.objectweb.asm.ClassReader.accept(Unknown Source)

      However, when we replace constructor call with miscellaneous method call, then error goes away.

      Same error may be caused by implicit construction of StringBuilder like for expression "abc" + this.d (d is an instance field in example above)

      The problem is not reproducible with BcelClassTransformer, but reproducible with all and every way continuable classes are instrumented (ant task, ContinuationClassLoader.forceLoadClass, ContinuationClassLoader.loadClass)

      Attachments

        1. Runner.java
          0.8 kB
          Valery Silaev
        2. Test.java
          0.8 kB
          Valery Silaev

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            vsilaev Valery Silaev
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment