1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 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.file; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstArray; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstLiteralBits; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Zeroes; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArrayAnnotatedOutput; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Writers; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Writer; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Arrays; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Representation of all the parts of a Dalvik class that are generally 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "inflated" into an in-memory representation at runtime. Instances of 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this class are represented in a compact streamable form in a 4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code dex} file, as opposed to a random-access form. 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class ClassDataItem extends OffsettedItem { 4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} what class this data is for, just for listing generation */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final CstType thisClass; 46de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of static fields */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<EncodedField> staticFields; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of initial values for static fields */ 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final HashMap<EncodedField, Constant> staticValues; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of instance fields */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<EncodedField> instanceFields; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of direct methods */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<EncodedMethod> directMethods; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of virtual methods */ 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<EncodedMethod> virtualMethods; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} static initializer list; set in {@link #addContents} */ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private CstArray staticValuesConstant; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} encoded form, ready for writing to a file; set during 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #place0} 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] encodedForm; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. Its sets of members are initially 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * empty. 74de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param thisClass {@code non-null;} what class this data is for, just 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for listing generation 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ClassDataItem(CstType thisClass) { 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(1, -1); 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisClass == null) { 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("thisClass == null"); 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.thisClass = thisClass; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.staticFields = new ArrayList<EncodedField>(20); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.staticValues = new HashMap<EncodedField, Constant>(40); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.instanceFields = new ArrayList<EncodedField>(20); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.directMethods = new ArrayList<EncodedMethod>(20); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.virtualMethods = new ArrayList<EncodedMethod>(20); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.staticValuesConstant = null; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ItemType itemType() { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ItemType.TYPE_CLASS_DATA_ITEM; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toString(); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether this instance is empty. 108de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} if this instance is empty or 11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false} if at least one element has been added to it 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isEmpty() { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return staticFields.isEmpty() && instanceFields.isEmpty() 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && directMethods.isEmpty() && virtualMethods.isEmpty(); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds a static field. 119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param field {@code non-null;} the field to add 12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param value {@code null-ok;} initial value for the field, if any 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addStaticField(EncodedField field, Constant value) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (field == null) { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("field == null"); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (staticValuesConstant != null) { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnsupportedOperationException( 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "static fields already sorted"); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticFields.add(field); 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticValues.put(field, value); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds an instance field. 139de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param field {@code non-null;} the field to add 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addInstanceField(EncodedField field) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (field == null) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("field == null"); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instanceFields.add(field); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 15199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Adds a direct ({@code static} and/or {@code private}) method. 152de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} the method to add 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addDirectMethod(EncodedMethod method) { 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == null) { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("method == null"); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project directMethods.add(method); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds a virtual method. 165de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} the method to add 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addVirtualMethod(EncodedMethod method) { 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == null) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("method == null"); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project virtualMethods.add(method); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets all the methods in this class. The returned list is not linked 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in any way to the underlying lists contained in this instance, but 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the objects contained in the list are shared. 180de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} list of all methods 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ArrayList<EncodedMethod> getMethods() { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = directMethods.size() + virtualMethods.size(); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<EncodedMethod> result = new ArrayList<EncodedMethod>(sz); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.addAll(directMethods); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.addAll(virtualMethods); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prints out the contents of this instance, in a debugging-friendly 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * way. 197de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 19899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to output to 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param verbose whether to be verbose with the output 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void debugPrint(Writer out, boolean verbose) { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrintWriter pw = Writers.printWriterFor(out); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = staticFields.size(); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pw.println(" sfields[" + i + "]: " + staticFields.get(i)); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sz = instanceFields.size(); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pw.println(" ifields[" + i + "]: " + instanceFields.get(i)); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sz = directMethods.size(); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pw.println(" dmeths[" + i + "]:"); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project directMethods.get(i).debugPrint(pw, verbose); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sz = virtualMethods.size(); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pw.println(" vmeths[" + i + "]:"); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project virtualMethods.get(i).debugPrint(pw, verbose); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addContents(DexFile file) { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!staticFields.isEmpty()) { 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getStaticValuesConstant(); // Force the fields to be sorted. 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (EncodedField field : staticFields) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field.addContents(file); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!instanceFields.isEmpty()) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(instanceFields); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (EncodedField field : instanceFields) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field.addContents(file); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!directMethods.isEmpty()) { 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(directMethods); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (EncodedMethod method : directMethods) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method.addContents(file); 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!virtualMethods.isEmpty()) { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(virtualMethods); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (EncodedMethod method : virtualMethods) { 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method.addContents(file); 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets a {@link CstArray} corresponding to {@link #staticValues} if 26199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * it contains any non-zero non-{@code null} values. 262de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 26399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the corresponding constant or {@code null} if 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * there are no values to encode 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public CstArray getStaticValuesConstant() { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((staticValuesConstant == null) && (staticFields.size() != 0)) { 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project staticValuesConstant = makeStaticValuesConstant(); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return staticValuesConstant; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets a {@link CstArray} corresponding to {@link #staticValues} if 27699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * it contains any non-zero non-{@code null} values. 277de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 27899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the corresponding constant or {@code null} if 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * there are no values to encode 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private CstArray makeStaticValuesConstant() { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // First sort the statics into their final order. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(staticFields); 284de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the size of staticValues minus any trailing zeros/nulls (both 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * nulls per se as well as instances of CstKnownNull). 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = staticFields.size(); 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (size > 0) { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EncodedField field = staticFields.get(size - 1); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Constant cst = staticValues.get(field); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cst instanceof CstLiteralBits) { 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Note: CstKnownNull extends CstLiteralBits. 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (((CstLiteralBits) cst).getLongBits() != 0) { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (cst != null) { 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size--; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size == 0) { 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 308de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // There is something worth encoding, so build up a result. 310de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstArray.List list = new CstArray.List(size); 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < size; i++) { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EncodedField field = staticFields.get(i); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Constant cst = staticValues.get(field); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cst == null) { 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cst = Zeroes.zeroFor(field.getRef().getType()); 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.set(i, cst); 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.setImmutable(); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new CstArray(list); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void place0(Section addedTo, int offset) { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Encode the data and note the size. 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(); 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeOutput(addedTo.getFile(), out); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodedForm = out.toByteArray(); 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setWriteSize(encodedForm.length); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes out the encoded form of this instance. 339de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 34099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code non-null;} file this instance is part of 34199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void encodeOutput(DexFile file, AnnotatedOutput out) { 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean annotates = out.annotates(); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, offsetString() + " class data for " + 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass.toHuman()); 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeSize(file, out, "static_fields", staticFields.size()); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeSize(file, out, "instance_fields", instanceFields.size()); 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeSize(file, out, "direct_methods", directMethods.size()); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeSize(file, out, "virtual_methods", virtualMethods.size()); 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeList(file, out, "static_fields", staticFields); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeList(file, out, "instance_fields", instanceFields); 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeList(file, out, "direct_methods", directMethods); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeList(file, out, "virtual_methods", virtualMethods); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.endAnnotation(); 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 365de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #encodeOutput}, which writes out the given 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * size value, annotating it as well (if annotations are enabled). 369de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 37099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code non-null;} file this instance is part of 37199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 37299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param label {@code non-null;} the label for the purposes of annotation 37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param size {@code >= 0;} the size to write 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static void encodeSize(DexFile file, AnnotatedOutput out, 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String label, int size) { 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out.annotates()) { 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(String.format(" %-21s %08x", label + "_size:", 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size)); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeUnsignedLeb128(size); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #encodeOutput}, which writes out the given 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * list. It also annotates the items (if any and if annotations 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are enabled). 389de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code non-null;} file this instance is part of 39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 39299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param label {@code non-null;} the label for the purposes of annotation 39399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param list {@code non-null;} the list in question 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static void encodeList(DexFile file, AnnotatedOutput out, 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String label, ArrayList<? extends EncodedMember> list) { 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = list.size(); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lastIndex = 0; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size == 0) { 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 403de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out.annotates()) { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " " + label + ":"); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < size; i++) { 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIndex = list.get(i).encode(file, out, lastIndex, i); 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void writeTo0(DexFile file, AnnotatedOutput out) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean annotates = out.annotates(); 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The output is to be annotated, so redo the work previously 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * done by place0(), except this time annotations will actually 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * get emitted. 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodeOutput(file, out); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodedForm); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 430