List of usage examples for org.objectweb.asm.tree InsnList InsnList
InsnList
From source file:fr.insalyon.telecom.jooflux.InvokeMethodTransformer.java
License:Mozilla Public License
private InsnList generateInvokeDynamicStatic(String name, String owner, String desc) { InsnList insnList = new InsnList(); Handle methodHandle = new Handle(Opcodes.H_INVOKESTATIC, BOOTSTRAP_CLASS, "dynvokeStatic", BOOTSTRAP_SIGNATURE);/*from ww w . j av a 2s.c o m*/ insnList.add(new InvokeDynamicInsnNode(owner + "." + name, desc, methodHandle, "")); return insnList; }
From source file:fr.insalyon.telecom.jooflux.InvokeMethodTransformer.java
License:Mozilla Public License
private InsnList generateInvokeDynamicVirtualInterfaceSpecial(String name, String owner, String desc, String bootstrapMethod) { InsnList insnList = new InsnList(); Handle methodHandle = new Handle(Opcodes.H_INVOKESTATIC, BOOTSTRAP_CLASS, bootstrapMethod, BOOTSTRAP_SIGNATURE);//from w w w . ja v a 2 s .com List<Type> argsList = new ArrayList<Type>(Arrays.asList(new Type[] { Type.getObjectType(owner) })); argsList.addAll(Arrays.asList(Type.getArgumentTypes(desc))); String descReceiver = Type.getMethodDescriptor(Type.getReturnType(desc), argsList.toArray(new Type[argsList.size()])); insnList.add(new InvokeDynamicInsnNode(owner + "." + name, descReceiver, methodHandle, "")); return 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 ww .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 w w w . j a va 2s . co 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: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. java 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 . ja v a2 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 a2s . c o m*/ // 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: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;// w ww . j a v a 2 s . co m 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/*from ww w . jav a 2 s.c o m*/ 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); } }
From source file:me.themallard.bitmmo.impl.plugin.chathook.ChatHook.java
License:Open Source License
private void hookRecieveMessage(ClassNode cn) { Pattern p = new PatternBuilder().add(new InstructionElement(DUP), new InstructionElement(INVOKESPECIAL), new LdcElement(new LdcInsnNode("\n"))).build(); for (MethodNode mn : cn.methods) { if (!p.contains(mn.instructions)) continue; int offset = p.getOffset(mn.instructions); MethodInsnNode getMsgInsn = (MethodInsnNode) mn.instructions.get(offset + 5); InsnList inject = new InsnList(); inject.add(new VarInsnNode(ALOAD, 1)); inject.add(new MethodInsnNode(INVOKEVIRTUAL, getMsgInsn.owner, getMsgInsn.name, "()Ljava/lang/String;", false));/*from ww w . j a v a 2 s . c o m*/ inject.add(new MethodInsnNode(INVOKESTATIC, "me/themallard/bitmmo/impl/plugin/chathook/ChatHookManager", "onReceiveMessage", "(Ljava/lang/String;)V", false)); mn.instructions.insertBefore(mn.instructions.get(offset), inject); } }