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.file; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.util.ExceptionWithContext; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.DalvCode; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.DalvInsnList; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Representation of all the parts needed for concrete methods in a 3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code dex} file. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class CodeItem extends OffsettedItem { 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** file alignment of this class, in bytes */ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int ALIGNMENT = 4; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** write size of the header of this class, in bytes */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int HEADER_SIZE = 16; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} method that this code implements */ 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final CstMethodRef ref; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the bytecode instructions and associated data */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final DalvCode code; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} the catches, if needed; set in {@link #addContents} */ 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private CatchStructs catches; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** whether this instance is for a {@code static} method */ 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean isStatic; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} list of possibly-thrown exceptions; just used in 56de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * generating debugging output (listings) 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final TypeList throwsList; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 6199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the debug info or {@code null} if there is none; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set in {@link #addContents} 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DebugInfoItem debugInfo; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 68de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ref {@code non-null;} method that this code implements 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param code {@code non-null;} the underlying code 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param isStatic whether this instance is for a {@code static} 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param throwsList {@code non-null;} list of possibly-thrown exceptions, 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just used in generating debugging output (listings) 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public CodeItem(CstMethodRef ref, DalvCode code, boolean isStatic, 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeList throwsList) { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(ALIGNMENT, -1); 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ref == null) { 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("ref == null"); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (code == null) { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("code == null"); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (throwsList == null) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("throwsList == null"); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.ref = ref; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.code = code; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.isStatic = isStatic; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.throwsList = throwsList; 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.catches = null; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.debugInfo = null; 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 ItemType itemType() { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ItemType.TYPE_CODE_ITEM; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addContents(DexFile file) { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MixedItemSection byteData = file.getByteData(); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeIdsSection typeIds = file.getTypeIds(); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (code.hasPositions() || code.hasLocals()) { 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugInfo = new DebugInfoItem(code, isStatic, ref); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byteData.add(debugInfo); 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (code.hasAnyCatches()) { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Type type : code.getCatchTypes()) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeIds.intern(type); 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches = new CatchStructs(code); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Constant c : code.getInsnConstants()) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project file.internIfAppropriate(c); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "CodeItem{" + toHuman() + "}"; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ref.toHuman(); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the reference to the method this instance implements. 142de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the method reference 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public CstMethodRef getRef() { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ref; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does a human-friendly dump of this instance. 151de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to dump 15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code non-null;} per-line prefix to use 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param verbose whether to be verbose with the output 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void debugPrint(PrintWriter out, String prefix, boolean verbose) { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(ref.toHuman() + ":"); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DalvInsnList insns = code.getInsns(); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println("regs: " + Hex.u2(getRegistersSize()) + 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "; ins: " + Hex.u2(getInsSize()) + "; outs: " + 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u2(getOutsSize())); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.debugPrint(out, prefix, verbose); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String prefix2 = prefix + " "; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (catches != null) { 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(prefix); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println("catches"); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches.debugPrint(out, prefix2); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugInfo != null) { 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(prefix); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println("debug info"); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugInfo.debugPrint(out, prefix2); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void place0(Section addedTo, int offset) { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final DexFile file = addedTo.getFile(); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int catchesSize; 186de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In order to get the catches and insns, all the code's 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constants need to be assigned indices. 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project code.assignIndices(new DalvCode.AssignIndicesCallback() { 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getIndex(Constant cst) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IndexedItem item = file.findItemOrNull(cst); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (item == null) { 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return item.getIndex(); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (catches != null) { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches.encode(file); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchesSize = catches.writeSize(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchesSize = 0; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The write size includes the header, two bytes per code 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unit, post-code padding if necessary, and however much 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * space the catches need. 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnsSize = code.getInsns().codeSize(); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((insnsSize & 1) != 0) { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insnsSize++; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setWriteSize(HEADER_SIZE + (insnsSize * 2) + catchesSize); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void writeTo0(DexFile file, AnnotatedOutput out) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean annotates = out.annotates(); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regSz = getRegistersSize(); 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outsSz = getOutsSize(); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insSz = getInsSize(); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnsSz = code.getInsns().codeSize(); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean needPadding = (insnsSz & 1) != 0; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int triesSz = (catches == null) ? 0 : catches.triesSize(); 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int debugOff = (debugInfo == null) ? 0 : debugInfo.getAbsoluteOffset(); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, offsetString() + ' ' + ref.toHuman()); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(2, " registers_size: " + Hex.u2(regSz)); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(2, " ins_size: " + Hex.u2(insSz)); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(2, " outs_size: " + Hex.u2(outsSz)); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(2, " tries_size: " + Hex.u2(triesSz)); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " debug_off: " + Hex.u4(debugOff)); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " insns_size: " + Hex.u4(insnsSz)); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This isn't represented directly here, but it is useful to see. 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = throwsList.size(); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size != 0) { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " throws " + StdTypeList.toHuman(throwsList)); 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(regSz); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(insSz); 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(outsSz); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(triesSz); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(debugOff); 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(insnsSz); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writeCodes(file, out); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (catches != null) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (needPadding) { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(2, " padding: 0"); 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(0); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches.writeTo(file, out); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These are pointed at in the code header (above), but it's less 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distracting to expand on them at the bottom of the code. 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugInfo != null) { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " debug info"); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugInfo.annotateTo(file, out, " "); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #writeTo0} which writes out the actual bytecode. 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 28599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code non-null;} file we are part of 28699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void writeCodes(DexFile file, AnnotatedOutput out) { 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DalvInsnList insns = code.getInsns(); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.writeTo(out); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (RuntimeException ex) { 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ExceptionWithContext.withContext(ex, "...while writing " + 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "instructions for " + ref.toHuman()); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the in registers count. 301de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the count 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getInsSize() { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ref.getParameterWordCount(isStatic); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the out registers count. 310de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the count 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getOutsSize() { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return code.getInsns().getOutsSize(); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the total registers count. 319de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the count 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getRegistersSize() { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return code.getInsns().getRegistersSize(); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 326