changeset 36:40a5bfd84915

Moved type mangling operations into rewriter. Contributed-by: Remi Forax * util/TypeUtil.java (convertDescToInternal): Adapted for array types. * (convertDescToInternals): New method for array of descriptors. * dex/dexlib/DexLibDexReader.java: Removed type mangling. * rewriter/DexRewriter.java: Added type mangling.
author Michael Starzinger <michi@complang.tuwien.ac.at>
date Thu, 17 Mar 2011 21:05:37 +0100
parents a166ad506192
children a14d5c5cd8f2
files src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java src/main/java/org/icedrobot/daneel/util/TypeUtil.java
diffstat 3 files changed, 46 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java	Thu Mar 17 20:50:08 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java	Thu Mar 17 21:05:37 2011 +0100
@@ -97,8 +97,8 @@
     public void accept(DexFileVisitor dv) {
         List<ClassDefItem> classItems = dex.ClassDefsSection.getItems();
         for (ClassDefItem classItem : classItems) {
-            DexClassVisitor cv = dv.visitClass(asInternalName(classItem
-                    .getClassType()));
+            DexClassVisitor cv = dv.visitClass(classItem.getClassType()
+                    .getTypeDescriptor());
             if (cv != null) {
                 accept(classItem, cv);
             }
@@ -133,14 +133,14 @@
         if (interfaceListItem != null) {
             interfaces = new String[interfaceListItem.getTypeCount()];
             for (int i = 0; i < interfaces.length; i++) {
-                interfaces[i] = asInternalName(interfaceListItem
-                        .getTypeIdItem(i));
+                interfaces[i] = interfaceListItem.getTypeIdItem(i)
+                        .getTypeDescriptor();
             }
         }
 
         cv.visit(classItem.getAccessFlags(),
-                asInternalName(classItem.getClassType()),
-                asInternalName(classItem.getSuperclass()), interfaces);
+                classItem.getClassType().getTypeDescriptor(),
+                classItem.getSuperclass().getTypeDescriptor(), interfaces);
 
         StringIdItem sourceFile = classItem.getSourceFile();
         if (sourceFile != null) {
@@ -183,7 +183,7 @@
 
             DexFieldVisitor fv = cv.visitField(field.accessFlags, fieldIdItem
                     .getFieldName().getStringValue(),
-                    asInternalName(fieldIdItem.getFieldType()),
+                    fieldIdItem.getFieldType().getTypeDescriptor(),
                     (constants == null ? null : getConstant(constants[i])));
             if (fv != null) {
                 // visit annotation
@@ -331,8 +331,8 @@
                 vsrcOrDest = i22c.getRegisterA();
                 vref = i22c.getRegisterB();
             }
-            mv.visitInstrField(opcode, vsrcOrDest, vref, asInternalName(field
-                    .getContainingClass()), field.getFieldName()
+            mv.visitInstrField(opcode, vsrcOrDest, vref, field
+                    .getContainingClass().getTypeDescriptor(), field.getFieldName()
                     .getStringValue(), field.getFieldType().getTypeDescriptor());
             break;
         }
@@ -361,7 +361,7 @@
                     | i35c.getRegisterE() << 4 | i35c.getRegisterD();
             mv.visitInstrMethod(opcode, i35c.getRegCount(),
                     i35c.getRegisterA(), vpacked,
-                    asInternalName(methodIdItem.getContainingClass()),
+                    methodIdItem.getContainingClass().getTypeDescriptor(),
                     methodIdItem.getMethodName().getStringValue(), desc);
             break;
         }
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Thu Mar 17 20:50:08 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Thu Mar 17 21:05:37 2011 +0100
@@ -89,6 +89,10 @@
     @Override
     public void visit(int access, String name, String supername,
             String[] interfaces) {
+        name = TypeUtil.convertDescToInternal(name);
+        supername = TypeUtil.convertDescToInternal(supername);
+        interfaces = (interfaces == null) ? null : TypeUtil
+                .convertDescToInternals(interfaces);
         cv.visit(V1_6, access, name, null, supername, interfaces);
     }
 
@@ -201,6 +205,7 @@
         @Override
         public void visitInstrField(Opcode opcode, int vsrcOrDest, int vref,
                 String owner, String name, String desc) {
+            owner = TypeUtil.convertDescToInternal(owner);
             if (opcode.compareTo(Opcode.IGET) >= 0
                     && opcode.compareTo(Opcode.IGET_SHORT) <= 0) {
                 mv.visitVarInsn(ALOAD, vref);
@@ -244,6 +249,7 @@
         @Override
         public void visitInstrMethod(Opcode opcode, int num, int va,
                 int vpacked, String owner, String name, String desc) {
+            owner = TypeUtil.convertDescToInternal(owner);
             switch (opcode) {
             case INVOKE_VIRTUAL:
             case INVOKE_STATIC:
--- a/src/main/java/org/icedrobot/daneel/util/TypeUtil.java	Thu Mar 17 20:50:08 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/util/TypeUtil.java	Thu Mar 17 21:05:37 2011 +0100
@@ -37,8 +37,6 @@
 
 package org.icedrobot.daneel.util;
 
-import org.icedrobot.daneel.DaneelException;
-
 /**
  * Utility methods for mangling names and type descriptors. For specifications
  * about the differences between each form of representation you should visit
@@ -74,15 +72,39 @@
     }
 
     /**
-     * Converts a type descriptor for a class type into a fully qualified
-     * internal class name.
+     * Converts a type descriptor into a fully qualified internal class name.
      * 
-     * @param desc The given type descriptor for a class type.
+     * @param desc The given type descriptor.
      * @return The internal class name for the given type descriptor.
      */
     public static String convertDescToInternal(String desc) {
-        if (!desc.startsWith("L") || !desc.endsWith(";"))
-            throw new DaneelException("Descriptor is not a class type.");
-        return desc.substring(1, desc.length() - 1);
+        int index = 0;
+        while (desc.charAt(index) == '[') {
+            index++;
+        }
+        int length = desc.length();
+        if (desc.charAt(index) != 'L' || desc.charAt(length - 1) != ';')
+            throw new IllegalArgumentException(
+                    "Descriptor is not a class type: " + desc);
+        if (index != 0)
+            return desc.substring(0, index).concat(
+                    desc.substring(index + 1, length - 1));
+        return desc.substring(index + 1, length - 1);
+    }
+
+    /**
+     * Converts an array of type descriptors into an array of a fully qualified
+     * internal class name.
+     * 
+     * @param descs The given array of type descriptors.
+     * @return The internal class names for the given type descriptors.
+     */
+    public static String[] convertDescToInternals(String[] descs) {
+        int length = descs.length;
+        String[] internalNames = new String[length];
+        for (int i = 0; i < length; i++) {
+            internalNames[i] = TypeUtil.convertDescToInternal(descs[i]);
+        }
+        return internalNames;
     }
 }