List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
From source file:org.evosuite.testcarver.instrument.Instrumenter.java
License:Open Source License
@SuppressWarnings("unchecked") private void addFieldRegistryRegisterCall(final MethodNode methodNode) { AbstractInsnNode ins = null; ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator(); int numInvokeSpecials = 0; // number of invokespecial calls before actual constructor call while (iter.hasNext()) { ins = iter.next();/*from w w w . j a v a 2s .co m*/ if (ins instanceof MethodInsnNode) { MethodInsnNode mins = (MethodInsnNode) ins; if (ins.getOpcode() == Opcodes.INVOKESPECIAL) { if (mins.name.startsWith("<init>")) { if (numInvokeSpecials == 0) { break; } else { numInvokeSpecials--; } } } } else if (ins instanceof TypeInsnNode) { TypeInsnNode typeIns = (TypeInsnNode) ins; if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) { numInvokeSpecials++; } } } final InsnList instructions = new InsnList(); instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(FieldRegistry.class), "register", "(Ljava/lang/Object;)V")); methodNode.instructions.insert(ins, instructions); }
From source file:org.evosuite.testcarver.instrument.Instrumenter.java
License:Open Source License
private void instrumentGETXXXFieldAccesses(final ClassNode cn, final String internalClassName, final MethodNode methodNode) { final InsnList instructions = methodNode.instructions; AbstractInsnNode ins = null; FieldInsnNode fieldIns = null;// w w w .j a va 2s. co m for (int i = 0; i < instructions.size(); i++) { ins = instructions.get(i); if (ins instanceof FieldInsnNode) { fieldIns = (FieldInsnNode) ins; /* * Is field referencing outermost instance? if yes, ignore it * http://tns-www.lcs.mit.edu/manuals/java-1.1.1/guide/innerclasses/spec/innerclasses.doc10.html */ if (fieldIns.name.endsWith("$0")) { continue; } final int opcode = ins.getOpcode(); if (opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC) { final InsnList il = new InsnList(); if (opcode == Opcodes.GETFIELD) { Type fieldType = Type.getType(fieldIns.desc); if (fieldType.getSize() == 1) { instructions.insertBefore(fieldIns, new InsnNode(Opcodes.DUP)); il.add(new InsnNode(Opcodes.SWAP)); } else if (fieldType.getSize() == 2) { instructions.insertBefore(fieldIns, new InsnNode(Opcodes.DUP)); // v // GETFIELD // v, w il.add(new InsnNode(Opcodes.DUP2_X1)); // w, v, w il.add(new InsnNode(Opcodes.POP2)); // w, v // -> Call // w } } else il.add(new InsnNode(Opcodes.ACONST_NULL)); il.add(new LdcInsnNode(this.captureId)); il.add(new LdcInsnNode(fieldIns.owner)); il.add(new LdcInsnNode(fieldIns.name)); il.add(new LdcInsnNode(fieldIns.desc)); il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(org.evosuite.testcarver.capture.FieldRegistry.class), "notifyReadAccess", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")); i += il.size(); instructions.insert(fieldIns, il); this.captureId++; } } } }
From source file:org.evosuite.testcarver.instrument.Instrumenter.java
License:Open Source License
private void instrumentPUTXXXFieldAccesses(final ClassNode cn, final String internalClassName, final MethodNode methodNode) { final InsnList instructions = methodNode.instructions; AbstractInsnNode ins = null; FieldInsnNode fieldIns = null;// ww w. j a va2 s . c om // needed get right receiver var in case of PUTFIELD for (int i = 0; i < instructions.size(); i++) { ins = instructions.get(i); if (ins instanceof FieldInsnNode) { fieldIns = (FieldInsnNode) ins; /* * Is field referencing outermost instance? if yes, ignore it * http://tns-www.lcs.mit.edu/manuals/java-1.1.1/guide/innerclasses/spec/innerclasses.doc10.html */ if (fieldIns.name.endsWith("$0")) { continue; } final int opcode = ins.getOpcode(); if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) { // construction of // Capturer.capture(final Object receiver, final String methodName, final Object[] methodParams) // call final InsnList il = new InsnList(); if (opcode == Opcodes.PUTFIELD) { Type fieldType = Type.getType(fieldIns.desc); if (fieldType.getSize() == 1) { instructions.insertBefore(fieldIns, new InsnNode(Opcodes.DUP2)); il.add(new InsnNode(Opcodes.POP)); } else if (fieldType.getSize() == 2) { InsnList uglyList = new InsnList(); // v, w uglyList.add(new InsnNode(Opcodes.DUP2_X1)); // w, v, w uglyList.add(new InsnNode(Opcodes.POP2)); // w, v uglyList.add(new InsnNode(Opcodes.DUP)); // w, v, v uglyList.add(new InsnNode(Opcodes.DUP2_X2)); // v, v, w, v, v uglyList.add(new InsnNode(Opcodes.POP2)); // v, v, w instructions.insertBefore(fieldIns, uglyList); // PUTFIELD // v } } else il.add(new InsnNode(Opcodes.ACONST_NULL)); il.add(new LdcInsnNode(this.captureId)); il.add(new LdcInsnNode(fieldIns.owner)); il.add(new LdcInsnNode(fieldIns.name)); il.add(new LdcInsnNode(fieldIns.desc)); il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(FieldRegistry.class), "notifyModification", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")); // PUTFIELDRegistry.notifyModification also adds corresponding GETFIELD capture instructions this.captureId++; i += il.size(); instructions.insert(fieldIns, il); this.captureId++; } } } }
From source file:org.evosuite.testcarver.instrument.Instrumenter.java
License:Open Source License
/** * public int myMethod(int i)//from w w w . j a va2 s. c o m { try { return _sw_prototype_original_myMethod(i) } finally { Capturer.enable(); } } * @param classNode * @param className * @param methodNode */ @SuppressWarnings("unchecked") private MethodNode wrapMethod(final ClassNode classNode, final String className, final MethodNode methodNode) { methodNode.maxStack += 4; // create wrapper for original method final MethodNode wrappingMethodNode = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()])); wrappingMethodNode.maxStack = methodNode.maxStack; // assign annotations to wrapping method wrappingMethodNode.visibleAnnotations = methodNode.visibleAnnotations; wrappingMethodNode.visibleParameterAnnotations = methodNode.visibleParameterAnnotations; // remove annotations from wrapped method to avoid wrong behavior controlled by annotations methodNode.visibleAnnotations = null; methodNode.visibleParameterAnnotations = null; // rename original method methodNode.access = TransformerUtil.modifyVisibility(methodNode.access, Opcodes.ACC_PRIVATE); final LabelNode l0 = new LabelNode(); final LabelNode l1 = new LabelNode(); final LabelNode l2 = new LabelNode(); final InsnList wInstructions = wrappingMethodNode.instructions; if ("<init>".equals(methodNode.name)) { // wrap a constructor methodNode.name = WRAP_NAME_PREFIX + "init" + WRAP_NAME_PREFIX; // move call to other constructors to new method AbstractInsnNode ins = null; ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator(); int numInvokeSpecials = 0; // number of invokespecial calls before actual constructor call while (iter.hasNext()) { ins = iter.next(); iter.remove(); wInstructions.add(ins); if (ins instanceof MethodInsnNode) { MethodInsnNode mins = (MethodInsnNode) ins; if (ins.getOpcode() == Opcodes.INVOKESPECIAL) { if (mins.name.startsWith("<init>")) { if (numInvokeSpecials == 0) { break; } else { numInvokeSpecials--; } } } } else if (ins instanceof TypeInsnNode) { TypeInsnNode typeIns = (TypeInsnNode) ins; if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) { numInvokeSpecials++; } } } } else { methodNode.name = WRAP_NAME_PREFIX + methodNode.name; } int varReturnValue = 0; final Type returnType = Type.getReturnType(methodNode.desc); if (returnType.equals(Type.VOID_TYPE)) { wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, "java/lang/Throwable")); } else { wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/Throwable")); //--- create "Object returnValue = null;" if (!TransformerUtil.isStatic(methodNode.access)) { // load "this" varReturnValue++; } // consider method arguments to find right variable index final Type[] argTypes = Type.getArgumentTypes(methodNode.desc); for (int i = 0; i < argTypes.length; i++) { varReturnValue++; // long/double take two registers if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) { varReturnValue++; } } // push NULL on the stack and initialize variable for return value for it wInstructions.add(new InsnNode(Opcodes.ACONST_NULL)); wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue)); } int var = 0; // --- L0 wInstructions.add(l0); wInstructions.add(this.addCaptureCall(TransformerUtil.isStatic(methodNode.access), className, wrappingMethodNode.name, wrappingMethodNode.desc, Type.getArgumentTypes(methodNode.desc))); // --- construct call to wrapped methode if (!TransformerUtil.isStatic(methodNode.access)) { // load "this" to call method wInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); var++; } final Type[] argTypes = Type.getArgumentTypes(methodNode.desc); for (int i = 0; i < argTypes.length; i++) { this.addLoadInsn(wInstructions, argTypes[i], var++); // long/double take two registers if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) { var++; } } if (TransformerUtil.isStatic(methodNode.access)) { wInstructions.add( new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, methodNode.name, methodNode.desc)); } else { wInstructions.add( new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, methodNode.name, methodNode.desc)); } var++; if (returnType.equals(Type.VOID_TYPE)) { wInstructions.add(new JumpInsnNode(Opcodes.GOTO, l2)); // --- L1 wInstructions.add(l1); wInstructions.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" })); wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var)); this.addCaptureEnableStatement(className, methodNode, wInstructions, -1); wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var)); wInstructions.add(new InsnNode(Opcodes.ATHROW)); // FIXME <--- DUPLICATE CODE // --- L2 wInstructions.add(l2); wInstructions.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null)); this.addCaptureEnableStatement(className, methodNode, wInstructions, -1); wInstructions.add(new InsnNode(Opcodes.RETURN)); } else { // construct store of the wrapped method call's result this.addBoxingStmt(wInstructions, returnType); wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue)); wInstructions.add(new VarInsnNode(Opcodes.ALOAD, varReturnValue)); this.addUnBoxingStmt(wInstructions, returnType); final int storeOpcode = returnType.getOpcode(Opcodes.ISTORE); wInstructions.add(new VarInsnNode(storeOpcode, ++var)); // might be only var // --- L1 wInstructions.add(l1); this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue); // construct load of the wrapped method call's result int loadOpcode = returnType.getOpcode(Opcodes.ILOAD); wInstructions.add(new VarInsnNode(loadOpcode, var)); // construct return of the wrapped method call's result this.addReturnInsn(wInstructions, returnType); //---- L2 wInstructions.add(l2); wInstructions.add( new FrameNode(Opcodes.F_FULL, 2, new Object[] { className, this.getInternalName(returnType) }, 1, new Object[] { "java/lang/Throwable" })); wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var)); this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue); wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var)); wInstructions.add(new InsnNode(Opcodes.ATHROW)); } transformWrapperCalls(methodNode); return wrappingMethodNode; }
From source file:org.evosuite.testcarver.instrument.Instrumenter.java
License:Open Source License
@SuppressWarnings("unchecked") private void transformWrapperCalls(MethodNode mn) { Iterator<AbstractInsnNode> iterator = mn.instructions.iterator(); List<Class<?>> wrapperClasses = getWrapperClasses(); while (iterator.hasNext()) { AbstractInsnNode insn = iterator.next(); if (insn instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) insn; if (methodInsnNode.name.equals("<init>")) { String ownerName = methodInsnNode.owner.replace('/', '.'); for (Class<?> wrapperClass : wrapperClasses) { if (wrapperClass.getName().equals(ownerName)) { logger.debug("Replacing call " + methodInsnNode.name); methodInsnNode.owner = "org/evosuite/testcarver/wrapper/" + methodInsnNode.owner; break; }//w w w . j a va 2 s. c o m } } else { String ownerName = methodInsnNode.owner.replace('/', '.'); for (Class<?> wrapperClass : wrapperClasses) { if (wrapperClass.getName().equals(ownerName)) { if (methodInsnNode.getOpcode() == Opcodes.INVOKESTATIC) { logger.debug("Replacing call " + methodInsnNode.name); methodInsnNode.owner = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + methodInsnNode.owner; } Type[] parameterTypes = Type.getArgumentTypes(methodInsnNode.desc); try { Class<?>[] parameterClasses = new Class<?>[parameterTypes.length]; int pos = 0; for (Type parameter : parameterTypes) { switch (parameter.getSort()) { case Type.OBJECT: parameterClasses[pos++] = Class.forName(parameter.getClassName()); break; case Type.BOOLEAN: parameterClasses[pos++] = boolean.class; break; case Type.BYTE: parameterClasses[pos++] = byte.class; break; case Type.CHAR: parameterClasses[pos++] = char.class; break; case Type.DOUBLE: parameterClasses[pos++] = double.class; break; case Type.FLOAT: parameterClasses[pos++] = float.class; break; case Type.INT: parameterClasses[pos++] = int.class; break; case Type.LONG: parameterClasses[pos++] = long.class; break; case Type.SHORT: parameterClasses[pos++] = short.class; break; } } Method method = wrapperClass.getMethod(methodInsnNode.name, parameterClasses); if (Modifier.isFinal(method.getModifiers())) { if (methodInsnNode.getOpcode() != Opcodes.INVOKESTATIC) { methodInsnNode.setOpcode(Opcodes.INVOKESTATIC); Type[] args = Type.getArgumentTypes(methodInsnNode.desc); Type returnType = Type.getReturnType(methodInsnNode.desc); Type[] newargs = new Type[args.length + 1]; newargs[0] = Type.getObjectType(methodInsnNode.owner); for (int i = 0; i < args.length; i++) newargs[i + 1] = args[i]; methodInsnNode.desc = Type.getMethodDescriptor(returnType, newargs); methodInsnNode.owner = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + methodInsnNode.owner; } else { methodInsnNode.name += "_final"; } logger.debug( "Method is final: " + methodInsnNode.owner + "." + methodInsnNode.name); } else { logger.debug("Method is not final: " + methodInsnNode.owner + "." + methodInsnNode.name); } } catch (Exception e) { logger.warn("Error while instrumenting: " + e); } break; } } // } else if(methodInsnNode.name.equals("getTime")) { // if(methodInsnNode.owner.equals("java/util/Calendar")) { // logger.debug("Replacing call "+methodInsnNode.name); // methodInsnNode.owner = "org/evosuite/testcarver/wrapper/java/util/Calendar"; // methodInsnNode.name = "getTime"; // methodInsnNode.desc = "(Ljava/util/Calendar;)Ljava/util/Date;"; // methodInsnNode.setOpcode(Opcodes.INVOKESTATIC); // } // } } } else if (insn.getOpcode() == Opcodes.NEW || insn.getOpcode() == Opcodes.CHECKCAST) { TypeInsnNode typeInsnNode = (TypeInsnNode) insn; Type generatedType = Type.getType(typeInsnNode.desc); String name = generatedType.getInternalName().replace('/', '.'); logger.debug("Checking for replacement of " + name); for (Class<?> wrapperClass : wrapperClasses) { if (wrapperClass.getName().equals(name)) { logger.debug("Replacing new " + name); typeInsnNode.desc = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + generatedType.getInternalName(); break; } } } } }
From source file:org.friz.bytecode.insn.InsnMatcher.java
License:Open Source License
/** * Matches the specified expression with the additional constraint. * @param expr The expression.// w ww . j a v a 2 s. co m * @param constraint The constraint. * @param reverse If the list should be reversed. * @return An {@link Iterator} of {@code {@link AbstractInsnNode}[]}. */ private Iterator<AbstractInsnNode[]> match(String expr, Constraint constraint, boolean reverse) { List<AbstractInsnNode[]> matches = new ArrayList<>(); String charList = listToChars(); if (reverse) charList = new StringBuilder(charList).reverse().toString(); Pattern regex = Pattern.compile(compilePattern(expr)); Matcher matcher = regex.matcher(charList); while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); AbstractInsnNode[] match = new AbstractInsnNode[end - start]; int ptr = 0; for (Iterator<AbstractInsnNode> it = list.iterator(); it.hasNext();) { AbstractInsnNode node = it.next(); if (node.getOpcode() != -1) { if (ptr >= start && ptr < end) { match[ptr - start] = node; } ptr++; } } if (constraint.satisfies(match)) matches.add(match); } return matches.iterator(); }
From source file:org.friz.bytecode.insn.InsnNodeUtility.java
License:Open Source License
/** * Reads the value of a numeric push instruction (which can be an * {@code ICONST_*} instruction, an {@code BIPUSH} instruction, an * {@code SIPUSH} instruction or a {@code LDC_*} instruction. * @param push The instruction node./* ww w . ja v a 2s . co m*/ * @return The numeric value. */ public static long getNumericPushValue(AbstractInsnNode push) { if (push instanceof InsnNode) { switch (push.getOpcode()) { case Opcodes.ICONST_M1: return -1; case Opcodes.ICONST_0: return 0; case Opcodes.ICONST_1: return 1; case Opcodes.ICONST_2: return 2; case Opcodes.ICONST_3: return 3; case Opcodes.ICONST_4: return 4; case Opcodes.ICONST_5: return 5; default: throw new AssertionError(); } } else if (push instanceof IntInsnNode) { return ((IntInsnNode) push).operand; } else { return ((Number) ((LdcInsnNode) push).cst).longValue(); } }
From source file:org.friz.bytecode.insn.InsnNodeUtility.java
License:Open Source License
public static AbstractInsnNode getNextInsn(AbstractInsnNode n) { while (n != null && n.getOpcode() == -1) { n = n.getNext();//from w ww . j av a 2s . c o m } return n; }
From source file:org.friz.bytecode.insn.InsnNodeUtility.java
License:Open Source License
public static AbstractInsnNode getPrevInsn(AbstractInsnNode n) { while (n != null && n.getOpcode() == -1) { n = n.getPrevious();/*www . jav a 2 s. c om*/ } return n; }
From source file:org.friz.transformers.IntShiftTransformer.java
License:Open Source License
@Override public void transform(Collection<ClassElement> elements) { for (ClassElement element : elements) { for (MethodElement method : element.methods()) { InsnMatcher matcher = new InsnMatcher(method.insn()); for (Iterator<AbstractInsnNode[]> it = matcher.match("pushinstruction ((ISHL)|(ISHR)|(IUSHR))"); it .hasNext();) {/*ww w .j ava 2 s . co m*/ AbstractInsnNode[] nodes = it.next(); AbstractInsnNode node = nodes[0]; if (node instanceof IntInsnNode || node instanceof LdcInsnNode || (node instanceof InsnNode && (node.getOpcode() >= 2 && node.getOpcode() <= 8))) { long push = InsnNodeUtility.getNumericPushValue(node); long realpush = push & 0x1f; if (push != realpush) { method.insn().set(node, InsnNodeUtility.createNumericPushInsn(realpush)); pInc(0); } else { tInc(0); } } } } } }