Merges the input frame of the given Frame with the input and output frames of this Frame. Returns true if the given frame has been changed by this operation (the input and output frames of this Frame are never changed). @param symbolTable the type table to use to lo
(
final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex)
| 1116 | * @return <tt>true</tt> if the input frame of 'frame' has been changed by this operation. |
| 1117 | */ |
| 1118 | final boolean merge( |
| 1119 | final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex) { |
| 1120 | boolean frameChanged = false; |
| 1121 | |
| 1122 | // Compute the concrete types of the local variables at the end of the basic block corresponding |
| 1123 | // to this frame, by resolving its abstract output types, and merge these concrete types with |
| 1124 | // those of the local variables in the input frame of dstFrame. |
| 1125 | int nLocal = inputLocals.length; |
| 1126 | int nStack = inputStack.length; |
| 1127 | if (dstFrame.inputLocals == null) { |
| 1128 | dstFrame.inputLocals = new int[nLocal]; |
| 1129 | frameChanged = true; |
| 1130 | } |
| 1131 | for (int i = 0; i < nLocal; ++i) { |
| 1132 | int concreteOutputType; |
| 1133 | if (outputLocals != null && i < outputLocals.length) { |
| 1134 | int abstractOutputType = outputLocals[i]; |
| 1135 | if (abstractOutputType == 0) { |
| 1136 | // If the local variable has never been assigned in this basic block, it is equal to its |
| 1137 | // value at the beginning of the block. |
| 1138 | concreteOutputType = inputLocals[i]; |
| 1139 | } else { |
| 1140 | int dim = abstractOutputType & DIM_MASK; |
| 1141 | int kind = abstractOutputType & KIND_MASK; |
| 1142 | if (kind == LOCAL_KIND) { |
| 1143 | // By definition, a LOCAL_KIND type designates the concrete type of a local variable at |
| 1144 | // the beginning of the basic block corresponding to this frame (which is known when |
| 1145 | // this method is called, but was not when the abstract type was computed). |
| 1146 | concreteOutputType = dim + inputLocals[abstractOutputType & VALUE_MASK]; |
| 1147 | if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 |
| 1148 | && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { |
| 1149 | concreteOutputType = TOP; |
| 1150 | } |
| 1151 | } else if (kind == STACK_KIND) { |
| 1152 | // By definition, a STACK_KIND type designates the concrete type of a local variable at |
| 1153 | // the beginning of the basic block corresponding to this frame (which is known when |
| 1154 | // this method is called, but was not when the abstract type was computed). |
| 1155 | concreteOutputType = dim + inputStack[nStack - (abstractOutputType & VALUE_MASK)]; |
| 1156 | if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 |
| 1157 | && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { |
| 1158 | concreteOutputType = TOP; |
| 1159 | } |
| 1160 | } else { |
| 1161 | concreteOutputType = abstractOutputType; |
| 1162 | } |
| 1163 | } |
| 1164 | } else { |
| 1165 | // If the local variable has never been assigned in this basic block, it is equal to its |
| 1166 | // value at the beginning of the block. |
| 1167 | concreteOutputType = inputLocals[i]; |
| 1168 | } |
| 1169 | // concreteOutputType might be an uninitialized type from the input locals or from the input |
| 1170 | // stack. However, if a constructor has been called for this class type in the basic block, |
| 1171 | // then this type is no longer uninitialized at the end of basic block. |
| 1172 | if (initializations != null) { |
| 1173 | concreteOutputType = getInitializedType(symbolTable, concreteOutputType); |
| 1174 | } |
| 1175 | frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputLocals, i); |
no test coverage detected