64
64
* right shift of {@link #DIM_SHIFT}.
65
65
* <li>the KIND field, stored in 4 bits, indicates the kind of VALUE used. These 4 bits can be
66
66
* retrieved with {@link #KIND_MASK} and, without any shift, must be equal to {@link
67
- * #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND}, {@link #LOCAL_KIND}
68
- * or {@link #STACK_KIND}.
67
+ * #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND}, {@link
68
+ * #FORWARD_UNINITIALIZED_KIND},{@link #LOCAL_KIND} or {@link #STACK_KIND}.
69
69
* <li>the FLAGS field, stored in 2 bits, contains up to 2 boolean flags. Currently only one flag
70
70
* is defined, namely {@link #TOP_IF_LONG_OR_DOUBLE_FLAG}.
71
71
* <li>the VALUE field, stored in the remaining 20 bits, contains either
78
78
* <li>the index of a {@link Symbol#TYPE_TAG} {@link Symbol} in the type table of a {@link
79
79
* SymbolTable}, if KIND is equal to {@link #REFERENCE_KIND}.
80
80
* <li>the index of an {@link Symbol#UNINITIALIZED_TYPE_TAG} {@link Symbol} in the type
81
- * table of a SymbolTable, if KIND is equal to {@link #UNINITIALIZED_KIND}.
81
+ * table of a {@link SymbolTable}, if KIND is equal to {@link #UNINITIALIZED_KIND}.
82
+ * <li>the index of a {@link Symbol#FORWARD_UNINITIALIZED_TYPE_TAG} {@link Symbol} in the
83
+ * type table of a {@link SymbolTable}, if KIND is equal to {@link
84
+ * #FORWARD_UNINITIALIZED_KIND}.
82
85
* <li>the index of a local variable in the input stack frame, if KIND is equal to {@link
83
86
* #LOCAL_KIND}.
84
87
* <li>a position relatively to the top of the stack of the input stack frame, if KIND is
88
91
*
89
92
* <p>Output frames can contain abstract types of any kind and with a positive or negative array
90
93
* dimension (and even unassigned types, represented by 0 - which does not correspond to any valid
91
- * abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND or
92
- * UNINITIALIZED_KIND abstract types of positive or {@literal null} array dimension. In all cases
93
- * the type table contains only internal type names (array type descriptors are forbidden - array
94
- * dimensions must be represented through the DIM field).
94
+ * abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND,
95
+ * UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract types of positive or {@literal null}
96
+ * array dimension. In all cases the type table contains only internal type names (array type
97
+ * descriptors are forbidden - array dimensions must be represented through the DIM field).
95
98
*
96
99
* <p>The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE +
97
100
* TOP), for local variables as well as in the operand stack. This is necessary to be able to
@@ -159,8 +162,9 @@ class Frame {
159
162
private static final int CONSTANT_KIND = 1 << KIND_SHIFT ;
160
163
private static final int REFERENCE_KIND = 2 << KIND_SHIFT ;
161
164
private static final int UNINITIALIZED_KIND = 3 << KIND_SHIFT ;
162
- private static final int LOCAL_KIND = 4 << KIND_SHIFT ;
163
- private static final int STACK_KIND = 5 << KIND_SHIFT ;
165
+ private static final int FORWARD_UNINITIALIZED_KIND = 4 << KIND_SHIFT ;
166
+ private static final int LOCAL_KIND = 5 << KIND_SHIFT ;
167
+ private static final int STACK_KIND = 6 << KIND_SHIFT ;
164
168
165
169
// Possible flags for the FLAGS field of an abstract type.
166
170
@@ -220,13 +224,13 @@ class Frame {
220
224
221
225
/**
222
226
* The abstract types that are initialized in the basic block. A constructor invocation on an
223
- * UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace <i>every occurrence</i> of this
224
- * type in the local variables and in the operand stack. This cannot be done during the first step
225
- * of the algorithm since, during this step, the local variables and the operand stack types are
226
- * still abstract. It is therefore necessary to store the abstract types of the constructors which
227
- * are invoked in the basic block, in order to do this replacement during the second step of the
228
- * algorithm, where the frames are fully computed. Note that this array can contain abstract types
229
- * that are relative to the input locals or to the input stack.
227
+ * UNINITIALIZED, FORWARD_UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace <i>every
228
+ * occurrence</i> of this type in the local variables and in the operand stack. This cannot be
229
+ * done during the first step of the algorithm since, during this step, the local variables and
230
+ * the operand stack types are still abstract. It is therefore necessary to store the abstract
231
+ * types of the constructors which are invoked in the basic block, in order to do this replacement
232
+ * during the second step of the algorithm, where the frames are fully computed. Note that this
233
+ * array can contain abstract types that are relative to the input locals or to the input stack.
230
234
*/
231
235
private int [] initializations ;
232
236
@@ -284,8 +288,12 @@ static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Obj
284
288
String descriptor = Type .getObjectType ((String ) type ).getDescriptor ();
285
289
return getAbstractTypeFromDescriptor (symbolTable , descriptor , 0 );
286
290
} else {
287
- return UNINITIALIZED_KIND
288
- | symbolTable .addUninitializedType ("" , ((Label ) type ).bytecodeOffset );
291
+ Label label = (Label ) type ;
292
+ if ((label .flags & Label .FLAG_RESOLVED ) != 0 ) {
293
+ return UNINITIALIZED_KIND | symbolTable .addUninitializedType ("" , label .bytecodeOffset );
294
+ } else {
295
+ return FORWARD_UNINITIALIZED_KIND | symbolTable .addForwardUninitializedType ("" , label );
296
+ }
289
297
}
290
298
}
291
299
@@ -637,12 +645,14 @@ private void addInitializedType(final int abstractType) {
637
645
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
638
646
* @param abstractType an abstract type.
639
647
* @return the REFERENCE_KIND abstract type corresponding to abstractType if it is
640
- * UNINITIALIZED_THIS or an UNINITIALIZED_KIND abstract type for one of the types on which a
641
- * constructor is invoked in the basic block. Otherwise returns abstractType.
648
+ * UNINITIALIZED_THIS or an UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract type for
649
+ * one of the types on which a constructor is invoked in the basic block. Otherwise returns
650
+ * abstractType.
642
651
*/
643
652
private int getInitializedType (final SymbolTable symbolTable , final int abstractType ) {
644
653
if (abstractType == UNINITIALIZED_THIS
645
- || (abstractType & (DIM_MASK | KIND_MASK )) == UNINITIALIZED_KIND ) {
654
+ || (abstractType & (DIM_MASK | KIND_MASK )) == UNINITIALIZED_KIND
655
+ || (abstractType & (DIM_MASK | KIND_MASK )) == FORWARD_UNINITIALIZED_KIND ) {
646
656
for (int i = 0 ; i < initializationCount ; ++i ) {
647
657
int initializedType = initializations [i ];
648
658
int dim = initializedType & DIM_MASK ;
@@ -1253,11 +1263,12 @@ final boolean merge(
1253
1263
*
1254
1264
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
1255
1265
* @param sourceType the abstract type with which the abstract type array element must be merged.
1256
- * This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link
1257
- * #UNINITIALIZED_KIND} kind, with positive or {@literal null} array dimensions.
1266
+ * This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link
1267
+ * #UNINITIALIZED_KIND} or {@link #FORWARD_UNINITIALIZED_KIND} kind, with positive or
1268
+ * {@literal null} array dimensions.
1258
1269
* @param dstTypes an array of abstract types. These types should be of {@link #CONSTANT_KIND},
1259
- * {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or {@literal
1260
- * null} array dimensions.
1270
+ * {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND} or {@link #FORWARD_UNINITIALIZED_KIND}
1271
+ * kind, with positive or {@literal null} array dimensions.
1261
1272
* @param dstIndex the index of the type that must be merged in dstTypes.
1262
1273
* @return {@literal true} if the type array has been modified by this operation.
1263
1274
*/
@@ -1400,7 +1411,8 @@ final void accept(final MethodWriter methodWriter) {
1400
1411
*
1401
1412
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
1402
1413
* @param abstractType an abstract type, restricted to {@link Frame#CONSTANT_KIND}, {@link
1403
- * Frame#REFERENCE_KIND} or {@link Frame#UNINITIALIZED_KIND} types.
1414
+ * Frame#REFERENCE_KIND}, {@link Frame#UNINITIALIZED_KIND} or {@link
1415
+ * Frame#FORWARD_UNINITIALIZED_KIND} types.
1404
1416
* @param output where the abstract type must be put.
1405
1417
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4">JVMS
1406
1418
* 4.7.4</a>
@@ -1422,6 +1434,10 @@ static void putAbstractType(
1422
1434
case UNINITIALIZED_KIND :
1423
1435
output .putByte (ITEM_UNINITIALIZED ).putShort ((int ) symbolTable .getType (typeValue ).data );
1424
1436
break ;
1437
+ case FORWARD_UNINITIALIZED_KIND :
1438
+ output .putByte (ITEM_UNINITIALIZED );
1439
+ symbolTable .getForwardUninitializedLabel (typeValue ).put (output );
1440
+ break ;
1425
1441
default :
1426
1442
throw new AssertionError ();
1427
1443
}
0 commit comments