ByteCodeForm.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *   https://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing,
  13.  * software distributed under the License is distributed on an
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15.  * KIND, either express or implied.  See the License for the
  16.  * specific language governing permissions and limitations
  17.  * under the License.
  18.  */
  19. package org.apache.commons.compress.harmony.unpack200.bytecode.forms;

  20. import java.util.Arrays;
  21. import java.util.HashMap;
  22. import java.util.Map;

  23. import org.apache.commons.compress.harmony.pack200.Pack200Exception;
  24. import org.apache.commons.compress.harmony.unpack200.bytecode.ByteCode;
  25. import org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute;
  26. import org.apache.commons.compress.harmony.unpack200.bytecode.OperandManager;

  27. /**
  28.  * Abstract byte code form.
  29.  */
  30. public abstract class ByteCodeForm {

  31.     protected static final boolean WIDENED = true;

  32.     protected static final ByteCodeForm[] byteCodeArray = new ByteCodeForm[256];
  33.     protected static final Map<String, ByteCodeForm> byteCodesByName = new HashMap<>(256);
  34.     static {
  35.         byteCodeArray[0] = new NoArgumentForm(0, "nop");
  36.         byteCodeArray[1] = new NoArgumentForm(1, "aconst_null");
  37.         byteCodeArray[2] = new NoArgumentForm(2, "iconst_m1");
  38.         byteCodeArray[3] = new NoArgumentForm(3, "iconst_0");
  39.         byteCodeArray[4] = new NoArgumentForm(4, "iconst_1");
  40.         byteCodeArray[5] = new NoArgumentForm(5, "iconst_2");
  41.         byteCodeArray[6] = new NoArgumentForm(6, "iconst_3");
  42.         byteCodeArray[7] = new NoArgumentForm(7, "iconst_4");
  43.         byteCodeArray[8] = new NoArgumentForm(8, "iconst_5");
  44.         byteCodeArray[9] = new NoArgumentForm(9, "lconst_0");
  45.         byteCodeArray[10] = new NoArgumentForm(10, "lconst_1");
  46.         byteCodeArray[11] = new NoArgumentForm(11, "fconst_0");
  47.         byteCodeArray[12] = new NoArgumentForm(12, "fconst_1");
  48.         byteCodeArray[13] = new NoArgumentForm(13, "fconst_2");
  49.         byteCodeArray[14] = new NoArgumentForm(14, "dconst_0");
  50.         byteCodeArray[15] = new NoArgumentForm(15, "dconst_1");
  51.         byteCodeArray[16] = new ByteForm(16, "bipush", new int[] { 16, -1 });
  52.         byteCodeArray[17] = new ShortForm(17, "sipush", new int[] { 17, -1, -1 });
  53.         byteCodeArray[18] = new StringRefForm(18, "ldc", new int[] { 18, -1 });
  54.         byteCodeArray[19] = new StringRefForm(19, "ldc_w", new int[] { 19, -1, -1 }, WIDENED);
  55.         byteCodeArray[20] = new LongForm(20, "ldc2_w", new int[] { 20, -1, -1 });
  56.         byteCodeArray[21] = new LocalForm(21, "iload", new int[] { 21, -1 });
  57.         byteCodeArray[22] = new LocalForm(22, "lload", new int[] { 22, -1 });
  58.         byteCodeArray[23] = new LocalForm(23, "fload", new int[] { 23, -1 });
  59.         byteCodeArray[24] = new LocalForm(24, "dload", new int[] { 24, -1 });
  60.         byteCodeArray[25] = new LocalForm(25, "aload", new int[] { 25, -1 });
  61.         byteCodeArray[26] = new NoArgumentForm(26, "iload_0");
  62.         byteCodeArray[27] = new NoArgumentForm(27, "iload_1");
  63.         byteCodeArray[28] = new NoArgumentForm(28, "iload_2");
  64.         byteCodeArray[29] = new NoArgumentForm(29, "iload_3");
  65.         byteCodeArray[30] = new NoArgumentForm(30, "lload_0");
  66.         byteCodeArray[31] = new NoArgumentForm(31, "lload_1");
  67.         byteCodeArray[32] = new NoArgumentForm(32, "lload_2");
  68.         byteCodeArray[33] = new NoArgumentForm(33, "lload_3");
  69.         byteCodeArray[34] = new NoArgumentForm(34, "fload_0");
  70.         byteCodeArray[35] = new NoArgumentForm(35, "fload_1");
  71.         byteCodeArray[36] = new NoArgumentForm(36, "fload_2");
  72.         byteCodeArray[37] = new NoArgumentForm(37, "fload_3");
  73.         byteCodeArray[38] = new NoArgumentForm(38, "dload_0");
  74.         byteCodeArray[39] = new NoArgumentForm(39, "dload_1");
  75.         byteCodeArray[40] = new NoArgumentForm(40, "dload_2");
  76.         byteCodeArray[41] = new NoArgumentForm(41, "dload_3");
  77.         byteCodeArray[42] = new NoArgumentForm(42, "aload_0");
  78.         byteCodeArray[43] = new NoArgumentForm(43, "aload_1");
  79.         byteCodeArray[44] = new NoArgumentForm(44, "aload_2");
  80.         byteCodeArray[45] = new NoArgumentForm(45, "aload_3");
  81.         byteCodeArray[46] = new NoArgumentForm(46, "iaload");
  82.         byteCodeArray[47] = new NoArgumentForm(47, "laload");
  83.         byteCodeArray[48] = new NoArgumentForm(48, "faload");
  84.         byteCodeArray[49] = new NoArgumentForm(49, "daload");
  85.         byteCodeArray[50] = new NoArgumentForm(50, "aaload");
  86.         byteCodeArray[51] = new NoArgumentForm(51, "baload");
  87.         byteCodeArray[52] = new NoArgumentForm(52, "caload");
  88.         byteCodeArray[53] = new NoArgumentForm(53, "saload");
  89.         byteCodeArray[54] = new LocalForm(54, "istore", new int[] { 54, -1 });
  90.         byteCodeArray[55] = new LocalForm(55, "lstore", new int[] { 55, -1 });
  91.         byteCodeArray[56] = new LocalForm(56, "fstore", new int[] { 56, -1 });
  92.         byteCodeArray[57] = new LocalForm(57, "dstore", new int[] { 57, -1 });
  93.         byteCodeArray[58] = new LocalForm(58, "astore", new int[] { 58, -1 });
  94.         byteCodeArray[59] = new NoArgumentForm(59, "istore_0");
  95.         byteCodeArray[60] = new NoArgumentForm(60, "istore_1");
  96.         byteCodeArray[61] = new NoArgumentForm(61, "istore_2");
  97.         byteCodeArray[62] = new NoArgumentForm(62, "istore_3");
  98.         byteCodeArray[63] = new NoArgumentForm(63, "lstore_0");
  99.         byteCodeArray[64] = new NoArgumentForm(64, "lstore_1");
  100.         byteCodeArray[65] = new NoArgumentForm(65, "lstore_2");
  101.         byteCodeArray[66] = new NoArgumentForm(66, "lstore_3");
  102.         byteCodeArray[67] = new NoArgumentForm(67, "fstore_0");
  103.         byteCodeArray[68] = new NoArgumentForm(68, "fstore_1");
  104.         byteCodeArray[69] = new NoArgumentForm(69, "fstore_2");
  105.         byteCodeArray[70] = new NoArgumentForm(70, "fstore_3");
  106.         byteCodeArray[71] = new NoArgumentForm(71, "dstore_0");
  107.         byteCodeArray[72] = new NoArgumentForm(72, "dstore_1");
  108.         byteCodeArray[73] = new NoArgumentForm(73, "dstore_2");
  109.         byteCodeArray[74] = new NoArgumentForm(74, "dstore_3");
  110.         byteCodeArray[75] = new NoArgumentForm(75, "astore_0");
  111.         byteCodeArray[76] = new NoArgumentForm(76, "astore_1");
  112.         byteCodeArray[77] = new NoArgumentForm(77, "astore_2");
  113.         byteCodeArray[78] = new NoArgumentForm(78, "astore_3");
  114.         byteCodeArray[79] = new NoArgumentForm(79, "iastore");
  115.         byteCodeArray[80] = new NoArgumentForm(80, "lastore");
  116.         byteCodeArray[81] = new NoArgumentForm(81, "fastore");
  117.         byteCodeArray[82] = new NoArgumentForm(82, "dastore");
  118.         byteCodeArray[83] = new NoArgumentForm(83, "aastore");
  119.         byteCodeArray[84] = new NoArgumentForm(84, "bastore");
  120.         byteCodeArray[85] = new NoArgumentForm(85, "castore");
  121.         byteCodeArray[86] = new NoArgumentForm(86, "sastore");
  122.         byteCodeArray[87] = new NoArgumentForm(87, "pop");
  123.         byteCodeArray[88] = new NoArgumentForm(88, "pop2");
  124.         byteCodeArray[89] = new NoArgumentForm(89, "dup");
  125.         byteCodeArray[90] = new NoArgumentForm(90, "dup_x1");
  126.         byteCodeArray[91] = new NoArgumentForm(91, "dup_x2");
  127.         byteCodeArray[92] = new NoArgumentForm(92, "dup2");
  128.         byteCodeArray[93] = new NoArgumentForm(93, "dup2_x1");
  129.         byteCodeArray[94] = new NoArgumentForm(94, "dup2_x2");
  130.         byteCodeArray[95] = new NoArgumentForm(95, "swap");
  131.         byteCodeArray[96] = new NoArgumentForm(96, "iadd");
  132.         byteCodeArray[97] = new NoArgumentForm(97, "ladd");
  133.         byteCodeArray[98] = new NoArgumentForm(98, "fadd");
  134.         byteCodeArray[99] = new NoArgumentForm(99, "dadd");
  135.         byteCodeArray[100] = new NoArgumentForm(100, "isub");
  136.         byteCodeArray[101] = new NoArgumentForm(101, "lsub");
  137.         byteCodeArray[102] = new NoArgumentForm(102, "fsub");
  138.         byteCodeArray[103] = new NoArgumentForm(103, "dsub");
  139.         byteCodeArray[104] = new NoArgumentForm(104, "imul");
  140.         byteCodeArray[105] = new NoArgumentForm(105, "lmul");
  141.         byteCodeArray[106] = new NoArgumentForm(106, "fmul");
  142.         byteCodeArray[107] = new NoArgumentForm(107, "dmul");
  143.         byteCodeArray[108] = new NoArgumentForm(108, "idiv");
  144.         byteCodeArray[109] = new NoArgumentForm(109, "ldiv");
  145.         byteCodeArray[110] = new NoArgumentForm(110, "fdiv");
  146.         byteCodeArray[111] = new NoArgumentForm(111, "ddiv");
  147.         byteCodeArray[112] = new NoArgumentForm(112, "irem");
  148.         byteCodeArray[113] = new NoArgumentForm(113, "lrem");
  149.         byteCodeArray[114] = new NoArgumentForm(114, "frem");
  150.         byteCodeArray[115] = new NoArgumentForm(115, "drem");
  151.         byteCodeArray[116] = new NoArgumentForm(116, "");
  152.         byteCodeArray[117] = new NoArgumentForm(117, "lneg");
  153.         byteCodeArray[118] = new NoArgumentForm(118, "fneg");
  154.         byteCodeArray[119] = new NoArgumentForm(119, "dneg");
  155.         byteCodeArray[120] = new NoArgumentForm(120, "ishl");
  156.         byteCodeArray[121] = new NoArgumentForm(121, "lshl");
  157.         byteCodeArray[122] = new NoArgumentForm(122, "ishr");
  158.         byteCodeArray[123] = new NoArgumentForm(123, "lshr");
  159.         byteCodeArray[124] = new NoArgumentForm(124, "iushr");
  160.         byteCodeArray[125] = new NoArgumentForm(125, "lushr");
  161.         byteCodeArray[126] = new NoArgumentForm(126, "iand");
  162.         byteCodeArray[127] = new NoArgumentForm(127, "land");
  163.         byteCodeArray[128] = new NoArgumentForm(128, "ior");
  164.         byteCodeArray[129] = new NoArgumentForm(129, "lor");
  165.         byteCodeArray[130] = new NoArgumentForm(130, "ixor");
  166.         byteCodeArray[131] = new NoArgumentForm(131, "lxor");
  167.         byteCodeArray[132] = new IincForm(132, "iinc", new int[] { 132, -1, -1 });
  168.         byteCodeArray[133] = new NoArgumentForm(133, "i2l");
  169.         byteCodeArray[134] = new NoArgumentForm(134, "i2f");
  170.         byteCodeArray[135] = new NoArgumentForm(135, "i2d");
  171.         byteCodeArray[136] = new NoArgumentForm(136, "l2i");
  172.         byteCodeArray[137] = new NoArgumentForm(137, "l2f");
  173.         byteCodeArray[138] = new NoArgumentForm(138, "l2d");
  174.         byteCodeArray[139] = new NoArgumentForm(139, "f2i");
  175.         byteCodeArray[140] = new NoArgumentForm(140, "f2l");
  176.         byteCodeArray[141] = new NoArgumentForm(141, "f2d");
  177.         byteCodeArray[142] = new NoArgumentForm(142, "d2i");
  178.         byteCodeArray[143] = new NoArgumentForm(143, "d2l");
  179.         byteCodeArray[144] = new NoArgumentForm(144, "d2f");
  180.         byteCodeArray[145] = new NoArgumentForm(145, "i2b");
  181.         byteCodeArray[146] = new NoArgumentForm(146, "i2c");
  182.         byteCodeArray[147] = new NoArgumentForm(147, "i2s");
  183.         byteCodeArray[148] = new NoArgumentForm(148, "lcmp");
  184.         byteCodeArray[149] = new NoArgumentForm(149, "fcmpl");
  185.         byteCodeArray[150] = new NoArgumentForm(150, "fcmpg");
  186.         byteCodeArray[151] = new NoArgumentForm(151, "dcmpl");
  187.         byteCodeArray[152] = new NoArgumentForm(152, "dcmpg");
  188.         byteCodeArray[153] = new LabelForm(153, "ifeq", new int[] { 153, -1, -1 });
  189.         byteCodeArray[154] = new LabelForm(154, "ifne", new int[] { 154, -1, -1 });
  190.         byteCodeArray[155] = new LabelForm(155, "iflt", new int[] { 155, -1, -1 });
  191.         byteCodeArray[156] = new LabelForm(156, "ifge", new int[] { 156, -1, -1 });
  192.         byteCodeArray[157] = new LabelForm(157, "ifgt", new int[] { 157, -1, -1 });
  193.         byteCodeArray[158] = new LabelForm(158, "ifle", new int[] { 158, -1, -1 });
  194.         byteCodeArray[159] = new LabelForm(159, "if_icmpeq", new int[] { 159, -1, -1 });
  195.         byteCodeArray[160] = new LabelForm(160, "if_icmpne", new int[] { 160, -1, -1 });
  196.         byteCodeArray[161] = new LabelForm(161, "if_icmplt", new int[] { 161, -1, -1 });
  197.         byteCodeArray[162] = new LabelForm(162, "if_icmpge", new int[] { 162, -1, -1 });
  198.         byteCodeArray[163] = new LabelForm(163, "if_icmpgt", new int[] { 163, -1, -1 });
  199.         byteCodeArray[164] = new LabelForm(164, "if_icmple", new int[] { 164, -1, -1 });
  200.         byteCodeArray[165] = new LabelForm(165, "if_acmpeq", new int[] { 165, -1, -1 });
  201.         byteCodeArray[166] = new LabelForm(166, "if_acmpne", new int[] { 166, -1, -1 });
  202.         byteCodeArray[167] = new LabelForm(167, "goto", new int[] { 167, -1, -1 });
  203.         byteCodeArray[168] = new LabelForm(168, "jsr", new int[] { 168, -1, -1 });
  204.         byteCodeArray[169] = new LocalForm(169, "ret", new int[] { 169, -1 });
  205.         byteCodeArray[170] = new TableSwitchForm(170, "tableswitch");
  206.         byteCodeArray[171] = new LookupSwitchForm(171, "lookupswitch");
  207.         byteCodeArray[172] = new NoArgumentForm(172, "ireturn");
  208.         byteCodeArray[173] = new NoArgumentForm(173, "lreturn");
  209.         byteCodeArray[174] = new NoArgumentForm(174, "freturn");
  210.         byteCodeArray[175] = new NoArgumentForm(175, "dreturn");
  211.         byteCodeArray[176] = new NoArgumentForm(176, "areturn");
  212.         byteCodeArray[177] = new NoArgumentForm(177, "return");
  213.         byteCodeArray[178] = new FieldRefForm(178, "getstatic", new int[] { 178, -1, -1 });
  214.         byteCodeArray[179] = new FieldRefForm(179, "putstatic", new int[] { 179, -1, -1 });
  215.         byteCodeArray[180] = new FieldRefForm(180, "getfield", new int[] { 180, -1, -1 });
  216.         byteCodeArray[181] = new FieldRefForm(181, "putfield", new int[] { 181, -1, -1 });
  217.         byteCodeArray[182] = new MethodRefForm(182, "invokevirtual", new int[] { 182, -1, -1 });
  218.         byteCodeArray[183] = new MethodRefForm(183, "invokespecial", new int[] { 183, -1, -1 });
  219.         byteCodeArray[184] = new MethodRefForm(184, "invokestatic", new int[] { 184, -1, -1 });
  220.         byteCodeArray[185] = new IMethodRefForm(185, "invokeinterface", new int[] { 185, -1, -1, /* count */-1, 0 });
  221.         byteCodeArray[186] = new NoArgumentForm(186, "xxxunusedxxx");
  222.         byteCodeArray[187] = new NewClassRefForm(187, "new", new int[] { 187, -1, -1 });
  223.         byteCodeArray[188] = new ByteForm(188, "newarray", new int[] { 188, -1 });
  224.         byteCodeArray[189] = new ClassRefForm(189, "anewarray", new int[] { 189, -1, -1 });
  225.         byteCodeArray[190] = new NoArgumentForm(190, "arraylength");
  226.         byteCodeArray[191] = new NoArgumentForm(191, "athrow");
  227.         byteCodeArray[192] = new ClassRefForm(192, "checkcast", new int[] { 192, -1, -1 });
  228.         byteCodeArray[193] = new ClassRefForm(193, "instanceof", new int[] { 193, -1, -1 });
  229.         byteCodeArray[194] = new NoArgumentForm(194, "monitorenter");
  230.         byteCodeArray[195] = new NoArgumentForm(195, "monitorexit");
  231.         byteCodeArray[196] = new WideForm(196, "wide");
  232.         byteCodeArray[197] = new MultiANewArrayForm(197, "multianewarray", new int[] { 197, -1, -1, -1 });
  233.         byteCodeArray[198] = new LabelForm(198, "ifnull", new int[] { 198, -1, -1 });
  234.         byteCodeArray[199] = new LabelForm(199, "ifnonnull", new int[] { 199, -1, -1 });
  235.         byteCodeArray[200] = new LabelForm(200, "goto_w", new int[] { 200, -1, -1, -1, -1 }, WIDENED);
  236.         byteCodeArray[201] = new LabelForm(201, "jsr_w", new int[] { 201, -1, -1, -1, -1 }, WIDENED);

  237.         // Extra ones defined by pack200
  238.         byteCodeArray[202] = new ThisFieldRefForm(202, "getstatic_this", new int[] { 178, -1, -1 });
  239.         byteCodeArray[203] = new ThisFieldRefForm(203, "putstatic_this", new int[] { 179, -1, -1 });
  240.         byteCodeArray[204] = new ThisFieldRefForm(204, "getfield_this", new int[] { 180, -1, -1 });
  241.         byteCodeArray[205] = new ThisFieldRefForm(205, "putfield_this", new int[] { 181, -1, -1 });
  242.         byteCodeArray[206] = new ThisMethodRefForm(206, "invokevirtual_this", new int[] { 182, -1, -1 });
  243.         byteCodeArray[207] = new ThisMethodRefForm(207, "invokespecial_this", new int[] { 183, -1, -1 });
  244.         byteCodeArray[208] = new ThisMethodRefForm(208, "invokestatic_this", new int[] { 184, -1, -1 });
  245.         byteCodeArray[209] = new ThisFieldRefForm(209, "aload_0_getstatic_this", new int[] { 42, 178, -1, -1 });
  246.         byteCodeArray[210] = new ThisFieldRefForm(210, "aload_0_putstatic_this", new int[] { 42, 179, -1, -1 });
  247.         byteCodeArray[211] = new ThisFieldRefForm(211, "aload_0_getfield_this", new int[] { 42, 180, -1, -1 });
  248.         byteCodeArray[212] = new ThisFieldRefForm(212, "aload_0_putfield_this", new int[] { 42, 181, -1, -1 });
  249.         byteCodeArray[213] = new ThisMethodRefForm(213, "aload_0_invokevirtual_this", new int[] { 42, 182, -1, -1 });
  250.         byteCodeArray[214] = new ThisMethodRefForm(214, "aload_0_invokespecial_this", new int[] { 42, 183, -1, -1 });
  251.         byteCodeArray[215] = new ThisMethodRefForm(215, "aload_0_invokestatic_this", new int[] { 42, 184, -1, -1 });
  252.         byteCodeArray[216] = new SuperFieldRefForm(216, "getstatic_super", new int[] { 178, -1, -1 });
  253.         byteCodeArray[217] = new SuperFieldRefForm(217, "putstatic_super", new int[] { 179, -1, -1 });
  254.         byteCodeArray[218] = new SuperFieldRefForm(218, "getfield_super", new int[] { 180, -1, -1 });
  255.         byteCodeArray[219] = new SuperFieldRefForm(219, "putfield_super", new int[] { 181, -1, -1 });
  256.         byteCodeArray[220] = new SuperMethodRefForm(220, "invokevirtual_super", new int[] { 182, -1, -1 });
  257.         byteCodeArray[221] = new SuperMethodRefForm(221, "invokespecial_super", new int[] { 183, -1, -1 });
  258.         byteCodeArray[222] = new SuperMethodRefForm(222, "invokestatic_super", new int[] { 184, -1, -1 });
  259.         byteCodeArray[223] = new SuperFieldRefForm(223, "aload_0_getstatic_super", new int[] { 42, 178, -1, -1 });
  260.         byteCodeArray[224] = new SuperFieldRefForm(224, "aload_0_putstatic_super", new int[] { 42, 179, -1, -1 });
  261.         byteCodeArray[225] = new SuperFieldRefForm(225, "aload_0_getfield_super", new int[] { 42, 180, -1, -1 });
  262.         byteCodeArray[226] = new SuperFieldRefForm(226, "aload_0_putfield_super", new int[] { 42, 181, -1, -1 });
  263.         byteCodeArray[227] = new SuperMethodRefForm(227, "aload_0_invokevirtual_super", new int[] { 42, 182, -1, -1 });
  264.         byteCodeArray[228] = new SuperMethodRefForm(228, "aload_0_invokespecial_super", new int[] { 42, 183, -1, -1 });
  265.         byteCodeArray[229] = new SuperMethodRefForm(229, "aload_0_invokestatic_super", new int[] { 42, 184, -1, -1 });
  266.         byteCodeArray[230] = new ThisInitMethodRefForm(230, "invokespecial_this_init", new int[] { 183, -1, -1 });
  267.         byteCodeArray[231] = new SuperInitMethodRefForm(231, "invokespecial_super_init", new int[] { 183, -1, -1 });
  268.         byteCodeArray[232] = new NewInitMethodRefForm(232, "invokespecial_new_init", new int[] { 183, -1, -1 });
  269.         byteCodeArray[233] = new NarrowClassRefForm(233, "cldc", new int[] { 18, -1 });
  270.         byteCodeArray[234] = new IntRefForm(234, "ildc", new int[] { 18, -1 });
  271.         byteCodeArray[235] = new FloatRefForm(235, "fldc", new int[] { 18, -1 });
  272.         byteCodeArray[236] = new NarrowClassRefForm(236, "cldc_w", new int[] { 19, -1, -1 }, WIDENED);
  273.         byteCodeArray[237] = new IntRefForm(237, "ildc_w", new int[] { 19, -1, -1 }, WIDENED);
  274.         byteCodeArray[238] = new FloatRefForm(238, "fldc_w", new int[] { 19, -1, -1 }, WIDENED);
  275.         byteCodeArray[239] = new DoubleForm(239, "dldc2_w", new int[] { 20, -1, -1 });

  276.         // Reserved bytecodes
  277.         byteCodeArray[254] = new NoArgumentForm(254, "impdep1");
  278.         byteCodeArray[255] = new NoArgumentForm(255, "impdep2");

  279.         // Bytecodes that aren't defined in the spec but are useful when
  280.         // unpacking (all must be >255)
  281.         // maybe wide versions of the others? etc.

  282.         // Put all the bytecodes in a HashMap so we can
  283.         // get them by either name or number
  284.         for (final ByteCodeForm byteCode : byteCodeArray) {
  285.             if (byteCode != null) {
  286.                 byteCodesByName.put(byteCode.getName(), byteCode);
  287.             }
  288.         }
  289.     }

  290.     /**
  291.      * Gets a ByteCodeForm.
  292.      *
  293.      * @param opcode opcode index.
  294.      * @return the matching ByteCodeForm at the given opcode.
  295.      */
  296.     public static ByteCodeForm get(final int opcode) {
  297.         return byteCodeArray[opcode];
  298.     }

  299.     private final int opcode;
  300.     private final String name;
  301.     private final int[] rewrite;
  302.     private int firstOperandIndex;

  303.     private int operandLength;

  304.     /**
  305.      * Constructs a new instance with the specified opcode and name. Assume no rewrite.
  306.      *
  307.      * @param opcode index corresponding to the opcode's value.
  308.      * @param name   printable name of the opcode.
  309.      */
  310.     public ByteCodeForm(final int opcode, final String name) {
  311.         this(opcode, name, new int[] { opcode });
  312.     }

  313.     /**
  314.      * Constructs a new instance with the specified opcode, name, operandType and rewrite.
  315.      *
  316.      * @param opcode  index corresponding to the opcode's value.
  317.      * @param name    String printable name of the opcode.
  318.      * @param rewrite Operand positions (which will later be rewritten in ByteCodes) are indicated by -1.
  319.      */
  320.     public ByteCodeForm(final int opcode, final String name, final int[] rewrite) {
  321.         this.opcode = opcode;
  322.         this.name = name;
  323.         this.rewrite = rewrite;
  324.         calculateOperandPosition();
  325.     }

  326.     protected void calculateOperandPosition() {
  327.         firstOperandIndex = -1;
  328.         operandLength = -1;

  329.         // Find the first negative number in the rewrite array
  330.         int iterationIndex = 0;
  331.         while (iterationIndex < rewrite.length) {
  332.             if (rewrite[iterationIndex] < 0) {
  333.                 // Found the first opcode to substitute
  334.                 firstOperandIndex = iterationIndex;
  335.                 iterationIndex = rewrite.length;
  336.             } else {
  337.                 iterationIndex++;
  338.             }
  339.         }

  340.         if (firstOperandIndex == -1) {
  341.             // Nothing more to do since the opcode has no operands
  342.             return;
  343.         }

  344.         // Find the last negative number in the rewrite array
  345.         int lastOperandIndex = -1;
  346.         iterationIndex = firstOperandIndex;
  347.         while (iterationIndex < rewrite.length) {
  348.             if (rewrite[iterationIndex] < 0) {
  349.                 lastOperandIndex = iterationIndex;
  350.             }
  351.             iterationIndex++;
  352.         }

  353.         // Now we have the first index and the last index.
  354.         final int difference = lastOperandIndex - firstOperandIndex;

  355.         // If last < first, something is wrong.
  356.         if (difference < 0) {
  357.             throw new Error("Logic error: not finding rewrite operands correctly");
  358.         }
  359.         operandLength = difference + 1;
  360.     }

  361.     public int firstOperandIndex() {
  362.         return firstOperandIndex;
  363.     }

  364.     /**
  365.      * The ByteCodeForm knows how to fix up a bytecode if it needs to be fixed up because it holds a Label bytecode.
  366.      *
  367.      * @param byteCode      a ByteCode to be fixed up
  368.      * @param codeAttribute a CodeAttribute used to determine how the ByteCode should be fixed up.
  369.      */
  370.     public void fixUpByteCodeTargets(final ByteCode byteCode, final CodeAttribute codeAttribute) {
  371.         // Most ByteCodeForms don't have any fixing up to do.
  372.     }

  373.     /**
  374.      * Gets the name.
  375.      *
  376.      * @return the name.
  377.      */
  378.     public String getName() {
  379.         return name;
  380.     }

  381.     /**
  382.      * Gets the opcode.
  383.      *
  384.      * @return the opcode.
  385.      */
  386.     public int getOpcode() {
  387.         return opcode;
  388.     }

  389.     /**
  390.      * Gets the rewrite array.
  391.      *
  392.      * @return the rewrite array.
  393.      */
  394.     public int[] getRewrite() {
  395.         return rewrite;
  396.     }

  397.     /**
  398.      * Gets a copy of the rewrite array.
  399.      *
  400.      * @return a copy of the rewrite array.
  401.      */
  402.     public int[] getRewriteCopy() {
  403.         return Arrays.copyOf(rewrite, rewrite.length);
  404.     }

  405.     /**
  406.      * This method will answer true if the receiver is a multi-bytecode instruction (such as aload0_putfield_super); otherwise, it will answer false.
  407.      *
  408.      * @return boolean true if multibytecode, false otherwise
  409.      */
  410.     public boolean hasMultipleByteCodes() {
  411.         // Currently, all multi-bytecode instructions
  412.         // begin with aload_0, so this is how we test.
  413.         if (rewrite.length > 1 && rewrite[0] == 42) {
  414.             // If there's an instruction (not a negative
  415.             // number, which is an operand) after the
  416.             // aload_0, it's a multibytecode instruction.
  417.             return rewrite[1] > 0;
  418.         }
  419.         return false;
  420.     }

  421.     /**
  422.      * Tests whether this instance has an operand.
  423.      *
  424.      * @return whether this instance has an operand.
  425.      */
  426.     public boolean hasNoOperand() {
  427.         return false;
  428.     }

  429.     public boolean nestedMustStartClassPool() {
  430.         return false;
  431.     }

  432.     /**
  433.      * Gets the operand length.
  434.      *
  435.      * @return the operand length.
  436.      */
  437.     public int operandLength() {
  438.         return operandLength;
  439.     }

  440.     /**
  441.      * Sets the rewrite of the byteCode.
  442.      *
  443.      * @param byteCode       ByteCode to be updated (!)
  444.      * @param operandManager OperandTable from which to draw info
  445.      * @param codeLength     Length of bytes (excluding this bytecode) from the beginning of the method. Used in calculating padding for some variable-length
  446.      *                       bytecodes (such as lookupswitch, tableswitch).
  447.      * @throws Pack200Exception if a type is not supported or an index not in the range [0, {@link Integer#MAX_VALUE}].
  448.      */
  449.     public abstract void setByteCodeOperands(ByteCode byteCode, OperandManager operandManager, int codeLength) throws Pack200Exception;

  450.     @Override
  451.     public String toString() {
  452.         return this.getClass().getName() + "(" + getName() + ")";
  453.     }
  454. }