List of usage examples for org.objectweb.asm.tree InsnList add
public void add(final InsnList insnList)
From source file:hellfirepvp.astralsorcery.core.patch.helper.PatchModifyAttributes.java
License:Open Source License
@Override public void patch(ClassNode cn) { MethodNode mn = getMethod(cn, "getAttributeModifiers", "func_111283_C", "(Lnet/minecraft/inventory/EntityEquipmentSlot;)Lcom/google/common/collect/Multimap;"); InsnList list = new InsnList(); list.add(new VarInsnNode(Opcodes.ALOAD, 0)); list.add(new VarInsnNode(Opcodes.ALOAD, 1)); list.add(new VarInsnNode(Opcodes.ALOAD, 2)); list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "hellfirepvp/astralsorcery/common/util/SwordSharpenHelper", "applySharpenModifier", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/inventory/EntityEquipmentSlot;Lcom/google/common/collect/Multimap;)V", false));/*from w w w .java 2s. c o m*/ mn.instructions.insert(mn.instructions.getLast().getPrevious().getPrevious(), list); }
From source file:io.awacs.plugin.stacktrace.ClassTransformer.java
License:Apache License
/** * ??/*from ww w.j a v a 2s. c o m*/ * 1?StackFrames.push(0)??? * 2???this??? * 3?StackFrames.push(1)??? * 4?? */ private void transformPlainMethod(MethodNode mn, ClassNode cn) { InsnList before = new InsnList(); before.add(new LdcInsnNode(cn.name.replaceAll("/", "."))); before.add(new LdcInsnNode(mn.name)); before.add(new LdcInsnNode(0)); before.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames", "push", "(Ljava/lang/String;Ljava/lang/String;I)V", false)); InsnList end = new InsnList(); end.add(new LdcInsnNode(cn.name.replaceAll("/", "."))); end.add(new LdcInsnNode(mn.name)); end.add(new LdcInsnNode(1)); end.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames", "push", "(Ljava/lang/String;Ljava/lang/String;I)V", false)); List<AbstractInsnNode> insts = new LinkedList<>(); for (int i = 0; i < mn.instructions.size(); i++) { int opcode = mn.instructions.get(i).getOpcode(); if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) { insts.add(mn.instructions.get(i)); } } if (!insts.isEmpty()) { mn.instructions.insert(before); for (AbstractInsnNode node : insts) { mn.instructions.insertBefore(node, end); } } mn.maxStack = mn.maxStack + 5; }
From source file:ivorius.ivtoolkit.asm.IvInsnHelper.java
License:Apache License
public static void insertDUP3(InsnList list) { list.add(new InsnNode(DUP2_X1)); // 1 2 3 1 2 list.add(new InsnNode(POP2)); // 3 1 2 list.add(new InsnNode(DUP_X2)); // 3 1 2 3 list.add(new InsnNode(DUP_X2)); // 3 1 2 3 3 list.add(new InsnNode(POP)); // 1 2 3 3 list.add(new InsnNode(DUP2_X1)); // 1 2 3 1 2 3 }
From source file:ivorius.ivtoolkit.asm.IvInsnHelper.java
License:Apache License
public static void insertDUP4(InsnList list) { list.add(new InsnNode(DUP2_X2)); // 1 2 3 4 1 2 list.add(new InsnNode(POP2)); // 3 4 1 2 list.add(new InsnNode(DUP2_X2)); // 3 4 1 2 3 4 list.add(new InsnNode(DUP2_X2)); // 3 4 1 2 3 4 3 4 list.add(new InsnNode(POP2)); // 1 2 3 4 3 4 list.add(new InsnNode(DUP2_X2)); // 1 2 3 4 1 2 3 4 }
From source file:jaspex.speculation.newspec.FlowFrame.java
License:Open Source License
/** Mtodo que implementa a deteco e correco do problema dos mltiplos fluxos de controlo. * Retorna true se alterou o mtodo, e false cc. **///from w ww . j a va 2 s. c o m private static boolean computeControlFlowGraph(String owner, String superOwner, MethodNode mn, LabelMap labelMap, boolean ranBefore) { //Log.debug("Visiting: {}.{}", owner, mn.name); FlowAnalyzer analyzer = new FlowAnalyzer(new FutureVerifier(owner, superOwner)); try { analyzer.analyze(owner, mn); //if (ranBefore) printCode(mn, Arrays.asList(analyzer.getFrames()), null, null); FrameInjector.injectFrames(mn, analyzer.getFrames()); return false; } catch (AnalyzerException e) { /*e.printStackTrace();*/ } // Se chegmos aqui, o Analyzer detectou problemas, e vamos ter que fazer correces no mtodo // Detectar o primeiro LabelNode onde aparece um MergedUninitializedValue LabelNode problemLabelNode = null; FlowFrame problemFrame = null; int problemPosition = -1; boolean problemInStack = false; List<FlowFrame> frames = listGenericCast(Arrays.asList(analyzer.getFrames())); outer: for (int i = 0; i < frames.size(); i++) { FlowFrame f = frames.get(i); if (f == null) continue; int localsStartPos = 0; int stackStartPos = 0; // Identificar se alguma entrada nos locals/stack da frame deve ser escolhida como // problemtica // Isto um loop porque algumas das entradas encontradas podem ser backwards edges, // e no estamos interessadas nessas while (true) { for (int j = localsStartPos; j < f.getLocals(); j++) { if (f.getLocal(j) instanceof MergedUninitializedValue) { problemPosition = j; problemInStack = false; localsStartPos = j + 1; } } for (int j = stackStartPos; j < f.getStackSize() && (problemPosition < 0); j++) { if (f.getStack(j) instanceof MergedUninitializedValue) { problemPosition = j; problemInStack = true; stackStartPos = j + 1; } } // J processamos completamente a frame e no encontramos nada, ou s // encontramos backwards edges, passar prxima if (problemPosition < 0) continue outer; if ((f.predecessors().size() > 0) && (getPredecessorWithFuture(f, problemInStack, problemPosition) == null)) { // Isto pode acontecer quando instruco que encontrmos o target de // um "backwards edge". Nesse caso, no esta a instruco que queremos // processar, mas queremos uma que tenha como predecessor um Future, // no um MergedUninitializedValue /*Log.debug("Found result of backwards edge at " + (problemInStack ? "stack" : "locals") + " position " + i + ", continuing");*/ problemPosition = -1; continue; } if (problemInStack && !(mn.instructions.get(i) instanceof LabelNode) && (mn.instructions.get(i - 1) instanceof VarInsnNode)) { // Caso especial: Uma instruco de load colocou um // MergedUninitializedValue na stack, e como no estava l na instruco // anterior o getPredecessorWithFuture no detecta este caso, mas no // estamos interessados nesta frame, estamos interessadas na que originou // o MUV que estava nos locals problemPosition = -1; continue; } // Frame e posio escolhidas so consideradas problemticas break; } AbstractInsnNode insn = mn.instructions.get(i); // First node with problematic frame should be a LabelNode if (!(insn instanceof LabelNode)) throw new AssertionError(); problemLabelNode = (LabelNode) insn; problemFrame = f; printCode(mn, frames, problemFrame.predecessors(), f); Log.trace("First problematic frame is " + f + "\n\t\tPredecessors: " + f.predecessors()); break; } if (problemLabelNode == null) { Log.warn("Errors found during analysis, bytecode possibly invalid, bailing out"); throw new AssertionError(); // Causar revert de todas as alteraes no mtodo //return false; } // Duplicar cdigo problemtico, para depois o alterar com o DelayGetFutureMethodVisitor InsnList il = new InsnList(); // Label que marca o inicio do cdigo a copiar LabelNode copiedBlockStartLabel = new LabelNode(); // Criar mapa para passar ao AbstractInsnNode (ver javadoc ASM) //LabelMap labelMap = new LabelMap(); labelMap.put(problemLabelNode, copiedBlockStartLabel); // Adiciona copiedBlockStartLabel nova il il.add(problemLabelNode.clone(labelMap)); // Usado para manter a ltima (inclusiv) instruco do bloco copiado AbstractInsnNode lastInsn = null; // Simular execuo das frames durante a cpia // O objectivo disto resolver problemas como o NewSpecExample17, onde cdigo copiado deve // fazer branch para: // -- Cdigo copiado numa iterao anterior ("cdigo novo") se a frame continuar a conter um // futuro, porque o cdigo novo o que suposto lidar com a existncia do futuro // -- Cdigo existente do mtodo ("cdigo antigo") se a frame j no contm um futuro, o que // significa que a concretizao se faz durante o bloco actual FlowFrame currentFrame = analyzer.newFrame(problemFrame); if (problemInStack) { currentFrame.setStack(problemPosition, ((MergedUninitializedValue) currentFrame.getStack(problemPosition)).getFuture()); } else { currentFrame.setLocal(problemPosition, ((MergedUninitializedValue) currentFrame.getLocal(problemPosition)).getFuture()); } for (AbstractInsnNode n = problemLabelNode.getNext(); n != null; n = n.getNext()) { if (n instanceof LabelNode) { LabelNode labelNode = (LabelNode) n; if (getNextIgnoreLabelLineNop(labelNode) instanceof FrameNode) { // Se label se refere a uma frame, o bloco terminou // FIXME: Tem que se saltar sempre para labels novas, se existirem? il.add(new JumpInsnNode(GOTO, labelMap.get(labelNode))); break; } else { // Caso contrrio, substituimos por uma nova label, para permitir // que os LineNumberNodes continuem a existir no novo cdigo. labelMap.put(labelNode, new LabelNode()); } } // Detectar, no caso de um salto, qual a label que se deve utilizar (ver comentrios acima) // FIXME: Ser que no caso do switch/case algumas das labels tm que apontar para o cdigo // novo, e outras para o antigo? if (n instanceof JumpInsnNode || n instanceof LookupSwitchInsnNode || n instanceof TableSwitchInsnNode) { // Se ProblemPosition ainda tem um Futuro, saltar para cdigo novo if ((problemInStack && isFuture(currentFrame.getStack(problemPosition))) || (!problemInStack && isFuture(currentFrame.getLocal(problemPosition)))) { il.add(n.clone(labelMap)); } else { // Deixou de ter um Futuro, saltar para cdigo antigo il.add(n.clone(new LabelMap())); } } else { il.add(n.clone(labelMap)); } lastInsn = n; // Se chegamos ao fim do bloco (GOTO, ATHROW ou *RETURN) tambm paramos a cpia if (n.getOpcode() == GOTO || n.getOpcode() == ATHROW || returnOpcodes.contains(n.getOpcode())) break; // Actualizar currentFrame -- simular execuo da instruco actual try { currentFrame = analyzer.computeNextFrame(currentFrame, n); } catch (AnalyzerException e) { // Ocorreu um erro, continuamos com a ltima frame vlida //Log.debug("WARNING: AnalyzerException during computeNextFrame"); } //Log.debug("CurrentFrame: " + currentFrame + " (isFuture? " + // (isFuture(currentFrame.getLocal(problemPosition)) ? "yes" : "no") + ")"); } LabelNode copiedBlockEndLabel = new LabelNode(); il.add(copiedBlockEndLabel); mn.instructions.add(il); il = mn.instructions; // Detectar qual dos seus predecessores originou o Futuro que ficou no MergedUninitializedValue if (problemFrame.predecessors().isEmpty()) { // ProblemFrame o inicio de um exception handler // Popular predecessors da problemFrame com control flows de exceptions analyzer.populateExceptionPredecessors(problemFrame); //printCode(mn, frames, problemFrame.predecessors()); // Adicionar um novo tryCatchBlock com: // - Range [Primeira instruco com Future, // ltima instruco que tem future *E* faz parte da lista de predecessors] // Razo: Lista de predecessors --> handler ainda est activo // Tem future --> future pode ser substituido mais tarde // (por exemplo { i = doA(); j = doB(); i = 0 }) // - Target: Novo bloco copiado -- copiedBlockStartLabel AbstractInsnNode startBlockInsn = null; AbstractInsnNode endBlockInsn = null; for (FlowFrame f : problemFrame.predecessors()) { BasicValue v = problemInStack ? f.getStack(problemPosition) : f.getLocal(problemPosition); if (isFuture(v)) { AbstractInsnNode insn = insnForFrame(il, frames, f); if (startBlockInsn == null) { startBlockInsn = insn; } if (endBlockInsn != null) { // Detectar se o bloco actual terminou if (getTryCatchBlock(mn, startBlockInsn, insn) == null) break; } endBlockInsn = insn; } else if (startBlockInsn != null) { break; } } // Provavelmente o problema do NewSpecExample20, ver comentrios no ficheiro if (startBlockInsn == null || endBlockInsn == null) { throw new AssertionError("KNOWN BUG: Probably picked the wrong code to copy"); } //Log.debug("PredecessorInsn [Exception]: First " + startBlockInsn + " Last " + endBlockInsn); LabelNode startBlockLabel = labelBefore(il, startBlockInsn); LabelNode endBlockLabel = labelAfter(il, endBlockInsn); TryCatchBlockNode originalBlock = getTryCatchBlock(mn, startBlockInsn, endBlockInsn); assert (originalBlock != null); mn.tryCatchBlocks.add(0, new SafeTryCatchBlockNode(startBlockLabel, endBlockLabel, copiedBlockStartLabel, originalBlock.type)); if (originalBlock.start.equals(startBlockLabel) && originalBlock.end.equals(endBlockLabel)) { // Novo bloco substitui completamente o antigo mn.tryCatchBlocks.remove(originalBlock); } else { // Como o novo try/catch substitui o antigo, para que o verificador da JVM e do ASM // lidem melhor com a coisa (embora segundo os specs no seria necessrio), vamos // alterar o inicio e/ou o fim do bloco original para deixar de conter as instruces // que esto cobertas pelo novo bloco if (originalBlock.start.equals(startBlockLabel)) { originalBlock.start = endBlockLabel; } else if (originalBlock.end.equals(endBlockLabel)) { originalBlock.end = startBlockLabel; } else { Log.debug("FIXME: Original (old) try catch block should be adjusted"); } } } else { // Existem predecessores, problemFrame um bloco de cdigo normal FlowFrame predecessorWithFuture = getPredecessorWithFuture(problemFrame, problemInStack, problemPosition); if (predecessorWithFuture == null) throw new AssertionError(); AbstractInsnNode predecessorInsn = insnForFrame(il, frames, predecessorWithFuture); //Log.debug("PredecessorInsn: " + predecessorInsn); // Detectar como vai ser feito o salto para a nova seco do cdigo // Casos possveis: // - Predecessor instruco imediatamente antes da labelnode (e no um salto) // -> No alteramos, adicionamos goto // -> Se for um salto, podemos ou no ter que alterar, dependendo de ser ou no // um salto para a labelNode que marca o incio da seco problemtica // - Predecessor jump / table|lookup switch // -> Temos que alterar // Fazendo clone com o labelmap obtemos um n que tem o salto para a nova label trocado // pelo salto para a antiga. if (directlyPrecedes(predecessorInsn, problemLabelNode) && !hasLabelAsTarget(predecessorInsn, problemLabelNode)) { // No temos que alterar n, saltamos directamente para novo bloco il.insert(predecessorInsn, new JumpInsnNode(GOTO, copiedBlockStartLabel)); } else { if (!((predecessorInsn instanceof LookupSwitchInsnNode) || (predecessorInsn instanceof TableSwitchInsnNode) || (predecessorInsn instanceof JumpInsnNode))) { throw new AssertionError(); // Instruco tem que ser salto } // N tem que ser alterado AbstractInsnNode replacementNode = predecessorInsn.clone(labelMap); il.set(predecessorInsn, replacementNode); if (lastInsn == predecessorInsn) lastInsn = replacementNode; } } // Corrigir exception handlers do mtodo // Como blocos de cdigo so copiados, temos tambm que copiar os exception handlers, // para que os try/catch continuem a funcionar correctamente List<AbstractInsnNode> copiedCodeRange = getRange(problemLabelNode, lastInsn); List<SafeTryCatchBlockNode> newTryCatchBlocks = new ArrayList<SafeTryCatchBlockNode>(); for (TryCatchBlockNode tryCatchBlock : mn.tryCatchBlocks) { List<AbstractInsnNode> blockRange = getRange(tryCatchBlock.start, tryCatchBlock.end); blockRange.retainAll(copiedCodeRange); if (blockRange.isEmpty()) continue; // Corner case: Supostamente um try/catch block cobre [start, end[, enquanto // que o getRange devolve [start, end] if (blockRange.size() == 1 && problemLabelNode == tryCatchBlock.end) continue; //Log.debug("Exception handler table needs fixup"); // Determinar a nova label de inicio LabelNode newStart; if (copiedCodeRange.contains(tryCatchBlock.start)) { // loco excepo comea j dentro do copiedCodeRange newStart = labelMap.getMapping(tryCatchBlock.start); } else { // Bloco excepo comea fora do copiedCodeRange newStart = copiedBlockStartLabel; } // Determinar a nova label de fim LabelNode newEnd; if (copiedCodeRange.contains(tryCatchBlock.end)) { // Bloco excepo comea dentro do copiedCodeRange newEnd = labelMap.getMapping(tryCatchBlock.end); } else { // Bloco excepo acaba fora do copiedCodeRange newEnd = copiedBlockEndLabel; } newTryCatchBlocks .add(new SafeTryCatchBlockNode(newStart, newEnd, tryCatchBlock.handler, tryCatchBlock.type)); } mn.tryCatchBlocks.addAll(newTryCatchBlocks); return true; }
From source file:jvstm.atomic.ProcessParNestAnnotations.java
License:Open Source License
protected static void processClassFile(File classFile) { alreadyProcessed = new ArrayList<String>(); callablesCreated = new HashMap<String, String>(); InputStream is = null;// w w w . j a v a 2 s . c o m try { // get an input stream to read the bytecode of the class is = new FileInputStream(classFile); ClassNode cn = new ClassNode(ASM4); ClassReader cr = new ClassReader(is); cr.accept(cn, 0); List<MethodNode> parNestedMethods = new ArrayList<MethodNode>(); MethodNode combinerMethod = null; MethodNode execMethod = null; List<MethodNode> staticMethodsToAdd = new ArrayList<MethodNode>(); boolean parallelSpawn = extendsParallelSpawn(cn); boolean unsafeSpawn = extendsUnsafeSpawn(cn); if (parallelSpawn || unsafeSpawn) { Iterator<MethodNode> methodIter = cn.methods.iterator(); while (methodIter.hasNext()) { MethodNode mn = methodIter.next(); if (mn.name.equals("exec") && execMethod == null) { execMethod = mn; continue; } if (mn.invisibleAnnotations == null) { continue; } for (AnnotationNode an : mn.invisibleAnnotations) { if (an.desc.equals(PAR_NEST.getDescriptor())) { // Ensure the method can be called from outside mn.access = (mn.access & ~ACC_PRIVATE) | ACC_PUBLIC; parNestedMethods.add(mn); String uniqueMethodName = createUniqueMethodName(mn.name); String callableClass; if (parallelSpawn) { callableClass = cn.name + "$nested$work$unit$" + uniqueMethodName; } else { callableClass = cn.name + "$unsafe$work$unit$" + uniqueMethodName; } callablesCreated.put(mn.name, callableClass); boolean readOnlyCallable = (an.values == null) ? false : (Boolean) an.values.get(1); generateCallable(classFile, cn.name, callableClass, mn, readOnlyCallable, unsafeSpawn); staticMethodsToAdd.add(generateStaticCallableCreation(cn, cn.name, callableClass, mn)); break; } else if (an.desc.equals(COMBINER.getDescriptor())) { if (combinerMethod != null) { throw new RuntimeException("Class: " + cn.name + " contains two @Combiner methods: " + combinerMethod.name + " and " + mn.name); } combinerMethod = mn; } } } // TODO Verify the @Combiner method // The return should be of the same type of the parameterization // of the ParallelSpawn for (MethodNode methodToAdd : staticMethodsToAdd) { cn.methods.add(methodToAdd); } if (alreadyProcessed.size() == 0) { throw new RuntimeException( "Class: " + cn.name + " must have at least one method annotated with @ParNested"); } if (combinerMethod == null) { throw new RuntimeException( "Class: " + cn.name + " must have one method annotated with @Combiner"); } List<Integer> localVariablesIdx = new ArrayList<Integer>(); int numberLocalVariables = 0; int listIndex = execMethod.maxLocals; execMethod.maxLocals++; InsnList preamble = new InsnList(); preamble.add(new TypeInsnNode(NEW, ARRAY_LIST.getInternalName())); preamble.add(new InsnNode(DUP)); preamble.add(new MethodInsnNode(INVOKESPECIAL, ARRAY_LIST.getInternalName(), "<init>", "()V")); preamble.add(new VarInsnNode(ASTORE, listIndex)); Iterator<AbstractInsnNode> execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode instr = execInstIter.next(); // Look out for calls to methods if (instr.getOpcode() == INVOKEVIRTUAL || instr.getOpcode() == INVOKESPECIAL) { MethodInsnNode methodInstr = (MethodInsnNode) instr; // Is method being called annotated with @ParNested for (MethodNode parNestedMethod : parNestedMethods) { if (parNestedMethod.name.equals(methodInstr.name)) { numberLocalVariables++; } } } } for (int i = 0; i < numberLocalVariables; i++) { localVariablesIdx.add(i, execMethod.maxLocals); execMethod.maxLocals++; } int callablesManipulated = 0; execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode instr = execInstIter.next(); // Look out for calls to methods if (instr.getOpcode() != INVOKEVIRTUAL && instr.getOpcode() != INVOKESPECIAL) { continue; } MethodInsnNode methodInstr = (MethodInsnNode) instr; // Is method being called annotated with @ParNested boolean isParNestedMethod = false; for (MethodNode parNestedMethod : parNestedMethods) { if (parNestedMethod.name.equals(methodInstr.name)) { isParNestedMethod = true; break; } } if (!isParNestedMethod) { continue; } // Let's change this call // If it was a call to: @ParNested public int add(int i1, // int i2) // add(foo, bar) -> add$static$callable$creator(this, foo, // bar) // the 'this' will be already in the right place in the // stack // because the method being called now is static whereas // previously // it was not methodInstr.setOpcode(INVOKESTATIC); methodInstr.name = methodInstr.name + "$static$callable$creator"; for (MethodNode staticCreated : staticMethodsToAdd) { if (staticCreated.name.equals(methodInstr.name)) { methodInstr.desc = staticCreated.desc; break; } } InsnList midterm = new InsnList(); // Store the callable instantiated in local variable midterm.add(new VarInsnNode(ASTORE, localVariablesIdx.get(callablesManipulated))); // Load the list midterm.add(new VarInsnNode(ALOAD, listIndex)); // Load the callable midterm.add(new VarInsnNode(ALOAD, localVariablesIdx.get(callablesManipulated))); // Add it to the list midterm.add(new MethodInsnNode(INVOKEVIRTUAL, ARRAY_LIST.getInternalName(), "add", "(Ljava/lang/Object;)Z")); // Pop the boolean that results from the add(Object) // May reuse a POP if the previous call had a return if (methodInstr.getNext().getOpcode() != POP) { midterm.add(new InsnNode(POP)); } // Add this set of instructions after the call to the // constrution of the callable execMethod.instructions.insert(methodInstr, midterm); callablesManipulated++; } // Insert the preamble in the start execMethod.instructions.insert(preamble); InsnList finish = new InsnList(); // Push 'this' for the call to the combiner method finish.add(new VarInsnNode(ALOAD, 0)); // Call the static method current() of jvstm.Transaction finish.add(new MethodInsnNode(INVOKESTATIC, TRANSACTION.getInternalName(), "current", "()Ljvstm/Transaction;")); // Load the callables list finish.add(new VarInsnNode(ALOAD, listIndex)); // Call the manage parnested method finish.add(new MethodInsnNode(INVOKEVIRTUAL, TRANSACTION.getInternalName(), "manageNestedParallelTxs", "(Ljava/util/List;)Ljava/util/List;")); // Call the combiner method finish.add(new MethodInsnNode(INVOKEVIRTUAL, cn.name, combinerMethod.name, combinerMethod.desc)); // Return what the combiner returns finish.add(new InsnNode(ARETURN)); // Remove the "return null" that's supposed to be at the end of // the exec method execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode curNode = execInstIter.next(); if (!execInstIter.hasNext()) { // Insert the finish in the end execMethod.instructions.insert(curNode.getPrevious().getPrevious(), finish); execMethod.instructions.remove(curNode.getPrevious()); execMethod.instructions.remove(curNode); break; } } } ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cn.accept(cw); writeClassFile(classFile, cw.toByteArray()); } catch (IOException e) { throw new Error("Error processing class file", e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } } }
From source file:jvstm.atomic.ProcessParNestAnnotations.java
License:Open Source License
private static MethodNode generateStaticCallableCreation(ClassNode classNode, String className, String callableClass, MethodNode mn) { MethodNode staticMethod = new MethodNode(V1_6, mn.access | ACC_STATIC, mn.name + "$static$callable$creator", "(L" + className + ";" + mn.desc.substring(1, mn.desc.indexOf(')') + 1) + "L" + callableClass + ";", mn.signature, new String[0]); InsnList content = new InsnList(); content.add(new TypeInsnNode(NEW, callableClass)); content.add(new InsnNode(DUP)); int pos = 0;/*from w ww . j av a 2 s .c om*/ // Push the instance of the class being modified (first argument of this // synthetized method) content.add(new VarInsnNode(ALOAD, pos++)); // Push arguments of original method on the stack for callable creation for (Type t : Type.getArgumentTypes(mn.desc)) { content.add(new VarInsnNode(t.getOpcode(ILOAD), pos)); pos += t.getSize(); } // Instantiate the callable content.add(new MethodInsnNode(INVOKESPECIAL, callableClass, "<init>", getCallableCtorDesc(className, mn))); // Return it from the static method content.add(new InsnNode(ARETURN)); staticMethod.instructions.add(content); return staticMethod; }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
@SuppressWarnings("unchecked") static ArrayList<BasicBlock> dupCopyContents(boolean deepCopy, BasicBlock targetBB, BasicBlock returnToBB, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<Label, LabelNode> labelCopyMap) throws KilimException { ArrayList<BasicBlock> newBBs = new ArrayList<BasicBlock>(targetBB.getSubBlocks().size()); for (BasicBlock orig : targetBB.getSubBlocks()) { BasicBlock dup = bbCopyMap.get(orig); dup.flags = orig.flags;/* w ww .j a va 2 s .co m*/ dup.caughtExceptionType = orig.caughtExceptionType; dup.startPos = orig.startPos; dup.endPos = orig.endPos; dup.flow = orig.flow; dup.numPredecessors = orig.numPredecessors; dup.startFrame = null; dup.usage = orig.usage.copy(); dup.handlers = orig.handlers; if (orig.follower != null) { dup.follower = bbCopyMap.get(orig.follower); if (dup.follower == null) { assert dup.lastInstruction() == RET; } } dup.successors = new ArrayList<BasicBlock>(orig.successors.size()); if (orig.lastInstruction() == RET) { dup.addSuccessor(returnToBB); } else { for (BasicBlock s : orig.successors) { BasicBlock b = bbCopyMap.get(s); dup.addSuccessor(b); } } if (deepCopy) { MethodFlow flow = targetBB.flow; InsnList instructions = flow.instructions; // copy instructions dup.startLabel = labelCopyMap.get(orig.startLabel).getLabel(); dup.startPos = instructions.size(); dup.endPos = dup.startPos + (orig.endPos - orig.startPos); // Note: last instruction (@endPos) isn't copied in the loop. // If it has labels, a new instruction is generated; either // way the last instruction is appended separately. int newPos = instructions.size(); int end = orig.endPos; // create new labels and instructions for (int i = orig.startPos; i <= end; i++, newPos++) { Label l = flow.getLabelAt(i); if (l != null) { l = labelCopyMap.get(l).getLabel(); assert l != null; flow.setLabel(newPos, l); } if (i != end) { // last insn gets special treatment instructions.add(instructions.get(i)); } } AbstractInsnNode lastInsn = (AbstractInsnNode) instructions.get(orig.endPos); LabelNode dupLabel; int opcode = lastInsn.getOpcode(); if (lastInsn instanceof JumpInsnNode) { JumpInsnNode jin = (JumpInsnNode) lastInsn; if (lastInsn.getOpcode() != JSR) { dupLabel = labelCopyMap.get(jin.label); assert dupLabel != null; lastInsn = new JumpInsnNode(lastInsn.getOpcode(), dupLabel); } } else if (opcode == TABLESWITCH) { TableSwitchInsnNode tsin = (TableSwitchInsnNode) lastInsn; LabelNode[] labels = new LabelNode[tsin.labels.size()]; for (int i = 0; i < labels.length; i++) { dupLabel = labelCopyMap.get(tsin.labels.get(i)); assert dupLabel != null; labels[i] = dupLabel; } dupLabel = labelCopyMap.get(tsin.dflt); assert dupLabel != null; lastInsn = new TableSwitchInsnNode(tsin.min, tsin.max, dupLabel, labels); } else if (opcode == LOOKUPSWITCH) { LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) lastInsn; LabelNode[] labels = new LabelNode[lsin.labels.size()]; for (int i = 0; i < labels.length; i++) { dupLabel = labelCopyMap.get(lsin.labels.get(i)); assert dupLabel != null; labels[i] = dupLabel; } dupLabel = labelCopyMap.get(lsin.dflt); assert dupLabel != null; int[] keys = new int[lsin.keys.size()]; for (int i = 0; i < keys.length; i++) { keys[i] = (Integer) lsin.keys.get(i); } lastInsn = new LookupSwitchInsnNode(dupLabel, keys, labels); } instructions.add(lastInsn); // new handlers dup.handlers = new ArrayList<Handler>(orig.handlers.size()); if (orig.handlers.size() > 0) { for (Handler oh : orig.handlers) { Handler h = new Handler(dup.startPos + (oh.from - orig.startPos), dup.endPos + (oh.to - orig.endPos), oh.type, oh.catchBB); dup.handlers.add(h); } } } newBBs.add(dup); } return newBBs; }
From source file:me.themallard.bitmmo.impl.plugin.applethook.AppletHook.java
License:Open Source License
private void addGraphicsHook(MethodNode mn, boolean update) { String method = update ? "update" : "paint"; String desc = mn.desc;//from www. j ava 2 s. c om InsnList insns = new InsnList(); insns.add(new VarInsnNode(ALOAD, 1)); insns.add(new MethodInsnNode(INVOKESTATIC, "me/themallard/bitmmo/impl/plugin/applethook/AppletHookManager", method, desc, false)); mn.instructions.insertBefore(mn.instructions.get(mn.instructions.size() - 1), insns); }
From source file:me.themallard.bitmmo.impl.plugin.chathook.ChatHook.java
License:Open Source License
private void hookSendMessage(ClassNode cn) { Pattern p = new PatternBuilder().add(new InstructionElement(INVOKESTATIC), new AnyElement(), new LdcElement(new LdcInsnNode("Chat")), new InstructionElement(INVOKEVIRTUAL), new InstructionElement(POP)).build(); for (MethodNode mn : cn.methods) { if (!p.contains(mn.instructions)) continue; int offset = p.getOffset(mn.instructions) - 9; // steal/* www . ja va 2 s. c om*/ JumpInsnNode jin = (JumpInsnNode) mn.instructions.get(offset - 1); InsnList inject = new InsnList(); inject.add(new VarInsnNode(ALOAD, 2)); inject.add(new MethodInsnNode(INVOKESTATIC, "me/themallard/bitmmo/impl/plugin/chathook/ChatHookManager", "onChatMessage", "(Ljava/lang/String;)Z", false)); inject.add(new JumpInsnNode(IFNE, jin.label)); // inject.add(new InsnNode(POP)); mn.instructions.insertBefore(mn.instructions.get(offset), inject); } }