List of usage examples for org.objectweb.asm.tree InsnList size
int size
To view the source code for org.objectweb.asm.tree InsnList size.
Click Source Link
From source file:com.android.tools.lint.client.api.LintDriver.java
License:Apache License
@Nullable private static MethodInsnNode findConstructorInvocation(@NonNull MethodNode method, @NonNull String className) { InsnList nodes = ((MethodNode) method).instructions; for (int i = 0, n = nodes.size(); i < n; i++) { AbstractInsnNode instruction = nodes.get(i); if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) { MethodInsnNode call = (MethodInsnNode) instruction; if (className.equals(call.owner)) { return call; }/*from w w w . ja va 2 s . c o m*/ } } return null; }
From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java
License:Open Source License
private void processMethod(MethodNode methodNode) { InsnList insns = methodNode.instructions; // Filter out debugging nodes/labels int count = 0; int maxCount = insns.size(); AbstractInsnNode[] nodes = new AbstractInsnNode[maxCount]; for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext()) if (node.getOpcode() > 0) nodes[count++] = node;// w ww.j av a 2s. c o m // Find mapper get() calls and create an own flyweight instance for each for (int i = 0; i <= count - 4; i++) { if (!(nodes[i + 0] instanceof VarInsnNode)) continue; if (!(nodes[i + 1] instanceof FieldInsnNode)) continue; if (!(nodes[i + 2] instanceof VarInsnNode)) continue; if (!(nodes[i + 3] instanceof MethodInsnNode)) continue; VarInsnNode loadThis = (VarInsnNode) nodes[i + 0]; FieldInsnNode getField = (FieldInsnNode) nodes[i + 1]; VarInsnNode loadEntity = (VarInsnNode) nodes[i + 2]; MethodInsnNode getMethod = (MethodInsnNode) nodes[i + 3]; if (loadThis.var != 0 || loadThis.getOpcode() != ALOAD) continue; if (!getField.owner.equals(metadata.internalName) || !getField.desc.equals("L" + WeaverConstants.MAPPER_NAME + ";") || !metadata.mappersByName.containsKey(getField.name)) continue; if (loadEntity.getOpcode() != ILOAD) continue; if (!getMethod.owner.equals(WeaverConstants.MAPPER_NAME) || !getMethod.desc.equals("(I)L" + WeaverConstants.COMPONENT_NAME + ";") || !getMethod.name.equals("get")) continue; SystemMapper mapper = metadata.mappersByName.get(getField.name); // Add field to hold the flyweight String fieldName = "flyweight$" + flyweightFields.size(); String fieldDesc = mapper.componentType.getDescriptor(); FieldNode fieldNode = new FieldNode(ACC_PRIVATE, fieldName, fieldDesc, null, null); fieldNode.visitAnnotation("Lcom/github/antag99/retinazer/SkipWire;", true); FlyweightField flyweightField = new FlyweightField(); flyweightField.fieldNode = fieldNode; flyweightField.mapper = mapper; flyweightFields.add(flyweightField); // Rewrite access to use the flyweight getField.owner = metadata.internalName; getField.name = fieldName; getField.desc = fieldDesc; insns.insert(getField, new InsnNode(DUP)); insns.insert(loadEntity, new FieldInsnNode(PUTFIELD, mapper.componentType.getInternalName(), WeaverConstants.INDEX_FIELD_NAME, WeaverConstants.INDEX_FIELD_DESC)); insns.remove(getMethod); } }
From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java
License:Open Source License
private void _doTestToClass(boolean proxyClassesDumpEnabled, boolean logEnabled) throws FileNotFoundException { class TestClass { }/*www .ja va2 s. c o m*/ ClassNode classNode = _loadClass(TestClass.class); MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "<clinit>", "()V", null, null); methodNode.visitCode(); methodNode.visitInsn(Opcodes.RETURN); methodNode.visitEnd(); List<MethodNode> methodNodes = classNode.methods; methodNodes.add(methodNode); ClassLoader classLoader = new URLClassLoader(new URL[0], null); Level level = Level.WARNING; if (logEnabled) { level = Level.INFO; } try (CaptureHandler captureHandler = JDKLoggerTestUtil .configureJDKLogger(IntrabandProxyUtil.class.getName(), level)) { List<LogRecord> logRecords = captureHandler.getLogRecords(); IntrabandProxyUtil.toClass(classNode, classLoader); if (proxyClassesDumpEnabled) { StringBundler sb = new StringBundler(6); sb.append(SystemProperties.get(SystemProperties.TMP_DIR)); sb.append(StringPool.SLASH); sb.append(PropsValues.INTRABAND_PROXY_DUMP_CLASSES_DIR); sb.append(StringPool.SLASH); sb.append(classNode.name); sb.append(".class"); String filePath = sb.toString(); File classFile = new File(filePath); Assert.assertTrue(classFile.exists()); ClassNode reloadedClassNode = _loadClass(new FileInputStream(classFile)); MethodNode clinitMethodNode = ASMUtil.findMethodNode(reloadedClassNode.methods, "<clinit>", Type.VOID_TYPE); InsnList insnList = clinitMethodNode.instructions; Assert.assertEquals(1, insnList.size()); _assertInsnNode(insnList.getFirst(), Opcodes.RETURN); if (logEnabled) { Assert.assertEquals(1, logRecords.size()); LogRecord logRecord = logRecords.get(0); Assert.assertEquals(logRecord.getMessage(), "Dumpped class ".concat(filePath)); } } if (!proxyClassesDumpEnabled || !logEnabled) { Assert.assertTrue(logRecords.isEmpty()); } } try { IntrabandProxyUtil.toClass(classNode, classLoader); Assert.fail(); } catch (RuntimeException re) { Throwable throwable = re.getCause(); Assert.assertSame(InvocationTargetException.class, throwable.getClass()); throwable = throwable.getCause(); Assert.assertSame(LinkageError.class, throwable.getClass()); String message = throwable.getMessage(); Assert.assertTrue(message.contains( "duplicate class definition for name: \"" + Type.getInternalName(TestClass.class) + "\"")); } }
From source file:com.lion328.xenonlauncher.patcher.StringReplaceFilePatcher.java
License:Open Source License
@Override public byte[] patchFile(String name, byte[] original) { if (!name.endsWith(".class")) { return original; }//from w ww . j a v a 2 s .c o m ClassReader reader = new ClassReader(original); ClassNode node = new ClassNode(); reader.accept(node, 0); List fields = node.fields; FieldNode field; for (Object obj : fields) { if (!(obj instanceof FieldNode)) { continue; } field = (FieldNode) obj; if (field.value instanceof String) { field.value = ((String) field.value).replace(find, replace); } } List methods = node.methods; MethodNode method; for (Object obj : methods) { if (!(obj instanceof MethodNode)) { continue; } method = (MethodNode) obj; InsnList insns = method.instructions; for (int i = 0; i < insns.size(); i++) { AbstractInsnNode insn = insns.get(i); if (!(insn instanceof LdcInsnNode)) { continue; } LdcInsnNode ldc = (LdcInsnNode) insn; if (!(ldc.cst instanceof String)) { continue; } ldc.cst = ((String) ldc.cst).replace(find, replace); } } ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); }
From source file:com.offbynull.coroutines.instrumenter.generators.GenericGenerators.java
License:Open Source License
/** * Combines multiple instructions in to a single instruction list. You can include normal instructions ({@link AbstractInsnNode}), * instruction lists ({@link InsnList}), or instruction generators ({@link InstructionGenerator}). * @param insns instructions// w w w . j a v a 2 s . co m * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @return merged instructions */ public static InsnList merge(Object... insns) { Validate.notNull(insns); Validate.noNullElements(insns); InsnList ret = new InsnList(); for (Object insn : insns) { if (insn instanceof AbstractInsnNode) { // add single instruction AbstractInsnNode insnNode = (AbstractInsnNode) insn; ret.add(insnNode); } else if (insn instanceof InsnList) { // add instruction list InsnList insnList = (InsnList) insn; for (int i = 0; i < insnList.size(); i++) { Validate.notNull(insnList.get(i)); } ret.add((InsnList) insn); } else if (insn instanceof InstructionGenerator) { // generate conditional merger instruction list and add InsnList insnList = ((InstructionGenerator) insn).generate(); for (int i = 0; i < insnList.size(); i++) { Validate.notNull(insnList.get(i)); } ret.add(insnList); } else { // unrecognized throw new IllegalArgumentException(); } } return ret; }
From source file:com.sun.tdk.jcov.instrument.BlockCodeMethodAdapter.java
License:Open Source License
private SimpleBasicBlock[] completeComputationOfCodeLabelNodes() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; int[] allToReal = new int[instructions.size()]; int allIdx = 0; int insnIdx = 0; ListIterator iit = instructions.iterator(); // Create the method entry block and basic block AbstractInsnNode insnFirst = peek(iit); SimpleBasicBlock bbFirst = getBB(insnFirst, 0); // DataBlock blockFirst = new DataBlockMethEnter(); // bbFirst.add(blockFirst); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); allToReal[allIdx++] = insnIdx;/*from w w w . j a v a 2 s. c o m*/ int bci = bcis[insnIdx]; int opcode = insn.getOpcode(); if (opcode < 0) { // a pseudo-instruction if (insn.getType() == AbstractInsnNode.LINE) { LineNumberNode lineNode = (LineNumberNode) insn; method().addLineEntry(bci, lineNode.line); } } else { // a real instruction ++insnIdx; // advance the real instruction index //System.out.println( "#" + (insnIdx - 1) + // " bci: " + bci + " " + // instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") + // " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]"); switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case IFNULL: case IFNONNULL: case JSR: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; LabelNode insnTrue = jumpInsn.label; int bciFalse = bcis[insnIdx]; // fall-through DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1); /* DataBlockTarget blockTrue = new DataBlockTargetCond(true); DataBlockTarget blockFalse = new DataBlockTargetCond(false); branch.addTarget(blockTrue); branch.addTarget(blockFalse); */ AbstractInsnNode insnFalse = peek(iit); assert (insnFalse != null); // must be fall-through code SimpleBasicBlock bbTrue = getBB(insnTrue); SimpleBasicBlock bbFalse = getBB(insnFalse, bciFalse); exits.add(branch); // assign a new label for branch counting // LabelNode nlab = new LabelNode(); // jumpInsn.label = nlab; // branch to new label // bbTrue.add(blockTrue, nlab); //bbFalse.add(blockFalse); break; } case TABLESWITCH: { TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting //LabelNode nlab = new LabelNode(); //switchInsn.dflt = nlab; // branch to new label //bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator lit = switchInsn.labels.listIterator(); int key = switchInsn.min; while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); //DataBlockTargetCase blockCase = new DataBlockTargetCase(key++); //branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); // lit.set(nlab); // bbCase.add(blockCase, nlab); } break; } case LOOKUPSWITCH: { LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting // LabelNode nlab = new LabelNode(); // switchInsn.dflt = nlab; // branch to new label // bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator kit = switchInsn.keys.listIterator(); ListIterator lit = switchInsn.labels.listIterator(); while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); Integer key = (Integer) kit.next(); // DataBlockTargetCase blockCase = new DataBlockTargetCase(key.intValue()); // branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); //lit.set(nlab); //bbCase.add(blockCase, nlab); } break; } case GOTO: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; // Create origin info, a branch int bciEnd = bcis[insnIdx] - 1; DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd); exits.add(branch); // Create destination info, a block target LabelNode insnTarget = jumpInsn.label; SimpleBasicBlock bbTarget = getBB(insnTarget); //DataBlockTarget blockTarget = new DataBlockTargetGoto(); //branch.addTarget(blockTarget); // assign a new label for branch counting //LabelNode nlab = new LabelNode(); //jumpInsn.label = nlab; // branch to new label //bbTarget.add(blockTarget, nlab); break; } case ATHROW: case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: { int bciNext = bcis[insnIdx]; DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode()); exits.add(exit); AbstractInsnNode insnNext = peek(iit); if (insnNext != null) { // If there is code after this, it has to be the start of a // new basic block getBB(insnNext, bciNext); } break; } default: break; } // try add src block } } // Now go through the try-catch blocks LabelNode previousHandler = null; for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) { TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next(); LabelNode insnHandler = tcbn.handler; if (insnHandler != previousHandler) { previousHandler = insnHandler; // Create destination info, a block target SimpleBasicBlock bbCatch = getBB(insnHandler); } } if (method().getCharacterRangeTable() != null) { boolean newBlock = true; int skip = 0; iit = instructions.iterator(); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; if (bci == skip) { continue; } if (insnToBB.get(insn) != null) { skip = bcis[allToReal[instructions.indexOf(insn)]]; } if (insn.getOpcode() < 0) { continue; } for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) { if (entry.startBCI() == bci) { if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) { newBlock = false; if (insnToBB.get(insn) == null) { //System.out.println("Should add block at: " + bci + " in " + method().name + // " for " + Constants.opcNames[insn.getOpcode()]); getBB(insn); break; } } } else { if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) { newBlock = true; } } } } } // Compute the startBCI for any basic blocks that don't have it' SimpleBasicBlock[] basicBlocks = new SimpleBasicBlock[insnToBB.size()]; int i = 0; for (Map.Entry<AbstractInsnNode, SimpleBasicBlock> entry : insnToBB.entrySet()) { SimpleBasicBlock bb = entry.getValue(); if (bb.startBCI() < 0) { AbstractInsnNode insn = entry.getKey(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; bb.setStartBCI(bci); } basicBlocks[i++] = bb; } Arrays.sort(basicBlocks); return basicBlocks; }
From source file:com.sun.tdk.jcov.instrument.BranchCodeMethodAdapter.java
License:Open Source License
/** * Do fix ups so that: There are unique CodeLabelNodes at the beginning of * each basic block; All branch-mode blocks hang off CodeLabelNodes Misc * info, like case values, are attached Fall throughs from one block to * another are computed//w w w. ja v a 2 s . c o m * */ private BasicBlock[] completeComputationOfCodeLabelNodes() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; int[] allToReal = new int[instructions.size()]; int allIdx = 0; int insnIdx = 0; ListIterator iit = instructions.iterator(); // Create the method entry block and basic block AbstractInsnNode insnFirst = peek(iit); BasicBlock bbFirst = getBB(insnFirst, 0); DataBlock blockFirst = new DataBlockMethEnter(bbFirst.rootId()); bbFirst.add(blockFirst); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); allToReal[allIdx++] = insnIdx; int bci = bcis[insnIdx]; int opcode = insn.getOpcode(); if (opcode < 0) { // a pseudo-instruction if (insn.getType() == AbstractInsnNode.LINE) { LineNumberNode lineNode = (LineNumberNode) insn; method().addLineEntry(bci, lineNode.line); } } else { // a real instruction ++insnIdx; // advance the real instruction index //System.out.println( "#" + (insnIdx - 1) + // " bci: " + bci + " " + // instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") + // " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]"); switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case IFNULL: case IFNONNULL: //case JSR: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; LabelNode insnTrue = jumpInsn.label; int bciFalse = bcis[insnIdx]; // fall-through DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1); DataBlockTarget blockTrue = new DataBlockTargetCond(branch.rootId(), true); DataBlockTarget blockFalse = new DataBlockTargetCond(branch.rootId(), false); branch.addTarget(blockTrue); branch.addTarget(blockFalse); AbstractInsnNode insnFalse = peek(iit); assert (insnFalse != null); // must be fall-through code BasicBlock bbTrue = getBB(insnTrue); BasicBlock bbFalse = getBB(insnFalse, bciFalse); exits.add(branch); // assign a new label for branch counting LabelNode nlab = new LabelNode(); jumpInsn.label = nlab; // branch to new label bbTrue.add(blockTrue, nlab); bbFalse.add(blockFalse); break; } case TABLESWITCH: { TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; BasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting LabelNode nlab = new LabelNode(); switchInsn.dflt = nlab; // branch to new label bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator lit = switchInsn.labels.listIterator(); int key = switchInsn.min; while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); BasicBlock bbCase = getBB(labCase); DataBlockTargetCase blockCase = new DataBlockTargetCase(bbCase.rootId(), key++); branch.addTarget(blockCase); // assign a new label to the case for branch counting nlab = new LabelNode(); lit.set(nlab); bbCase.add(blockCase, nlab); } break; } case LOOKUPSWITCH: { LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; BasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting LabelNode nlab = new LabelNode(); switchInsn.dflt = nlab; // branch to new label bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator kit = switchInsn.keys.listIterator(); ListIterator lit = switchInsn.labels.listIterator(); while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); BasicBlock bbCase = getBB(labCase); Integer key = (Integer) kit.next(); DataBlockTargetCase blockCase = new DataBlockTargetCase(branch.rootId(), key.intValue()); branch.addTarget(blockCase); // assign a new label to the case for branch counting nlab = new LabelNode(); lit.set(nlab); bbCase.add(blockCase, nlab); } break; } case GOTO: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; // Create origin info, a branch int bciEnd = bcis[insnIdx] - 1; DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd); exits.add(branch); // Create destination info, a block target LabelNode insnTarget = jumpInsn.label; BasicBlock bbTarget = getBB(insnTarget); DataBlockTarget blockTarget = new DataBlockTargetGoto(bbTarget.rootId()); branch.addTarget(blockTarget); // assign a new label for branch counting LabelNode nlab = new LabelNode(); jumpInsn.label = nlab; // branch to new label bbTarget.add(blockTarget, nlab); break; } case ATHROW: case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: { int bciNext = bcis[insnIdx]; DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode()); exits.add(exit); AbstractInsnNode insnNext = peek(iit); if (insnNext != null) { // If there is code after this, it has to be the start of a // new basic block getBB(insnNext, bciNext); } break; } default: break; } // try add src block } } // Now go through the try-catch blocks LabelNode previousHandler = null; for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) { TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next(); LabelNode insnHandler = tcbn.handler; if (insnHandler != previousHandler) { previousHandler = insnHandler; // Create destination info, a block target BasicBlock bbCatch = getBB(insnHandler); DataBlockCatch blockCatch = new DataBlockCatch(bbCatch.rootId()); // assign a new label for catch counting LabelNode nlab = new LabelNode(); tcbn.handler = nlab; // change handler bbCatch.add(blockCatch, nlab); } } if (method().getCharacterRangeTable() != null) { boolean newBlock = true; int skip = 0; iit = instructions.iterator(); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; if (bci == skip) { continue; } if (insnToBB.get(insn) != null) { skip = bcis[allToReal[instructions.indexOf(insn)]]; } if (insn.getOpcode() < 0) { continue; } for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) { if (entry.startBCI() == bci) { if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) { newBlock = false; if (insnToBB.get(insn) == null) { //System.out.println("Should add block at: " + bci + " in " + method().name + // " for " + Constants.opcNames[insn.getOpcode()]); getBB(insn); break; } } } else { if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) { newBlock = true; } } } } } // Compute the startBCI for any basic blocks that don't have it' BasicBlock[] basicBlocks = new BasicBlock[insnToBB.size()]; int i = 0; for (Map.Entry<AbstractInsnNode, BasicBlock> entry : insnToBB.entrySet()) { BasicBlock bb = entry.getValue(); if (bb.startBCI() < 0) { AbstractInsnNode insn = entry.getKey(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; bb.setStartBCI(bci); } basicBlocks[i++] = bb; } Arrays.sort(basicBlocks); return basicBlocks; }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testReplacingThisWithOtherVariable() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor"); printMethodNode(donorMethod);//from w w w.ja v a2 s .co m //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //write a class Class c = createClassFromClassNode(donorSource, NEWCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("before_whatDoIThinkAbout", String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "AAAA" }); System.out.println("TestDonorClass.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
@Test public void testInjectingIntoMethodWithLotsOfParameters() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF2); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor Method Before Modifications:"); printMethodNode(donorMethod);/* w w w . j a v a2s. c o m*/ String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.Concatenator"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); ClassNode exampleSource = loadLocalClass("com.triage.bytecodemaster.fortesting.JustLikeGroovyClass"); MethodNode exampleMethod = findMethod(exampleSource, "before_whatDoIThinkAbout"); System.out.println("Example Method-- Should be just like the Donor Source"); printMethodNode(exampleMethod); MethodNode targetMethod = findMethod(targetSource, "concat"); System.out.println("Target Method <Before Mods>"); printMethodNode(targetMethod); //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; InsnList targetInstructions = targetMethod.instructions; //make a new local variable in the donor method. //this variable needs to have a slot high enough that it doesnt //conflict with either the target or the source method //it will hold references to the objects we replace with 'this' LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); targetInstructions.insertBefore(targetInstructions.getFirst(), begin); targetInstructions.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = targetMethod.maxLocals; targetMethod.maxLocals += type.getSize(); targetMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label targetInstructions.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch targetInstructions.insert(getTestBase, setRef); //replace all references to 'this' in the DONOR method with the new variable //in the TARGET code for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } //remove return methods. this will prevent a return. it should cause the donor //method to have parameters that overlap with the target, which has more parameters if (node.getOpcode() == Opcodes.RETURN || node.getOpcode() == Opcodes.ARETURN) { instructionsToInject.remove(node); } } System.out.println(">>>>>>>>>Finished Modifying Donor Method <<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //stash instructions at the beginning of the original method, //but after populating the new variable targetInstructions.insert(setRef, instructionsToInject); System.out.println("Modified Target:"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("concat", String.class, String.class, String.class, String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "A", "B", "C", "D" }); System.out.println("Concatenator.concat Result: " + result); assertTrue(result.equals("ABCD")); }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testMergedInReplacingThisWithOtherVariable() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); //load the target class String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.TestFriend"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); MethodNode targetMethod = findMethod(targetSource, "whatDoIThinkAbout"); System.out.println("Target"); printMethodNode(targetMethod);// w ww. j a v a 2 s . com System.out.println("Donor"); printMethodNode(donorMethod); //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); //insert the donorMethod targetMethod.instructions.insert(instructionsToInject); System.out.println(">>>>>>>>>Final Method<<<<<<<<"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("whatDoIThinkAbout", TestPerson.class); TestPerson testPerson = new TestPerson(); testPerson.setName("AAAA"); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { testPerson }); System.out.println("TestFriend.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }