use of org.apache.bcel.generic.ClassGenException in project jop by jop-devel.
the class InstructionFinder method search.
/**
* Search for the given pattern in the instruction list. You can search for
* any valid opcode via its symbolic name, e.g. "istore". You can also use a
* super class or an interface name to match a whole set of instructions, e.g.
* "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all
* "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp"
* for "if_icmpxx", "if_acmp" for "if_acmpxx".
*
* BUGFIX: wrong length (WP)
*
* Consecutive instruction names must be separated by white space which will
* be removed during the compilation of the pattern.
*
* For the rest the usual pattern matching rules for regular expressions
* apply.
* <P>
* Example pattern:
*
* <pre>
* search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
* </pre>
*
* <p>
* If you alter the instruction list upon a match such that other matching
* areas are affected, you should call reread() to update the finder and call
* search() again, because the matches are cached.
*
* @param pattern
* the instruction pattern to search for, where case is ignored
* @param from
* where to start the search in the instruction list
* @param constraint
* optional CodeConstraint to check the found code pattern for
* user-defined constraints
* @return iterator of matches where e.nextElement() returns an array of
* instruction handles describing the matched area
*/
public final Iterator search(String pattern, InstructionHandle from, CodeConstraint constraint) {
String search = compilePattern(pattern);
int start = -1;
for (int i = 0; i < handles.length; i++) {
if (handles[i] == from) {
// Where to start search from (index)
start = i;
break;
}
}
if (start == -1) {
throw new ClassGenException("Instruction handle " + from + " not found in instruction list.");
}
Pattern regex = Pattern.compile(search);
List matches = new ArrayList();
Matcher matcher = regex.matcher(il_string);
while (start < il_string.length() && matcher.find(start)) {
int startExpr = matcher.start();
int endExpr = matcher.end();
// int lenExpr = (endExpr - startExpr) + 1;
int lenExpr = (endExpr - startExpr);
InstructionHandle[] match = getMatch(startExpr, lenExpr);
if ((constraint == null) || constraint.checkCode(match)) {
matches.add(match);
}
start = endExpr;
}
return matches.iterator();
}
Aggregations