View Javadoc
1 package org.apache.bcel.generic; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache BCEL" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache BCEL", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 /*** 58 * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or 59 * TABLESWITCH instruction, depending on whether the match values (int[]) can be 60 * sorted with no gaps between the numbers. 61 * 62 * @version $Id: SWITCH.java,v 1.1.1.1 2001/10/29 20:00:27 jvanzyl Exp $ 63 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 64 */ 65 public final class SWITCH implements CompoundInstruction { 66 private int[] match; 67 private InstructionHandle[] targets; 68 private Select instruction; 69 private int match_length; 70 71 /*** 72 * Template for switch() constructs. If the match array can be 73 * sorted in ascending order with gaps no larger than max_gap 74 * between the numbers, a TABLESWITCH instruction is generated, and 75 * a LOOKUPSWITCH otherwise. The former may be more efficient, but 76 * needs more space. 77 * 78 * Note, that the key array always will be sorted, though we leave 79 * the original arrays unaltered. 80 * 81 * @param match array of match values (case 2: ... case 7: ..., etc.) 82 * @param targets the instructions to be branched to for each case 83 * @param target the default target 84 * @param max_gap maximum gap that may between case branches 85 */ 86 public SWITCH(int[] match, InstructionHandle[] targets, 87 InstructionHandle target, int max_gap) { 88 this.match = (int[])match.clone(); 89 this.targets = (InstructionHandle[])targets.clone(); 90 91 if((match_length = match.length) < 2) // (almost) empty switch, or just default 92 instruction = new TABLESWITCH(match, targets, target); 93 else { 94 sort(0, match_length - 1); 95 96 if(matchIsOrdered(max_gap)) { 97 fillup(max_gap, target); 98 99 instruction = new TABLESWITCH(this.match, this.targets, target); 100 } 101 else 102 instruction = new LOOKUPSWITCH(this.match, this.targets, target); 103 } 104 } 105 106 public SWITCH(int[] match, InstructionHandle[] targets, 107 InstructionHandle target) { 108 this(match, targets, target, 1); 109 } 110 111 private final void fillup(int max_gap, InstructionHandle target) { 112 int max_size = match_length + match_length * max_gap; 113 int[] m_vec = new int[max_size]; 114 InstructionHandle[] t_vec = new InstructionHandle[max_size]; 115 int count = 1; 116 117 m_vec[0] = match[0]; 118 t_vec[0] = targets[0]; 119 120 for(int i=1; i < match_length; i++) { 121 int prev = match[i-1]; 122 int gap = match[i] - prev; 123 124 for(int j=1; j < gap; j++) { 125 m_vec[count] = prev + j; 126 t_vec[count] = target; 127 count++; 128 } 129 130 m_vec[count] = match[i]; 131 t_vec[count] = targets[i]; 132 count++; 133 } 134 135 match = new int[count]; 136 targets = new InstructionHandle[count]; 137 138 System.arraycopy(m_vec, 0, match, 0, count); 139 System.arraycopy(t_vec, 0, targets, 0, count); 140 } 141 142 /*** 143 * Sort match and targets array with QuickSort. 144 */ 145 private final void sort(int l, int r) { 146 int i = l, j = r; 147 int h, m = match[(l + r) / 2]; 148 InstructionHandle h2; 149 150 do { 151 while(match[i] < m) i++; 152 while(m < match[j]) j--; 153 154 if(i <= j) { 155 h=match[i]; match[i]=match[j]; match[j]=h; // Swap elements 156 h2=targets[i]; targets[i]=targets[j]; targets[j]=h2; // Swap instructions, too 157 i++; j--; 158 } 159 } while(i <= j); 160 161 if(l < j) sort(l, j); 162 if(i < r) sort(i, r); 163 } 164 165 /*** 166 * @return match is sorted in ascending order with no gap bigger than max_gap? 167 */ 168 private final boolean matchIsOrdered(int max_gap) { 169 for(int i=1; i < match_length; i++) 170 if(match[i] - match[i-1] > max_gap) 171 return false; 172 173 return true; 174 } 175 176 public final InstructionList getInstructionList() { 177 return new InstructionList(instruction); 178 } 179 180 public final Instruction getInstruction() { 181 return instruction; 182 } 183 }

This page was automatically generated by Maven