Java Code Examples for proguard.classfile.instruction.Instruction#length()
The following examples show how to use
proguard.classfile.instruction.Instruction#length() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 6 votes |
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor) { if (instructionVisitor != CodeAttributeEditor.this) { throw new UnsupportedOperationException("Unexpected visitor ["+instructionVisitor+"]"); } for (int index = 0; index < instructions.length; index++) { Instruction instruction = instructions[index]; instruction.accept(clazz, method, codeAttribute, offset, CodeAttributeEditor.this); offset += instruction.length(offset); } }
Example 2
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Moves the given code block to the new offsets. * @param clazz the class file of the code to be changed. * @param method the method of the code to be changed. * @param codeAttribute the code to be changed. * @param oldCode the original code to be moved. * @param oldLength the original code length. */ private void moveInstructions(Clazz clazz, Method method, CodeAttribute codeAttribute, byte[] oldCode, int oldLength) { // Start writing instructions at the beginning. newOffset = 0; int oldOffset = 0; do { // Get the next instruction. Instruction instruction = InstructionFactory.create(oldCode, oldOffset); // Move the instruction to its new offset. moveInstruction(clazz, method, codeAttribute, oldOffset, instruction); oldOffset += instruction.length(oldOffset); } while (oldOffset < oldLength); }
Example 3
Source File: UnreachableExceptionRemover.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Returns whether the specified block of code may throw exceptions. */ private boolean mayThrowExceptions(Clazz clazz, Method method, CodeAttribute codeAttribute, int startOffset, int endOffset) { byte[] code = codeAttribute.code; // Go over all instructions. int offset = startOffset; while (offset < endOffset) { // Get the current instruction. Instruction instruction = InstructionFactory.create(code, offset); // Check if it may be throwing exceptions. if (exceptionInstructionChecker.mayThrowExceptions(clazz, method, codeAttribute, offset, instruction)) { return true; } // Go to the next instruction. offset += instruction.length(offset); } return false; }
Example 4
Source File: ReachableCodeMarker.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Marks the code starting at the given offset. */ private void markCode(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset) { boolean oldNext = next; byte[] code = codeAttribute.code; // Continue with the current instruction as long as we haven't marked it // yet. while (!isReachable[offset]) { // Get the current instruction. Instruction instruction = InstructionFactory.create(code, offset); // Mark it as reachable. isReachable[offset] = true; // By default, we'll assume we can continue with the next // instruction in a moment. next = true; // Mark the branch targets, if any. instruction.accept(clazz, method, codeAttribute, offset, this); // Can we really continue with the next instruction? if (!next) { break; } // Go to the next instruction. offset += instruction.length(offset); } next = oldNext; }
Example 5
Source File: EvaluationSimplifier.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Deletes the given branch instruction, or replaces it by a simpler branch * instruction, if possible. */ private void replaceBranchInstruction(Clazz clazz, int offset, Instruction instruction) { InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset); // Is there exactly one branch target (not from a goto or jsr)? if (branchTargets != null && branchTargets.instructionOffsetCount() == 1) { // Is it branching to the next instruction? int branchOffset = branchTargets.instructionOffset(0) - offset; if (branchOffset == instruction.length(offset)) { if (DEBUG) System.out.println(" Ignoring zero branch instruction at ["+offset+"]"); } else { // Replace the branch instruction by a simple branch instruction. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO_W, branchOffset).shrink(); replaceInstruction(clazz, offset, instruction, replacementInstruction); } } }
Example 6
Source File: SideEffectMethodMarker.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Returns whether the given code has any side effects. */ private boolean hasSideEffects(Clazz clazz, Method method, CodeAttribute codeAttribute) { byte[] code = codeAttribute.code; int length = codeAttribute.u4codeLength; // Go over all instructions. int offset = 0; do { // Get the current instruction. Instruction instruction = InstructionFactory.create(code, offset); // Check if it may be throwing exceptions. if (sideEffectInstructionChecker.hasSideEffects(clazz, method, codeAttribute, offset, instruction)) { return true; } // Go to the next instruction. offset += instruction.length(offset); } while (offset < length); return false; }
Example 7
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
public void write(byte[] code, int offset) { for (int index = 0; index < instructions.length; index++) { Instruction instruction = instructions[index]; instruction.write(code, offset); offset += instruction.length(offset); } }
Example 8
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Fills out the instruction offset map for the given instruction. * @param oldOffset the instruction's old offset. * @param instruction the instruction to be moved. */ private void mapInstruction(int oldOffset, Instruction instruction) { instructionOffsetMap[oldOffset] = newOffset; // Account for the pre-inserted instruction, if any. Instruction preInstruction = preInsertions[oldOffset]; if (preInstruction != null) { newOffset += preInstruction.length(newOffset); } // Account for the replacement instruction, or for the current // instruction, if it shouldn't be deleted. Instruction replacementInstruction = replacements[oldOffset]; if (replacementInstruction != null) { newOffset += replacementInstruction.length(newOffset); } else if (!deleted[oldOffset]) { // Note that the instruction's length may change at its new offset, // e.g. if it is a switch instruction. newOffset += instruction.length(newOffset); } // Account for the post-inserted instruction, if any. Instruction postInstruction = postInsertions[oldOffset]; if (postInstruction != null) { newOffset += postInstruction.length(newOffset); } }
Example 9
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Fills out the instruction offset map for the given code block. * @param oldCode the instructions to be moved. * @param oldLength the code length. * @return the new code length. */ private int mapInstructions(byte[] oldCode, int oldLength) { // Start mapping instructions at the beginning. newOffset = 0; lengthIncreased = false; int oldOffset = 0; do { // Get the next instruction. Instruction instruction = InstructionFactory.create(oldCode, oldOffset); // Compute the mapping of the instruction. mapInstruction(oldOffset, instruction); oldOffset += instruction.length(oldOffset); if (newOffset > oldOffset) { lengthIncreased = true; } } while (oldOffset < oldLength); // Also add an entry for the first offset after the code. instructionOffsetMap[oldOffset] = newOffset; return newOffset; }
Example 10
Source File: CodeAttributeEditor.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Checks if it is possible to modifies the given code without having to * update any offsets. * @param codeAttribute the code to be changed. * @return the new code length. */ private boolean canPerformSimpleReplacements(CodeAttribute codeAttribute) { if (!simple) { return false; } byte[] code = codeAttribute.code; int codeLength = codeAttribute.u4codeLength; // Go over all replacement instructions. for (int offset = 0; offset < codeLength; offset++) { // Check if the replacement instruction, if any, has a different // length than the original instruction. Instruction replacementInstruction = replacements[offset]; if (replacementInstruction != null && replacementInstruction.length(offset) != InstructionFactory.create(code, offset).length(offset)) { return false; } } return true; }
Example 11
Source File: CodeAttributeComposer.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Appends the given instruction with the given old offset. * @param oldInstructionOffset the old offset of the instruction, to which * branches and other references in the current * code fragment are pointing. * @param instruction the instruction to be appended. */ public void appendInstruction(int oldInstructionOffset, Instruction instruction) { if (DEBUG) { println("["+codeLength+"] <- ", instruction.toString(oldInstructionOffset)); } // Make sure the code array is large enough. int newCodeLength = codeLength + instruction.length(codeLength); ensureCodeLength(newCodeLength); // Remember the old offset of the appended instruction. oldInstructionOffsets[codeLength] = oldInstructionOffset; // Write the instruction. // instruction.accept(null, // null, // new CodeAttribute(0, 0, 0, 0, code, 0, null, 0, null), // codeLength, // instructionWriter); instruction.write(code, codeLength); // Fill out the new offset of the appended instruction. instructionOffsetMap[level][oldInstructionOffset] = codeLength; // Continue appending at the next instruction offset. codeLength = newCodeLength; }
Example 12
Source File: CodeAttribute.java From java-n-IDE-for-Android with Apache License 2.0 | 5 votes |
/** * Applies the given instruction visitor to all instructions in the * specified range of offsets. */ public void instructionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, InstructionVisitor instructionVisitor) { int offset = startOffset; while (offset < endOffset) { // Note that the instruction is only volatile. Instruction instruction = InstructionFactory.create(code, offset); int instructionLength = instruction.length(offset); instruction.accept(clazz, method, this, offset, instructionVisitor); offset += instructionLength; } }
Example 13
Source File: CodeSubroutineInliner.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) { branchTargetFinder.visitCodeAttribute(clazz, method, codeAttribute); // Don't bother if there aren't any subroutines anyway. if (!containsSubroutines(codeAttribute)) { return; } if (DEBUG) { System.out.println("SubroutineInliner: processing ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"]"); } // Append the body of the code. codeAttributeComposer.reset(); codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); // Copy the non-subroutine instructions. int offset = 0; while (offset < codeAttribute.u4codeLength) { Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); int instructionLength = instruction.length(offset); // Is this returning subroutine? if (branchTargetFinder.isSubroutine(offset) && branchTargetFinder.isSubroutineReturning(offset)) { // Skip the subroutine. if (DEBUG) { System.out.println(" Skipping original subroutine instruction "+instruction.toString(offset)); } // Append a label at this offset instead. codeAttributeComposer.appendLabel(offset); } else { // Copy the instruction, inlining any subroutine call recursively. instruction.accept(clazz, method, codeAttribute, offset, this); } offset += instructionLength; } // Copy the exceptions. Note that exceptions with empty try blocks // are automatically removed. codeAttribute.exceptionsAccept(clazz, method, subroutineExceptionInliner); if (DEBUG) { System.out.println(" Appending label after code at ["+offset+"]"); } // Append a label just after the code. codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); // End and update the code attribute. codeAttributeComposer.endCodeFragment(); codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute); }
Example 14
Source File: CodeAttributeComposer.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
/** * Wraps up the current code fragment, continuing with the previous one on * the stack. */ public void endCodeFragment() { if (level < 0) { throw new IllegalArgumentException("Code fragment not begun ["+level+"]"); } // Remap the instructions of the code fragment. int instructionOffset = codeFragmentOffsets[level]; while (instructionOffset < codeLength) { // Get the next instruction. Instruction instruction = InstructionFactory.create(code, instructionOffset); // Does this instruction still have to be remapped? if (oldInstructionOffsets[instructionOffset] >= 0) { // Adapt the instruction for its new offset. instruction.accept(null, null, null, instructionOffset, this); // Write the instruction back. // instruction.accept(null, // null, // new CodeAttribute(0, 0, 0, 0, code, 0, null, 0, null), // instructionOffset, // instructionWriter); instruction.write(code, instructionOffset); // Don't remap this instruction again. oldInstructionOffsets[instructionOffset] = -1; } // Continue remapping at the next instruction offset. instructionOffset += instruction.length(instructionOffset); } // Correct the estimated maximum code length, now that we know the // actual length of this code fragment. maximumCodeLength += codeLength - codeFragmentOffsets[level] - codeFragmentLengths[level]; // Try to remap the exception handlers that couldn't be remapped before. if (allowExternalExceptionHandlers) { for (int index = 0; index < exceptionTableLength; index++) { ExceptionInfo exceptionInfo = exceptionTable[index]; // Unmapped exception handlers are still negated. int handlerPC = -exceptionInfo.u2handlerPC; if (handlerPC > 0) { if (remappableInstructionOffset(handlerPC)) { exceptionInfo.u2handlerPC = remapInstructionOffset(handlerPC); } else if (level == 0) { throw new IllegalStateException("Couldn't remap exception handler offset ["+handlerPC+"]"); } } } } level--; }
Example 15
Source File: PartialEvaluator.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { // DEBUG = DEBUG_RESULTS = // clazz.getName().equals("abc/Def") && // method.getName(clazz).equals("abc"); // TODO: Remove this when the partial evaluator has stabilized. // Catch any unexpected exceptions from the actual visiting method. try { // Process the code. visitCodeAttribute0(clazz, method, codeAttribute); } catch (RuntimeException ex) { System.err.println("Unexpected error while performing partial evaluation:"); System.err.println(" Class = ["+clazz.getName()+"]"); System.err.println(" Method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]"); System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")"); if (DEBUG) { method.accept(clazz, new ClassPrinter()); System.out.println("Evaluation results:"); int offset = 0; do { if (isBranchOrExceptionTarget(offset)) { System.out.println("Branch target from ["+branchOriginValues[offset]+"]:"); if (isTraced(offset)) { System.out.println(" Vars: "+variablesBefore[offset]); System.out.println(" Stack: "+stacksBefore[offset]); } } Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); System.out.println(instruction.toString(offset)); if (isTraced(offset)) { int initializationOffset = branchTargetFinder.initializationOffset(offset); if (initializationOffset != NONE) { System.out.println(" is to be initialized at ["+initializationOffset+"]"); } InstructionOffsetValue branchTargets = branchTargets(offset); if (branchTargets != null) { System.out.println(" has overall been branching to "+branchTargets); } System.out.println(" Vars: "+variablesAfter[offset]); System.out.println(" Stack: "+stacksAfter[offset]); } offset += instruction.length(offset); } while (offset < codeAttribute.u4codeLength); } throw ex; } }
Example 16
Source File: PartialEvaluator.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) { // Evaluate the instructions, starting at the entry point. if (DEBUG) { System.out.println(); System.out.println("Partial evaluation: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); System.out.println(" Max locals = "+codeAttribute.u2maxLocals); System.out.println(" Max stack = "+codeAttribute.u2maxStack); } // Reuse the existing variables and stack objects, ensuring the right size. TracedVariables variables = new TracedVariables(codeAttribute.u2maxLocals); TracedStack stack = new TracedStack(codeAttribute.u2maxStack); // Initialize the reusable arrays and variables. initializeArrays(codeAttribute); initializeParameters(clazz, method, codeAttribute, variables); // Find all instruction offsets,... codeAttribute.accept(clazz, method, branchTargetFinder); // Start executing the first instruction block. evaluateInstructionBlockAndExceptionHandlers(clazz, method, codeAttribute, variables, stack, 0, codeAttribute.u4codeLength); if (DEBUG_RESULTS) { System.out.println("Evaluation results:"); int offset = 0; do { if (isBranchOrExceptionTarget(offset)) { System.out.println("Branch target from ["+branchOriginValues[offset]+"]:"); if (isTraced(offset)) { System.out.println(" Vars: "+variablesBefore[offset]); System.out.println(" Stack: "+stacksBefore[offset]); } } Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); System.out.println(instruction.toString(offset)); if (isTraced(offset)) { int initializationOffset = branchTargetFinder.initializationOffset(offset); if (initializationOffset != NONE) { System.out.println(" is to be initialized at ["+initializationOffset+"]"); } InstructionOffsetValue branchTargets = branchTargets(offset); if (branchTargets != null) { System.out.println(" has overall been branching to "+branchTargets); } System.out.println(" Vars: "+variablesAfter[offset]); System.out.println(" Stack: "+stacksAfter[offset]); } offset += instruction.length(offset); } while (offset < codeAttribute.u4codeLength); } }
Example 17
Source File: CodeSubroutineInliner.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { int startPC = Math.max(exceptionInfo.u2startPC, clipStart); int endPC = Math.min(exceptionInfo.u2endPC, clipEnd); int handlerPC = exceptionInfo.u2handlerPC; int catchType = exceptionInfo.u2catchType; // Exclude any subroutine invocations that jump out of the try block, // by adding a try block before (and later on, after) each invocation. for (int offset = startPC; offset < endPC; offset++) { if (branchTargetFinder.isSubroutineInvocation(offset)) { Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); int instructionLength = instruction.length(offset); // Is it a subroutine invocation? if (!exceptionInfo.isApplicable(offset + ((BranchInstruction)instruction).branchOffset)) { if (DEBUG) { System.out.println(" Appending extra exception ["+startPC+" -> "+offset+"] -> "+handlerPC); } // Append a try block that ends before the subroutine invocation. codeAttributeComposer.appendException(new ExceptionInfo(startPC, offset, handlerPC, catchType)); // The next try block will start after the subroutine invocation. startPC = offset + instructionLength; } } } if (DEBUG) { if (startPC == exceptionInfo.u2startPC && endPC == exceptionInfo.u2endPC) { System.out.println(" Appending exception ["+startPC+" -> "+endPC+"] -> "+handlerPC); } else { System.out.println(" Appending clipped exception ["+exceptionInfo.u2startPC+" -> "+exceptionInfo.u2endPC+"] ~> ["+startPC+" -> "+endPC+"] -> "+handlerPC); } } // Append the exception. Note that exceptions with empty try blocks // are automatically ignored. codeAttributeComposer.appendException(new ExceptionInfo(startPC, endPC, handlerPC, catchType)); }