< prev index next >

src/com/sun/org/apache/bcel/internal/util/InstructionFinder.java

Print this page
rev 2384 : 8046274: Removing dependency on jakarta-regexp
Reviewed-by: lancea
   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 package com.sun.org.apache.bcel.internal.util;
   6 
   7 /* ====================================================================
   8  * The Apache Software License, Version 1.1













   9  *
  10  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  11  * reserved.
  12  *
  13  * Redistribution and use in source and binary forms, with or without
  14  * modification, are permitted provided that the following conditions
  15  * are met:
  16  *
  17  * 1. Redistributions of source code must retain the above copyright
  18  *    notice, this list of conditions and the following disclaimer.
  19  *
  20  * 2. Redistributions in binary form must reproduce the above copyright
  21  *    notice, this list of conditions and the following disclaimer in
  22  *    the documentation and/or other materials provided with the
  23  *    distribution.
  24  *
  25  * 3. The end-user documentation included with the redistribution,
  26  *    if any, must include the following acknowledgment:
  27  *       "This product includes software developed by the
  28  *        Apache Software Foundation (http://www.apache.org/)."
  29  *    Alternately, this acknowledgment may appear in the software itself,
  30  *    if and wherever such third-party acknowledgments normally appear.
  31  *
  32  * 4. The names "Apache" and "Apache Software Foundation" and
  33  *    "Apache BCEL" must not be used to endorse or promote products
  34  *    derived from this software without prior written permission. For
  35  *    written permission, please contact apache@apache.org.
  36  *
  37  * 5. Products derived from this software may not be called "Apache",
  38  *    "Apache BCEL", nor may "Apache" appear in their name, without
  39  *    prior written permission of the Apache Software Foundation.
  40  *
  41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52  * SUCH DAMAGE.
  53  * ====================================================================
  54  *
  55  * This software consists of voluntary contributions made by many
  56  * individuals on behalf of the Apache Software Foundation.  For more
  57  * information on the Apache Software Foundation, please see
  58  * <http://www.apache.org/>.
  59  */
  60 
  61 import java.util.*;
  62 import com.sun.org.apache.bcel.internal.Constants;
  63 import com.sun.org.apache.bcel.internal.generic.*;
  64 import com.sun.org.apache.regexp.internal.*;


  65 
  66 /**
  67  * InstructionFinder is a tool to search for given instructions patterns,
  68  * i.e., match sequences of instructions in an instruction list via
  69  * regular expressions. This can be used, e.g., in order to implement
  70  * a peep hole optimizer that looks for code patterns and replaces
  71  * them with faster equivalents.
  72  *
  73  * <p>This class internally uses the <a href="http://jakarta.apache.org/regexp/">
  74  * Regexp</a> package to search for regular expressions.
  75  *
  76  * A typical application would look like this:
  77 <pre>
  78     InstructionFinder f   = new InstructionFinder(il);
  79     String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
  80 
  81     for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
  82       InstructionHandle[] match = (InstructionHandle[])i.next();
  83       ...
  84       il.delete(match[1], match[5]);


 214    * user-defined constraints
 215    * @return iterator of matches where e.nextElement() returns an array of instruction handles
 216    * describing the matched area
 217    */
 218   public final Iterator search(String pattern, InstructionHandle from,
 219                                CodeConstraint constraint)
 220   {
 221     String search = compilePattern(pattern);
 222     int  start    = -1;
 223 
 224     for(int i=0; i < handles.length; i++) {
 225       if(handles[i] == from) {
 226         start = i; // Where to start search from (index)
 227         break;
 228       }
 229     }
 230 
 231     if(start == -1)
 232       throw new ClassGenException("Instruction handle " + from +
 233                                   " not found in instruction list.");
 234     try {
 235       RE regex = new RE(search);
 236       ArrayList matches = new ArrayList();
 237 
 238       while(start < il_string.length() && regex.match(il_string, start)) {
 239         int startExpr = regex.getParenStart(0);
 240         int endExpr   = regex.getParenEnd(0);
 241         int lenExpr   = regex.getParenLength(0);
 242 







 243         InstructionHandle[] match = getMatch(startExpr, lenExpr);
 244 
 245         if((constraint == null) || constraint.checkCode(match))
 246           matches.add(match);
 247         start = endExpr;
 248       }
 249 
 250       return matches.iterator();
 251     } catch(RESyntaxException e) {
 252       System.err.println(e);
 253     }
 254 
 255     return null;
 256   }
 257 
 258   /**
 259    * Start search beginning from the start of the given instruction list.
 260    *
 261    * @param pattern the instruction pattern to search for, where case is ignored
 262    * @return iterator of matches where e.nextElement()
 263    * returns an array of instruction handles describing the matched
 264    * area
 265    */
 266   public final Iterator search(String pattern) {
 267     return search(pattern, il.getStart(), null);
 268   }
 269 
 270   /**
 271    * Start search beginning from `from'.
 272    *
 273    * @param pattern the instruction pattern to search for, where case is ignored
 274    * @param from where to start the search in the instruction list
 275    * @return  iterator of matches where e.nextElement() returns an array of instruction handles


   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 package com.sun.org.apache.bcel.internal.util;
   6 
   7 /*
   8  * Licensed to the Apache Software Foundation (ASF) under one or more
   9  * contributor license agreements.  See the NOTICE file distributed with
  10  * this work for additional information regarding copyright ownership.
  11  * The ASF licenses this file to You under the Apache License, Version 2.0
  12  * (the "License"); you may not use this file except in compliance with
  13  * the License.  You may obtain a copy of the License at
  14  *
  15  *      http://www.apache.org/licenses/LICENSE-2.0
  16  *
  17  *  Unless required by applicable law or agreed to in writing, software
  18  *  distributed under the License is distributed on an "AS IS" BASIS,
  19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20  *  See the License for the specific language governing permissions and
  21  *  limitations under the License.
  22  *

















































  23  */
  24 

  25 import com.sun.org.apache.bcel.internal.Constants;
  26 import com.sun.org.apache.bcel.internal.generic.*;
  27 import java.util.*;
  28 import java.util.regex.Matcher;
  29 import java.util.regex.Pattern;
  30 
  31 /**
  32  * InstructionFinder is a tool to search for given instructions patterns,
  33  * i.e., match sequences of instructions in an instruction list via
  34  * regular expressions. This can be used, e.g., in order to implement
  35  * a peep hole optimizer that looks for code patterns and replaces
  36  * them with faster equivalents.
  37  *
  38  * <p>This class internally uses the <a href="http://jakarta.apache.org/regexp/">
  39  * Regexp</a> package to search for regular expressions.
  40  *
  41  * A typical application would look like this:
  42 <pre>
  43     InstructionFinder f   = new InstructionFinder(il);
  44     String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
  45 
  46     for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
  47       InstructionHandle[] match = (InstructionHandle[])i.next();
  48       ...
  49       il.delete(match[1], match[5]);


 179    * user-defined constraints
 180    * @return iterator of matches where e.nextElement() returns an array of instruction handles
 181    * describing the matched area
 182    */
 183   public final Iterator search(String pattern, InstructionHandle from,
 184                                CodeConstraint constraint)
 185   {
 186     String search = compilePattern(pattern);
 187     int  start    = -1;
 188 
 189     for(int i=0; i < handles.length; i++) {
 190       if(handles[i] == from) {
 191         start = i; // Where to start search from (index)
 192         break;
 193       }
 194     }
 195 
 196     if(start == -1)
 197       throw new ClassGenException("Instruction handle " + from +
 198                                   " not found in instruction list.");








 199 
 200     Pattern regex = Pattern.compile(search);
 201     List<InstructionHandle[]> matches = new ArrayList<>();
 202     Matcher matcher = regex.matcher(il_string);
 203     while(start < il_string.length() && matcher.find(start)) {
 204       int startExpr = matcher.start();
 205       int endExpr   = matcher.end();
 206       int lenExpr   = endExpr - startExpr;
 207       InstructionHandle[] match = getMatch(startExpr, lenExpr);
 208 
 209       if((constraint == null) || constraint.checkCode(match))
 210         matches.add(match);
 211       start = endExpr;
 212     }
 213 
 214     return matches.iterator();





 215   }
 216 
 217   /**
 218    * Start search beginning from the start of the given instruction list.
 219    *
 220    * @param pattern the instruction pattern to search for, where case is ignored
 221    * @return iterator of matches where e.nextElement()
 222    * returns an array of instruction handles describing the matched
 223    * area
 224    */
 225   public final Iterator search(String pattern) {
 226     return search(pattern, il.getStart(), null);
 227   }
 228 
 229   /**
 230    * Start search beginning from `from'.
 231    *
 232    * @param pattern the instruction pattern to search for, where case is ignored
 233    * @param from where to start the search in the instruction list
 234    * @return  iterator of matches where e.nextElement() returns an array of instruction handles


< prev index next >