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 theSymbolTable
's type table (inSymbol
andSymbolTable
).
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)