1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.bcel.generic;
20
21 import java.util.Arrays;
22
23
24
25
26
27 public final class SWITCH implements CompoundInstruction {
28
29
30
31
32 private static boolean matchIsOrdered(final int[] match, final int matchLength, final int maxGap) {
33 for (int i = 1; i < matchLength; i++) {
34 if (match[i] - match[i - 1] > maxGap) {
35 return false;
36 }
37 }
38 return true;
39 }
40
41
42
43
44 private static void sort(final int l, final int r, final int[] match, final InstructionHandle[] targets) {
45 int i = l;
46 int j = r;
47 int h;
48 final int m = match[l + r >>> 1];
49 InstructionHandle h2;
50 do {
51 while (match[i] < m) {
52 i++;
53 }
54 while (m < match[j]) {
55 j--;
56 }
57 if (i <= j) {
58 h = match[i];
59 match[i] = match[j];
60 match[j] = h;
61 h2 = targets[i];
62 targets[i] = targets[j];
63 targets[j] = h2;
64 i++;
65 j--;
66 }
67 } while (i <= j);
68 if (l < j) {
69 sort(l, j, match, targets);
70 }
71 if (i < r) {
72 sort(i, r, match, targets);
73 }
74 }
75
76 private final Select instruction;
77
78 public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target) {
79 this(match, targets, target, 1);
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int maxGap) {
95 final int[] matchClone = match.clone();
96 final InstructionHandle[] targetsClone = targets.clone();
97 final int matchLength = match.length;
98 if (matchLength < 2) {
99 instruction = new TABLESWITCH(match, targets, target);
100 } else {
101 sort(0, matchLength - 1, matchClone, targetsClone);
102 if (matchIsOrdered(matchClone, matchLength, maxGap)) {
103 final int maxSize = matchLength + matchLength * maxGap;
104 final int[] mVec = new int[maxSize];
105 final InstructionHandle[] tVec = new InstructionHandle[maxSize];
106 int count = 1;
107 mVec[0] = match[0];
108 tVec[0] = targets[0];
109 for (int i = 1; i < matchLength; i++) {
110 final int prev = match[i - 1];
111 final int gap = match[i] - prev;
112 for (int j = 1; j < gap; j++) {
113 mVec[count] = prev + j;
114 tVec[count] = target;
115 count++;
116 }
117 mVec[count] = match[i];
118 tVec[count] = targets[i];
119 count++;
120 }
121 instruction = new TABLESWITCH(Arrays.copyOf(mVec, count), Arrays.copyOf(tVec, count), target);
122 } else {
123 instruction = new LOOKUPSWITCH(matchClone, targetsClone, target);
124 }
125 }
126 }
127
128 public Instruction getInstruction() {
129 return instruction;
130 }
131
132 @Override
133 public InstructionList getInstructionList() {
134 return new InstructionList(instruction);
135 }
136 }