1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm.tree.analysis; 60 61 import java.util.List; 62 63 import jdk.internal.org.objectweb.asm.Handle; 64 import jdk.internal.org.objectweb.asm.Opcodes; 65 import jdk.internal.org.objectweb.asm.Type; 66 import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode; 67 import jdk.internal.org.objectweb.asm.tree.FieldInsnNode; 68 import jdk.internal.org.objectweb.asm.tree.IntInsnNode; 69 import jdk.internal.org.objectweb.asm.tree.InvokeDynamicInsnNode; 70 import jdk.internal.org.objectweb.asm.tree.LdcInsnNode; 71 import jdk.internal.org.objectweb.asm.tree.MethodInsnNode; 72 import jdk.internal.org.objectweb.asm.tree.MultiANewArrayInsnNode; 73 import jdk.internal.org.objectweb.asm.tree.TypeInsnNode; 74 75 /** 76 * An {@link Interpreter} for {@link BasicValue} values. 77 * 78 * @author Eric Bruneton 79 * @author Bing Ran 80 */ 81 public class BasicInterpreter extends Interpreter<BasicValue> implements 82 Opcodes { 83 84 public BasicInterpreter() { 85 super(ASM6); 86 } 87 88 protected BasicInterpreter(final int api) { 89 super(api); 90 } 91 92 @Override 93 public BasicValue newValue(final Type type) { 94 if (type == null) { 95 return BasicValue.UNINITIALIZED_VALUE; 96 } 97 switch (type.getSort()) { 98 case Type.VOID: 99 return null; 100 case Type.BOOLEAN: 101 case Type.CHAR: 102 case Type.BYTE: 103 case Type.SHORT: 104 case Type.INT: 105 return BasicValue.INT_VALUE; 106 case Type.FLOAT: 107 return BasicValue.FLOAT_VALUE; 108 case Type.LONG: 109 return BasicValue.LONG_VALUE; 110 case Type.DOUBLE: 111 return BasicValue.DOUBLE_VALUE; 112 case Type.ARRAY: 113 case Type.OBJECT: 114 return BasicValue.REFERENCE_VALUE; 115 default: 116 throw new Error("Internal error"); 117 } 118 } 119 120 @Override 121 public BasicValue newOperation(final AbstractInsnNode insn) 122 throws AnalyzerException { 123 switch (insn.getOpcode()) { 124 case ACONST_NULL: 125 return newValue(Type.getObjectType("null")); 126 case ICONST_M1: 127 case ICONST_0: 128 case ICONST_1: 129 case ICONST_2: 130 case ICONST_3: 131 case ICONST_4: 132 case ICONST_5: 133 return BasicValue.INT_VALUE; 134 case LCONST_0: 135 case LCONST_1: 136 return BasicValue.LONG_VALUE; 137 case FCONST_0: 138 case FCONST_1: 139 case FCONST_2: 140 return BasicValue.FLOAT_VALUE; 141 case DCONST_0: 142 case DCONST_1: 143 return BasicValue.DOUBLE_VALUE; 144 case BIPUSH: 145 case SIPUSH: 146 return BasicValue.INT_VALUE; 147 case LDC: 148 Object cst = ((LdcInsnNode) insn).cst; 149 if (cst instanceof Integer) { 150 return BasicValue.INT_VALUE; 151 } else if (cst instanceof Float) { 152 return BasicValue.FLOAT_VALUE; 153 } else if (cst instanceof Long) { 154 return BasicValue.LONG_VALUE; 155 } else if (cst instanceof Double) { 156 return BasicValue.DOUBLE_VALUE; 157 } else if (cst instanceof String) { 158 return newValue(Type.getObjectType("java/lang/String")); 159 } else if (cst instanceof Type) { 160 int sort = ((Type) cst).getSort(); 161 if (sort == Type.OBJECT || sort == Type.ARRAY) { 162 return newValue(Type.getObjectType("java/lang/Class")); 163 } else if (sort == Type.METHOD) { 164 return newValue(Type 165 .getObjectType("java/lang/invoke/MethodType")); 166 } else { 167 throw new IllegalArgumentException("Illegal LDC constant " 168 + cst); 169 } 170 } else if (cst instanceof Handle) { 171 return newValue(Type 172 .getObjectType("java/lang/invoke/MethodHandle")); 173 } else { 174 throw new IllegalArgumentException("Illegal LDC constant " 175 + cst); 176 } 177 case JSR: 178 return BasicValue.RETURNADDRESS_VALUE; 179 case GETSTATIC: 180 return newValue(Type.getType(((FieldInsnNode) insn).desc)); 181 case NEW: 182 return newValue(Type.getObjectType(((TypeInsnNode) insn).desc)); 183 default: 184 throw new Error("Internal error."); 185 } 186 } 187 188 @Override 189 public BasicValue copyOperation(final AbstractInsnNode insn, 190 final BasicValue value) throws AnalyzerException { 191 return value; 192 } 193 194 @Override 195 public BasicValue unaryOperation(final AbstractInsnNode insn, 196 final BasicValue value) throws AnalyzerException { 197 switch (insn.getOpcode()) { 198 case INEG: 199 case IINC: 200 case L2I: 201 case F2I: 202 case D2I: 203 case I2B: 204 case I2C: 205 case I2S: 206 return BasicValue.INT_VALUE; 207 case FNEG: 208 case I2F: 209 case L2F: 210 case D2F: 211 return BasicValue.FLOAT_VALUE; 212 case LNEG: 213 case I2L: 214 case F2L: 215 case D2L: 216 return BasicValue.LONG_VALUE; 217 case DNEG: 218 case I2D: 219 case L2D: 220 case F2D: 221 return BasicValue.DOUBLE_VALUE; 222 case IFEQ: 223 case IFNE: 224 case IFLT: 225 case IFGE: 226 case IFGT: 227 case IFLE: 228 case TABLESWITCH: 229 case LOOKUPSWITCH: 230 case IRETURN: 231 case LRETURN: 232 case FRETURN: 233 case DRETURN: 234 case ARETURN: 235 case PUTSTATIC: 236 return null; 237 case GETFIELD: 238 return newValue(Type.getType(((FieldInsnNode) insn).desc)); 239 case NEWARRAY: 240 switch (((IntInsnNode) insn).operand) { 241 case T_BOOLEAN: 242 return newValue(Type.getType("[Z")); 243 case T_CHAR: 244 return newValue(Type.getType("[C")); 245 case T_BYTE: 246 return newValue(Type.getType("[B")); 247 case T_SHORT: 248 return newValue(Type.getType("[S")); 249 case T_INT: 250 return newValue(Type.getType("[I")); 251 case T_FLOAT: 252 return newValue(Type.getType("[F")); 253 case T_DOUBLE: 254 return newValue(Type.getType("[D")); 255 case T_LONG: 256 return newValue(Type.getType("[J")); 257 default: 258 throw new AnalyzerException(insn, "Invalid array type"); 259 } 260 case ANEWARRAY: 261 String desc = ((TypeInsnNode) insn).desc; 262 return newValue(Type.getType("[" + Type.getObjectType(desc))); 263 case ARRAYLENGTH: 264 return BasicValue.INT_VALUE; 265 case ATHROW: 266 return null; 267 case CHECKCAST: 268 desc = ((TypeInsnNode) insn).desc; 269 return newValue(Type.getObjectType(desc)); 270 case INSTANCEOF: 271 return BasicValue.INT_VALUE; 272 case MONITORENTER: 273 case MONITOREXIT: 274 case IFNULL: 275 case IFNONNULL: 276 return null; 277 default: 278 throw new Error("Internal error."); 279 } 280 } 281 282 @Override 283 public BasicValue binaryOperation(final AbstractInsnNode insn, 284 final BasicValue value1, final BasicValue value2) 285 throws AnalyzerException { 286 switch (insn.getOpcode()) { 287 case IALOAD: 288 case BALOAD: 289 case CALOAD: 290 case SALOAD: 291 case IADD: 292 case ISUB: 293 case IMUL: 294 case IDIV: 295 case IREM: 296 case ISHL: 297 case ISHR: 298 case IUSHR: 299 case IAND: 300 case IOR: 301 case IXOR: 302 return BasicValue.INT_VALUE; 303 case FALOAD: 304 case FADD: 305 case FSUB: 306 case FMUL: 307 case FDIV: 308 case FREM: 309 return BasicValue.FLOAT_VALUE; 310 case LALOAD: 311 case LADD: 312 case LSUB: 313 case LMUL: 314 case LDIV: 315 case LREM: 316 case LSHL: 317 case LSHR: 318 case LUSHR: 319 case LAND: 320 case LOR: 321 case LXOR: 322 return BasicValue.LONG_VALUE; 323 case DALOAD: 324 case DADD: 325 case DSUB: 326 case DMUL: 327 case DDIV: 328 case DREM: 329 return BasicValue.DOUBLE_VALUE; 330 case AALOAD: 331 return BasicValue.REFERENCE_VALUE; 332 case LCMP: 333 case FCMPL: 334 case FCMPG: 335 case DCMPL: 336 case DCMPG: 337 return BasicValue.INT_VALUE; 338 case IF_ICMPEQ: 339 case IF_ICMPNE: 340 case IF_ICMPLT: 341 case IF_ICMPGE: 342 case IF_ICMPGT: 343 case IF_ICMPLE: 344 case IF_ACMPEQ: 345 case IF_ACMPNE: 346 case PUTFIELD: 347 return null; 348 default: 349 throw new Error("Internal error."); 350 } 351 } 352 353 @Override 354 public BasicValue ternaryOperation(final AbstractInsnNode insn, 355 final BasicValue value1, final BasicValue value2, 356 final BasicValue value3) throws AnalyzerException { 357 return null; 358 } 359 360 @Override 361 public BasicValue naryOperation(final AbstractInsnNode insn, 362 final List<? extends BasicValue> values) throws AnalyzerException { 363 int opcode = insn.getOpcode(); 364 if (opcode == MULTIANEWARRAY) { 365 return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); 366 } else if (opcode == INVOKEDYNAMIC) { 367 return newValue(Type 368 .getReturnType(((InvokeDynamicInsnNode) insn).desc)); 369 } else { 370 return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); 371 } 372 } 373 374 @Override 375 public void returnOperation(final AbstractInsnNode insn, 376 final BasicValue value, final BasicValue expected) 377 throws AnalyzerException { 378 } 379 380 @Override 381 public BasicValue merge(final BasicValue v, final BasicValue w) { 382 if (!v.equals(w)) { 383 return BasicValue.UNINITIALIZED_VALUE; 384 } 385 return v; 386 } 387 }