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.rop.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Class that describes all the immutable parts of register-based operations. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Rop { 2899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** minimum {@code BRANCH_*} value */ 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_MIN = 1; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates a non-branching op */ 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_NONE = 1; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates a function/method return */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_RETURN = 2; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates an unconditional goto */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_GOTO = 3; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates a two-way branch */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_IF = 4; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates a switch-style branch */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_SWITCH = 5; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indicates a throw-style branch (both always-throws and may-throw) */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_THROW = 6; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** maximum {@code BRANCH_*} value */ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int BRANCH_MAX = 6; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the opcode; one of the constants in {@link RegOps} */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int opcode; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} result type of this operation; {@link Type#VOID} for 57de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * no-result operations 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Type result; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} types of all the sources of this operation */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final TypeList sources; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of possible types thrown by this operation */ 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final TypeList exceptions; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the branchingness of this op; one of the {@code BRANCH_*} 69de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * constants in this class 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int branchingness; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether this is a function/method call op or similar */ 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean isCallLike; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} nickname, if specified (used for debugging) */ 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final String nickname; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. This method is private. Use one of the 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public constructors. 82de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result type of this operation; {@link 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Type#VOID} for no-result operations 8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param exceptions {@code non-null;} list of possible types thrown by this 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operation 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param branchingness the branchingness of this op; one of the 9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code BRANCH_*} constants 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param isCallLike whether the op is a function/method call or similar 9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param nickname {@code null-ok;} optional nickname (used for debugging) 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, Type result, TypeList sources, 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeList exceptions, int branchingness, boolean isCallLike, 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String nickname) { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("result == null"); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sources == null) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("sources == null"); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (exceptions == null) { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("exceptions == null"); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((branchingness < BRANCH_MIN) || (branchingness > BRANCH_MAX)) { 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus branchingness"); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((exceptions.size() != 0) && (branchingness != BRANCH_THROW)) { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("exceptions / branchingness " + 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "mismatch"); 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.opcode = opcode; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.result = result; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.sources = sources; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.exceptions = exceptions; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.branchingness = branchingness; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.isCallLike = isCallLike; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.nickname = nickname; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 128de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * Constructs an instance. The constructed instance is never a 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call-like op (see {@link #isCallLike}). 130de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result type of this operation; {@link 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Type#VOID} for no-result operations 13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param exceptions {@code non-null;} list of possible types thrown by this 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operation 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param branchingness the branchingness of this op; one of the 13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code BRANCH_*} constants 13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param nickname {@code null-ok;} optional nickname (used for debugging) 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, Type result, TypeList sources, 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeList exceptions, int branchingness, String nickname) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(opcode, result, sources, exceptions, branchingness, false, 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nickname); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 148de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * Constructs a no-exception instance. The constructed instance is never a 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call-like op (see {@link #isCallLike}). 150de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result type of this operation; {@link 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Type#VOID} for no-result operations 15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param branchingness the branchingness of this op; one of the 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code BRANCH_*} constants 15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param nickname {@code null-ok;} optional nickname (used for debugging) 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, Type result, TypeList sources, int branchingness, 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String nickname) { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false, 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nickname); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a non-branching no-exception instance. The 16799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code branchingness} is always {@code BRANCH_NONE}, 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and it is never a call-like op (see {@link #isCallLike}). 169de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 17199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result type of this operation; {@link 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Type#VOID} for no-result operations 17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param nickname {@code null-ok;} optional nickname (used for debugging) 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, Type result, TypeList sources, String nickname) { 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE, 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project false, nickname); 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a non-empty exceptions instance. Its 18399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code branchingness} is always {@code BRANCH_THROW}, 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * but it is never a call-like op (see {@link #isCallLike}). 185de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result type of this operation; {@link 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Type#VOID} for no-result operations 18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 19099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param exceptions {@code non-null;} list of possible types thrown by this 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operation 19299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param nickname {@code null-ok;} optional nickname (used for debugging) 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, Type result, TypeList sources, TypeList exceptions, 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String nickname) { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false, 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nickname); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a non-nicknamed instance with non-empty exceptions, which 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is always a call-like op (see {@link #isCallLike}). Its 20399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code branchingness} is always {@code BRANCH_THROW}. 204de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode; one of the constants in {@link RegOps} 20699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param sources {@code non-null;} types of all the sources of this operation 20799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param exceptions {@code non-null;} list of possible types thrown by this 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * operation 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop(int opcode, TypeList sources, TypeList exceptions) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true, 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project null); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object other) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (this == other) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(other instanceof Rop)) { 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rop rop = (Rop) other; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (opcode == rop.opcode) && 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (branchingness == rop.branchingness) && 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (result == rop.result) && 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.equals(rop.sources) && 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exceptions.equals(rop.exceptions); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int h = (opcode * 31) + branchingness; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project h = (h * 31) + result.hashCode(); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project h = (h * 31) + sources.hashCode(); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project h = (h * 31) + exceptions.hashCode(); 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return h; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(40); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("Rop{"); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(RegOps.opName(opcode)); 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != Type.VOID) { 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(result); 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" <-"); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = sources.size(); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(sources.getType(i)); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isCallLike) { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" call"); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sz = exceptions.size(); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz != 0) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" throws"); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type one = exceptions.getType(i); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (one == Type.THROWABLE) { 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("<any>"); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(exceptions.getType(i)); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (branchingness) { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case BRANCH_NONE: sb.append(" flows"); break; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case BRANCH_RETURN: sb.append(" returns"); break; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case BRANCH_GOTO: sb.append(" gotos"); break; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case BRANCH_IF: sb.append(" ifs"); break; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case BRANCH_SWITCH: sb.append(" switches"); break; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: sb.append(" " + Hex.u1(branchingness)); break; 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('}'); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the opcode. 309de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the opcode 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getOpcode() { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return opcode; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the result type. A return value of {@link Type#VOID} 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * means this operation returns nothing. 319de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 32099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the result spec 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Type getResult() { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the source types. 328de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 32999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the source types 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList getSources() { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the list of exception types that might be thrown. 337de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 33899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the list of exception types 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList getExceptions() { 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return exceptions; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the branchingness of this instance. 346de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the branchingness 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getBranchingness() { 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return branchingness; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this opcode is a function/method call or similar. 355de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 35699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff this opcode is call-like 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isCallLike() { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return isCallLike; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this opcode is commutative (the order of its sources are 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unimportant) or not. All commutative Rops have exactly two sources and 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have no branchiness. 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if rop is commutative 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isCommutative() { 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opcode) { 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case RegOps.AND: 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case RegOps.OR: 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case RegOps.XOR: 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case RegOps.ADD: 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case RegOps.MUL: 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the nickname. If this instance has no nickname, this returns 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the result of calling {@link #toString}. 386de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 38799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the nickname 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getNickname() { 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nickname != null) { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return nickname; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toString(); 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this operation can possibly throw an exception. This 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is just a convenient wrapper for 40099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code getExceptions().size() != 0}. 401de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 40299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff this operation can possibly throw 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final boolean canThrow() { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (exceptions.size() != 0); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 408