use of com.android.dx.rop.cst.CstType in project buck by facebook.
the class ValueEncoder method writeAnnotation.
/**
* Writes out the encoded form of the given annotation, that is,
* as an {@code encoded_annotation} and not including a
* {@code value_type} prefix. If the output stream keeps
* (debugging) annotations and {@code topLevel} is
* {@code true}, then this method will write (debugging)
* annotations.
*
* @param annotation {@code non-null;} annotation instance to write
* @param topLevel {@code true} iff the given annotation is the
* top-level annotation or {@code false} if it is a sub-annotation
* of some other annotation
*/
public void writeAnnotation(Annotation annotation, boolean topLevel) {
boolean annotates = topLevel && out.annotates();
StringIdsSection stringIds = file.getStringIds();
TypeIdsSection typeIds = file.getTypeIds();
CstType type = annotation.getType();
int typeIdx = typeIds.indexOf(type);
if (annotates) {
out.annotate(" type_idx: " + Hex.u4(typeIdx) + " // " + type.toHuman());
}
out.writeUleb128(typeIds.indexOf(annotation.getType()));
Collection<NameValuePair> pairs = annotation.getNameValuePairs();
int size = pairs.size();
if (annotates) {
out.annotate(" size: " + Hex.u4(size));
}
out.writeUleb128(size);
int at = 0;
for (NameValuePair pair : pairs) {
CstString name = pair.getName();
int nameIdx = stringIds.indexOf(name);
Constant value = pair.getValue();
if (annotates) {
out.annotate(0, " elements[" + at + "]:");
at++;
out.annotate(" name_idx: " + Hex.u4(nameIdx) + " // " + name.toHuman());
}
out.writeUleb128(nameIdx);
if (annotates) {
out.annotate(" value: " + constantToHuman(value));
}
writeConstant(value);
}
if (annotates) {
out.endAnnotation();
}
}
use of com.android.dx.rop.cst.CstType in project RocooFix by dodola.
the class ClassReferenceListBuilder method addDependencies.
private void addDependencies(ConstantPool pool) {
for (Constant constant : pool.getEntries()) {
if (constant instanceof CstType) {
checkDescriptor(((CstType) constant).getClassType());
} else if (constant instanceof CstFieldRef) {
checkDescriptor(((CstFieldRef) constant).getType());
} else if (constant instanceof CstMethodRef) {
Prototype proto = ((CstMethodRef) constant).getPrototype();
checkDescriptor(proto.getReturnType());
StdTypeList args = proto.getParameterTypes();
for (int i = 0; i < args.size(); i++) {
checkDescriptor(args.get(i));
}
}
}
}
use of com.android.dx.rop.cst.CstType in project RocooFix by dodola.
the class ClassReferenceListBuilder method addClassWithHierachy.
private void addClassWithHierachy(String classBinaryName) {
if (classNames.contains(classBinaryName)) {
return;
}
try {
DirectClassFile classFile = path.getClass(classBinaryName + CLASS_EXTENSION);
classNames.add(classBinaryName);
CstType superClass = classFile.getSuperclass();
if (superClass != null) {
addClassWithHierachy(superClass.getClassType().getClassName());
}
TypeList interfaceList = classFile.getInterfaces();
int interfaceNumber = interfaceList.size();
for (int i = 0; i < interfaceNumber; i++) {
addClassWithHierachy(interfaceList.getType(i).getClassName());
}
} catch (FileNotFoundException e) {
// Ignore: The referenced type is not in the path it must be part of the libraries.
}
}
use of com.android.dx.rop.cst.CstType in project RocooFix by dodola.
the class ClassReferenceListBuilder method addSupperClass.
public void addSupperClass(String name) {
if (name.endsWith(CLASS_EXTENSION)) {
classNames.add(name.substring(0, name.length() - CLASS_EXTENSION.length()));
}
if (name.endsWith(CLASS_EXTENSION)) {
DirectClassFile classFile;
try {
classFile = path.getClass(name);
CstType superClass = classFile.getSuperclass();
if (superClass != null) {
String superClassName = superClass.getClassType().getClassName();
classNames.add(superClassName);
}
} catch (FileNotFoundException e) {
// throw new IOException("Class " + name +
// " is missing form original class path " + path, e);
}
}
}
use of com.android.dx.rop.cst.CstType in project J2ME-Loader by nikita36078.
the class BytecodeArray method parseNewarray.
/**
* Helper to deal with {@code newarray}.
*
* @param offset the offset to the {@code newarray} opcode itself
* @param visitor {@code non-null;} visitor to use
* @return instruction length, in bytes
*/
private int parseNewarray(int offset, Visitor visitor) {
int value = bytes.getUnsignedByte(offset + 1);
CstType type;
switch(value) {
case ByteOps.NEWARRAY_BOOLEAN:
{
type = CstType.BOOLEAN_ARRAY;
break;
}
case ByteOps.NEWARRAY_CHAR:
{
type = CstType.CHAR_ARRAY;
break;
}
case ByteOps.NEWARRAY_DOUBLE:
{
type = CstType.DOUBLE_ARRAY;
break;
}
case ByteOps.NEWARRAY_FLOAT:
{
type = CstType.FLOAT_ARRAY;
break;
}
case ByteOps.NEWARRAY_BYTE:
{
type = CstType.BYTE_ARRAY;
break;
}
case ByteOps.NEWARRAY_SHORT:
{
type = CstType.SHORT_ARRAY;
break;
}
case ByteOps.NEWARRAY_INT:
{
type = CstType.INT_ARRAY;
break;
}
case ByteOps.NEWARRAY_LONG:
{
type = CstType.LONG_ARRAY;
break;
}
default:
{
throw new SimException("bad newarray code " + Hex.u1(value));
}
}
// Revisit the previous bytecode to find out the length of the array
int previousOffset = visitor.getPreviousOffset();
ConstantParserVisitor constantVisitor = new ConstantParserVisitor();
int arrayLength = 0;
/*
* For visitors that don't record the previous offset, -1 will be
* seen here
*/
if (previousOffset >= 0) {
parseInstruction(previousOffset, constantVisitor);
if (constantVisitor.cst instanceof CstInteger && constantVisitor.length + previousOffset == offset) {
arrayLength = constantVisitor.value;
}
}
/*
* Try to match the array initialization idiom. For example, if the
* subsequent code is initializing an int array, we are expecting the
* following pattern repeatedly:
* dup
* push index
* push value
* *astore
*
* where the index value will be incrimented sequentially from 0 up.
*/
int nInit = 0;
int curOffset = offset + 2;
int lastOffset = curOffset;
ArrayList<Constant> initVals = new ArrayList<Constant>();
if (arrayLength != 0) {
while (true) {
boolean punt = false;
// First, check if the next bytecode is dup.
int nextByte = bytes.getUnsignedByte(curOffset++);
if (nextByte != ByteOps.DUP)
break;
/*
* Next, check if the expected array index is pushed to
* the stack.
*/
parseInstruction(curOffset, constantVisitor);
if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstInteger) || constantVisitor.value != nInit)
break;
// Next, fetch the init value and record it.
curOffset += constantVisitor.length;
/*
* Next, find out what kind of constant is pushed onto
* the stack.
*/
parseInstruction(curOffset, constantVisitor);
if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstLiteralBits))
break;
curOffset += constantVisitor.length;
initVals.add(constantVisitor.cst);
nextByte = bytes.getUnsignedByte(curOffset++);
// Now, check if the value is stored to the array properly.
switch(value) {
case ByteOps.NEWARRAY_BYTE:
case ByteOps.NEWARRAY_BOOLEAN:
{
if (nextByte != ByteOps.BASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_CHAR:
{
if (nextByte != ByteOps.CASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_DOUBLE:
{
if (nextByte != ByteOps.DASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_FLOAT:
{
if (nextByte != ByteOps.FASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_SHORT:
{
if (nextByte != ByteOps.SASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_INT:
{
if (nextByte != ByteOps.IASTORE) {
punt = true;
}
break;
}
case ByteOps.NEWARRAY_LONG:
{
if (nextByte != ByteOps.LASTORE) {
punt = true;
}
break;
}
default:
punt = true;
break;
}
if (punt) {
break;
}
lastOffset = curOffset;
nInit++;
}
}
/*
* For singleton arrays it is still more economical to
* generate the aput.
*/
if (nInit < 2 || nInit != arrayLength) {
visitor.visitNewarray(offset, 2, type, null);
return 2;
} else {
visitor.visitNewarray(offset, lastOffset - offset, type, initVals);
return lastOffset - offset;
}
}
Aggregations