Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8364119

Discrepancy in StackMapFrameInfo locals() Output vs. JVMS Append Frame Specification in ClassFile API

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • None
    • core-libs
    • None

      Based on recent testing and inspection, there is a mismatch between the behavior of the ClassFile API's StackMapFrameInfo (particularly for append_frame types per JVMS §4.7.4) and the Java Virtual Machine Specification (JVMS). Specifically, the locals() stack() methods for StackMapFrameInfo on an append frame returns a list of all locals currently allocated (from the beginning of the code block), rather than a list of only the new locals introduced by the append frame as the JVMS prescribes:

      According to JVMS (https://docs.oracle.com/javase/specs/jvms/se24/html/jvms-4.html#jvms-4.7.4):

      append_frame {
          u1 frame_type = APPEND; // 252-254
          u2 offset_delta;
          verification_type_info locals[frame_type - 251]; // size here is frame_type - 251
      }

      Typically, locals() for such a frame should return a list of size k (frame_type - 251).

      Current ClassFile API Behavior:

      - The method returns a list of all currently allocated local variables, not just the new ones added by the append frame, which can be confusing for developers expecting JVMS-compliant sublists.

      - Additionally, the API refers directly to the JVMS (“Models the StackMapTable attribute (JVMS 4.7.4)...”), which might lead to the expectation that the method follows the JVMS format exactly.

      Request for Clarification:

      Clarify in the ClassFile API documentation that :
      List<StackMapFrameInfo.VerificationTypeInfo> locals() returns the complete set of currently active local variables at that frame, and not just the appended locals as specified in JVMS for append_frame. (same for stack() method)
      For example, change the documentation from:

      List<StackMapFrameInfo.VerificationTypeInfo> locals()
      Returns the expanded local variable types.

      to something like:

      List<StackMapFrameInfo.VerificationTypeInfo> locals()
      Returns the complete list of local variables that are currently allocated for this frame.
      (This differs from the JVMS §4.7.4 definition, where the verification_type_info array only includes the changes relative to the previous frame.)

      Optionally, can we have an additional method to retrieve just the "delta" (the locals newly introduced by the append_frame)?


      Reproduction Example:

      HelloWorld.java
      (Please see the attached file.)

      StackMapTable (using javap):

      StackMapTable: number_of_entries = 1
              frame_type = 252 /* append */
                offset_delta = 8
                locals = [ int ]


      StackMapTable (using Class-File API):

      Please refer to StackMapFrameTest.java.

      This code will return 2 as the length of the locals (this (OBJECT), int), which is different from what javap reported.

      Conclusion

      The observed behavior of the ClassFile API’s StackMapFrameInfo.locals() method (and similarly for stack()) deviates from the literal definition in JVMS §4.7.4 for append_frame types, as it returns the complete set of currently allocated local variables instead of only the newly introduced entries for that frame.



        1. StackMapFrameTest.java
          1 kB
        2. HelloWorld.java
          0.3 kB
        3. HelloWorld.class
          0.6 kB

            asotona Adam Sotona
            hnassour Hamza Nassour
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: