00001 package de.fub.bytecode.generic;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 public final class SWITCH implements CompoundInstruction {
00012 private int[] match;
00013 private InstructionHandle[] targets;
00014 private Select instruction;
00015 private int match_length;
00016
00017 public SWITCH(int[] match, InstructionHandle[] targets,
00018 InstructionHandle target) {
00019 this(match, targets, target, 1);
00020 }
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 public SWITCH(int[] match, InstructionHandle[] targets,
00037 InstructionHandle target, int max_gap) {
00038 this.match = (int[])match.clone();
00039 this.targets = (InstructionHandle[])targets.clone();
00040
00041 if((match_length = match.length) < 2)
00042 instruction = new TABLESWITCH(match, targets, target);
00043 else {
00044 sort(0, match_length - 1);
00045
00046 if(matchIsOrdered(max_gap)) {
00047 fillup(max_gap, target);
00048
00049 instruction = new TABLESWITCH(this.match, this.targets, target);
00050 }
00051 else
00052 instruction = new LOOKUPSWITCH(this.match, this.targets, target);
00053 }
00054 }
00055 private final void fillup(int max_gap, InstructionHandle target) {
00056 int max_size = match_length + match_length * max_gap;
00057 int[] m_vec = new int[max_size];
00058 InstructionHandle[] t_vec = new InstructionHandle[max_size];
00059 int count = 1;
00060
00061 m_vec[0] = match[0];
00062 t_vec[0] = targets[0];
00063
00064 for(int i=1; i < match_length; i++) {
00065 int prev = match[i-1];
00066 int gap = match[i] - prev;
00067
00068 for(int j=1; j < gap; j++) {
00069 m_vec[count] = prev + j;
00070 t_vec[count] = target;
00071 count++;
00072 }
00073
00074 m_vec[count] = match[i];
00075 t_vec[count] = targets[i];
00076 count++;
00077 }
00078
00079 match = new int[count];
00080 targets = new InstructionHandle[count];
00081
00082 System.arraycopy(m_vec, 0, match, 0, count);
00083 System.arraycopy(t_vec, 0, targets, 0, count);
00084 }
00085 public final Instruction getInstruction() {
00086 return instruction;
00087 }
00088 public final InstructionList getInstructionList() {
00089 return new InstructionList(instruction);
00090 }
00091
00092
00093
00094 private final boolean matchIsOrdered(int max_gap) {
00095 for(int i=1; i < match_length; i++)
00096 if(match[i] - match[i-1] > max_gap)
00097 return false;
00098
00099 return true;
00100 }
00101
00102
00103
00104 private final void sort(int l, int r) {
00105 int i = l, j = r;
00106 int h, m = match[(l + r) / 2];
00107 InstructionHandle h2;
00108
00109 do {
00110 while(match[i] < m) i++;
00111 while(m < match[j]) j--;
00112
00113 if(i <= j) {
00114 h=match[i]; match[i]=match[j]; match[j]=h;
00115 h2=targets[i]; targets[i]=targets[j]; targets[j]=h2;
00116 i++; j--;
00117 }
00118 } while(i <= j);
00119
00120 if(l < j) sort(l, j);
00121 if(i < r) sort(i, r);
00122 }
00123 }