001/*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2011 INRIA, France Telecom 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package io.ebean.enhance.asm.tree.analysis; 031 032import io.ebean.enhance.asm.Type; 033import io.ebean.enhance.asm.tree.AbstractInsnNode; 034 035import java.util.List; 036 037/** 038 * A semantic bytecode interpreter. More precisely, this interpreter only 039 * manages the computation of values from other values: it does not manage the 040 * transfer of values to or from the stack, and to or from the local variables. 041 * This separation allows a generic bytecode {@link Analyzer} to work with 042 * various semantic interpreters, without needing to duplicate the code to 043 * simulate the transfer of values. 044 * 045 * @param <V> 046 * type of the Value used for the analysis. 047 * 048 * @author Eric Bruneton 049 */ 050public abstract class Interpreter<V extends Value> { 051 052 protected final int api; 053 054 protected Interpreter(final int api) { 055 this.api = api; 056 } 057 058 /** 059 * Creates a new value that represents the given type. 060 * 061 * Called for method parameters (including <code>this</code>), exception 062 * handler variable and with <code>null</code> type for variables reserved 063 * by long and double types. 064 * 065 * @param type 066 * a primitive or reference type, or <tt>null</tt> to represent 067 * an uninitialized value. 068 * @return a value that represents the given type. The size of the returned 069 * value must be equal to the size of the given type. 070 */ 071 public abstract V newValue(Type type); 072 073 /** 074 * Interprets a bytecode instruction without arguments. This method is 075 * called for the following opcodes: 076 * 077 * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, 078 * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, 079 * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW 080 * 081 * @param insn 082 * the bytecode instruction to be interpreted. 083 * @return the result of the interpretation of the given instruction. 084 * @throws AnalyzerException 085 * if an error occured during the interpretation. 086 */ 087 public abstract V newOperation(AbstractInsnNode insn) 088 throws AnalyzerException; 089 090 /** 091 * Interprets a bytecode instruction that moves a value on the stack or to 092 * or from local variables. This method is called for the following opcodes: 093 * 094 * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, 095 * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP 096 * 097 * @param insn 098 * the bytecode instruction to be interpreted. 099 * @param value 100 * the value that must be moved by the instruction. 101 * @return the result of the interpretation of the given instruction. The 102 * returned value must be <tt>equal</tt> to the given value. 103 * @throws AnalyzerException 104 * if an error occured during the interpretation. 105 */ 106 public abstract V copyOperation(AbstractInsnNode insn, V value) 107 throws AnalyzerException; 108 109 /** 110 * Interprets a bytecode instruction with a single argument. This method is 111 * called for the following opcodes: 112 * 113 * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, 114 * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, 115 * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, 116 * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST, 117 * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL 118 * 119 * @param insn 120 * the bytecode instruction to be interpreted. 121 * @param value 122 * the argument of the instruction to be interpreted. 123 * @return the result of the interpretation of the given instruction. 124 * @throws AnalyzerException 125 * if an error occured during the interpretation. 126 */ 127 public abstract V unaryOperation(AbstractInsnNode insn, V value) 128 throws AnalyzerException; 129 130 /** 131 * Interprets a bytecode instruction with two arguments. This method is 132 * called for the following opcodes: 133 * 134 * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, 135 * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, 136 * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, 137 * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL, 138 * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, 139 * IF_ACMPEQ, IF_ACMPNE, PUTFIELD 140 * 141 * @param insn 142 * the bytecode instruction to be interpreted. 143 * @param value1 144 * the first argument of the instruction to be interpreted. 145 * @param value2 146 * the second argument of the instruction to be interpreted. 147 * @return the result of the interpretation of the given instruction. 148 * @throws AnalyzerException 149 * if an error occured during the interpretation. 150 */ 151 public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2) 152 throws AnalyzerException; 153 154 /** 155 * Interprets a bytecode instruction with three arguments. This method is 156 * called for the following opcodes: 157 * 158 * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE 159 * 160 * @param insn 161 * the bytecode instruction to be interpreted. 162 * @param value1 163 * the first argument of the instruction to be interpreted. 164 * @param value2 165 * the second argument of the instruction to be interpreted. 166 * @param value3 167 * the third argument of the instruction to be interpreted. 168 * @return the result of the interpretation of the given instruction. 169 * @throws AnalyzerException 170 * if an error occured during the interpretation. 171 */ 172 public abstract V ternaryOperation(AbstractInsnNode insn, V value1, 173 V value2, V value3) throws AnalyzerException; 174 175 /** 176 * Interprets a bytecode instruction with a variable number of arguments. 177 * This method is called for the following opcodes: 178 * 179 * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, 180 * MULTIANEWARRAY and INVOKEDYNAMIC 181 * 182 * @param insn 183 * the bytecode instruction to be interpreted. 184 * @param values 185 * the arguments of the instruction to be interpreted. 186 * @return the result of the interpretation of the given instruction. 187 * @throws AnalyzerException 188 * if an error occured during the interpretation. 189 */ 190 public abstract V naryOperation(AbstractInsnNode insn, 191 List<? extends V> values) throws AnalyzerException; 192 193 /** 194 * Interprets a bytecode return instruction. This method is called for the 195 * following opcodes: 196 * 197 * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN 198 * 199 * @param insn 200 * the bytecode instruction to be interpreted. 201 * @param value 202 * the argument of the instruction to be interpreted. 203 * @param expected 204 * the expected return type of the analyzed method. 205 * @throws AnalyzerException 206 * if an error occured during the interpretation. 207 */ 208 public abstract void returnOperation(AbstractInsnNode insn, V value, 209 V expected) throws AnalyzerException; 210 211 /** 212 * Merges two values. The merge operation must return a value that 213 * represents both values (for instance, if the two values are two types, 214 * the merged value must be a common super type of the two types. If the two 215 * values are integer intervals, the merged value must be an interval that 216 * contains the previous ones. Likewise for other types of values). 217 * 218 * @param v 219 * a value. 220 * @param w 221 * another value. 222 * @return the merged value. If the merged value is equal to <tt>v</tt>, 223 * this method <i>must</i> return <tt>v</tt>. 224 */ 225 public abstract V merge(V v, V w); 226}