1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.cf;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.util.ExceptionWithContext;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.ConcreteMethod;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.Ropper;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.direct.DirectClassFile;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Field;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.FieldList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Method;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.MethodList;
273dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornsteinimport com.android.dx.dex.DexOptions;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.DalvCode;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.PositionList;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.RopTranslator;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.file.ClassDefItem;
324c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.dex.file.DexFile;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.file.EncodedField;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.file.EncodedMethod;
354c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.dex.file.FieldIdsSection;
364c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.dex.file.MethodIdsSection;
374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.dex.file.TypeIdsSection;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.Annotations;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.AnnotationsList;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags;
41fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.DexTranslationAdvice;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.LocalVariableExtractor;
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.LocalVariableInfo;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RopMethod;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.TranslationAdvice;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
474c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.rop.cst.ConstantPool;
484c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.rop.cst.CstBaseMethodRef;
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstBoolean;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstByte;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstChar;
524c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.rop.cst.CstEnumRef;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstFieldRef;
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstInteger;
554c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarcheimport com.android.dx.rop.cst.CstInterfaceMethodRef;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstShort;
58333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.TypedConstant;
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.Optimizer;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Static method that turns {@code byte[]}s containing Java
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classfiles into {@link ClassDefItem} instances.
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class CfTranslator {
7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** set to {@code true} to enable development-time debugging code */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final boolean DEBUG = false;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This class is uninstantiable.
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CfTranslator() {
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // This space intentionally left blank.
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Takes a {@code byte[]}, interprets it as a Java classfile, and
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * translates it into a {@link ClassDefItem}.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} contents of the file
873dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param cfOptions options for class translation
883dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param dexOptions options for dex output
8999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the translated class
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
914c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    public static ClassDefItem translate(DirectClassFile cf, byte[] bytes,
924c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            CfOptions cfOptions, DexOptions dexOptions, DexFile dexFile) {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
944c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            return translate0(cf, bytes, cfOptions, dexOptions, dexFile);
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (RuntimeException ex) {
964c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            String msg = "...while processing " + cf.getFilePath();
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw ExceptionWithContext.withContext(ex, msg);
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Performs the main act of translation. This method is separated
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * from {@link #translate} just to keep things a bit simpler in
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * terms of exception handling.
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
10699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} contents of the file
1093dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param cfOptions options for class translation
1103dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param dexOptions options for dex output
11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the translated class
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1134c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    private static ClassDefItem translate0(DirectClassFile cf, byte[] bytes,
1144c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            CfOptions cfOptions, DexOptions dexOptions, DexFile dexFile) {
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1163dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein        OptimizerOptions.loadOptimizeLists(cfOptions.optimizeListFile,
1173dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                cfOptions.dontOptimizeListFile);
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Build up a class to output.
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstType thisClass = cf.getThisClass();
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int classAccessFlags = cf.getAccessFlags() & ~AccessFlags.ACC_SUPER;
123333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson        CstString sourceFile = (cfOptions.positionInfo == PositionList.NONE) ? null :
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cf.getSourceFile();
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassDefItem out =
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new ClassDefItem(thisClass, classAccessFlags,
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    cf.getSuperclass(), cf.getInterfaces(), sourceFile);
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Annotations classAnnotations =
1303dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein            AttributeTranslator.getClassAnnotations(cf, cfOptions);
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classAnnotations.size() != 0) {
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.setClassAnnotations(classAnnotations);
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1354c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        FieldIdsSection fieldIdsSection = dexFile.getFieldIds();
1364c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        MethodIdsSection methodIdsSection = dexFile.getMethodIds();
1374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        TypeIdsSection typeIdsSection = dexFile.getTypeIds();
1384c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        processFields(cf, out, fieldIdsSection);
1394c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        processMethods(cf, cfOptions, dexOptions, out, methodIdsSection);
1404c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche
1414c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        // intern constant pool method, field and type references
1424c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        ConstantPool constantPool = cf.getConstantPool();
1434c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        int constantPoolSize = constantPool.size();
1444c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche
1454c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        synchronized (dexFile) {
1464c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            for (int i = 0; i < constantPoolSize; i++) {
1474c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                Constant constant = constantPool.getOrNull(i);
1484c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                if (constant instanceof CstMethodRef) {
1494c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    methodIdsSection.intern((CstBaseMethodRef) constant);
1504c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                } else if (constant instanceof CstInterfaceMethodRef) {
1514c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    methodIdsSection.intern(((CstInterfaceMethodRef) constant).toMethodRef());
1524c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                } else if (constant instanceof CstFieldRef) {
1534c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    fieldIdsSection.intern((CstFieldRef) constant);
1544c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                } else if (constant instanceof CstEnumRef) {
1554c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    fieldIdsSection.intern(((CstEnumRef) constant).getFieldRef());
1564c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                } else if (constant instanceof CstType) {
1574c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    typeIdsSection.intern((CstType) constant);
1584c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                }
1594c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            }
1604c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return out;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the fields of the given class.
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
16899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param cf {@code non-null;} class being translated
16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} output class
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1714c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    private static void processFields(
1724c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            DirectClassFile cf, ClassDefItem out, FieldIdsSection fieldIdsSection) {
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstType thisClass = cf.getThisClass();
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FieldList fields = cf.getFields();
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = fields.size();
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Field one = fields.get(i);
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstFieldRef field = new CstFieldRef(thisClass, one.getNat());
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int accessFlags = one.getAccessFlags();
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (AccessFlags.isStatic(accessFlags)) {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    TypedConstant constVal = one.getConstantValue();
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    EncodedField fi = new EncodedField(field, accessFlags);
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (constVal != null) {
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        constVal = coerceConstant(constVal, field.getType());
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addStaticField(fi, constVal);
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    EncodedField fi = new EncodedField(field, accessFlags);
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addInstanceField(fi);
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
195de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                Annotations annotations =
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    AttributeTranslator.getAnnotations(one.getAttributes());
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (annotations.size() != 0) {
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addFieldAnnotations(field, annotations);
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
2004c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                synchronized (fieldIdsSection) {
2014c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                    fieldIdsSection.intern(field);
2024c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                }
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch (RuntimeException ex) {
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String msg = "...while processing " + one.getName().toHuman() +
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " " + one.getDescriptor().toHuman();
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw ExceptionWithContext.withContext(ex, msg);
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper for {@link #processFields}, which translates constants into
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * more specific types if necessary.
214de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
21599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param constant {@code non-null;} the constant in question
21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param type {@code non-null;} the desired type
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static TypedConstant coerceConstant(TypedConstant constant,
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Type type) {
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Type constantType = constant.getType();
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (constantType.equals(type)) {
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return constant;
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (type.getBasicType()) {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Type.BT_BOOLEAN: {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return CstBoolean.make(((CstInteger) constant).getValue());
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Type.BT_BYTE: {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return CstByte.make(((CstInteger) constant).getValue());
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Type.BT_CHAR: {
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return CstChar.make(((CstInteger) constant).getValue());
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Type.BT_SHORT: {
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return CstShort.make(((CstInteger) constant).getValue());
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: {
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new UnsupportedOperationException("can't coerce " +
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        constant + " to " + type);
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the methods of the given class.
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
24999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param cf {@code non-null;} class being translated
2503dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param cfOptions {@code non-null;} options for class translation
2513dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein     * @param dexOptions {@code non-null;} options for dex output
25299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} output class
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2543dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein    private static void processMethods(DirectClassFile cf, CfOptions cfOptions,
2554c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche            DexOptions dexOptions, ClassDefItem out, MethodIdsSection methodIds) {
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstType thisClass = cf.getThisClass();
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        MethodList methods = cf.getMethods();
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = methods.size();
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Method one = methods.get(i);
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int accessFlags = one.getAccessFlags();
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean isStatic = AccessFlags.isStatic(accessFlags);
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean isPrivate = AccessFlags.isPrivate(accessFlags);
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean isNative = AccessFlags.isNative(accessFlags);
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean isAbstract = AccessFlags.isAbstract(accessFlags);
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean isConstructor = meth.isInstanceInit() ||
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    meth.isClassInit();
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                DalvCode code;
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (isNative || isAbstract) {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // There's no code for native or abstract methods.
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    code = null;
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ConcreteMethod concrete =
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        new ConcreteMethod(one, cf,
2793dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                                (cfOptions.positionInfo != PositionList.NONE),
2803dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                                cfOptions.localInfo);
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    TranslationAdvice advice;
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    advice = DexTranslationAdvice.THE_ONE;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RopMethod rmeth = Ropper.convert(concrete, advice);
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RopMethod nonOptRmeth = null;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    int paramSize;
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    paramSize = meth.getParameterWordCount(isStatic);
291de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
292de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                    String canonicalName
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            = thisClass.getClassType().getDescriptor()
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                + "." + one.getName().getString();
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2963dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                    if (cfOptions.optimize &&
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            OptimizerOptions.shouldOptimize(canonicalName)) {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (DEBUG) {
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            System.err.println("Optimizing " + canonicalName);
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        nonOptRmeth = rmeth;
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        rmeth = Optimizer.optimize(rmeth,
3043dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                                paramSize, isStatic, cfOptions.localInfo, advice);
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (DEBUG) {
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            OptimizerOptions.compareOptimizerStep(nonOptRmeth,
3083dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                                    paramSize, isStatic, cfOptions, advice, rmeth);
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3113dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                        if (cfOptions.statistics) {
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            CodeStatistics.updateRopStatistics(
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    nonOptRmeth, rmeth);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LocalVariableInfo locals = null;
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3193dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                    if (cfOptions.localInfo) {
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        locals = LocalVariableExtractor.extract(rmeth);
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3233dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                    code = RopTranslator.translate(rmeth, cfOptions.positionInfo,
3243dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                            locals, paramSize, dexOptions);
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3263dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                    if (cfOptions.statistics && nonOptRmeth != null) {
3273dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                        updateDexStatistics(cfOptions, dexOptions, rmeth, nonOptRmeth, locals,
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                paramSize, concrete.getCode().size());
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Preserve the synchronized flag as its "declared" variant...
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (AccessFlags.isSynchronized(accessFlags)) {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * ...but only native methods are actually allowed to be
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * synchronized.
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (!isNative) {
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
344de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (isConstructor) {
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeList exceptions = AttributeTranslator.getExceptions(one);
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EncodedMethod mi =
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    new EncodedMethod(meth, accessFlags, code, exceptions);
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (meth.isInstanceInit() || meth.isClassInit() ||
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    isStatic || isPrivate) {
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addDirectMethod(mi);
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addVirtualMethod(mi);
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
360de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                Annotations annotations =
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    AttributeTranslator.getMethodAnnotations(one);
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (annotations.size() != 0) {
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addMethodAnnotations(meth, annotations);
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
366de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                AnnotationsList list =
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    AttributeTranslator.getParameterAnnotations(one);
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (list.size() != 0) {
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    out.addParameterAnnotations(meth, list);
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
3714c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                synchronized (methodIds) {
3724c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                  methodIds.intern(meth);
3734c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche                }
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch (RuntimeException ex) {
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String msg = "...while processing " + one.getName().toHuman() +
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " " + one.getDescriptor().toHuman();
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw ExceptionWithContext.withContext(ex, msg);
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper that updates the dex statistics.
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
3853dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein    private static void updateDexStatistics(CfOptions cfOptions, DexOptions dexOptions,
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RopMethod optRmeth, RopMethod nonOptRmeth,
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LocalVariableInfo locals, int paramSize, int originalByteCount) {
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Run rop->dex again on optimized vs. non-optimized method to
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * collect statistics. We have to totally convert both ways,
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * since converting the "real" method getting added to the
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * file would corrupt it (by messing with its constant pool
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * indices).
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DalvCode optCode = RopTranslator.translate(optRmeth,
3973dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                cfOptions.positionInfo, locals, paramSize, dexOptions);
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DalvCode nonOptCode = RopTranslator.translate(nonOptRmeth,
3993dfda9ad1964510e4a7948a240b30cd710e86341Dan Bornstein                cfOptions.positionInfo, locals, paramSize, dexOptions);
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Fake out the indices, so code.getInsns() can work well enough
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * for the current purpose.
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
406de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        DalvCode.AssignIndicesCallback callback =
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new DalvCode.AssignIndicesCallback() {
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                public int getIndex(Constant cst) {
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Everything is at index 0!
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return 0;
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            };
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        optCode.assignIndices(callback);
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        nonOptCode.assignIndices(callback);
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CodeStatistics.updateDexStatistics(nonOptCode, optCode);
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CodeStatistics.updateOriginalByteCount(originalByteCount);
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
421