1 30 package com.tc.asm.tree.analysis; 31 32 import java.util.HashSet ; 33 import java.util.List ; 34 import java.util.Set ; 35 36 import com.tc.asm.Opcodes; 37 import com.tc.asm.Type; 38 import com.tc.asm.tree.AbstractInsnNode; 39 import com.tc.asm.tree.FieldInsnNode; 40 import com.tc.asm.tree.LdcInsnNode; 41 import com.tc.asm.tree.MethodInsnNode; 42 43 48 public class DataflowInterpreter implements Opcodes, Interpreter { 49 50 public Value newValue(final Type type) { 51 return new DataflowValue(type == null ? 1 : type.getSize()); 52 } 53 54 public Value newOperation(final AbstractInsnNode insn) { 55 int size; 56 switch (insn.getOpcode()) { 57 case LCONST_0: 58 case LCONST_1: 59 case DCONST_0: 60 case DCONST_1: 61 size = 2; 62 break; 63 case LDC: 64 Object cst = ((LdcInsnNode) insn).cst; 65 size = cst instanceof Long || cst instanceof Double ? 2 : 1; 66 break; 67 case GETSTATIC: 68 size = Type.getType(((FieldInsnNode) insn).desc).getSize(); 69 break; 70 default: 71 size = 1; 72 } 73 return new DataflowValue(size, insn); 74 } 75 76 public Value copyOperation(final AbstractInsnNode insn, final Value value) { 77 return new DataflowValue(value.getSize(), insn); 78 } 79 80 public Value unaryOperation(final AbstractInsnNode insn, final Value value) 81 { 82 int size; 83 switch (insn.getOpcode()) { 84 case LNEG: 85 case DNEG: 86 case I2L: 87 case I2D: 88 case L2D: 89 case F2L: 90 case F2D: 91 case D2L: 92 size = 2; 93 break; 94 case GETFIELD: 95 size = Type.getType(((FieldInsnNode) insn).desc).getSize(); 96 break; 97 default: 98 size = 1; 99 } 100 return new DataflowValue(size, insn); 101 } 102 103 public Value binaryOperation( 104 final AbstractInsnNode insn, 105 final Value value1, 106 final Value value2) 107 { 108 int size; 109 switch (insn.getOpcode()) { 110 case LALOAD: 111 case DALOAD: 112 case LADD: 113 case DADD: 114 case LSUB: 115 case DSUB: 116 case LMUL: 117 case DMUL: 118 case LDIV: 119 case DDIV: 120 case LREM: 121 case DREM: 122 case LSHL: 123 case LSHR: 124 case LUSHR: 125 case LAND: 126 case LOR: 127 case LXOR: 128 size = 2; 129 break; 130 default: 131 size = 1; 132 } 133 return new DataflowValue(size, insn); 134 } 135 136 public Value ternaryOperation( 137 final AbstractInsnNode insn, 138 final Value value1, 139 final Value value2, 140 final Value value3) 141 { 142 return new DataflowValue(1, insn); 143 } 144 145 public Value naryOperation(final AbstractInsnNode insn, final List values) { 146 int size; 147 if (insn.getOpcode() == MULTIANEWARRAY) { 148 size = 1; 149 } else { 150 size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize(); 151 } 152 return new DataflowValue(size, insn); 153 } 154 155 public Value merge(final Value v, final Value w) { 156 DataflowValue dv = (DataflowValue) v; 157 DataflowValue dw = (DataflowValue) w; 158 if (dv.insns instanceof SmallSet && dw.insns instanceof SmallSet) { 159 Set s = ((SmallSet) dv.insns).union((SmallSet) dw.insns); 160 if (s == dv.insns && dv.size == dw.size) { 161 return v; 162 } else { 163 return new DataflowValue(Math.min(dv.size, dw.size), s); 164 } 165 } 166 if (dv.size != dw.size || !dv.insns.containsAll(dw.insns)) { 167 Set s = new HashSet (); 168 s.addAll(dv.insns); 169 s.addAll(dw.insns); 170 return new DataflowValue(Math.min(dv.size, dw.size), s); 171 } 172 return v; 173 } 174 } 175 | Popular Tags |