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.HashSet; 62 import java.util.List; 63 import java.util.Set; 64 65 import jdk.internal.org.objectweb.asm.Opcodes; 66 import jdk.internal.org.objectweb.asm.Type; 67 import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode; 68 import jdk.internal.org.objectweb.asm.tree.FieldInsnNode; 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 73 /** 74 * An {@link Interpreter} for {@link SourceValue} values. 75 * 76 * @author Eric Bruneton 77 */ 78 public class SourceInterpreter extends Interpreter<SourceValue> implements 79 Opcodes { 80 81 public SourceInterpreter() { 82 super(ASM5); 83 } 84 85 protected SourceInterpreter(final int api) { 86 super(api); 87 } 88 89 @Override 90 public SourceValue newValue(final Type type) { 91 if (type == Type.VOID_TYPE) { 92 return null; 93 } 94 return new SourceValue(type == null ? 1 : type.getSize()); 95 } 96 97 @Override 98 public SourceValue newOperation(final AbstractInsnNode insn) { 99 int size; 100 switch (insn.getOpcode()) { 101 case LCONST_0: 102 case LCONST_1: 103 case DCONST_0: 104 case DCONST_1: 105 size = 2; 106 break; 107 case LDC: 108 Object cst = ((LdcInsnNode) insn).cst; 109 size = cst instanceof Long || cst instanceof Double ? 2 : 1; 110 break; 111 case GETSTATIC: 112 size = Type.getType(((FieldInsnNode) insn).desc).getSize(); 113 break; 114 default: 115 size = 1; 116 } 117 return new SourceValue(size, insn); 118 } 119 120 @Override 121 public SourceValue copyOperation(final AbstractInsnNode insn, 122 final SourceValue value) { 123 return new SourceValue(value.getSize(), insn); 124 } 125 126 @Override 127 public SourceValue unaryOperation(final AbstractInsnNode insn, 128 final SourceValue value) { 129 int size; 130 switch (insn.getOpcode()) { 131 case LNEG: 132 case DNEG: 133 case I2L: 134 case I2D: 135 case L2D: 136 case F2L: 137 case F2D: 138 case D2L: 139 size = 2; 140 break; 141 case GETFIELD: 142 size = Type.getType(((FieldInsnNode) insn).desc).getSize(); 143 break; 144 default: 145 size = 1; 146 } 147 return new SourceValue(size, insn); 148 } 149 150 @Override 151 public SourceValue binaryOperation(final AbstractInsnNode insn, 152 final SourceValue value1, final SourceValue value2) { 153 int size; 154 switch (insn.getOpcode()) { 155 case LALOAD: 156 case DALOAD: 157 case LADD: 158 case DADD: 159 case LSUB: 160 case DSUB: 161 case LMUL: 162 case DMUL: 163 case LDIV: 164 case DDIV: 165 case LREM: 166 case DREM: 167 case LSHL: 168 case LSHR: 169 case LUSHR: 170 case LAND: 171 case LOR: 172 case LXOR: 173 size = 2; 174 break; 175 default: 176 size = 1; 177 } 178 return new SourceValue(size, insn); 179 } 180 181 @Override 182 public SourceValue ternaryOperation(final AbstractInsnNode insn, 183 final SourceValue value1, final SourceValue value2, 184 final SourceValue value3) { 185 return new SourceValue(1, insn); 186 } 187 188 @Override 189 public SourceValue naryOperation(final AbstractInsnNode insn, 190 final List<? extends SourceValue> values) { 191 int size; 192 int opcode = insn.getOpcode(); 193 if (opcode == MULTIANEWARRAY) { 194 size = 1; 195 } else { 196 String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc 197 : ((MethodInsnNode) insn).desc; 198 size = Type.getReturnType(desc).getSize(); 199 } 200 return new SourceValue(size, insn); 201 } 202 203 @Override 204 public void returnOperation(final AbstractInsnNode insn, 205 final SourceValue value, final SourceValue expected) { 206 } 207 208 @Override 209 public SourceValue merge(final SourceValue d, final SourceValue w) { 210 if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) { 211 Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns) 212 .union((SmallSet<AbstractInsnNode>) w.insns); 213 if (s == d.insns && d.size == w.size) { 214 return d; 215 } else { 216 return new SourceValue(Math.min(d.size, w.size), s); 217 } 218 } 219 if (d.size != w.size || !d.insns.containsAll(w.insns)) { 220 HashSet<AbstractInsnNode> s = new HashSet<AbstractInsnNode>(); 221 s.addAll(d.insns); 222 s.addAll(w.insns); 223 return new SourceValue(Math.min(d.size, w.size), s); 224 } 225 return d; 226 } 227 }