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 85 public BasicInterpreter() { 86 super(ASM4); 87 } 88 89 protected BasicInterpreter(final int api) { 90 super(api); 91 } 92 93 @Override 94 public BasicValue newValue(final Type type) { 95 if (type == null) { 96 return BasicValue.UNINITIALIZED_VALUE; 97 } 98 switch (type.getSort()) { 99 case Type.VOID: 100 return null; 101 case Type.BOOLEAN: 102 case Type.CHAR: 103 case Type.BYTE: 104 case Type.SHORT: 105 case Type.INT: 106 return BasicValue.INT_VALUE; 107 case Type.FLOAT: 108 return BasicValue.FLOAT_VALUE; 109 case Type.LONG: 110 return BasicValue.LONG_VALUE; 111 case Type.DOUBLE: 112 return BasicValue.DOUBLE_VALUE; 113 case Type.ARRAY: 114 case Type.OBJECT: 115 return BasicValue.REFERENCE_VALUE; 116 default: 117 throw new Error("Internal error"); 118 } 119 } 120 121 @Override 122 public BasicValue newOperation(final AbstractInsnNode insn) 123 throws AnalyzerException 124 { 125 switch (insn.getOpcode()) { 126 case ACONST_NULL: 127 return newValue(Type.getObjectType("null")); 128 case ICONST_M1: 129 case ICONST_0: 130 case ICONST_1: 131 case ICONST_2: 132 case ICONST_3: 133 case ICONST_4: 134 case ICONST_5: 135 return BasicValue.INT_VALUE; 136 case LCONST_0: 137 case LCONST_1: 138 return BasicValue.LONG_VALUE; 139 case FCONST_0: 140 case FCONST_1: 141 case FCONST_2: 142 return BasicValue.FLOAT_VALUE; 143 case DCONST_0: 144 case DCONST_1: 145 return BasicValue.DOUBLE_VALUE; 146 case BIPUSH: 147 case SIPUSH: 148 return BasicValue.INT_VALUE; 149 case LDC: 150 Object cst = ((LdcInsnNode) insn).cst; 151 if (cst instanceof Integer) { 152 return BasicValue.INT_VALUE; 153 } else if (cst instanceof Float) { 154 return BasicValue.FLOAT_VALUE; 155 } else if (cst instanceof Long) { 156 return BasicValue.LONG_VALUE; 157 } else if (cst instanceof Double) { 158 return BasicValue.DOUBLE_VALUE; 159 } else if (cst instanceof String) { 160 return newValue(Type.getObjectType("java/lang/String")); 161 } else if (cst instanceof Type) { 162 int sort = ((Type) cst).getSort(); 163 if (sort == Type.OBJECT || sort == Type.ARRAY) { 164 return newValue(Type.getObjectType("java/lang/Class")); 165 } else if (sort == Type.METHOD) { 166 return newValue(Type.getObjectType("java/lang/invoke/MethodType")); 167 } else { 168 throw new IllegalArgumentException("Illegal LDC constant " + cst); 169 } 170 } else if (cst instanceof Handle) { 171 return newValue(Type.getObjectType("java/lang/invoke/MethodHandle")); 172 } else { 173 throw new IllegalArgumentException("Illegal LDC constant " + cst); 174 } 175 case JSR: 176 return BasicValue.RETURNADDRESS_VALUE; 177 case GETSTATIC: 178 return newValue(Type.getType(((FieldInsnNode) insn).desc)); 179 case NEW: 180 return newValue(Type.getObjectType(((TypeInsnNode) insn).desc)); 181 default: 182 throw new Error("Internal error."); 183 } 184 } 185 186 @Override 187 public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value) 188 throws AnalyzerException 189 { 190 return value; 191 } 192 193 @Override 194 public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value) 195 throws AnalyzerException 196 { 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( 284 final AbstractInsnNode insn, 285 final BasicValue value1, 286 final BasicValue value2) throws AnalyzerException 287 { 288 switch (insn.getOpcode()) { 289 case IALOAD: 290 case BALOAD: 291 case CALOAD: 292 case SALOAD: 293 case IADD: 294 case ISUB: 295 case IMUL: 296 case IDIV: 297 case IREM: 298 case ISHL: 299 case ISHR: 300 case IUSHR: 301 case IAND: 302 case IOR: 303 case IXOR: 304 return BasicValue.INT_VALUE; 305 case FALOAD: 306 case FADD: 307 case FSUB: 308 case FMUL: 309 case FDIV: 310 case FREM: 311 return BasicValue.FLOAT_VALUE; 312 case LALOAD: 313 case LADD: 314 case LSUB: 315 case LMUL: 316 case LDIV: 317 case LREM: 318 case LSHL: 319 case LSHR: 320 case LUSHR: 321 case LAND: 322 case LOR: 323 case LXOR: 324 return BasicValue.LONG_VALUE; 325 case DALOAD: 326 case DADD: 327 case DSUB: 328 case DMUL: 329 case DDIV: 330 case DREM: 331 return BasicValue.DOUBLE_VALUE; 332 case AALOAD: 333 return BasicValue.REFERENCE_VALUE; 334 case LCMP: 335 case FCMPL: 336 case FCMPG: 337 case DCMPL: 338 case DCMPG: 339 return BasicValue.INT_VALUE; 340 case IF_ICMPEQ: 341 case IF_ICMPNE: 342 case IF_ICMPLT: 343 case IF_ICMPGE: 344 case IF_ICMPGT: 345 case IF_ICMPLE: 346 case IF_ACMPEQ: 347 case IF_ACMPNE: 348 case PUTFIELD: 349 return null; 350 default: 351 throw new Error("Internal error."); 352 } 353 } 354 355 @Override 356 public BasicValue ternaryOperation( 357 final AbstractInsnNode insn, 358 final BasicValue value1, 359 final BasicValue value2, 360 final BasicValue value3) throws AnalyzerException 361 { 362 return null; 363 } 364 365 @Override 366 public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values) 367 throws AnalyzerException 368 { 369 int opcode = insn.getOpcode(); 370 if (opcode == MULTIANEWARRAY) { 371 return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); 372 } else if (opcode == INVOKEDYNAMIC){ 373 return newValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc)); 374 } else { 375 return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); 376 } 377 } 378 379 @Override 380 public void returnOperation( 381 final AbstractInsnNode insn, 382 final BasicValue value, 383 final BasicValue expected) throws AnalyzerException 384 { 385 } 386 387 @Override 388 public BasicValue merge(final BasicValue v, final BasicValue w) { 389 if (!v.equals(w)) { 390 return BasicValue.UNINITIALIZED_VALUE; 391 } 392 return v; 393 } 394 }