This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git
The following commit(s) were added to refs/heads/master by this push:
new d6ff11ae Build TABLESWITCH from sorted arrays in SWITCH (#518)
d6ff11ae is described below
commit d6ff11aefb960aa212d39dbd2e70d571e39307ee
Author: Naveed Khan <[email protected]>
AuthorDate: Sat Jul 11 19:26:43 2026 +0000
Build TABLESWITCH from sorted arrays in SWITCH (#518)
The TABLESWITCH branch filled the table from the caller's unsorted
match/targets arrays instead of the sorted clones the LOOKUPSWITCH branch uses,
so an unsorted match array produced a table with out-of-order case values and a
low/high header that disagrees with the emitted offset count.
---
src/main/java/org/apache/bcel/generic/SWITCH.java | 12 +++---
.../java/org/apache/bcel/generic/SWITCHTest.java | 49 ++++++++++++++++++++++
2 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/apache/bcel/generic/SWITCH.java
b/src/main/java/org/apache/bcel/generic/SWITCH.java
index fdb01ff0..3c5ed4fc 100644
--- a/src/main/java/org/apache/bcel/generic/SWITCH.java
+++ b/src/main/java/org/apache/bcel/generic/SWITCH.java
@@ -111,18 +111,18 @@ public final class SWITCH implements CompoundInstruction {
final int[] mVec = new int[maxSize];
final InstructionHandle[] tVec = new
InstructionHandle[maxSize];
int count = 1;
- mVec[0] = match[0];
- tVec[0] = targets[0];
+ mVec[0] = matchClone[0];
+ tVec[0] = targetsClone[0];
for (int i = 1; i < matchLength; i++) {
- final int prev = match[i - 1];
- final int gap = match[i] - prev;
+ final int prev = matchClone[i - 1];
+ final int gap = matchClone[i] - prev;
for (int j = 1; j < gap; j++) {
mVec[count] = prev + j;
tVec[count] = target;
count++;
}
- mVec[count] = match[i];
- tVec[count] = targets[i];
+ mVec[count] = matchClone[i];
+ tVec[count] = targetsClone[i];
count++;
}
instruction = new TABLESWITCH(Arrays.copyOf(mVec, count),
Arrays.copyOf(tVec, count), target);
diff --git a/src/test/java/org/apache/bcel/generic/SWITCHTest.java
b/src/test/java/org/apache/bcel/generic/SWITCHTest.java
new file mode 100644
index 00000000..a741dfc5
--- /dev/null
+++ b/src/test/java/org/apache/bcel/generic/SWITCHTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bcel.generic;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+import org.junit.jupiter.api.Test;
+
+class SWITCHTest {
+
+ /**
+ * {@link SWITCH} documents that the key array is sorted internally while
the caller's arrays are left unaltered,
+ * so an unsorted match array whose sorted form is gap-free must produce a
TABLESWITCH whose case values are
+ * ascending and paired with their targets. Filling the table from the
unsorted originals instead yields
+ * out-of-order match values padded with the default target.
+ */
+ @Test
+ void testUnsortedMatchBuildsSortedTableSwitch() {
+ final InstructionList il = new InstructionList();
+ final InstructionHandle defaultTarget =
il.append(InstructionConst.NOP);
+ final InstructionHandle target1 = il.append(InstructionConst.NOP);
+ final InstructionHandle target2 = il.append(InstructionConst.NOP);
+ final InstructionHandle target3 = il.append(InstructionConst.NOP);
+ // Sorted form {1, 2, 3} is gap-free, so a TABLESWITCH is generated.
+ final int[] match = {2, 1, 3};
+ final InstructionHandle[] targets = {target2, target1, target3};
+ final Select select = (Select) new SWITCH(match, targets,
defaultTarget).getInstruction();
+ assertInstanceOf(TABLESWITCH.class, select);
+ assertArrayEquals(new int[] {1, 2, 3}, select.getMatchs());
+ assertArrayEquals(new InstructionHandle[] {target1, target2, target3},
select.getTargets());
+ }
+}