下面列出了org.objectweb.asm.Type#getObjectType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Type mapType(Type t) {
switch (t.getSort()) {
case Type.ARRAY:
String s = mapDesc(t.getElementType().getDescriptor());
for (int i = 0; i < t.getDimensions(); ++i) {
s = '[' + s;
}
return Type.getType(s);
case Type.OBJECT:
s = map(t.getInternalName());
return s != null ? Type.getObjectType(s) : t;
case Type.METHOD:
return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
}
return t;
}
@Override
public ClassSignature lookupRelatedClass(String internalName, String internalNameOrig) {
final Type type = Type.getObjectType(internalName);
if (type.getSort() != Type.OBJECT) {
return null;
}
try {
// use binary name, so we need to convert:
return getClassFromClassLoader(type.getClassName());
} catch (ClassNotFoundException cnfe) {
final String origClassName = Type.getObjectType(internalNameOrig).getClassName();
if (options.contains(Option.FAIL_ON_MISSING_CLASSES)) {
throw new RelatedClassLoadingException(cnfe, origClassName);
} else {
logger.warn(String.format(Locale.ENGLISH,
"Class '%s' cannot be loaded (while looking up details about referenced class '%s'). Please fix the classpath!",
type.getClassName(), origClassName
));
return null;
}
} catch (IOException ioe) {
throw new RelatedClassLoadingException(ioe, Type.getObjectType(internalNameOrig).getClassName());
}
}
public void visitEnd() {
if (!methodDone && methodStartLabel != null && constructor) {
methodDone = true;
Label methodEndLabel = super.mark();
super.catchException(methodStartLabel, methodEndLabel, Type
.getType(RuntimeException.class));
super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
LOG_INTERNAL_ALLOC_DEC, VOID_SIGNATURE);
super.visitInsn(Opcodes.ATHROW);
if (exceptions != null) {
for (String ex : exceptions) {
super.catchException(methodStartLabel, methodEndLabel,
Type.getObjectType(ex));
super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
LOG_INTERNAL_ALLOC_DEC, VOID_SIGNATURE);
super.visitInsn(Opcodes.ATHROW);
}
}
}
super.visitEnd();
}
public void visitEnd() {
if (exit) {
done = true;
Label methodEndLabel = super.mark();
super.catchException(methodStartLabel,methodEndLabel,Type.getType(RuntimeException.class));
super.visitMethodInsn(Opcodes.INVOKESTATIC, className, LOG_INTERNAL_STOP_METHOD, LOG_METHOD_SIGNATURE);
super.visitInsn(Opcodes.ATHROW);
if (exceptions!=null) {
for(String ex: exceptions) {
super.catchException(methodStartLabel,methodEndLabel,Type.getObjectType(ex));
super.visitMethodInsn(Opcodes.INVOKESTATIC, className, LOG_INTERNAL_STOP_METHOD, LOG_METHOD_SIGNATURE);
super.visitInsn(Opcodes.ATHROW);
}
}
}
super.visitEnd();
}
@Override
public BasicValue naryOperation(
final AbstractInsnNode insn, final List<? extends BasicValue> values)
throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
for (BasicValue value : values) {
if (!BasicValue.INT_VALUE.equals(value)) {
throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, value);
}
}
} else {
int i = 0;
int j = 0;
if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
if (!isSubTypeOf(values.get(i++), newValue(owner))) {
throw new AnalyzerException(insn, "Method owner", newValue(owner), values.get(0));
}
}
String methodDescriptor =
(opcode == INVOKEDYNAMIC)
? ((InvokeDynamicInsnNode) insn).desc
: ((MethodInsnNode) insn).desc;
Type[] args = Type.getArgumentTypes(methodDescriptor);
while (i < values.size()) {
BasicValue expected = newValue(args[j++]);
BasicValue actual = values.get(i++);
if (!isSubTypeOf(actual, expected)) {
throw new AnalyzerException(insn, "Argument " + j, expected, actual);
}
}
}
return super.naryOperation(insn, values);
}
public static String retrieveCanonicalNameFromClass(File classFile) throws FileNotFoundException, IOException {
ClassNode classNode = new ClassNode();
InputStream classFileInputStream = new FileInputStream(classFile);
try {
ClassReader classReader = new ClassReader(classFileInputStream);
classReader.accept((ClassVisitor) classNode, 0);
} finally {
classFileInputStream.close();
}
Type classType = Type.getObjectType(classNode.name);
return classType.getClassName();
}
/**
* Returns the descriptor of a static method for an instance method with the given receiver and
* description, simply by pre-pending the given descriptor's parameter list with the given
* receiver type.
*/
static String companionDefaultMethodDescriptor(String interfaceName, String desc) {
Type type = Type.getMethodType(desc);
Type[] companionArgs = new Type[type.getArgumentTypes().length + 1];
companionArgs[0] = Type.getObjectType(interfaceName);
System.arraycopy(type.getArgumentTypes(), 0, companionArgs, 1, type.getArgumentTypes().length);
return Type.getMethodDescriptor(type.getReturnType(), companionArgs);
}
/**
* Computes the initial execution stack frame of the given method.
*
* @param owner the internal name of the class to which 'method' belongs.
* @param method the method to be analyzed.
* @return the initial execution stack frame of the 'method'.
*/
private Frame<V> computeInitialFrame(final String owner, final MethodNode method) {
Frame<V> frame = newFrame(method.maxLocals, method.maxStack);
int currentLocal = 0;
boolean isInstanceMethod = (method.access & ACC_STATIC) == 0;
if (isInstanceMethod) {
Type ownerType = Type.getObjectType(owner);
frame.setLocal(
currentLocal, interpreter.newParameterValue(isInstanceMethod, currentLocal, ownerType));
currentLocal++;
}
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
for (Type argumentType : argumentTypes) {
frame.setLocal(
currentLocal,
interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentType));
currentLocal++;
if (argumentType.getSize() == 2) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
}
while (currentLocal < method.maxLocals) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
frame.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(method.desc)));
return frame;
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean itf) {
Type receiver = Type.getObjectType(owner);
if (incompatibleChange != InstantRunVerifierStatus.INCOMPATIBLE) {
if (opcode == Opcodes.INVOKEVIRTUAL && blackListedMethods.containsKey(receiver)) {
for (Method method : blackListedMethods.get(receiver)) {
if (method.getName().equals(name) && method.getDescriptor().equals(desc)) {
incompatibleChange = InstantRunVerifierStatus.INCOMPATIBLE;
}
}
}
}
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
public ASMClassBuilder setObfuscatedClassName(String obfuscatedInternalClassName) {
obfuscatedName =
!Strings.isNullOrEmpty(obfuscatedInternalClassName)
? Type.getObjectType(obfuscatedInternalClassName)
: null;
return this;
}
/**
* Computes the initial execution stack frame of the given method.
*
* @param owner the internal name of the class to which 'method' belongs.
* @param method the method to be analyzed.
* @return the initial execution stack frame of the 'method'.
*/
private Frame<V> computeInitialFrame(final String owner, final MethodNode method) {
Frame<V> frame = newFrame(method.maxLocals, method.maxStack);
int currentLocal = 0;
boolean isInstanceMethod = (method.access & ACC_STATIC) == 0;
if (isInstanceMethod) {
Type ownerType = Type.getObjectType(owner);
frame.setLocal(
currentLocal, interpreter.newParameterValue(isInstanceMethod, currentLocal, ownerType));
currentLocal++;
}
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
for (Type argumentType : argumentTypes) {
frame.setLocal(
currentLocal,
interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentType));
currentLocal++;
if (argumentType.getSize() == 2) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
}
while (currentLocal < method.maxLocals) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
frame.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(method.desc)));
return frame;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
currentType = Type.getObjectType(name);
super.visit(version, access, name, signature, superName, interfaces);
}
public void visitFieldInsn(int opcode, String owner, String fieldName,
String desc) {
if (firstInstruction)
addInc();
if (logPointerChange && opcode == Opcodes.PUTFIELD
&& desc.charAt(0) == 'L') {
if (constructor && !doneSuperConstructor && name.equals(owner)
&& finalFields.contains(fieldName))
delayedFieldPointer.put(fieldName, desc);
else {
// instrument reference changes from
// putfield ...,obj,v' => ...
// to
// dup2 ...,obj,v' => ...,obj,v',obj,v'
// swap ...,obj,v',obj,v' => ...,obj,v',v',obj
// dup ...,obj,v',v',obj => ...,obj,v',v',obj,obj
// getfield ...,obj,v',v',obj,obj => ...,obj,v',v',obj,v
// invokespecial
// pointerchangelog(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
// ...,obj,v',v',obj,v => ...,obj,v'
// putfield ...,obj,v' =>
super.visitInsn(Opcodes.DUP2);
super.visitInsn(Opcodes.SWAP);
super.visitInsn(Opcodes.DUP);
super.visitFieldInsn(Opcodes.GETFIELD, owner, fieldName,
desc);
super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
LOG_INTERNAL_POINTER_CHANGE,
POINTER_CHANGE_SIGNATURE);
}
} else if (logPointerChange && opcode == Opcodes.PUTSTATIC
&& desc.charAt(0) == 'L') {
// if (finalFields.contains(fieldName)) {
// // assume field is initially null
// super.visitInsn(Opcodes.DUP);
// } else {
// instrument reference changes from
// putstatic ...,v' => ...
// to
// dup ...,v' => ...,v',v'
// ldc owner.class ...,v',v' => ...,v',v',k
// getstatic ...,v',v',k => ...,v',v',k,v
// invokespecial
// staticpointerchangelog(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Object;)V
// ...,v',v',k,v => ...,v'
super.visitInsn(Opcodes.DUP);
super.visitLdcInsn(Type.getObjectType(owner));
super.visitFieldInsn(Opcodes.GETSTATIC, owner, fieldName, desc);
super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
LOG_INTERNAL_STATIC_POINTER_CHANGE,
STATIC_POINTER_CHANGE_SIGNATURE);
// }
}
super.visitFieldInsn(opcode, owner, fieldName, desc);
}
@Override
protected Type getSuperClass(final Type t) {
String superClass = repo.getInformation(t.getInternalName()).getSuperClassName();
return superClass == null ? null : Type.getObjectType(superClass);
}
Type getArrayType(int type) {
Type t = getArrayElementType(type);
return Type.getObjectType("[" + t.getDescriptor());
}
public ClassInfo(ClassReader cr) {
this.reader = cr;
this.access = cr.getAccess();
this.type = Type.getObjectType(cr.getClassName());
}
public AbstractValue newOperation(AbstractInsnNode insnNode) {
switch (insnNode.getOpcode()) {
case ACONST_NULL:
return new NullValue(insnNode);
case ICONST_M1:
return ConstantValue.fromInteger(insnNode, -1);
case ICONST_0:
return ConstantValue.fromInteger(insnNode, 0);
case ICONST_1:
return ConstantValue.fromInteger(insnNode, 1);
case ICONST_2:
return ConstantValue.fromInteger(insnNode, 2);
case ICONST_3:
return ConstantValue.fromInteger(insnNode, 3);
case ICONST_4:
return ConstantValue.fromInteger(insnNode, 4);
case ICONST_5:
return ConstantValue.fromInteger(insnNode, 5);
case LCONST_0:
return ConstantValue.fromLong(insnNode, 0);
case LCONST_1:
return ConstantValue.fromLong(insnNode, 1);
case FCONST_0:
return ConstantValue.fromFloat(insnNode, 0);
case FCONST_1:
return ConstantValue.fromFloat(insnNode, 1);
case FCONST_2:
return ConstantValue.fromFloat(insnNode, 2);
case DCONST_0:
return ConstantValue.fromDouble(insnNode, 0);
case DCONST_1:
return ConstantValue.fromDouble(insnNode, 1);
case BIPUSH:
case SIPUSH:
return ConstantValue.fromInteger(insnNode, ((IntInsnNode) insnNode).operand);
case LDC: {
final Object cst = ((LdcInsnNode) insnNode).cst;
if (cst instanceof Integer) {
return ConstantValue.fromInteger(insnNode, (Integer) cst);
} else if (cst instanceof Float) {
return ConstantValue.fromFloat(insnNode, (Float) cst);
} else if (cst instanceof Long) {
return ConstantValue.fromLong(insnNode, (Long) cst);
} else if (cst instanceof Double) {
return ConstantValue.fromDouble(insnNode, (Double) cst);
} else if (cst instanceof String) {
return ConstantValue.fromString(insnNode, (String) cst);
} else if (cst instanceof Type) {
final int sort = ((Type) cst).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY || sort == Type.METHOD) {
return new UnknownValue(insnNode, ((Type) cst));
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
}
case JSR:
throw new UnsupportedOperationException(
"Do not support instruction types JSR - Deprecated in Java 6");
case GETSTATIC: {
final FieldInsnNode f = (FieldInsnNode) insnNode;
return new UnknownValue(insnNode, Type.getType(f.desc));
}
case NEW: {
final TypeInsnNode type = (TypeInsnNode) insnNode;
return new UnknownValue(insnNode, Type.getObjectType(type.desc));
}
default:
throw new IllegalArgumentException("Invalid instruction opcode.");
}
}
/**
* Fills missing index-to-descriptor mappings.
*
* @param labels
* Map of label names to instances.
* @param frames
* Stack-frame analysis data.
*
* @throws AssemblerException
* When multiple types for a single variable have conflicting array-levels.
*/
void visitWithFrames(Frame<AbstractValue>[] frames, Map<String, LabelNode> labels) throws AssemblerException {
// TODO: Reuse variable slots of the same sort if the scope of the variables do not collide
for(Map.Entry<String, Integer> entry : nameToIndex.entrySet()) {
// Skip already visitied
String name = entry.getKey();
String startName = nameToStart.get(name);
String endName = nameToEnd.get(name);
LabelNode start = labels.get(startName);
LabelNode end = labels.get(endName);
if (start == null || end == null)
continue;
// Collect the types stored in this index
Set<Type> types = new HashSet<>();
int index = entry.getValue();
for(Frame<AbstractValue> frame : frames) {
if(frame == null)
continue;
AbstractValue value = frame.getLocal(index);
if(value != null && value.getType() != null)
types.add(value.getType());
}
Iterator<Type> it = types.iterator();
// If we don't have type information, abort for this index
if (!it.hasNext())
continue;
Type lastElementType = it.next();
int arrayLevel = TypeUtil.getArrayDepth(lastElementType);
while (it.hasNext()) {
int lastArrayLevel = TypeUtil.getArrayDepth(lastElementType);
Type type1 = it.next();
if (lastArrayLevel != TypeUtil.getArrayDepth(type1)) {
// TODO: See above TODO about variable index re-use
// - The problem here is this logic assumes no index re-use...
// - This should throw an exception later, but for now
// we just pretend the variable is an object (since everything is)
lastElementType = TypeUtil.OBJECT_TYPE;
break;
//throw new VerifierException("Stored multiple array sizes in same variable slot: " + index);
}
if (lastElementType.equals(type1))
continue;
if(Recaf.getCurrentWorkspace() != null) {
Type lastType = lastElementType;
Type otherType = type1;
if (lastType.getSort() == Type.ARRAY)
lastType = lastType.getElementType();
if (otherType.getSort() == Type.ARRAY)
otherType = otherType.getElementType();
lastElementType = Type.getObjectType(Recaf.getCurrentWorkspace().getHierarchyGraph()
.getCommon(lastType.getInternalName(), otherType.getInternalName()));
}
else break;
}
while (lastElementType.getSort() == Type.ARRAY) {
lastElementType = lastElementType.getElementType();
}
// Save type
StringBuilder arr = new StringBuilder();
for(int i = 0; i < arrayLevel; i++)
arr.append('[');
// TODO: Boolean is saved as int, which is technically correct but not expected by most users
// - Sort is saved as INTEGER because we don't analyze difference between int/bool cases
if (lastElementType.getSort() < Type.ARRAY)
nameToDesc.put(name, arr.toString() + lastElementType.getDescriptor());
else
nameToDesc.put(name, arr.toString() + "L" + lastElementType.getInternalName() + ";");
}
}
/**
* Convert a type's internal name into a {@link TypeElement}
* from the {@code DepanJava} plug-in with the proper id.
*
* @param desc descriptor for a {@link Type}
* @return {@code TypeElement} suitable for addition to a dependency graph
*/
public static TypeElement fromInternalName(String internalName) {
Type type = Type.getObjectType(internalName);
String fullyQualifiedName = getFullyQualifiedTypeName(type);
return new TypeElement(fullyQualifiedName);
}
/**
* Convert a type named as an interface into a {@link InterfaceElement}
* from the {@code DepanJava} plug-in with the proper id.
*
* @param interfaceName name of a supported interface, often an abbreviated
* name of a type
* @return {@code InterfaceElement} suitable for addition to a
* dependency graph
*/
public static InterfaceElement fromInterfaceName(String interfaceName) {
Type type = Type.getObjectType(interfaceName);
String fullyQualifiedName = getFullyQualifiedInterfaceName(type);
return new InterfaceElement(fullyQualifiedName);
}