use of com.taobao.android.dx.rop.type.TypeList in project atlas by alibaba.
the class CfTranslator method processMethods.
/**
* Processes the methods of the given class.
*
* @param cf {@code non-null;} class being translated
* @param cfOptions {@code non-null;} options for class translation
* @param dexOptions {@code non-null;} options for dex output
* @param out {@code non-null;} output class
* @param dexFile {@code non-null;} dex output
*/
private static void processMethods(DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, OptimizerOptions optimizerOptions, ClassDefItem out, DexFile dexFile) {
CstType thisClass = cf.getThisClass();
MethodList methods = cf.getMethods();
int sz = methods.size();
for (int i = 0; i < sz; i++) {
Method one = methods.get(i);
try {
CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
int accessFlags = one.getAccessFlags();
boolean isStatic = AccessFlags.isStatic(accessFlags);
boolean isPrivate = AccessFlags.isPrivate(accessFlags);
boolean isNative = AccessFlags.isNative(accessFlags);
boolean isAbstract = AccessFlags.isAbstract(accessFlags);
boolean isConstructor = meth.isInstanceInit() || meth.isClassInit();
DalvCode code;
if (isNative || isAbstract) {
// There's no code for native or abstract methods.
code = null;
} else {
ConcreteMethod concrete = new ConcreteMethod(one, cf, (cfOptions.positionInfo != PositionList.NONE), cfOptions.localInfo);
TranslationAdvice advice;
advice = DexTranslationAdvice.THE_ONE;
RopMethod rmeth = Ropper.convert(concrete, advice, methods);
RopMethod nonOptRmeth = null;
int paramSize;
paramSize = meth.getParameterWordCount(isStatic);
String canonicalName = thisClass.getClassType().getDescriptor() + "." + one.getName().getString();
if (cfOptions.optimize && optimizerOptions.shouldOptimize(canonicalName)) {
if (DEBUG) {
System.err.println("Optimizing " + canonicalName);
}
nonOptRmeth = rmeth;
rmeth = new Optimizer().optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
if (DEBUG) {
OptimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
}
if (cfOptions.statistics) {
cfOptions.codeStatistics.updateRopStatistics(nonOptRmeth, rmeth);
}
}
LocalVariableInfo locals = null;
if (cfOptions.localInfo) {
locals = LocalVariableExtractor.extract(rmeth);
}
code = RopTranslator.translate(rmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
if (cfOptions.statistics && nonOptRmeth != null) {
updateDexStatistics(cfOptions, dexOptions, rmeth, nonOptRmeth, locals, paramSize, concrete.getCode().size());
}
}
// Preserve the synchronized flag as its "declared" variant...
if (AccessFlags.isSynchronized(accessFlags)) {
accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
/*
* ...but only native methods are actually allowed to be
* synchronized.
*/
if (!isNative) {
accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
}
}
if (isConstructor) {
accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
}
TypeList exceptions = AttributeTranslator.getExceptions(one);
EncodedMethod mi = new EncodedMethod(meth, accessFlags, code, exceptions);
if (meth.isInstanceInit() || meth.isClassInit() || isStatic || isPrivate) {
out.addDirectMethod(mi);
} else {
out.addVirtualMethod(mi);
}
Annotations annotations = AttributeTranslator.getMethodAnnotations(one);
if (annotations.size() != 0) {
if (list.contains(meth.toString())) {
System.out.println(meth.toString());
} else {
list.add(meth.toString());
}
out.addMethodAnnotations(meth, annotations, dexFile);
}
AnnotationsList list = AttributeTranslator.getParameterAnnotations(one);
if (list.size() != 0) {
out.addParameterAnnotations(meth, list, dexFile);
}
dexFile.getMethodIds().intern(meth);
} catch (RuntimeException ex) {
String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
throw ExceptionWithContext.withContext(ex, msg);
}
}
}
use of com.taobao.android.dx.rop.type.TypeList in project atlas by alibaba.
the class AttributeTranslator method getMethodAnnotations.
/**
* Gets the annotations out of a given method, similar to {@link
* #getAnnotations}, also including an annotation for the translation
* of the method-specific attribute {@code Exceptions}.
*
* @param method {@code non-null;} the method in question
* @return {@code non-null;} the set of annotations, which may be empty
*/
public static Annotations getMethodAnnotations(Method method) {
Annotations result = getAnnotations(method.getAttributes());
TypeList exceptions = getExceptions(method);
if (exceptions.size() != 0) {
Annotation throwsAnnotation = AnnotationUtils.makeThrows(exceptions);
result = Annotations.combine(result, throwsAnnotation);
}
return result;
}
use of com.taobao.android.dx.rop.type.TypeList in project atlas by alibaba.
the class BasicBlockList method catchesEqual.
/**
* Compares the catches of two blocks for equality. This includes
* both the catch types and target labels.
*
* @param block1 {@code non-null;} one block to compare
* @param block2 {@code non-null;} the other block to compare
* @return {@code true} if the two blocks' non-primary successors
* are identical
*/
public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
TypeList catches1 = block1.getExceptionHandlerTypes();
TypeList catches2 = block2.getExceptionHandlerTypes();
if (!StdTypeList.equalContents(catches1, catches2)) {
return false;
}
IntList succ1 = block1.getSuccessors();
IntList succ2 = block2.getSuccessors();
// Both are guaranteed to be the same size.
int size = succ1.size();
int primary1 = block1.getPrimarySuccessor();
int primary2 = block2.getPrimarySuccessor();
if (((primary1 == -1) || (primary2 == -1)) && (primary1 != primary2)) {
/*
* For the current purpose, both blocks in question must
* either both have a primary or both not have a primary to
* be considered equal, and it turns out here that that's not
* the case.
*/
return false;
}
for (int i = 0; i < size; i++) {
int label1 = succ1.get(i);
int label2 = succ2.get(i);
if (label1 == primary1) {
/*
* It should be the case that block2's primary is at the
* same index. If not, we consider the blocks unequal for
* the current purpose.
*/
if (label2 != primary2) {
return false;
}
continue;
}
if (label1 != label2) {
return false;
}
}
return true;
}
use of com.taobao.android.dx.rop.type.TypeList in project atlas by alibaba.
the class StdAttributeFactory method exceptions.
/**
* Parses an {@code Exceptions} attribute.
*/
private Attribute exceptions(DirectClassFile cf, int offset, int length, ParseObserver observer) {
if (length < 2) {
return throwSeverelyTruncated();
}
ByteArray bytes = cf.getBytes();
// number_of_exceptions
int count = bytes.getUnsignedShort(offset);
if (observer != null) {
observer.parsed(bytes, offset, 2, "number_of_exceptions: " + Hex.u2(count));
}
offset += 2;
length -= 2;
if (length != (count * 2)) {
throwBadLength((count * 2) + 2);
}
TypeList list = cf.makeTypeList(offset, count);
return new AttExceptions(list);
}
use of com.taobao.android.dx.rop.type.TypeList in project atlas by alibaba.
the class ClassDefItem method writeTo.
/**
* {@inheritDoc}
*/
@Override
public void writeTo(DexFile file, AnnotatedOutput out) {
boolean annotates = out.annotates();
TypeIdsSection typeIds = file.getTypeIds();
int classIdx = typeIds.indexOf(thisClass);
int superIdx = (superclass == null) ? -1 : typeIds.indexOf(superclass);
int interOff = OffsettedItem.getAbsoluteOffsetOr0(interfaces);
int annoOff = annotationsDirectory.isEmpty() ? 0 : annotationsDirectory.getAbsoluteOffset();
int sourceFileIdx = (sourceFile == null) ? -1 : file.getStringIds().indexOf(sourceFile);
int dataOff = classData.isEmpty() ? 0 : classData.getAbsoluteOffset();
int staticValuesOff = OffsettedItem.getAbsoluteOffsetOr0(staticValuesItem);
if (annotates) {
out.annotate(0, indexString() + ' ' + thisClass.toHuman());
out.annotate(4, " class_idx: " + Hex.u4(classIdx));
out.annotate(4, " access_flags: " + AccessFlags.classString(accessFlags));
out.annotate(4, " superclass_idx: " + Hex.u4(superIdx) + " // " + ((superclass == null) ? "<none>" : superclass.toHuman()));
out.annotate(4, " interfaces_off: " + Hex.u4(interOff));
if (interOff != 0) {
TypeList list = interfaces.getList();
int sz = list.size();
for (int i = 0; i < sz; i++) {
out.annotate(0, " " + list.getType(i).toHuman());
}
}
out.annotate(4, " source_file_idx: " + Hex.u4(sourceFileIdx) + " // " + ((sourceFile == null) ? "<none>" : sourceFile.toHuman()));
out.annotate(4, " annotations_off: " + Hex.u4(annoOff));
out.annotate(4, " class_data_off: " + Hex.u4(dataOff));
out.annotate(4, " static_values_off: " + Hex.u4(staticValuesOff));
}
out.writeInt(classIdx);
out.writeInt(accessFlags);
out.writeInt(superIdx);
out.writeInt(interOff);
out.writeInt(sourceFileIdx);
out.writeInt(annoOff);
out.writeInt(dataOff);
out.writeInt(staticValuesOff);
}
Aggregations