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