use of com.android.dx.rop.cst.CstNat in project J2ME-Loader by nikita36078.
the class AttributeTranslator method translateEnclosingMethod.
/**
* Gets the {@code EnclosingMethod} attribute out of a given
* {@link AttributeList}, if any, translating it to an annotation.
* If the class really has an enclosing method, this returns an
* {@code EnclosingMethod} annotation; if not, this returns
* an {@code EnclosingClass} annotation.
*
* @param attribs {@code non-null;} the attributes list to search in
* @return {@code null-ok;} the converted {@code EnclosingMethod} or
* {@code EnclosingClass} annotation, if there was an
* attribute to translate
*/
private static Annotation translateEnclosingMethod(AttributeList attribs) {
AttEnclosingMethod enclosingMethod = (AttEnclosingMethod) attribs.findFirst(AttEnclosingMethod.ATTRIBUTE_NAME);
if (enclosingMethod == null) {
return null;
}
CstType enclosingClass = enclosingMethod.getEnclosingClass();
CstNat nat = enclosingMethod.getMethod();
if (nat == null) {
/*
* Dalvik doesn't use EnclosingMethod annotations unless
* there really is an enclosing method. Anonymous classes
* are unambiguously identified by having an InnerClass
* annotation with an empty name along with an appropriate
* EnclosingClass.
*/
return AnnotationUtils.makeEnclosingClass(enclosingClass);
}
return AnnotationUtils.makeEnclosingMethod(new CstMethodRef(enclosingClass, nat));
}
use of com.android.dx.rop.cst.CstNat in project J2ME-Loader by nikita36078.
the class ConstantPoolParser method parse0.
/**
* Parses the constant for the given index if it hasn't already been
* parsed, also storing it in the constant pool. This will also
* have the side effect of parsing any entries the indicated one
* depends on.
*
* @param idx which constant
* @return {@code non-null;} the parsed constant
*/
private Constant parse0(int idx, BitSet wasUtf8) {
Constant cst = pool.getOrNull(idx);
if (cst != null) {
return cst;
}
int at = offsets[idx];
try {
int tag = bytes.getUnsignedByte(at);
switch(tag) {
case CONSTANT_Utf8:
{
cst = parseUtf8(at);
wasUtf8.set(idx);
break;
}
case CONSTANT_Integer:
{
int value = bytes.getInt(at + 1);
cst = CstInteger.make(value);
break;
}
case CONSTANT_Float:
{
int bits = bytes.getInt(at + 1);
cst = CstFloat.make(bits);
break;
}
case CONSTANT_Long:
{
long value = bytes.getLong(at + 1);
cst = CstLong.make(value);
break;
}
case CONSTANT_Double:
{
long bits = bytes.getLong(at + 1);
cst = CstDouble.make(bits);
break;
}
case CONSTANT_Class:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
cst = new CstType(Type.internClassName(name.getString()));
break;
}
case CONSTANT_String:
{
int stringIndex = bytes.getUnsignedShort(at + 1);
cst = parse0(stringIndex, wasUtf8);
break;
}
case CONSTANT_Fieldref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstFieldRef(type, nat);
break;
}
case CONSTANT_Methodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstMethodRef(type, nat);
break;
}
case CONSTANT_InterfaceMethodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstInterfaceMethodRef(type, nat);
break;
}
case CONSTANT_NameAndType:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
int descriptorIndex = bytes.getUnsignedShort(at + 3);
CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
cst = new CstNat(name, descriptor);
break;
}
case CONSTANT_MethodHandle:
{
int kind = bytes.getUnsignedByte(at + 1);
int constantIndex = bytes.getUnsignedShort(at + 2);
Constant ref;
switch(kind) {
case CstMethodHandle.KIND_GETFIELD:
case CstMethodHandle.KIND_GETSTATIC:
case CstMethodHandle.KIND_PUTFIELD:
case CstMethodHandle.KIND_PUTSTATIC:
CstFieldRef field = (CstFieldRef) parse0(constantIndex, wasUtf8);
ref = field;
break;
case CstMethodHandle.KIND_INVOKEVIRTUAL:
case CstMethodHandle.KIND_NEWINVOKESPECIAL:
CstMethodRef method = (CstMethodRef) parse0(constantIndex, wasUtf8);
ref = method;
break;
case CstMethodHandle.KIND_INVOKESTATIC:
case CstMethodHandle.KIND_INVOKESPECIAL:
ref = parse0(constantIndex, wasUtf8);
if (!(ref instanceof CstMethodRef || ref instanceof CstInterfaceMethodRef)) {
throw new ParseException("Unsupported ref constant type for MethodHandle " + ref.getClass());
}
break;
case CstMethodHandle.KIND_INVOKEINTERFACE:
CstInterfaceMethodRef interfaceMethod = (CstInterfaceMethodRef) parse0(constantIndex, wasUtf8);
ref = interfaceMethod;
break;
default:
throw new ParseException("Unsupported MethodHandle kind: " + kind);
}
cst = CstMethodHandle.make(kind, ref);
break;
}
case CONSTANT_MethodType:
{
int descriptorIndex = bytes.getUnsignedShort(at + 1);
CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
cst = CstMethodType.make(descriptor);
break;
}
case CONSTANT_InvokeDynamic:
{
int bootstrapMethodIndex = bytes.getUnsignedShort(at + 1);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = CstInvokeDynamic.make(bootstrapMethodIndex, nat);
break;
}
default:
{
throw new ParseException("unknown tag byte: " + Hex.u1(tag));
}
}
} catch (ParseException ex) {
ex.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw ex;
} catch (RuntimeException ex) {
ParseException pe = new ParseException(ex);
pe.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw pe;
}
pool.set(idx, cst);
return cst;
}
use of com.android.dx.rop.cst.CstNat in project buck by facebook.
the class Main method dumpMethod.
/**
* Dumps any method with the given name in the given file.
*
* @param dex {@code non-null;} the dex file
* @param fqName {@code non-null;} the fully-qualified name of the
* method(s)
* @param out {@code non-null;} where to dump to
*/
private void dumpMethod(DexFile dex, String fqName, OutputStreamWriter out) {
boolean wildcard = fqName.endsWith("*");
int lastDot = fqName.lastIndexOf('.');
if ((lastDot <= 0) || (lastDot == (fqName.length() - 1))) {
context.err.println("bogus fully-qualified method name: " + fqName);
return;
}
String className = fqName.substring(0, lastDot).replace('.', '/');
String methodName = fqName.substring(lastDot + 1);
ClassDefItem clazz = dex.getClassOrNull(className);
if (clazz == null) {
context.err.println("no such class: " + className);
return;
}
if (wildcard) {
methodName = methodName.substring(0, methodName.length() - 1);
}
ArrayList<EncodedMethod> allMeths = clazz.getMethods();
TreeMap<CstNat, EncodedMethod> meths = new TreeMap<CstNat, EncodedMethod>();
/*
* Figure out which methods to include in the output, and get them
* all sorted, so that the printout code is robust with respect to
* changes in the underlying order.
*/
for (EncodedMethod meth : allMeths) {
String methName = meth.getName().getString();
if ((wildcard && methName.startsWith(methodName)) || (!wildcard && methName.equals(methodName))) {
meths.put(meth.getRef().getNat(), meth);
}
}
if (meths.size() == 0) {
context.err.println("no such method: " + fqName);
return;
}
PrintWriter pw = new PrintWriter(out);
for (EncodedMethod meth : meths.values()) {
// TODO: Better stuff goes here, perhaps.
meth.debugPrint(pw, args.verboseDump);
/*
* The (default) source file is an attribute of the class, but
* it's useful to see it in method dumps.
*/
CstString sourceFile = clazz.getSourceFile();
if (sourceFile != null) {
pw.println(" source file: " + sourceFile.toQuoted());
}
Annotations methodAnnotations = clazz.getMethodAnnotations(meth.getRef());
AnnotationsList parameterAnnotations = clazz.getParameterAnnotations(meth.getRef());
if (methodAnnotations != null) {
pw.println(" method annotations:");
for (Annotation a : methodAnnotations.getAnnotations()) {
pw.println(" " + a);
}
}
if (parameterAnnotations != null) {
pw.println(" parameter annotations:");
int sz = parameterAnnotations.size();
for (int i = 0; i < sz; i++) {
pw.println(" parameter " + i);
Annotations annotations = parameterAnnotations.get(i);
for (Annotation a : annotations.getAnnotations()) {
pw.println(" " + a);
}
}
}
}
pw.flush();
}
use of com.android.dx.rop.cst.CstNat in project buck by facebook.
the class AttributeTranslator method translateEnclosingMethod.
/**
* Gets the {@code EnclosingMethod} attribute out of a given
* {@link AttributeList}, if any, translating it to an annotation.
* If the class really has an enclosing method, this returns an
* {@code EnclosingMethod} annotation; if not, this returns
* an {@code EnclosingClass} annotation.
*
* @param attribs {@code non-null;} the attributes list to search in
* @return {@code null-ok;} the converted {@code EnclosingMethod} or
* {@code EnclosingClass} annotation, if there was an
* attribute to translate
*/
private static Annotation translateEnclosingMethod(AttributeList attribs) {
AttEnclosingMethod enclosingMethod = (AttEnclosingMethod) attribs.findFirst(AttEnclosingMethod.ATTRIBUTE_NAME);
if (enclosingMethod == null) {
return null;
}
CstType enclosingClass = enclosingMethod.getEnclosingClass();
CstNat nat = enclosingMethod.getMethod();
if (nat == null) {
/*
* Dalvik doesn't use EnclosingMethod annotations unless
* there really is an enclosing method. Anonymous classes
* are unambiguously identified by having an InnerClass
* annotation with an empty name along with an appropriate
* EnclosingClass.
*/
return AnnotationUtils.makeEnclosingClass(enclosingClass);
}
return AnnotationUtils.makeEnclosingMethod(new CstMethodRef(enclosingClass, nat));
}
use of com.android.dx.rop.cst.CstNat in project buck by facebook.
the class ConstantPoolParser method parse0.
/**
* Parses the constant for the given index if it hasn't already been
* parsed, also storing it in the constant pool. This will also
* have the side effect of parsing any entries the indicated one
* depends on.
*
* @param idx which constant
* @return {@code non-null;} the parsed constant
*/
private Constant parse0(int idx, BitSet wasUtf8) {
Constant cst = pool.getOrNull(idx);
if (cst != null) {
return cst;
}
int at = offsets[idx];
try {
int tag = bytes.getUnsignedByte(at);
switch(tag) {
case CONSTANT_Utf8:
{
cst = parseUtf8(at);
wasUtf8.set(idx);
break;
}
case CONSTANT_Integer:
{
int value = bytes.getInt(at + 1);
cst = CstInteger.make(value);
break;
}
case CONSTANT_Float:
{
int bits = bytes.getInt(at + 1);
cst = CstFloat.make(bits);
break;
}
case CONSTANT_Long:
{
long value = bytes.getLong(at + 1);
cst = CstLong.make(value);
break;
}
case CONSTANT_Double:
{
long bits = bytes.getLong(at + 1);
cst = CstDouble.make(bits);
break;
}
case CONSTANT_Class:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
cst = new CstType(Type.internClassName(name.getString()));
break;
}
case CONSTANT_String:
{
int stringIndex = bytes.getUnsignedShort(at + 1);
cst = parse0(stringIndex, wasUtf8);
break;
}
case CONSTANT_Fieldref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstFieldRef(type, nat);
break;
}
case CONSTANT_Methodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstMethodRef(type, nat);
break;
}
case CONSTANT_InterfaceMethodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstInterfaceMethodRef(type, nat);
break;
}
case CONSTANT_NameAndType:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
int descriptorIndex = bytes.getUnsignedShort(at + 3);
CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
cst = new CstNat(name, descriptor);
break;
}
case CONSTANT_MethodHandle:
{
throw new ParseException("MethodHandle not supported");
}
case CONSTANT_MethodType:
{
throw new ParseException("MethodType not supported");
}
case CONSTANT_InvokeDynamic:
{
throw new ParseException("InvokeDynamic not supported");
}
default:
{
throw new ParseException("unknown tag byte: " + Hex.u1(tag));
}
}
} catch (ParseException ex) {
ex.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw ex;
} catch (RuntimeException ex) {
ParseException pe = new ParseException(ex);
pe.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw pe;
}
pool.set(idx, cst);
return cst;
}
Aggregations