Separate labels for control-flow and stack-map references
When creating a simple instrumentation pass I accidentally put code between a label
and the NEW bytecode that follows it. That led to the following error message from
the Java VM verifier:
java.lang.ClassFormatError: StackMapTable format error: bad offset for
Uninitialized in method <method name>
It took me some time to figure out what that meant.
The problem for my instrumentation is that the labels used to indicate stack-map
Uninitialized references to a NEW instruction are not separate from labels used for
control flow. Therefore, when I insert code after a label used for control-flow (in
my case a default case in a switch) I have to be careful that this doesn't separate
a NEW bytecode from the label used to identify it.
control-flow label:
NEW
->
control-flow label:
ldc <num>
invokestatic <method>
NEW
If new labels were always created instead of using existing control-flow labels to
reference NEW bytecodes in stack map entries I wouldn't have run into this problem.
My instrumentation would have inserted code between the control-flow label and the
NEW bytecode label.
control-flow label:
new label:
NEW
->
control-flow label:
ldc <num>
invokestatic <method>
new label:
NEW
Such a separation between labels used for control-flow and labels used to identify
NEW bytecodes for stack maps seems useful.