<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1187,6 +1187,101 @@ public class ClassFileWriter {
         putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset);
     }
 
+    public int addLookupSwitch(int ncases)
+    {
+        if (DEBUGCODE) {
+            System.out.println(&quot;Add &quot;+bytecodeStr(ByteCode.LOOKUPSWITCH)
+                               +&quot; &quot;+ncases);
+        }
+        if (ncases &lt; 0)
+            throw new ClassFileFormatException(&quot;Bad switch size: &quot;+ncases);
+
+        int newStack = itsStackTop + stackChange(ByteCode.LOOKUPSWITCH);
+        if (newStack &lt; 0 || Short.MAX_VALUE &lt; newStack) badStack(newStack);
+
+        int padSize = 3 &amp; ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4
+
+        int N = addReservedCodeSpace(1 + padSize + 4 * (2 + ncases * 2));
+        int switchStart = N;
+        itsCodeBuffer[N++] = (byte)ByteCode.LOOKUPSWITCH;
+        while (padSize != 0) {
+            itsCodeBuffer[N++] = 0;
+            --padSize;
+        }
+        N += 4; // skip default offset
+        putInt32(ncases, itsCodeBuffer, N);
+
+        itsStackTop = (short)newStack;
+        if (newStack &gt; itsMaxStack) itsMaxStack = (short)newStack;
+        if (DEBUGSTACK) {
+            System.out.println(&quot;After &quot;+bytecodeStr(ByteCode.LOOKUPSWITCH)
+                               +&quot; stack = &quot;+itsStackTop);
+        }
+
+        return switchStart;
+    }
+
+    public final void markLookupSwitchDefault(int switchStart)
+    {
+        setLookupSwitchJump(switchStart, -1, -1, itsCodeBufferTop);
+    }
+
+    public final void markLookupSwitchCase(int switchStart, int caseIndex, int caseValue)
+    {
+        setLookupSwitchJump(switchStart, caseIndex, caseValue, itsCodeBufferTop);
+    }
+
+    public final void markLookupSwitchCase(int switchStart, int caseIndex,
+                                           int caseValue, int stackTop)
+    {
+        if (!(0 &lt;= stackTop &amp;&amp; stackTop &lt;= itsMaxStack))
+            throw new IllegalArgumentException(&quot;Bad stack index: &quot;+stackTop);
+        itsStackTop = (short)stackTop;
+        setLookupSwitchJump(switchStart, caseIndex, caseValue, itsCodeBufferTop);
+    }
+
+    public void setLookupSwitchJump(int switchStart, int caseIndex,
+                                    int caseValue, int jumpTarget)
+    {
+        if (!(0 &lt;= jumpTarget &amp;&amp; jumpTarget &lt;= itsCodeBufferTop))
+            throw new IllegalArgumentException(&quot;Bad jump target: &quot;+jumpTarget);
+        if (!(caseIndex &gt;= -1))
+            throw new IllegalArgumentException(&quot;Bad case index: &quot;+caseIndex);
+
+        int padSize = 3 &amp; ~switchStart; // == 3 - switchStart % 4
+        int caseOffset;
+        if (caseIndex &lt; 0) {
+            // default label
+            caseOffset = switchStart + 1 + padSize;
+        } else {
+            caseOffset = switchStart + 1 + padSize + 8 * (1 + caseIndex);
+        }
+        if (!(0 &lt;= switchStart
+              &amp;&amp; switchStart &lt;= itsCodeBufferTop - 8 * 2 - padSize - 1))
+        {
+            throw new IllegalArgumentException(
+                switchStart+&quot; is outside a possible range of lookupswitch&quot;
+                +&quot; in already generated code&quot;);
+        }
+        if ((0xFF &amp; itsCodeBuffer[switchStart]) != ByteCode.LOOKUPSWITCH) {
+            throw new IllegalArgumentException(
+                switchStart+&quot; is not offset of lookupswitch statement&quot;);
+        }
+        if (!(0 &lt;= caseOffset &amp;&amp; caseOffset + 8 &lt;= itsCodeBufferTop)) {
+            // caseIndex &gt;= -1 does not guarantee that caseOffset &gt;= 0 due
+            // to a possible overflow.
+            throw new ClassFileFormatException(
+                &quot;Too big case index: &quot;+caseIndex);
+        }
+        // ALERT: perhaps check against case bounds?
+        if (caseIndex &lt; 0) {
+            putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset);
+        } else {
+            putInt32(caseValue, itsCodeBuffer, caseOffset);
+            putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset + 4);
+        }
+    }
+
     public int acquireLabel()
     {
         int top = itsLabelTableTop;</diff>
      <filename>src/org/mozilla/classfile/ClassFileWriter.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>17d4121db137a6642a3efdcce940c497599c0103</id>
    </parent>
  </parents>
  <author>
    <name>Hannes Walln&#246;fer</name>
    <email>hannesw@gmail.com</email>
  </author>
  <url>http://github.com/hns/rhino-8/commit/b05b48b8aac3fbd6c4a5b1efaf3b02309dc93edd</url>
  <id>b05b48b8aac3fbd6c4a5b1efaf3b02309dc93edd</id>
  <committed-date>2009-11-04T04:24:44-08:00</committed-date>
  <authored-date>2009-11-04T04:24:44-08:00</authored-date>
  <message>Add support for lookupswitch instruction</message>
  <tree>3770472db2c0a8c741c8ff22916ebc81d5fd60ad</tree>
  <committer>
    <name>Hannes Walln&#246;fer</name>
    <email>hannesw@gmail.com</email>
  </committer>
</commit>
