Mercurial > hg > icedrobot > daneel
changeset 26:b27ad11dfcf9
Added utility class for name and type mangling.
Reviewed-by: Roman Kennke
* util/TypeUtil.java: New utility class.
* rewriter/DexRewriter.java (visitMethod): Switched to above utility.
* dex/Code.java (acceptInsns): Likewise.
* ClassTransformer.java: Likewise.
author | Michael Starzinger <michi@complang.tuwien.ac.at> |
---|---|
date | Wed, 16 Mar 2011 23:13:52 +0100 |
parents | da537f70dec2 |
children | b0d7f00453ea |
files | src/main/java/org/icedrobot/daneel/ClassTransformer.java src/main/java/org/icedrobot/daneel/dex/Code.java src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java src/main/java/org/icedrobot/daneel/util/TypeUtil.java |
diffstat | 4 files changed, 82 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/ClassTransformer.java Wed Mar 16 22:52:53 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/ClassTransformer.java Wed Mar 16 23:13:52 2011 +0100 @@ -21,6 +21,7 @@ import org.icedrobot.daneel.dex.ClassData; import org.icedrobot.daneel.dex.ClassDef; import org.icedrobot.daneel.dex.FieldId; +import org.icedrobot.daneel.util.TypeUtil; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -52,8 +53,8 @@ private void visitClass() { int access = classDef.getAccessFlags(); - String name = extractName(classDef.getClassName()); - String superName = extractName(classDef.getSuperclass()); + String name = TypeUtil.convertDescToInternal(classDef.getClassName()); + String superName = TypeUtil.convertDescToInternal(classDef.getSuperclass()); writer.visit(Opcodes.V1_6, access, name, null, superName, null); } @@ -71,18 +72,4 @@ writer.visitEnd(); return writer.toByteArray(); } - - /** - * Converts a type descriptor for a class type into an internal class name - * as the ASM library expects it. For details about those type names see the - * "ASM 3.0 User Guide, Section 2.1.2 and 2.1.3". - * - * @param desc The given type descriptor. - * @return The internal class name. - */ - private static String extractName(String desc) { - if (!desc.startsWith("L") || !desc.endsWith(";")) - throw new DaneelException("Descriptor is not a class type."); - return desc.substring(1, desc.length() - 1); - } }
--- a/src/main/java/org/icedrobot/daneel/dex/Code.java Wed Mar 16 22:52:53 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/dex/Code.java Wed Mar 16 23:13:52 2011 +0100 @@ -26,6 +26,7 @@ import java.util.Map; import org.icedrobot.daneel.util.BufferUtil; +import org.icedrobot.daneel.util.TypeUtil; /** * A parser class capable of parsing {@code code_item} structures as part of DEX @@ -496,9 +497,10 @@ // Format 35c B|A|op CCCC G|F|E|D // Syntax: op {vD, vE, vF, vG, vA}, meth@CCCC method = dex.getMethodId(u2); - // XXX Don't use the shorty as type descriptor. + string = TypeUtil.convertProtoToDesc(method.getProtoId() + .getReturnType(), method.getProtoId().getParameters()); v.visitInstrMethod(op, n1, n2, u3, method.getClassName(), - method.getName(), method.getProtoId().getShorty()); + method.getName(), string); break; case INVOKE_VIRTUAL_RANGE: @@ -509,9 +511,10 @@ // Format 3rc AA|op BBBB CCCC // Syntax: op {vCCCC .. vNNNN}, meth@BBBB method = dex.getMethodId(u2); - // XXX Don't use the shorty as type descriptor. + string = TypeUtil.convertProtoToDesc(method.getProtoId() + .getReturnType(), method.getProtoId().getParameters()); v.visitInstrMethod(op, b1, u3, 0, method.getClassName(), - method.getName(), method.getProtoId().getShorty()); + method.getName(), string); break; case CMPL_FLOAT:
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java Wed Mar 16 22:52:53 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java Wed Mar 16 23:13:52 2011 +0100 @@ -12,6 +12,7 @@ import org.icedrobot.daneel.dex.DexMethodVisitor; import org.icedrobot.daneel.dex.Label; import org.icedrobot.daneel.dex.Opcode; +import org.icedrobot.daneel.util.TypeUtil; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; @@ -57,16 +58,8 @@ @Override public DexMethodVisitor visitMethod(int access, String name, String shorty, String returnType, String[] parameterTypes) { - StringBuilder desc = new StringBuilder(); - desc.append('('); - for (String parameterType : parameterTypes) { - desc.append(parameterType); - } - desc.append(')'); - desc.append(returnType); - - MethodVisitor mv = cv.visitMethod(access, name, desc.toString(), null, - null); + String desc = TypeUtil.convertProtoToDesc(returnType, parameterTypes); + MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); if (mv == null) { return null; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/icedrobot/daneel/util/TypeUtil.java Wed Mar 16 23:13:52 2011 +0100 @@ -0,0 +1,69 @@ +/* + * Daneel - Dalvik to Java bytecode compiler + * Copyright (C) 2011 IcedRobot team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General License for more details. + * + * You should have received a copy of the GNU General License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 + * the following material: + * <ul> + * <li>The Java(TM) Virtual Machine Specification, Section 4.2 and 4.3</li> + * <li>DEX - Dalvik Executable Format, Section "String Syntax"</li> + * <li>ASM 3.0 User Guide, Section 2.1.2 and 2.1.3</li> + * </ul> + */ +public class TypeUtil { + + /** + * Converts a method prototype (separate type descriptors for return type + * and parameter types) into a method descriptor. + * + * @param returnType The method's return type as a type descriptor or + * {@code "V"} in case the method returns {@code void}. + * @param parameterTypes The method's parameter types as type descriptors or + * {@code null} in case there are none. + * @return The method descriptor for the given method prototype. + */ + public static String convertProtoToDesc(String returnType, + String[] parameterTypes) { + StringBuilder builder = new StringBuilder(); + builder.append('('); + if (parameterTypes != null) + for (String parameterType : parameterTypes) + builder.append(parameterType); + builder.append(')'); + builder.append(returnType); + return builder.toString(); + } + + /** + * Converts a type descriptor for a class type into a fully qualified + * internal class name. + * + * @param desc The given type descriptor for a class type. + * @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); + } +}