001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.compress.harmony.unpack200.bytecode.forms; 020 021import java.util.Arrays; 022import java.util.HashMap; 023import java.util.Map; 024 025import org.apache.commons.compress.harmony.pack200.Pack200Exception; 026import org.apache.commons.compress.harmony.unpack200.bytecode.ByteCode; 027import org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute; 028import org.apache.commons.compress.harmony.unpack200.bytecode.OperandManager; 029 030/** 031 * Abstract byte code form. 032 */ 033public abstract class ByteCodeForm { 034 035 protected static final boolean WIDENED = true; 036 037 protected static final ByteCodeForm[] byteCodeArray = new ByteCodeForm[256]; 038 protected static final Map<String, ByteCodeForm> byteCodesByName = new HashMap<>(256); 039 static { 040 byteCodeArray[0] = new NoArgumentForm(0, "nop"); 041 byteCodeArray[1] = new NoArgumentForm(1, "aconst_null"); 042 byteCodeArray[2] = new NoArgumentForm(2, "iconst_m1"); 043 byteCodeArray[3] = new NoArgumentForm(3, "iconst_0"); 044 byteCodeArray[4] = new NoArgumentForm(4, "iconst_1"); 045 byteCodeArray[5] = new NoArgumentForm(5, "iconst_2"); 046 byteCodeArray[6] = new NoArgumentForm(6, "iconst_3"); 047 byteCodeArray[7] = new NoArgumentForm(7, "iconst_4"); 048 byteCodeArray[8] = new NoArgumentForm(8, "iconst_5"); 049 byteCodeArray[9] = new NoArgumentForm(9, "lconst_0"); 050 byteCodeArray[10] = new NoArgumentForm(10, "lconst_1"); 051 byteCodeArray[11] = new NoArgumentForm(11, "fconst_0"); 052 byteCodeArray[12] = new NoArgumentForm(12, "fconst_1"); 053 byteCodeArray[13] = new NoArgumentForm(13, "fconst_2"); 054 byteCodeArray[14] = new NoArgumentForm(14, "dconst_0"); 055 byteCodeArray[15] = new NoArgumentForm(15, "dconst_1"); 056 byteCodeArray[16] = new ByteForm(16, "bipush", new int[] { 16, -1 }); 057 byteCodeArray[17] = new ShortForm(17, "sipush", new int[] { 17, -1, -1 }); 058 byteCodeArray[18] = new StringRefForm(18, "ldc", new int[] { 18, -1 }); 059 byteCodeArray[19] = new StringRefForm(19, "ldc_w", new int[] { 19, -1, -1 }, WIDENED); 060 byteCodeArray[20] = new LongForm(20, "ldc2_w", new int[] { 20, -1, -1 }); 061 byteCodeArray[21] = new LocalForm(21, "iload", new int[] { 21, -1 }); 062 byteCodeArray[22] = new LocalForm(22, "lload", new int[] { 22, -1 }); 063 byteCodeArray[23] = new LocalForm(23, "fload", new int[] { 23, -1 }); 064 byteCodeArray[24] = new LocalForm(24, "dload", new int[] { 24, -1 }); 065 byteCodeArray[25] = new LocalForm(25, "aload", new int[] { 25, -1 }); 066 byteCodeArray[26] = new NoArgumentForm(26, "iload_0"); 067 byteCodeArray[27] = new NoArgumentForm(27, "iload_1"); 068 byteCodeArray[28] = new NoArgumentForm(28, "iload_2"); 069 byteCodeArray[29] = new NoArgumentForm(29, "iload_3"); 070 byteCodeArray[30] = new NoArgumentForm(30, "lload_0"); 071 byteCodeArray[31] = new NoArgumentForm(31, "lload_1"); 072 byteCodeArray[32] = new NoArgumentForm(32, "lload_2"); 073 byteCodeArray[33] = new NoArgumentForm(33, "lload_3"); 074 byteCodeArray[34] = new NoArgumentForm(34, "fload_0"); 075 byteCodeArray[35] = new NoArgumentForm(35, "fload_1"); 076 byteCodeArray[36] = new NoArgumentForm(36, "fload_2"); 077 byteCodeArray[37] = new NoArgumentForm(37, "fload_3"); 078 byteCodeArray[38] = new NoArgumentForm(38, "dload_0"); 079 byteCodeArray[39] = new NoArgumentForm(39, "dload_1"); 080 byteCodeArray[40] = new NoArgumentForm(40, "dload_2"); 081 byteCodeArray[41] = new NoArgumentForm(41, "dload_3"); 082 byteCodeArray[42] = new NoArgumentForm(42, "aload_0"); 083 byteCodeArray[43] = new NoArgumentForm(43, "aload_1"); 084 byteCodeArray[44] = new NoArgumentForm(44, "aload_2"); 085 byteCodeArray[45] = new NoArgumentForm(45, "aload_3"); 086 byteCodeArray[46] = new NoArgumentForm(46, "iaload"); 087 byteCodeArray[47] = new NoArgumentForm(47, "laload"); 088 byteCodeArray[48] = new NoArgumentForm(48, "faload"); 089 byteCodeArray[49] = new NoArgumentForm(49, "daload"); 090 byteCodeArray[50] = new NoArgumentForm(50, "aaload"); 091 byteCodeArray[51] = new NoArgumentForm(51, "baload"); 092 byteCodeArray[52] = new NoArgumentForm(52, "caload"); 093 byteCodeArray[53] = new NoArgumentForm(53, "saload"); 094 byteCodeArray[54] = new LocalForm(54, "istore", new int[] { 54, -1 }); 095 byteCodeArray[55] = new LocalForm(55, "lstore", new int[] { 55, -1 }); 096 byteCodeArray[56] = new LocalForm(56, "fstore", new int[] { 56, -1 }); 097 byteCodeArray[57] = new LocalForm(57, "dstore", new int[] { 57, -1 }); 098 byteCodeArray[58] = new LocalForm(58, "astore", new int[] { 58, -1 }); 099 byteCodeArray[59] = new NoArgumentForm(59, "istore_0"); 100 byteCodeArray[60] = new NoArgumentForm(60, "istore_1"); 101 byteCodeArray[61] = new NoArgumentForm(61, "istore_2"); 102 byteCodeArray[62] = new NoArgumentForm(62, "istore_3"); 103 byteCodeArray[63] = new NoArgumentForm(63, "lstore_0"); 104 byteCodeArray[64] = new NoArgumentForm(64, "lstore_1"); 105 byteCodeArray[65] = new NoArgumentForm(65, "lstore_2"); 106 byteCodeArray[66] = new NoArgumentForm(66, "lstore_3"); 107 byteCodeArray[67] = new NoArgumentForm(67, "fstore_0"); 108 byteCodeArray[68] = new NoArgumentForm(68, "fstore_1"); 109 byteCodeArray[69] = new NoArgumentForm(69, "fstore_2"); 110 byteCodeArray[70] = new NoArgumentForm(70, "fstore_3"); 111 byteCodeArray[71] = new NoArgumentForm(71, "dstore_0"); 112 byteCodeArray[72] = new NoArgumentForm(72, "dstore_1"); 113 byteCodeArray[73] = new NoArgumentForm(73, "dstore_2"); 114 byteCodeArray[74] = new NoArgumentForm(74, "dstore_3"); 115 byteCodeArray[75] = new NoArgumentForm(75, "astore_0"); 116 byteCodeArray[76] = new NoArgumentForm(76, "astore_1"); 117 byteCodeArray[77] = new NoArgumentForm(77, "astore_2"); 118 byteCodeArray[78] = new NoArgumentForm(78, "astore_3"); 119 byteCodeArray[79] = new NoArgumentForm(79, "iastore"); 120 byteCodeArray[80] = new NoArgumentForm(80, "lastore"); 121 byteCodeArray[81] = new NoArgumentForm(81, "fastore"); 122 byteCodeArray[82] = new NoArgumentForm(82, "dastore"); 123 byteCodeArray[83] = new NoArgumentForm(83, "aastore"); 124 byteCodeArray[84] = new NoArgumentForm(84, "bastore"); 125 byteCodeArray[85] = new NoArgumentForm(85, "castore"); 126 byteCodeArray[86] = new NoArgumentForm(86, "sastore"); 127 byteCodeArray[87] = new NoArgumentForm(87, "pop"); 128 byteCodeArray[88] = new NoArgumentForm(88, "pop2"); 129 byteCodeArray[89] = new NoArgumentForm(89, "dup"); 130 byteCodeArray[90] = new NoArgumentForm(90, "dup_x1"); 131 byteCodeArray[91] = new NoArgumentForm(91, "dup_x2"); 132 byteCodeArray[92] = new NoArgumentForm(92, "dup2"); 133 byteCodeArray[93] = new NoArgumentForm(93, "dup2_x1"); 134 byteCodeArray[94] = new NoArgumentForm(94, "dup2_x2"); 135 byteCodeArray[95] = new NoArgumentForm(95, "swap"); 136 byteCodeArray[96] = new NoArgumentForm(96, "iadd"); 137 byteCodeArray[97] = new NoArgumentForm(97, "ladd"); 138 byteCodeArray[98] = new NoArgumentForm(98, "fadd"); 139 byteCodeArray[99] = new NoArgumentForm(99, "dadd"); 140 byteCodeArray[100] = new NoArgumentForm(100, "isub"); 141 byteCodeArray[101] = new NoArgumentForm(101, "lsub"); 142 byteCodeArray[102] = new NoArgumentForm(102, "fsub"); 143 byteCodeArray[103] = new NoArgumentForm(103, "dsub"); 144 byteCodeArray[104] = new NoArgumentForm(104, "imul"); 145 byteCodeArray[105] = new NoArgumentForm(105, "lmul"); 146 byteCodeArray[106] = new NoArgumentForm(106, "fmul"); 147 byteCodeArray[107] = new NoArgumentForm(107, "dmul"); 148 byteCodeArray[108] = new NoArgumentForm(108, "idiv"); 149 byteCodeArray[109] = new NoArgumentForm(109, "ldiv"); 150 byteCodeArray[110] = new NoArgumentForm(110, "fdiv"); 151 byteCodeArray[111] = new NoArgumentForm(111, "ddiv"); 152 byteCodeArray[112] = new NoArgumentForm(112, "irem"); 153 byteCodeArray[113] = new NoArgumentForm(113, "lrem"); 154 byteCodeArray[114] = new NoArgumentForm(114, "frem"); 155 byteCodeArray[115] = new NoArgumentForm(115, "drem"); 156 byteCodeArray[116] = new NoArgumentForm(116, ""); 157 byteCodeArray[117] = new NoArgumentForm(117, "lneg"); 158 byteCodeArray[118] = new NoArgumentForm(118, "fneg"); 159 byteCodeArray[119] = new NoArgumentForm(119, "dneg"); 160 byteCodeArray[120] = new NoArgumentForm(120, "ishl"); 161 byteCodeArray[121] = new NoArgumentForm(121, "lshl"); 162 byteCodeArray[122] = new NoArgumentForm(122, "ishr"); 163 byteCodeArray[123] = new NoArgumentForm(123, "lshr"); 164 byteCodeArray[124] = new NoArgumentForm(124, "iushr"); 165 byteCodeArray[125] = new NoArgumentForm(125, "lushr"); 166 byteCodeArray[126] = new NoArgumentForm(126, "iand"); 167 byteCodeArray[127] = new NoArgumentForm(127, "land"); 168 byteCodeArray[128] = new NoArgumentForm(128, "ior"); 169 byteCodeArray[129] = new NoArgumentForm(129, "lor"); 170 byteCodeArray[130] = new NoArgumentForm(130, "ixor"); 171 byteCodeArray[131] = new NoArgumentForm(131, "lxor"); 172 byteCodeArray[132] = new IincForm(132, "iinc", new int[] { 132, -1, -1 }); 173 byteCodeArray[133] = new NoArgumentForm(133, "i2l"); 174 byteCodeArray[134] = new NoArgumentForm(134, "i2f"); 175 byteCodeArray[135] = new NoArgumentForm(135, "i2d"); 176 byteCodeArray[136] = new NoArgumentForm(136, "l2i"); 177 byteCodeArray[137] = new NoArgumentForm(137, "l2f"); 178 byteCodeArray[138] = new NoArgumentForm(138, "l2d"); 179 byteCodeArray[139] = new NoArgumentForm(139, "f2i"); 180 byteCodeArray[140] = new NoArgumentForm(140, "f2l"); 181 byteCodeArray[141] = new NoArgumentForm(141, "f2d"); 182 byteCodeArray[142] = new NoArgumentForm(142, "d2i"); 183 byteCodeArray[143] = new NoArgumentForm(143, "d2l"); 184 byteCodeArray[144] = new NoArgumentForm(144, "d2f"); 185 byteCodeArray[145] = new NoArgumentForm(145, "i2b"); 186 byteCodeArray[146] = new NoArgumentForm(146, "i2c"); 187 byteCodeArray[147] = new NoArgumentForm(147, "i2s"); 188 byteCodeArray[148] = new NoArgumentForm(148, "lcmp"); 189 byteCodeArray[149] = new NoArgumentForm(149, "fcmpl"); 190 byteCodeArray[150] = new NoArgumentForm(150, "fcmpg"); 191 byteCodeArray[151] = new NoArgumentForm(151, "dcmpl"); 192 byteCodeArray[152] = new NoArgumentForm(152, "dcmpg"); 193 byteCodeArray[153] = new LabelForm(153, "ifeq", new int[] { 153, -1, -1 }); 194 byteCodeArray[154] = new LabelForm(154, "ifne", new int[] { 154, -1, -1 }); 195 byteCodeArray[155] = new LabelForm(155, "iflt", new int[] { 155, -1, -1 }); 196 byteCodeArray[156] = new LabelForm(156, "ifge", new int[] { 156, -1, -1 }); 197 byteCodeArray[157] = new LabelForm(157, "ifgt", new int[] { 157, -1, -1 }); 198 byteCodeArray[158] = new LabelForm(158, "ifle", new int[] { 158, -1, -1 }); 199 byteCodeArray[159] = new LabelForm(159, "if_icmpeq", new int[] { 159, -1, -1 }); 200 byteCodeArray[160] = new LabelForm(160, "if_icmpne", new int[] { 160, -1, -1 }); 201 byteCodeArray[161] = new LabelForm(161, "if_icmplt", new int[] { 161, -1, -1 }); 202 byteCodeArray[162] = new LabelForm(162, "if_icmpge", new int[] { 162, -1, -1 }); 203 byteCodeArray[163] = new LabelForm(163, "if_icmpgt", new int[] { 163, -1, -1 }); 204 byteCodeArray[164] = new LabelForm(164, "if_icmple", new int[] { 164, -1, -1 }); 205 byteCodeArray[165] = new LabelForm(165, "if_acmpeq", new int[] { 165, -1, -1 }); 206 byteCodeArray[166] = new LabelForm(166, "if_acmpne", new int[] { 166, -1, -1 }); 207 byteCodeArray[167] = new LabelForm(167, "goto", new int[] { 167, -1, -1 }); 208 byteCodeArray[168] = new LabelForm(168, "jsr", new int[] { 168, -1, -1 }); 209 byteCodeArray[169] = new LocalForm(169, "ret", new int[] { 169, -1 }); 210 byteCodeArray[170] = new TableSwitchForm(170, "tableswitch"); 211 byteCodeArray[171] = new LookupSwitchForm(171, "lookupswitch"); 212 byteCodeArray[172] = new NoArgumentForm(172, "ireturn"); 213 byteCodeArray[173] = new NoArgumentForm(173, "lreturn"); 214 byteCodeArray[174] = new NoArgumentForm(174, "freturn"); 215 byteCodeArray[175] = new NoArgumentForm(175, "dreturn"); 216 byteCodeArray[176] = new NoArgumentForm(176, "areturn"); 217 byteCodeArray[177] = new NoArgumentForm(177, "return"); 218 byteCodeArray[178] = new FieldRefForm(178, "getstatic", new int[] { 178, -1, -1 }); 219 byteCodeArray[179] = new FieldRefForm(179, "putstatic", new int[] { 179, -1, -1 }); 220 byteCodeArray[180] = new FieldRefForm(180, "getfield", new int[] { 180, -1, -1 }); 221 byteCodeArray[181] = new FieldRefForm(181, "putfield", new int[] { 181, -1, -1 }); 222 byteCodeArray[182] = new MethodRefForm(182, "invokevirtual", new int[] { 182, -1, -1 }); 223 byteCodeArray[183] = new MethodRefForm(183, "invokespecial", new int[] { 183, -1, -1 }); 224 byteCodeArray[184] = new MethodRefForm(184, "invokestatic", new int[] { 184, -1, -1 }); 225 byteCodeArray[185] = new IMethodRefForm(185, "invokeinterface", new int[] { 185, -1, -1, /* count */-1, 0 }); 226 byteCodeArray[186] = new NoArgumentForm(186, "xxxunusedxxx"); 227 byteCodeArray[187] = new NewClassRefForm(187, "new", new int[] { 187, -1, -1 }); 228 byteCodeArray[188] = new ByteForm(188, "newarray", new int[] { 188, -1 }); 229 byteCodeArray[189] = new ClassRefForm(189, "anewarray", new int[] { 189, -1, -1 }); 230 byteCodeArray[190] = new NoArgumentForm(190, "arraylength"); 231 byteCodeArray[191] = new NoArgumentForm(191, "athrow"); 232 byteCodeArray[192] = new ClassRefForm(192, "checkcast", new int[] { 192, -1, -1 }); 233 byteCodeArray[193] = new ClassRefForm(193, "instanceof", new int[] { 193, -1, -1 }); 234 byteCodeArray[194] = new NoArgumentForm(194, "monitorenter"); 235 byteCodeArray[195] = new NoArgumentForm(195, "monitorexit"); 236 byteCodeArray[196] = new WideForm(196, "wide"); 237 byteCodeArray[197] = new MultiANewArrayForm(197, "multianewarray", new int[] { 197, -1, -1, -1 }); 238 byteCodeArray[198] = new LabelForm(198, "ifnull", new int[] { 198, -1, -1 }); 239 byteCodeArray[199] = new LabelForm(199, "ifnonnull", new int[] { 199, -1, -1 }); 240 byteCodeArray[200] = new LabelForm(200, "goto_w", new int[] { 200, -1, -1, -1, -1 }, WIDENED); 241 byteCodeArray[201] = new LabelForm(201, "jsr_w", new int[] { 201, -1, -1, -1, -1 }, WIDENED); 242 243 // Extra ones defined by pack200 244 byteCodeArray[202] = new ThisFieldRefForm(202, "getstatic_this", new int[] { 178, -1, -1 }); 245 byteCodeArray[203] = new ThisFieldRefForm(203, "putstatic_this", new int[] { 179, -1, -1 }); 246 byteCodeArray[204] = new ThisFieldRefForm(204, "getfield_this", new int[] { 180, -1, -1 }); 247 byteCodeArray[205] = new ThisFieldRefForm(205, "putfield_this", new int[] { 181, -1, -1 }); 248 byteCodeArray[206] = new ThisMethodRefForm(206, "invokevirtual_this", new int[] { 182, -1, -1 }); 249 byteCodeArray[207] = new ThisMethodRefForm(207, "invokespecial_this", new int[] { 183, -1, -1 }); 250 byteCodeArray[208] = new ThisMethodRefForm(208, "invokestatic_this", new int[] { 184, -1, -1 }); 251 byteCodeArray[209] = new ThisFieldRefForm(209, "aload_0_getstatic_this", new int[] { 42, 178, -1, -1 }); 252 byteCodeArray[210] = new ThisFieldRefForm(210, "aload_0_putstatic_this", new int[] { 42, 179, -1, -1 }); 253 byteCodeArray[211] = new ThisFieldRefForm(211, "aload_0_getfield_this", new int[] { 42, 180, -1, -1 }); 254 byteCodeArray[212] = new ThisFieldRefForm(212, "aload_0_putfield_this", new int[] { 42, 181, -1, -1 }); 255 byteCodeArray[213] = new ThisMethodRefForm(213, "aload_0_invokevirtual_this", new int[] { 42, 182, -1, -1 }); 256 byteCodeArray[214] = new ThisMethodRefForm(214, "aload_0_invokespecial_this", new int[] { 42, 183, -1, -1 }); 257 byteCodeArray[215] = new ThisMethodRefForm(215, "aload_0_invokestatic_this", new int[] { 42, 184, -1, -1 }); 258 byteCodeArray[216] = new SuperFieldRefForm(216, "getstatic_super", new int[] { 178, -1, -1 }); 259 byteCodeArray[217] = new SuperFieldRefForm(217, "putstatic_super", new int[] { 179, -1, -1 }); 260 byteCodeArray[218] = new SuperFieldRefForm(218, "getfield_super", new int[] { 180, -1, -1 }); 261 byteCodeArray[219] = new SuperFieldRefForm(219, "putfield_super", new int[] { 181, -1, -1 }); 262 byteCodeArray[220] = new SuperMethodRefForm(220, "invokevirtual_super", new int[] { 182, -1, -1 }); 263 byteCodeArray[221] = new SuperMethodRefForm(221, "invokespecial_super", new int[] { 183, -1, -1 }); 264 byteCodeArray[222] = new SuperMethodRefForm(222, "invokestatic_super", new int[] { 184, -1, -1 }); 265 byteCodeArray[223] = new SuperFieldRefForm(223, "aload_0_getstatic_super", new int[] { 42, 178, -1, -1 }); 266 byteCodeArray[224] = new SuperFieldRefForm(224, "aload_0_putstatic_super", new int[] { 42, 179, -1, -1 }); 267 byteCodeArray[225] = new SuperFieldRefForm(225, "aload_0_getfield_super", new int[] { 42, 180, -1, -1 }); 268 byteCodeArray[226] = new SuperFieldRefForm(226, "aload_0_putfield_super", new int[] { 42, 181, -1, -1 }); 269 byteCodeArray[227] = new SuperMethodRefForm(227, "aload_0_invokevirtual_super", new int[] { 42, 182, -1, -1 }); 270 byteCodeArray[228] = new SuperMethodRefForm(228, "aload_0_invokespecial_super", new int[] { 42, 183, -1, -1 }); 271 byteCodeArray[229] = new SuperMethodRefForm(229, "aload_0_invokestatic_super", new int[] { 42, 184, -1, -1 }); 272 byteCodeArray[230] = new ThisInitMethodRefForm(230, "invokespecial_this_init", new int[] { 183, -1, -1 }); 273 byteCodeArray[231] = new SuperInitMethodRefForm(231, "invokespecial_super_init", new int[] { 183, -1, -1 }); 274 byteCodeArray[232] = new NewInitMethodRefForm(232, "invokespecial_new_init", new int[] { 183, -1, -1 }); 275 byteCodeArray[233] = new NarrowClassRefForm(233, "cldc", new int[] { 18, -1 }); 276 byteCodeArray[234] = new IntRefForm(234, "ildc", new int[] { 18, -1 }); 277 byteCodeArray[235] = new FloatRefForm(235, "fldc", new int[] { 18, -1 }); 278 byteCodeArray[236] = new NarrowClassRefForm(236, "cldc_w", new int[] { 19, -1, -1 }, WIDENED); 279 byteCodeArray[237] = new IntRefForm(237, "ildc_w", new int[] { 19, -1, -1 }, WIDENED); 280 byteCodeArray[238] = new FloatRefForm(238, "fldc_w", new int[] { 19, -1, -1 }, WIDENED); 281 byteCodeArray[239] = new DoubleForm(239, "dldc2_w", new int[] { 20, -1, -1 }); 282 283 // Reserved bytecodes 284 byteCodeArray[254] = new NoArgumentForm(254, "impdep1"); 285 byteCodeArray[255] = new NoArgumentForm(255, "impdep2"); 286 287 // Bytecodes that aren't defined in the spec but are useful when 288 // unpacking (all must be >255) 289 // maybe wide versions of the others? etc. 290 291 // Put all the bytecodes in a HashMap so we can 292 // get them by either name or number 293 for (final ByteCodeForm byteCode : byteCodeArray) { 294 if (byteCode != null) { 295 byteCodesByName.put(byteCode.getName(), byteCode); 296 } 297 } 298 } 299 300 /** 301 * Gets a ByteCodeForm. 302 * 303 * @param opcode opcode index. 304 * @return the matching ByteCodeForm at the given opcode. 305 */ 306 public static ByteCodeForm get(final int opcode) { 307 return byteCodeArray[opcode]; 308 } 309 310 private final int opcode; 311 private final String name; 312 private final int[] rewrite; 313 private int firstOperandIndex; 314 315 private int operandLength; 316 317 /** 318 * Constructs a new instance with the specified opcode and name. Assume no rewrite. 319 * 320 * @param opcode index corresponding to the opcode's value. 321 * @param name printable name of the opcode. 322 */ 323 public ByteCodeForm(final int opcode, final String name) { 324 this(opcode, name, new int[] { opcode }); 325 } 326 327 /** 328 * Constructs a new instance with the specified opcode, name, operandType and rewrite. 329 * 330 * @param opcode index corresponding to the opcode's value. 331 * @param name String printable name of the opcode. 332 * @param rewrite Operand positions (which will later be rewritten in ByteCodes) are indicated by -1. 333 */ 334 public ByteCodeForm(final int opcode, final String name, final int[] rewrite) { 335 this.opcode = opcode; 336 this.name = name; 337 this.rewrite = rewrite; 338 calculateOperandPosition(); 339 } 340 341 protected void calculateOperandPosition() { 342 firstOperandIndex = -1; 343 operandLength = -1; 344 345 // Find the first negative number in the rewrite array 346 int iterationIndex = 0; 347 while (iterationIndex < rewrite.length) { 348 if (rewrite[iterationIndex] < 0) { 349 // Found the first opcode to substitute 350 firstOperandIndex = iterationIndex; 351 iterationIndex = rewrite.length; 352 } else { 353 iterationIndex++; 354 } 355 } 356 357 if (firstOperandIndex == -1) { 358 // Nothing more to do since the opcode has no operands 359 return; 360 } 361 362 // Find the last negative number in the rewrite array 363 int lastOperandIndex = -1; 364 iterationIndex = firstOperandIndex; 365 while (iterationIndex < rewrite.length) { 366 if (rewrite[iterationIndex] < 0) { 367 lastOperandIndex = iterationIndex; 368 } 369 iterationIndex++; 370 } 371 372 // Now we have the first index and the last index. 373 final int difference = lastOperandIndex - firstOperandIndex; 374 375 // If last < first, something is wrong. 376 if (difference < 0) { 377 throw new Error("Logic error: not finding rewrite operands correctly"); 378 } 379 operandLength = difference + 1; 380 } 381 382 public int firstOperandIndex() { 383 return firstOperandIndex; 384 } 385 386 /** 387 * The ByteCodeForm knows how to fix up a bytecode if it needs to be fixed up because it holds a Label bytecode. 388 * 389 * @param byteCode a ByteCode to be fixed up 390 * @param codeAttribute a CodeAttribute used to determine how the ByteCode should be fixed up. 391 */ 392 public void fixUpByteCodeTargets(final ByteCode byteCode, final CodeAttribute codeAttribute) { 393 // Most ByteCodeForms don't have any fixing up to do. 394 } 395 396 /** 397 * Gets the name. 398 * 399 * @return the name. 400 */ 401 public String getName() { 402 return name; 403 } 404 405 /** 406 * Gets the opcode. 407 * 408 * @return the opcode. 409 */ 410 public int getOpcode() { 411 return opcode; 412 } 413 414 /** 415 * Gets the rewrite array. 416 * 417 * @return the rewrite array. 418 */ 419 public int[] getRewrite() { 420 return rewrite; 421 } 422 423 /** 424 * Gets a copy of the rewrite array. 425 * 426 * @return a copy of the rewrite array. 427 */ 428 public int[] getRewriteCopy() { 429 return Arrays.copyOf(rewrite, rewrite.length); 430 } 431 432 /** 433 * This method will answer true if the receiver is a multi-bytecode instruction (such as aload0_putfield_super); otherwise, it will answer false. 434 * 435 * @return boolean true if multibytecode, false otherwise 436 */ 437 public boolean hasMultipleByteCodes() { 438 // Currently, all multi-bytecode instructions 439 // begin with aload_0, so this is how we test. 440 if (rewrite.length > 1 && rewrite[0] == 42) { 441 // If there's an instruction (not a negative 442 // number, which is an operand) after the 443 // aload_0, it's a multibytecode instruction. 444 return rewrite[1] > 0; 445 } 446 return false; 447 } 448 449 /** 450 * Tests whether this instance has an operand. 451 * 452 * @return whether this instance has an operand. 453 */ 454 public boolean hasNoOperand() { 455 return false; 456 } 457 458 public boolean nestedMustStartClassPool() { 459 return false; 460 } 461 462 /** 463 * Gets the operand length. 464 * 465 * @return the operand length. 466 */ 467 public int operandLength() { 468 return operandLength; 469 } 470 471 /** 472 * Sets the rewrite of the byteCode. 473 * 474 * @param byteCode ByteCode to be updated (!) 475 * @param operandManager OperandTable from which to draw info 476 * @param codeLength Length of bytes (excluding this bytecode) from the beginning of the method. Used in calculating padding for some variable-length 477 * bytecodes (such as lookupswitch, tableswitch). 478 * @throws Pack200Exception if a type is not supported or an index not in the range [0, {@link Integer#MAX_VALUE}]. 479 */ 480 public abstract void setByteCodeOperands(ByteCode byteCode, OperandManager operandManager, int codeLength) throws Pack200Exception; 481 482 @Override 483 public String toString() { 484 return this.getClass().getName() + "(" + getName() + ")"; 485 } 486}