List of usage examples for org.objectweb.asm.tree MethodNode MethodNode
public MethodNode(final int access, final String name, final String descriptor, final String signature, final String[] exceptions)
From source file:de.tuberlin.uebb.jbop.optimizer.ClassNodeBuilder.java
License:Open Source License
/** * adds a new method (public accessor) with the given name and descriptor to the classNode. * /*from w w w . ja v a 2 s . co m*/ * @param methodName * the method name * @param descriptor * the descriptor * @param modifiers * the modifiers * @return the abstract optimizer test */ public ClassNodeBuilder addMethod(final String methodName, final String descriptor, final int... modifiers) { methodVarIndex = 1; final int modifier = getEffectiveModifier(modifiers); final MethodNode method = new MethodNode(modifier, methodName, descriptor, null, new String[] {}); method.exceptions = new ArrayList<>(); method.invisibleAnnotations = new ArrayList<>(); method.visibleAnnotations = new ArrayList<>(); classNode.methods.add(method); setLastMethod(method); if (isInterface) { method.access |= ACC_ABSTRACT; } return this; }
From source file:de.unisb.cs.st.javalanche.mutation.bytecodeMutations.removeSystemExit.RemoveSystemExitMethodNode.java
License:Open Source License
public RemoveSystemExitMethodNode(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor mv) {/*from www.j a v a 2s. c om*/ super(new MethodNode(access, name, desc, signature, exceptions)); next = mv; }
From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.IdentifiableInstrumenter.java
License:Open Source License
@SuppressWarnings("unchecked") public void transform(final ClassNode classNode) { if (!this.tracer.wasRedefined(this.readClass.getName())) return;//www . j a v a 2 s . c o m if ((classNode.access & ACC_INTERFACE) != 0) return; // do not modify if the parent class already implements Identifiable // (this is the case if the parent class was redefined) if (this.tracer.wasRedefined(Type.getObjectType(classNode.superName).getClassName())) return; classNode.fields .add(new FieldNode(ACC_PRIVATE | ACC_SYNTHETIC | ACC_TRANSIENT, ID_FIELD_NAME, "J", null, null)); classNode.interfaces.add(Type.getInternalName(Identifiable.class)); final MethodNode getIdMethod = new MethodNode(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tracing_get_object_id", "()J", null, null); // first, check if the id field is already set: getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new FieldInsnNode(GETFIELD, classNode.name, ID_FIELD_NAME, "J")); getIdMethod.instructions.add(new InsnNode(LCONST_0)); getIdMethod.instructions.add(new InsnNode(LCMP)); final LabelNode l0 = new LabelNode(); getIdMethod.instructions.add(new JumpInsnNode(IFNE, l0)); // code to be executed if it is not set: // synchronized, so that the id is only set once getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new InsnNode(MONITORENTER)); // label for the try-catch block around the synchronized block final LabelNode l1 = new LabelNode(), l2 = new LabelNode(), l3 = new LabelNode(); getIdMethod.tryCatchBlocks.add(new TryCatchBlockNode(l1, l2, l3, null)); getIdMethod.instructions.add(l1); // recheck if the id is set: getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new FieldInsnNode(GETFIELD, classNode.name, ID_FIELD_NAME, "J")); getIdMethod.instructions.add(new InsnNode(LCONST_0)); getIdMethod.instructions.add(new InsnNode(LCMP)); getIdMethod.instructions.add(new JumpInsnNode(IFNE, l2)); // it is still unset: getIdMethod.instructions.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class), "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";")); getIdMethod.instructions.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class), "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";")); getIdMethod.instructions.add(new InsnNode(DUP)); getIdMethod.instructions.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "pauseTracing", "()V")); getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(ObjectIdentifier.class), "instance", "L" + Type.getInternalName(ObjectIdentifier.class) + ";")); getIdMethod.instructions.add(new InsnNode(ACONST_NULL)); getIdMethod.instructions.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(ObjectIdentifier.class), "getNewId", "(Ljava/lang/Object;)J")); getIdMethod.instructions.add(new FieldInsnNode(PUTFIELD, classNode.name, ID_FIELD_NAME, "J")); getIdMethod.instructions.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V")); getIdMethod.instructions.add(l2); getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new InsnNode(MONITOREXIT)); getIdMethod.instructions.add(new JumpInsnNode(GOTO, l0)); getIdMethod.instructions.add(l3); getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new InsnNode(MONITOREXIT)); getIdMethod.instructions.add(new InsnNode(ATHROW)); getIdMethod.instructions.add(l0); getIdMethod.instructions.add(new VarInsnNode(ALOAD, 0)); getIdMethod.instructions.add(new FieldInsnNode(GETFIELD, classNode.name, ID_FIELD_NAME, "J")); getIdMethod.instructions.add(new InsnNode(LRETURN)); classNode.methods.add(getIdMethod); // now, instrument all constructors: initialize object id at the beginning of each constructor /* for (final Object methodObj: classNode.methods) { final MethodNode method = (MethodNode) methodObj; if (method.name.equals("<init>") && (method.access & ACC_ABSTRACT) == 0) { final InsnList newInsns = new InsnList(); newInsns.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class), "getInstance", "()L"+Type.getInternalName(Tracer.class)+";")); newInsns.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class), "getThreadTracer", "()L"+Type.getInternalName(ThreadTracer.class)+";")); newInsns.add(new InsnNode(DUP)); newInsns.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "pauseTracing", "()V")); newInsns.add(new VarInsnNode(ALOAD, 0)); newInsns.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(ObjectIdentifier.class), "instance", "L" + Type.getInternalName(ObjectIdentifier.class) + ";")); // TODO this may give different ids to the same object!! newInsns.add(new InsnNode(ACONST_NULL)); newInsns.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(ObjectIdentifier.class), "getNewId", "(Ljava/lang/Object;)J")); newInsns.add(new FieldInsnNode(PUTFIELD, classNode.name, ID_FIELD_NAME, "J")); newInsns.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V")); method.instructions.insert(newInsns); } } */ }
From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.PauseTracingInstrumenter.java
License:Open Source License
@SuppressWarnings("unchecked") public void transformMethod(final MethodNode method, final ListIterator<MethodNode> methodIt, final String className) { if ((method.access & ACC_ABSTRACT) != 0 || (method.access & ACC_NATIVE) != 0) return;// w w w .j a v a 2 s. c o m int tracerLocalVarIndex = (method.access & Opcodes.ACC_STATIC) == 0 ? 1 : 0; for (final Type t : Type.getArgumentTypes(method.desc)) tracerLocalVarIndex += t.getSize(); // increment number of local variables by one (for the threadtracer) ++method.maxLocals; // and increment all local variable indexes after the new one by one for (final Object o : method.localVariables) { final LocalVariableNode localVar = (LocalVariableNode) o; if (localVar.index >= tracerLocalVarIndex) ++localVar.index; } final LabelNode l0 = new LabelNode(); final LabelNode l1 = new LabelNode(); final ListIterator<AbstractInsnNode> insnIt = method.instructions.iterator(); insnIt.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class), "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";", false)); insnIt.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class), "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";", false)); insnIt.add(new InsnNode(DUP)); insnIt.add(new VarInsnNode(ASTORE, tracerLocalVarIndex)); insnIt.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "pauseTracing", "()V", true)); insnIt.add(l0); while (insnIt.hasNext()) { final AbstractInsnNode insn = insnIt.next(); switch (insn.getType()) { case AbstractInsnNode.INSN: switch (insn.getOpcode()) { case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: insnIt.previous(); insnIt.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); insnIt.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V", true)); insnIt.next(); } break; case AbstractInsnNode.IINC_INSN: if (((IincInsnNode) insn).var >= tracerLocalVarIndex) ++((IincInsnNode) insn).var; break; case AbstractInsnNode.VAR_INSN: if (((VarInsnNode) insn).var >= tracerLocalVarIndex) ++((VarInsnNode) insn).var; break; default: break; } } method.instructions.add(l1); method.instructions.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); method.instructions.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V", true)); method.instructions.add(new InsnNode(ATHROW)); method.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null)); // finally: create a copy of the method that gets the ThreadTracer as argument if (!"<clinit>".equals(method.name) && this.tracer.wasRedefined(className)) { final Type[] oldMethodArguments = Type.getArgumentTypes(method.desc); final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1); newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class); final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(method.desc), newMethodArguments); final MethodNode newMethod = new MethodNode(method.access, method.name, newMethodDesc, method.signature, (String[]) method.exceptions.toArray(new String[method.exceptions.size()])); methodIt.add(newMethod); final Map<LabelNode, LabelNode> newMethodLabels = new LazyLabelMap(); // copy the local variables information to the new method for (final Object o : method.localVariables) { final LocalVariableNode lv = (LocalVariableNode) o; newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature, newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index)); } newMethod.maxLocals = method.maxLocals; newMethod.maxStack = method.maxStack; // copy the try-catch-blocks for (final Object o : method.tryCatchBlocks) { final TryCatchBlockNode tcb = (TryCatchBlockNode) o; newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start), newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type)); } // skip the first 4 instructions, replace them with this: newMethod.instructions.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); final Iterator<AbstractInsnNode> oldInsnIt = method.instructions.iterator(4); // and add all the other instructions while (oldInsnIt.hasNext()) { final AbstractInsnNode insn = oldInsnIt.next(); newMethod.instructions.add(insn.clone(newMethodLabels)); } } }
From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.TracingMethodInstrumenter.java
License:Open Source License
@SuppressWarnings("unchecked") public void transform(final ListIterator<MethodNode> methodIt) { // do not modify abstract or native methods if ((this.methodNode.access & ACC_ABSTRACT) != 0 || (this.methodNode.access & ACC_NATIVE) != 0) return;//from w w w . j a v a 2 s. c om // check out what labels are jump targets (only these have to be traced) analyze(this.methodNode); this.instructionIterator = new FixedInstructionIterator(this.methodNode.instructions); // in the old method, initialize the new local variable for the threadtracer this.instructionIterator.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class), "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";", false)); this.instructionIterator.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class), "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";", false)); this.instructionIterator.add(new InsnNode(DUP)); this.instructionIterator.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex)); this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "isPaused", "()Z", true)); final LabelNode noTracingLabel = new LabelNode(); this.instructionIterator.add(new JumpInsnNode(IFNE, noTracingLabel)); // create a copy of the (uninstrumented) instructions (later, while iterating through the instructions) final InsnList oldInstructions = new InsnList(); final Map<LabelNode, LabelNode> labelCopies = new LazyLabelMap(); // copy the try-catch-blocks final Object[] oldTryCatchblockNodes = this.methodNode.tryCatchBlocks.toArray(); for (final Object o : oldTryCatchblockNodes) { final TryCatchBlockNode tcb = (TryCatchBlockNode) o; final TryCatchBlockNode newTcb = new TryCatchBlockNode(labelCopies.get(tcb.start), labelCopies.get(tcb.end), labelCopies.get(tcb.handler), tcb.type); this.methodNode.tryCatchBlocks.add(newTcb); } // increment number of local variables by one (for the threadtracer) ++this.methodNode.maxLocals; // and increment all local variable indexes after the new one by one for (final Object o : this.methodNode.localVariables) { final LocalVariableNode localVar = (LocalVariableNode) o; if (localVar.index >= this.tracerLocalVarIndex) ++localVar.index; } // store information about local variables in the ReadMethod object List<LocalVariable> localVariables = new ArrayList<LocalVariable>(); for (final Object o : this.methodNode.localVariables) { final LocalVariableNode localVar = (LocalVariableNode) o; while (localVariables.size() <= localVar.index) localVariables.add(null); localVariables.set(localVar.index, new LocalVariable(localVar.index, localVar.name, localVar.desc)); } this.readMethod.setLocalVariables(localVariables.toArray(new LocalVariable[localVariables.size()])); localVariables = null; // each method must start with a (dedicated) label: assert this.readMethod.getInstructions().isEmpty(); traceLabel(null, InstructionType.METHODENTRY); assert this.readMethod.getInstructions().size() == 1 && this.readMethod.getInstructions().get(0) instanceof LabelMarker && ((LabelMarker) this.readMethod.getInstructions().get(0)).isAdditionalLabel(); this.readMethod.setMethodEntryLabel((LabelMarker) this.readMethod.getInstructions().get(0)); // needed later: final LabelNode l0 = new LabelNode(); this.instructionIterator.add(l0); // then, visit the instructions that were in the method before while (this.instructionIterator.hasNext()) { final AbstractInsnNode insnNode = this.instructionIterator.next(); switch (insnNode.getType()) { case AbstractInsnNode.INSN: transformInsn((InsnNode) insnNode); break; case AbstractInsnNode.INT_INSN: transformIntInsn((IntInsnNode) insnNode); break; case AbstractInsnNode.VAR_INSN: transformVarInsn((VarInsnNode) insnNode); break; case AbstractInsnNode.TYPE_INSN: transformTypeInsn((TypeInsnNode) insnNode); break; case AbstractInsnNode.FIELD_INSN: transformFieldInsn((FieldInsnNode) insnNode); break; case AbstractInsnNode.METHOD_INSN: transformMethodInsn((MethodInsnNode) insnNode); break; case AbstractInsnNode.JUMP_INSN: transformJumpInsn((JumpInsnNode) insnNode); break; case AbstractInsnNode.LABEL: transformLabel((LabelNode) insnNode); break; case AbstractInsnNode.LDC_INSN: transformLdcInsn((LdcInsnNode) insnNode); break; case AbstractInsnNode.IINC_INSN: transformIincInsn((IincInsnNode) insnNode); break; case AbstractInsnNode.TABLESWITCH_INSN: transformTableSwitchInsn((TableSwitchInsnNode) insnNode); break; case AbstractInsnNode.LOOKUPSWITCH_INSN: transformLookupSwitchInsn((LookupSwitchInsnNode) insnNode); break; case AbstractInsnNode.MULTIANEWARRAY_INSN: transformMultiANewArrayInsn((MultiANewArrayInsnNode) insnNode); break; case AbstractInsnNode.FRAME: // ignore break; case AbstractInsnNode.LINE: // ignore break; default: throw new RuntimeException("Unknown instruction type " + insnNode.getType() + " (" + insnNode.getClass().getSimpleName() + ")"); } oldInstructions.add(insnNode.clone(labelCopies)); } assert this.outstandingInitializations == 0; // add the (old) try-catch blocks to the readMethods // (can only be done down here since we use the information in the // labels map) for (final Object o : oldTryCatchblockNodes) { final TryCatchBlockNode tcb = (TryCatchBlockNode) o; this.readMethod.addTryCatchBlock(new TryCatchBlock(this.labels.get(tcb.start), this.labels.get(tcb.end), this.labels.get(tcb.handler), tcb.type)); } final LabelNode l1 = new LabelNode(); this.instructionIterator.add(l1); final int newPos = this.readMethod.getInstructions().size(); traceLabel(null, InstructionType.METHODEXIT); assert this.readMethod.getInstructions().size() == newPos + 1; final AbstractInstruction abnormalTerminationLabel = this.readMethod.getInstructions().get(newPos); assert abnormalTerminationLabel instanceof LabelMarker; this.readMethod.setAbnormalTerminationLabel((LabelMarker) abnormalTerminationLabel); this.methodNode.instructions.add(new InsnNode(ATHROW)); // add a try catch block around the method so that we can trace when this method is left // by a thrown exception this.methodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null)); // now add the code that is executed if no tracing should be performed this.methodNode.instructions.add(noTracingLabel); if (this.firstLine != -1) this.methodNode.instructions.add(new LineNumberNode(this.firstLine, noTracingLabel)); this.methodNode.instructions.add(new InsnNode(ACONST_NULL)); this.methodNode.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex)); this.methodNode.instructions.add(oldInstructions); // finally: create a copy of the method that gets the ThreadTracer as argument // this is only necessary for private methods or "<init>" if (this.tracer.wasRedefined(this.readMethod.getReadClass().getName()) && (this.methodNode.access & ACC_PRIVATE) != 0) { final Type[] oldMethodArguments = Type.getArgumentTypes(this.methodNode.desc); final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1); newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class); final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(this.methodNode.desc), newMethodArguments); final MethodNode newMethod = new MethodNode(this.methodNode.access, this.methodNode.name, newMethodDesc, this.methodNode.signature, (String[]) this.methodNode.exceptions.toArray(new String[this.methodNode.exceptions.size()])); methodIt.add(newMethod); int threadTracerParamPos = ((this.readMethod.getAccess() & Opcodes.ACC_STATIC) == 0 ? 1 : 0); for (final Type t : oldMethodArguments) threadTracerParamPos += t.getSize(); final Map<LabelNode, LabelNode> newMethodLabels = new LazyLabelMap(); // copy the local variables information to the new method for (final Object o : this.methodNode.localVariables) { final LocalVariableNode lv = (LocalVariableNode) o; newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature, newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index)); } newMethod.maxLocals = this.methodNode.maxLocals; newMethod.maxStack = this.methodNode.maxStack; // copy the try-catch-blocks for (final Object o : this.methodNode.tryCatchBlocks) { final TryCatchBlockNode tcb = (TryCatchBlockNode) o; newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start), newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type)); } // skip the first 6 instructions, replace them with these: newMethod.instructions.add(new VarInsnNode(ALOAD, threadTracerParamPos)); newMethod.instructions.add(new InsnNode(DUP)); newMethod.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex)); newMethod.instructions.add(new JumpInsnNode(IFNULL, newMethodLabels.get(noTracingLabel))); final Iterator<AbstractInsnNode> oldInsnIt = this.methodNode.instructions.iterator(6); // and add all the other instructions while (oldInsnIt.hasNext()) { final AbstractInsnNode insn = oldInsnIt.next(); newMethod.instructions.add(insn.clone(newMethodLabels)); } } ready(); }
From source file:dodola.anole.lib.ConstructorDelegationDetector.java
License:Apache License
/** * Splits the constructor in two methods, the "set up" and the "body" parts (see above). */// w ww . j a v a2 s .co m private static Constructor split(String owner, MethodNode method, VarInsnNode loadThis, MethodInsnNode delegation, int loadThisLine) { String[] exceptions = ((List<String>) method.exceptions).toArray(new String[method.exceptions.size()]); String newDesc = method.desc.replaceAll("\\((.*)\\)V", "([Ljava/lang/Object;$1)Ljava/lang/Object;"); MethodNode initArgs = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "init$args", newDesc, null, exceptions); AbstractInsnNode insn = loadThis.getNext(); while (insn != delegation) { insn.accept(initArgs); insn = insn.getNext(); } LabelNode labelBefore = new LabelNode(); labelBefore.accept(initArgs); GeneratorAdapter mv = new GeneratorAdapter(initArgs, initArgs.access, initArgs.name, initArgs.desc); // Copy the arguments back to the argument array // The init_args part cannot access the "this" object and can have side effects on the // local variables. Because of this we use the first argument (which we want to keep // so all the other arguments remain unchanged) as a reference to the array where to // return the values of the modified local variables. Type[] types = Type.getArgumentTypes(initArgs.desc); int stack = 1; // Skip the first one which is a reference to the local array. for (int i = 1; i < types.length; i++) { Type type = types[i]; // This is not this, but the array of local arguments final values. mv.visitVarInsn(Opcodes.ALOAD, 0); mv.push(i); mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), stack); mv.box(type); mv.arrayStore(Type.getType(Object.class)); stack += type.getSize(); } // Create the args array with the values to send to the delegated constructor Type[] returnTypes = Type.getArgumentTypes(delegation.desc); // The extra element for the qualified name of the constructor. mv.push(returnTypes.length + 1); mv.newArray(Type.getType(Object.class)); int args = mv.newLocal(Type.getType("[Ljava/lang/Object;")); mv.storeLocal(args); for (int i = returnTypes.length - 1; i >= 0; i--) { Type type = returnTypes[i]; mv.loadLocal(args); mv.swap(type, Type.getType(Object.class)); mv.push(i + 1); mv.swap(type, Type.INT_TYPE); mv.box(type); mv.arrayStore(Type.getType(Object.class)); } // Store the qualified name of the constructor in the first element of the array. mv.loadLocal(args); mv.push(0); mv.push(delegation.owner + "." + delegation.desc); // Name of the constructor to be called. mv.arrayStore(Type.getType(Object.class)); mv.loadLocal(args); mv.returnValue(); newDesc = method.desc.replace("(", "(L" + owner + ";"); MethodNode body = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "init$body", newDesc, null, exceptions); LabelNode labelAfter = new LabelNode(); labelAfter.accept(body); Set<LabelNode> bodyLabels = new HashSet<LabelNode>(); insn = delegation.getNext(); while (insn != null) { if (insn instanceof LabelNode) { bodyLabels.add((LabelNode) insn); } insn.accept(body); insn = insn.getNext(); } // manually transfer the exception table from the existing constructor to the new // "init$body" method. The labels were transferred just above so we can reuse them. //noinspection unchecked for (TryCatchBlockNode tryCatch : (List<TryCatchBlockNode>) method.tryCatchBlocks) { tryCatch.accept(body); } //noinspection unchecked for (LocalVariableNode variable : (List<LocalVariableNode>) method.localVariables) { boolean startsInBody = bodyLabels.contains(variable.start); boolean endsInBody = bodyLabels.contains(variable.end); if (!startsInBody && !endsInBody) { if (variable.index != 0) { // '#0' on init$args is not 'this' variable.accept(initArgs); } } else if (startsInBody && endsInBody) { variable.accept(body); } else if (!startsInBody && endsInBody) { // The variable spans from the args to the end of the method, create two: if (variable.index != 0) { // '#0' on init$args is not 'this' LocalVariableNode var0 = new LocalVariableNode(variable.name, variable.desc, variable.signature, variable.start, labelBefore, variable.index); var0.accept(initArgs); } LocalVariableNode var1 = new LocalVariableNode(variable.name, variable.desc, variable.signature, labelAfter, variable.end, variable.index); var1.accept(body); } else { throw new IllegalStateException("Local variable starts after it ends."); } } return new Constructor(loadThis, loadThisLine, initArgs, delegation, body); }
From source file:edu.ubc.mirrors.holograms.FrameAnalyzerAdaptor.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { final MethodVisitor superVisitor = super.visitMethod(access, name, desc, signature, exceptions); final Map<Label, LabelNode> labelNodes = new HashMap<Label, LabelNode>(); final FrameVerifier verifier = new FrameVerifier(vm, loader, holograms); MethodNode analyzer = new MethodNode(access, name, desc, null, null) { @Override/*w w w . j av a 2 s .c om*/ public void visitEnd() { FrameAnalyzer a = new FrameAnalyzer(verifier); Frame<FrameValue>[] frames = null; try { frames = a.analyze(thisType.getInternalName(), this); if (superVisitor != null) { if (insertFrames) { frames = a.insertFrames(); } accept(superVisitor); } } catch (Throwable e) { if (e instanceof IndexOutOfBoundsException && maxLocals == 0 && maxStack == 0) { throw new RuntimeException( "Data flow checking option requires valid, non zero maxLocals and maxStack values."); } if (frames == null) { frames = a.getFrames(); } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); printAnalyzerResult(this, frames, pw); pw.close(); throw new RuntimeException(sw.toString(), e); } } @Override protected LabelNode getLabelNode(Label l) { LabelNode node = labelNodes.get(l); if (node == null) { node = new LabelNode(l); labelNodes.put(l, node); } return node; } }; analyzer.instructions = new FrameInsnList(); // Inline subroutines since other pieces of the pipeline can't handle them return new JSRInlinerAdapter(analyzer, access, name, desc, signature, exceptions); }
From source file:edu.ubc.mirrors.test.NativeMethodCounter.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_NATIVE) != 0) { nativeMethodCount++;/*from w ww . j av a 2 s.co m*/ Set<MethodNode> methods = classesWithNativeMethods.get(currentClass); if (methods == null) { methods = new HashSet<MethodNode>(); classesWithNativeMethods.put(currentClass, methods); } methods.add(new MethodNode(access, name, desc, signature, exceptions)); } return super.visitMethod(access, name, desc, signature, exceptions); }
From source file:fr.insalyon.telecom.jooflux.InvokeMethodAdapter.java
License:Mozilla Public License
public InvokeMethodAdapter(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor methodVisitor) {// w w w .jav a 2 s .c om super(access, new MethodNode(access, name, desc, signature, exceptions)); this.methodVisitor = methodVisitor; }
From source file:gemlite.core.internal.asm.serialize.DataSerializeHelper.java
License:Apache License
private void implementInterface(ClassNode cn) { MethodNode toMethod = new MethodNode(ACC_PUBLIC, "toData", "(Ljava/io/DataOutput;)V", null, new String[] { "java/io/IOException" }); InsnList instToMethod = toMethod.instructions; MethodNode fromMethod = new MethodNode(ACC_PUBLIC, "fromData", "(Ljava/io/DataInput;)V", null, new String[] { "java/io/IOException", "java/lang/ClassNotFoundException" }); InsnList instFromMethod = fromMethod.instructions; for (int i = 0; i < cn.fields.size(); i++) { FieldNode fn = (FieldNode) cn.fields.get(i); fp.toMethod(cn.name, fn, instToMethod); fp.fromMethod(cn.name, fn, instFromMethod); }//from w w w . j a v a 2s . c o m instToMethod.add(new InsnNode(RETURN)); cn.methods.add(toMethod); instFromMethod.add(new InsnNode(RETURN)); cn.methods.add(fromMethod); // if (DomainMojoHelper.log().isDebugEnabled()) // DomainMojoHelper.log().debug(cn.name + " add toData and fromData method."); }