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());
+    }
+}

Reply via email to