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