diff options
Diffstat (limited to 'tools/external/asm/org/objectweb/asm/tree/analysis/DataflowInterpreter.java')
-rw-r--r-- | tools/external/asm/org/objectweb/asm/tree/analysis/DataflowInterpreter.java | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/tools/external/asm/org/objectweb/asm/tree/analysis/DataflowInterpreter.java b/tools/external/asm/org/objectweb/asm/tree/analysis/DataflowInterpreter.java new file mode 100644 index 000000000..07edd74f9 --- /dev/null +++ b/tools/external/asm/org/objectweb/asm/tree/analysis/DataflowInterpreter.java @@ -0,0 +1,174 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2005 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.tree.analysis; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; + +/** + * An {@link Interpreter} for {@link DataflowValue} values. + * + * @author Eric Bruneton + */ +public class DataflowInterpreter implements Opcodes, Interpreter { + + public Value newValue(final Type type) { + return new DataflowValue(type == null ? 1 : type.getSize()); + } + + public Value newOperation(final AbstractInsnNode insn) { + int size; + switch (insn.getOpcode()) { + case LCONST_0: + case LCONST_1: + case DCONST_0: + case DCONST_1: + size = 2; + break; + case LDC: + Object cst = ((LdcInsnNode) insn).cst; + size = cst instanceof Long || cst instanceof Double ? 2 : 1; + break; + case GETSTATIC: + size = Type.getType(((FieldInsnNode) insn).desc).getSize(); + break; + default: + size = 1; + } + return new DataflowValue(size, insn); + } + + public Value copyOperation(final AbstractInsnNode insn, final Value value) { + return new DataflowValue(value.getSize(), insn); + } + + public Value unaryOperation(final AbstractInsnNode insn, final Value value) + { + int size; + switch (insn.getOpcode()) { + case LNEG: + case DNEG: + case I2L: + case I2D: + case L2D: + case F2L: + case F2D: + case D2L: + size = 2; + break; + case GETFIELD: + size = Type.getType(((FieldInsnNode) insn).desc).getSize(); + break; + default: + size = 1; + } + return new DataflowValue(size, insn); + } + + public Value binaryOperation( + final AbstractInsnNode insn, + final Value value1, + final Value value2) + { + int size; + switch (insn.getOpcode()) { + case LALOAD: + case DALOAD: + case LADD: + case DADD: + case LSUB: + case DSUB: + case LMUL: + case DMUL: + case LDIV: + case DDIV: + case LREM: + case DREM: + case LSHL: + case LSHR: + case LUSHR: + case LAND: + case LOR: + case LXOR: + size = 2; + break; + default: + size = 1; + } + return new DataflowValue(size, insn); + } + + public Value ternaryOperation( + final AbstractInsnNode insn, + final Value value1, + final Value value2, + final Value value3) + { + return new DataflowValue(1, insn); + } + + public Value naryOperation(final AbstractInsnNode insn, final List values) { + int size; + if (insn.getOpcode() == MULTIANEWARRAY) { + size = 1; + } else { + size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize(); + } + return new DataflowValue(size, insn); + } + + public Value merge(final Value v, final Value w) { + DataflowValue dv = (DataflowValue) v; + DataflowValue dw = (DataflowValue) w; + if (dv.insns instanceof SmallSet && dw.insns instanceof SmallSet) { + Set s = ((SmallSet) dv.insns).union((SmallSet) dw.insns); + if (s == dv.insns && dv.size == dw.size) { + return v; + } else { + return new DataflowValue(Math.min(dv.size, dw.size), s); + } + } + if (dv.size != dw.size || !dv.insns.containsAll(dw.insns)) { + Set s = new HashSet(); + s.addAll(dv.insns); + s.addAll(dw.insns); + return new DataflowValue(Math.min(dv.size, dw.size), s); + } + return v; + } +} |