下面列出了org.objectweb.asm.tree.analysis.BasicValue#getType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public BasicValue merge(BasicValue v, BasicValue w) {
if (!v.equals(w)) {
Type t = v.getType();
Type u = w.getType();
int tsort = t == null ? -1 : t.getSort();
if (tsort == Type.OBJECT || tsort == Type.ARRAY) {
int usort = u == null ? -1 : u.getSort();
if (usort == Type.OBJECT || usort == Type.ARRAY) {
if ("Lnull;".equals(t.getDescriptor())) {
return w;
}
if ("Lnull;".equals(u.getDescriptor())) {
return v;
}
if (isAssignableFrom(t, u)) {
return v;
}
if (isAssignableFrom(u, t)) {
return w;
}
return new BasicValue(classHierarchy.getCommonSuperType(t, u));
}
}
return BasicValue.UNINITIALIZED_VALUE;
}
return v;
}
private static boolean isNull(BasicValue value) {
if (null == value)
return true;
if (!value.isReference())
return false;
Type type = value.getType();
return "Lnull;".equals(type.getDescriptor());
}
@Override
public BasicValue merge(BasicValue v, BasicValue w) {
if (!v.equals(w)) {
Type t = v.getType();
Type u = w.getType();
int tsort = t == null ? -1 : t.getSort();
if (tsort == Type.OBJECT || tsort == Type.ARRAY) {
int usort = u == null ? -1 : u.getSort();
if (usort == Type.OBJECT || usort == Type.ARRAY) {
if ("Lnull;".equals(t.getDescriptor())) {
return w;
}
if ("Lnull;".equals(u.getDescriptor())) {
return v;
}
if (isAssignableFrom(t, u)) {
return v;
}
if (isAssignableFrom(u, t)) {
return w;
}
return new BasicValue(classHierarchy.getCommonSuperType(t, u));
}
}
return BasicValue.UNINITIALIZED_VALUE;
}
return v;
}
private static boolean isNull(BasicValue value) {
if (null == value)
return true;
if (!value.isReference())
return false;
Type type = value.getType();
return "Lnull;".equals(type.getDescriptor());
}
private static boolean isNull(BasicValue value) {
if (null == value)
return true;
if (!value.isReference())
return false;
Type type = value.getType();
return "Lnull;".equals(type.getDescriptor());
}
/**
* Compute sizes required for the storage arrays that will contain the local variables table at this frame.
* @param frame frame to compute for
* @return size required by each storage array
* @throws NullPointerException if any argument is {@code null}
*/
public static StorageSizes computeSizes(Frame<BasicValue> frame) {
Validate.notNull(frame);
// Count size required for each storage array
int intsSize = 0;
int longsSize = 0;
int floatsSize = 0;
int doublesSize = 0;
int objectsSize = 0;
for (int i = 0; i < frame.getLocals(); i++) {
BasicValue basicValue = frame.getLocal(i);
Type type = basicValue.getType();
// If type == null, basicValue is pointing to uninitialized var -- basicValue.toString() will return '.'. This means that this
// slot contains nothing to save. So, skip this slot if we encounter it.
if (type == null) {
continue;
}
// If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
// the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
// point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, thereby
// keeping the same 'Lnull;' type.
if ("Lnull;".equals(type.getDescriptor())) {
continue;
}
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.BYTE:
case Type.SHORT:
case Type.CHAR:
case Type.INT:
intsSize++;
break;
case Type.FLOAT:
floatsSize++;
break;
case Type.LONG:
longsSize++;
break;
case Type.DOUBLE:
doublesSize++;
break;
case Type.ARRAY:
case Type.OBJECT:
objectsSize++;
break;
case Type.METHOD:
case Type.VOID:
default:
throw new IllegalStateException();
}
}
return new StorageSizes(intsSize, longsSize, floatsSize, doublesSize, objectsSize);
}
private void detailLocals(ContinuationPoint cp, MethodNode methodNode, StringBuilder output) {
int intIdx = 0;
int floatIdx = 0;
int doubleIdx = 0;
int longIdx = 0;
int objectIdx = 0;
for (int j = 0; j < cp.getFrame().getLocals(); j++) {
BasicValue local = cp.getFrame().getLocal(j);
if (local.getType() == null) {
// unused in frame, so skip over it
continue;
}
LocalVariableNode lvn = findLocalVariableNodeForInstruction(
methodNode.localVariables,
methodNode.instructions,
cp.getInvokeInstruction(),
j);
String name;
if (lvn == null || lvn.name == null) {
name = "???????";
} else {
name = lvn.name;
}
String accessor;
String type = null;
switch (local.getType().getSort()) {
case Type.INT:
accessor = "varInts[" + intIdx + "]";
type = "int";
intIdx++;
break;
case Type.FLOAT:
accessor = "varFloats[" + floatIdx + "]";
type = "float";
floatIdx++;
break;
case Type.LONG:
accessor = "varLongs[" + longIdx + "]";
type = "long";
longIdx++;
break;
case Type.DOUBLE:
accessor = "varDoubles[" + doubleIdx + "]";
type = "double";
doubleIdx++;
break;
case Type.ARRAY:
case Type.OBJECT:
accessor = "varObjects[" + objectIdx + "]";
type = local.getType().toString();
objectIdx++;
break;
default:
throw new IllegalStateException(local.getType().toString()); // should never happen
}
String line = String.format(Locale.ENGLISH, " %-20s // LVT index is %d / name is %s / type is %s",
accessor,
j,
name,
type);
output.append(line).append('\n');
}
}
/**
* Compute sizes required for the storage arrays that will contain the operand stack at this frame.
* @param frame frame to compute for
* @param offset the position within the operand stack to start calculating
* @param length the number of stack items to include in calculation
* @return size required by each storage array
* @throws NullPointerException if any argument is {@code null}
* @throws IllegalArgumentException if any numeric argument is negative, or if {@code offset + length} is larger than the size of the
* operand stack
*/
public static StorageSizes computeSizes(Frame<BasicValue> frame, int offset, int length) {
Validate.notNull(frame);
Validate.isTrue(offset >= 0);
Validate.isTrue(length >= 0);
Validate.isTrue(offset < frame.getStackSize());
Validate.isTrue(offset + length <= frame.getStackSize());
// Count size required for each storage array
int intsSize = 0;
int longsSize = 0;
int floatsSize = 0;
int doublesSize = 0;
int objectsSize = 0;
for (int i = offset + length - 1; i >= offset; i--) {
BasicValue basicValue = frame.getStack(i);
Type type = basicValue.getType();
// If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
// the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
// point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, thereby
// keeping the same 'Lnull;' type.
if ("Lnull;".equals(type.getDescriptor())) {
continue;
}
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.BYTE:
case Type.SHORT:
case Type.CHAR:
case Type.INT:
intsSize++;
break;
case Type.FLOAT:
floatsSize++;
break;
case Type.LONG:
longsSize++;
break;
case Type.DOUBLE:
doublesSize++;
break;
case Type.ARRAY:
case Type.OBJECT:
objectsSize++;
break;
case Type.METHOD:
case Type.VOID:
default:
throw new IllegalStateException();
}
}
return new StorageSizes(intsSize, longsSize, floatsSize, doublesSize, objectsSize);
}