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 82 public SourceInterpreter() { 83 super(ASM4); 84 } 85 86 protected SourceInterpreter(final int api) { 87 super(api); 88 } 89 90 @Override 91 public SourceValue newValue(final Type type) { 92 if (type == Type.VOID_TYPE) { 93 return null; 94 } 95 return new SourceValue(type == null ? 1 : type.getSize()); 96 } 97 98 @Override 99 public SourceValue newOperation(final AbstractInsnNode insn) { 100 int size; 101 switch (insn.getOpcode()) { 102 case LCONST_0: 103 case LCONST_1: 104 case DCONST_0: 105 case DCONST_1: 106 size = 2; 107 break; 108 case LDC: 109 Object cst = ((LdcInsnNode) insn).cst; 110 size = cst instanceof Long || cst instanceof Double ? 2 : 1; 111 break; 112 case GETSTATIC: 113 size = Type.getType(((FieldInsnNode) insn).desc).getSize(); 114 break; 115 default: 116 size = 1; 117 } 118 return new SourceValue(size, insn); 119 } 120 121 @Override 122 public SourceValue copyOperation(final AbstractInsnNode insn, final SourceValue value) { 123 return new SourceValue(value.getSize(), insn); 124 } 125 126 @Override 127 public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value) 128 { 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( 152 final AbstractInsnNode insn, 153 final SourceValue value1, 154 final SourceValue value2) 155 { 156 int size; 157 switch (insn.getOpcode()) { 158 case LALOAD: 159 case DALOAD: 160 case LADD: 161 case DADD: 162 case LSUB: 163 case DSUB: 164 case LMUL: 165 case DMUL: 166 case LDIV: 167 case DDIV: 168 case LREM: 169 case DREM: 170 case LSHL: 171 case LSHR: 172 case LUSHR: 173 case LAND: 174 case LOR: 175 case LXOR: 176 size = 2; 177 break; 178 default: 179 size = 1; 180 } 181 return new SourceValue(size, insn); 182 } 183 184 @Override 185 public SourceValue ternaryOperation( 186 final AbstractInsnNode insn, 187 final SourceValue value1, 188 final SourceValue value2, 189 final SourceValue value3) 190 { 191 return new SourceValue(1, insn); 192 } 193 194 @Override 195 public SourceValue naryOperation(final AbstractInsnNode insn, final List<? extends SourceValue> values) { 196 int size; 197 int opcode = insn.getOpcode(); 198 if (opcode == MULTIANEWARRAY) { 199 size = 1; 200 } else { 201 String desc = (opcode == INVOKEDYNAMIC)? 202 ((InvokeDynamicInsnNode) insn).desc: 203 ((MethodInsnNode) insn).desc; 204 size = Type.getReturnType(desc).getSize(); 205 } 206 return new SourceValue(size, insn); 207 } 208 209 @Override 210 public void returnOperation( 211 final AbstractInsnNode insn, 212 final SourceValue value, 213 final SourceValue expected) 214 { 215 } 216 217 @Override 218 public SourceValue merge(final SourceValue d, final SourceValue w) { 219 if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) { 220 Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns).union((SmallSet<AbstractInsnNode>) w.insns); 221 if (s == d.insns && d.size == w.size) { 222 return d; 223 } else { 224 return new SourceValue(Math.min(d.size, w.size), s); 225 } 226 } 227 if (d.size != w.size || !d.insns.containsAll(w.insns)) { 228 HashSet<AbstractInsnNode> s = new HashSet<AbstractInsnNode>(); 229 s.addAll(d.insns); 230 s.addAll(w.insns); 231 return new SourceValue(Math.min(d.size, w.size), s); 232 } 233 return d; 234 } 235 } | 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 } |