1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dx.cf.code; 18 19 import com.android.dx.rop.cst.CstType; 20 import com.android.dx.rop.type.Prototype; 21 import com.android.dx.rop.type.Type; 22 import com.android.dx.rop.type.TypeBearer; 23 import com.android.dx.util.Hex; 24 25 /** 26 * {@link Machine} which keeps track of known values but does not do 27 * smart/realistic reference type calculations. 28 */ 29 public class ValueAwareMachine extends BaseMachine { 30 /** 31 * Constructs an instance. 32 * 33 * @param prototype {@code non-null;} the prototype for the associated 34 * method 35 */ 36 public ValueAwareMachine(Prototype prototype) { 37 super(prototype); 38 } 39 40 /** {@inheritDoc} */ 41 public void run(Frame frame, int offset, int opcode) { 42 switch (opcode) { 43 case ByteOps.NOP: 44 case ByteOps.IASTORE: 45 case ByteOps.POP: 46 case ByteOps.POP2: 47 case ByteOps.IFEQ: 48 case ByteOps.IFNE: 49 case ByteOps.IFLT: 50 case ByteOps.IFGE: 51 case ByteOps.IFGT: 52 case ByteOps.IFLE: 53 case ByteOps.IF_ICMPEQ: 54 case ByteOps.IF_ICMPNE: 55 case ByteOps.IF_ICMPLT: 56 case ByteOps.IF_ICMPGE: 57 case ByteOps.IF_ICMPGT: 58 case ByteOps.IF_ICMPLE: 59 case ByteOps.IF_ACMPEQ: 60 case ByteOps.IF_ACMPNE: 61 case ByteOps.GOTO: 62 case ByteOps.RET: 63 case ByteOps.LOOKUPSWITCH: 64 case ByteOps.IRETURN: 65 case ByteOps.RETURN: 66 case ByteOps.PUTSTATIC: 67 case ByteOps.PUTFIELD: 68 case ByteOps.ATHROW: 69 case ByteOps.MONITORENTER: 70 case ByteOps.MONITOREXIT: 71 case ByteOps.IFNULL: 72 case ByteOps.IFNONNULL: { 73 // Nothing to do for these ops in this class. 74 clearResult(); 75 break; 76 } 77 case ByteOps.LDC: 78 case ByteOps.LDC2_W: { 79 setResult((TypeBearer) getAuxCst()); 80 break; 81 } 82 case ByteOps.ILOAD: 83 case ByteOps.ISTORE: { 84 setResult(arg(0)); 85 break; 86 } 87 case ByteOps.IALOAD: 88 case ByteOps.IADD: 89 case ByteOps.ISUB: 90 case ByteOps.IMUL: 91 case ByteOps.IDIV: 92 case ByteOps.IREM: 93 case ByteOps.INEG: 94 case ByteOps.ISHL: 95 case ByteOps.ISHR: 96 case ByteOps.IUSHR: 97 case ByteOps.IAND: 98 case ByteOps.IOR: 99 case ByteOps.IXOR: 100 case ByteOps.IINC: 101 case ByteOps.I2L: 102 case ByteOps.I2F: 103 case ByteOps.I2D: 104 case ByteOps.L2I: 105 case ByteOps.L2F: 106 case ByteOps.L2D: 107 case ByteOps.F2I: 108 case ByteOps.F2L: 109 case ByteOps.F2D: 110 case ByteOps.D2I: 111 case ByteOps.D2L: 112 case ByteOps.D2F: 113 case ByteOps.I2B: 114 case ByteOps.I2C: 115 case ByteOps.I2S: 116 case ByteOps.LCMP: 117 case ByteOps.FCMPL: 118 case ByteOps.FCMPG: 119 case ByteOps.DCMPL: 120 case ByteOps.DCMPG: 121 case ByteOps.ARRAYLENGTH: { 122 setResult(getAuxType()); 123 break; 124 } 125 case ByteOps.DUP: 126 case ByteOps.DUP_X1: 127 case ByteOps.DUP_X2: 128 case ByteOps.DUP2: 129 case ByteOps.DUP2_X1: 130 case ByteOps.DUP2_X2: 131 case ByteOps.SWAP: { 132 clearResult(); 133 for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) { 134 int which = (pattern & 0x0f) - 1; 135 addResult(arg(which)); 136 } 137 break; 138 } 139 140 case ByteOps.JSR: { 141 setResult(new ReturnAddress(getAuxTarget())); 142 break; 143 } 144 case ByteOps.GETSTATIC: 145 case ByteOps.GETFIELD: 146 case ByteOps.INVOKEVIRTUAL: 147 case ByteOps.INVOKESTATIC: 148 case ByteOps.INVOKEINTERFACE: { 149 Type type = ((TypeBearer) getAuxCst()).getType(); 150 if (type == Type.VOID) { 151 clearResult(); 152 } else { 153 setResult(type); 154 } 155 break; 156 } 157 case ByteOps.INVOKESPECIAL: { 158 Type thisType = arg(0).getType(); 159 if (thisType.isUninitialized()) { 160 frame.makeInitialized(thisType); 161 } 162 Type type = ((TypeBearer) getAuxCst()).getType(); 163 if (type == Type.VOID) { 164 clearResult(); 165 } else { 166 setResult(type); 167 } 168 break; 169 } 170 case ByteOps.NEW: { 171 Type type = ((CstType) getAuxCst()).getClassType(); 172 setResult(type.asUninitialized(offset)); 173 break; 174 } 175 case ByteOps.NEWARRAY: 176 case ByteOps.CHECKCAST: 177 case ByteOps.MULTIANEWARRAY: { 178 Type type = ((CstType) getAuxCst()).getClassType(); 179 setResult(type); 180 break; 181 } 182 case ByteOps.ANEWARRAY: { 183 Type type = ((CstType) getAuxCst()).getClassType(); 184 setResult(type.getArrayType()); 185 break; 186 } 187 case ByteOps.INSTANCEOF: { 188 setResult(Type.INT); 189 break; 190 } 191 default: { 192 throw new RuntimeException("shouldn't happen: " + 193 Hex.u1(opcode)); 194 } 195 } 196 197 storeResults(frame); 198 } 199 } 200