Skip to content

Add support for 'new' after 'invokespecial <init>' (in bytecode offset order).

The ASM code has always been assuming that an <init> call must be after a NEW instruction (in bytecode offset order). This assumption was based on the last paragraph of https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.2.4, but perhaps wrongly (since an exception to this rule is mentioned). In any case, I realized that this paragraph has been removed in later versions of the spec (https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.10.2.4).

The following adds support for the case of NEW after <init>:

  • support for forward label references in the stack map table (in Label),
  • a new abstract type format for forward label references in uninitialized_item stack map items (in Frame),
  • a corresponding new Symbol type to use in the SymbolTable's type table (in Symbol and SymbolTable).

The new Symbol type needs a reference to a Label. One option would have been to add a new field, of Label type, in Symbol. But this would have increased memory usage for all use cases, whereas this new data is only needed in rare cases. Another option would have been to change an existing String field of Symbol to Object, so that we could store either a String or a Label here, depending on the symbol's type. But this is a kind of hack which was used in previous ASM versions and has been removed since. The option I finally chose is to store a label index in the existing Symbol.value field. For this I had to add a new table of labels in SymbolTable, and a new hash set of labels as well. Since we don't want to depend on java.util, this unfortunately adds quite a bit of code in SymbolTable.

Closes #317995 (closed)

Merge request reports