1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm; 60 61 /** 62 * Information about the input and output stack map frames of a basic block. 63 * 64 * @author Eric Bruneton 65 */ 66 class Frame { 67 68 /* 69 * Frames are computed in a two steps process: during the visit of each 70 * instruction, the state of the frame at the end of current basic block is 71 * updated by simulating the action of the instruction on the previous state 72 * of this so called "output frame". In visitMaxs, a fix point algorithm is 73 * used to compute the "input frame" of each basic block, i.e. the stack map 74 * frame at the beginning of the basic block, starting from the input frame 75 * of the first basic block (which is computed from the method descriptor), 76 * and by using the previously computed output frames to compute the input 77 * state of the other blocks. 78 * 79 * All output and input frames are stored as arrays of integers. Reference 80 * and array types are represented by an index into a type table (which is 81 * not the same as the constant pool of the class, in order to avoid adding 82 * unnecessary constants in the pool - not all computed frames will end up 83 * being stored in the stack map table). This allows very fast type 84 * comparisons. 85 * 86 * Output stack map frames are computed relatively to the input frame of the 87 * basic block, which is not yet known when output frames are computed. It 88 * is therefore necessary to be able to represent abstract types such as 89 * "the type at position x in the input frame locals" or "the type at 90 * position x from the top of the input frame stack" or even "the type at 91 * position x in the input frame, with y more (or less) array dimensions". 92 * This explains the rather complicated type format used in output frames. 93 * 94 * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a 95 * signed number of array dimensions (from -8 to 7). KIND is either BASE, 96 * LOCAL or STACK. BASE is used for types that are not relative to the input 97 * frame. LOCAL is used for types that are relative to the input local 98 * variable types. STACK is used for types that are relative to the input 99 * stack types. VALUE depends on KIND. For LOCAL types, it is an index in 100 * the input local variable types. For STACK types, it is a position 101 * relatively to the top of input frame stack. For BASE types, it is either 102 * one of the constants defined below, or for OBJECT and UNINITIALIZED 103 * types, a tag and an index in the type table. 104 * 105 * Output frames can contain types of any kind and with a positive or 106 * negative dimension (and even unassigned types, represented by 0 - which 107 * does not correspond to any valid type value). Input frames can only 108 * contain BASE types of positive or null dimension. In all cases the type 109 * table contains only internal type names (array type descriptors are 110 * forbidden - dimensions must be represented through the DIM field). 111 * 112 * The LONG and DOUBLE types are always represented by using two slots (LONG 113 * + TOP or DOUBLE + TOP), for local variable types as well as in the 114 * operand stack. This is necessary to be able to simulate DUPx_y 115 * instructions, whose effect would be dependent on the actual type values 116 * if types were always represented by a single slot in the stack (and this 117 * is not possible, since actual type values are not always known - cf LOCAL 118 * and STACK type kinds). 119 */ 120 121 /** 122 * Mask to get the dimension of a frame type. This dimension is a signed 123 * integer between -8 and 7. 124 */ 125 static final int DIM = 0xF0000000; 126 127 /** 128 * Constant to be added to a type to get a type with one more dimension. 129 */ 130 static final int ARRAY_OF = 0x10000000; 131 132 /** 133 * Constant to be added to a type to get a type with one less dimension. 134 */ 135 static final int ELEMENT_OF = 0xF0000000; 136 137 /** 138 * Mask to get the kind of a frame type. 139 * 140 * @see #BASE 141 * @see #LOCAL 142 * @see #STACK 143 */ 144 static final int KIND = 0xF000000; 145 146 /** 147 * Flag used for LOCAL and STACK types. Indicates that if this type happens 148 * to be a long or double type (during the computations of input frames), 149 * then it must be set to TOP because the second word of this value has been 150 * reused to store other data in the basic block. Hence the first word no 151 * longer stores a valid long or double value. 152 */ 153 static final int TOP_IF_LONG_OR_DOUBLE = 0x800000; 154 155 /** 156 * Mask to get the value of a frame type. 157 */ 158 static final int VALUE = 0x7FFFFF; 159 160 /** 161 * Mask to get the kind of base types. 162 */ 163 static final int BASE_KIND = 0xFF00000; 164 165 /** 166 * Mask to get the value of base types. 167 */ 168 static final int BASE_VALUE = 0xFFFFF; 169 170 /** 171 * Kind of the types that are not relative to an input stack map frame. 172 */ 173 static final int BASE = 0x1000000; 174 175 /** 176 * Base kind of the base reference types. The BASE_VALUE of such types is an 177 * index into the type table. 178 */ 179 static final int OBJECT = BASE | 0x700000; 180 181 /** 182 * Base kind of the uninitialized base types. The BASE_VALUE of such types 183 * in an index into the type table (the Item at that index contains both an 184 * instruction offset and an internal class name). 185 */ 186 static final int UNINITIALIZED = BASE | 0x800000; 187 188 /** 189 * Kind of the types that are relative to the local variable types of an 190 * input stack map frame. The value of such types is a local variable index. 191 */ 192 private static final int LOCAL = 0x2000000; 193 194 /** 195 * Kind of the types that are relative to the stack of an input stack 196 * map frame. The value of such types is a position relatively to the top of 197 * this stack. 198 */ 199 private static final int STACK = 0x3000000; 200 201 /** 202 * The TOP type. This is a BASE type. 203 */ 204 static final int TOP = BASE | 0; 205 206 /** 207 * The BOOLEAN type. This is a BASE type mainly used for array types. 208 */ 209 static final int BOOLEAN = BASE | 9; 210 211 /** 212 * The BYTE type. This is a BASE type mainly used for array types. 213 */ 214 static final int BYTE = BASE | 10; 215 216 /** 217 * The CHAR type. This is a BASE type mainly used for array types. 218 */ 219 static final int CHAR = BASE | 11; 220 221 /** 222 * The SHORT type. This is a BASE type mainly used for array types. 223 */ 224 static final int SHORT = BASE | 12; 225 226 /** 227 * The INTEGER type. This is a BASE type. 228 */ 229 static final int INTEGER = BASE | 1; 230 231 /** 232 * The FLOAT type. This is a BASE type. 233 */ 234 static final int FLOAT = BASE | 2; 235 236 /** 237 * The DOUBLE type. This is a BASE type. 238 */ 239 static final int DOUBLE = BASE | 3; 240 241 /** 242 * The LONG type. This is a BASE type. 243 */ 244 static final int LONG = BASE | 4; 245 246 /** 247 * The NULL type. This is a BASE type. 248 */ 249 static final int NULL = BASE | 5; 250 251 /** 252 * The UNINITIALIZED_THIS type. This is a BASE type. 253 */ 254 static final int UNINITIALIZED_THIS = BASE | 6; 255 256 /** 257 * The stack size variation corresponding to each JVM instruction. This 258 * stack variation is equal to the size of the values produced by an 259 * instruction, minus the size of the values consumed by this instruction. 260 */ 261 static final int[] SIZE; 262 263 /** 264 * Computes the stack size variation corresponding to each JVM instruction. 265 */ 266 static { 267 int i; 268 int[] b = new int[202]; 269 String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD" 270 + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD" 271 + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED" 272 + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE"; 273 for (i = 0; i < b.length; ++i) { 274 b[i] = s.charAt(i) - 'E'; 275 } 276 SIZE = b; 277 278 // code to generate the above string 279 // 280 // int NA = 0; // not applicable (unused opcode or variable size opcode) 281 // 282 // b = new int[] { 283 // 0, //NOP, // visitInsn 284 // 1, //ACONST_NULL, // - 285 // 1, //ICONST_M1, // - 286 // 1, //ICONST_0, // - 287 // 1, //ICONST_1, // - 288 // 1, //ICONST_2, // - 289 // 1, //ICONST_3, // - 290 // 1, //ICONST_4, // - 291 // 1, //ICONST_5, // - 292 // 2, //LCONST_0, // - 293 // 2, //LCONST_1, // - 294 // 1, //FCONST_0, // - 295 // 1, //FCONST_1, // - 296 // 1, //FCONST_2, // - 297 // 2, //DCONST_0, // - 298 // 2, //DCONST_1, // - 299 // 1, //BIPUSH, // visitIntInsn 300 // 1, //SIPUSH, // - 301 // 1, //LDC, // visitLdcInsn 302 // NA, //LDC_W, // - 303 // NA, //LDC2_W, // - 304 // 1, //ILOAD, // visitVarInsn 305 // 2, //LLOAD, // - 306 // 1, //FLOAD, // - 307 // 2, //DLOAD, // - 308 // 1, //ALOAD, // - 309 // NA, //ILOAD_0, // - 310 // NA, //ILOAD_1, // - 311 // NA, //ILOAD_2, // - 312 // NA, //ILOAD_3, // - 313 // NA, //LLOAD_0, // - 314 // NA, //LLOAD_1, // - 315 // NA, //LLOAD_2, // - 316 // NA, //LLOAD_3, // - 317 // NA, //FLOAD_0, // - 318 // NA, //FLOAD_1, // - 319 // NA, //FLOAD_2, // - 320 // NA, //FLOAD_3, // - 321 // NA, //DLOAD_0, // - 322 // NA, //DLOAD_1, // - 323 // NA, //DLOAD_2, // - 324 // NA, //DLOAD_3, // - 325 // NA, //ALOAD_0, // - 326 // NA, //ALOAD_1, // - 327 // NA, //ALOAD_2, // - 328 // NA, //ALOAD_3, // - 329 // -1, //IALOAD, // visitInsn 330 // 0, //LALOAD, // - 331 // -1, //FALOAD, // - 332 // 0, //DALOAD, // - 333 // -1, //AALOAD, // - 334 // -1, //BALOAD, // - 335 // -1, //CALOAD, // - 336 // -1, //SALOAD, // - 337 // -1, //ISTORE, // visitVarInsn 338 // -2, //LSTORE, // - 339 // -1, //FSTORE, // - 340 // -2, //DSTORE, // - 341 // -1, //ASTORE, // - 342 // NA, //ISTORE_0, // - 343 // NA, //ISTORE_1, // - 344 // NA, //ISTORE_2, // - 345 // NA, //ISTORE_3, // - 346 // NA, //LSTORE_0, // - 347 // NA, //LSTORE_1, // - 348 // NA, //LSTORE_2, // - 349 // NA, //LSTORE_3, // - 350 // NA, //FSTORE_0, // - 351 // NA, //FSTORE_1, // - 352 // NA, //FSTORE_2, // - 353 // NA, //FSTORE_3, // - 354 // NA, //DSTORE_0, // - 355 // NA, //DSTORE_1, // - 356 // NA, //DSTORE_2, // - 357 // NA, //DSTORE_3, // - 358 // NA, //ASTORE_0, // - 359 // NA, //ASTORE_1, // - 360 // NA, //ASTORE_2, // - 361 // NA, //ASTORE_3, // - 362 // -3, //IASTORE, // visitInsn 363 // -4, //LASTORE, // - 364 // -3, //FASTORE, // - 365 // -4, //DASTORE, // - 366 // -3, //AASTORE, // - 367 // -3, //BASTORE, // - 368 // -3, //CASTORE, // - 369 // -3, //SASTORE, // - 370 // -1, //POP, // - 371 // -2, //POP2, // - 372 // 1, //DUP, // - 373 // 1, //DUP_X1, // - 374 // 1, //DUP_X2, // - 375 // 2, //DUP2, // - 376 // 2, //DUP2_X1, // - 377 // 2, //DUP2_X2, // - 378 // 0, //SWAP, // - 379 // -1, //IADD, // - 380 // -2, //LADD, // - 381 // -1, //FADD, // - 382 // -2, //DADD, // - 383 // -1, //ISUB, // - 384 // -2, //LSUB, // - 385 // -1, //FSUB, // - 386 // -2, //DSUB, // - 387 // -1, //IMUL, // - 388 // -2, //LMUL, // - 389 // -1, //FMUL, // - 390 // -2, //DMUL, // - 391 // -1, //IDIV, // - 392 // -2, //LDIV, // - 393 // -1, //FDIV, // - 394 // -2, //DDIV, // - 395 // -1, //IREM, // - 396 // -2, //LREM, // - 397 // -1, //FREM, // - 398 // -2, //DREM, // - 399 // 0, //INEG, // - 400 // 0, //LNEG, // - 401 // 0, //FNEG, // - 402 // 0, //DNEG, // - 403 // -1, //ISHL, // - 404 // -1, //LSHL, // - 405 // -1, //ISHR, // - 406 // -1, //LSHR, // - 407 // -1, //IUSHR, // - 408 // -1, //LUSHR, // - 409 // -1, //IAND, // - 410 // -2, //LAND, // - 411 // -1, //IOR, // - 412 // -2, //LOR, // - 413 // -1, //IXOR, // - 414 // -2, //LXOR, // - 415 // 0, //IINC, // visitIincInsn 416 // 1, //I2L, // visitInsn 417 // 0, //I2F, // - 418 // 1, //I2D, // - 419 // -1, //L2I, // - 420 // -1, //L2F, // - 421 // 0, //L2D, // - 422 // 0, //F2I, // - 423 // 1, //F2L, // - 424 // 1, //F2D, // - 425 // -1, //D2I, // - 426 // 0, //D2L, // - 427 // -1, //D2F, // - 428 // 0, //I2B, // - 429 // 0, //I2C, // - 430 // 0, //I2S, // - 431 // -3, //LCMP, // - 432 // -1, //FCMPL, // - 433 // -1, //FCMPG, // - 434 // -3, //DCMPL, // - 435 // -3, //DCMPG, // - 436 // -1, //IFEQ, // visitJumpInsn 437 // -1, //IFNE, // - 438 // -1, //IFLT, // - 439 // -1, //IFGE, // - 440 // -1, //IFGT, // - 441 // -1, //IFLE, // - 442 // -2, //IF_ICMPEQ, // - 443 // -2, //IF_ICMPNE, // - 444 // -2, //IF_ICMPLT, // - 445 // -2, //IF_ICMPGE, // - 446 // -2, //IF_ICMPGT, // - 447 // -2, //IF_ICMPLE, // - 448 // -2, //IF_ACMPEQ, // - 449 // -2, //IF_ACMPNE, // - 450 // 0, //GOTO, // - 451 // 1, //JSR, // - 452 // 0, //RET, // visitVarInsn 453 // -1, //TABLESWITCH, // visiTableSwitchInsn 454 // -1, //LOOKUPSWITCH, // visitLookupSwitch 455 // -1, //IRETURN, // visitInsn 456 // -2, //LRETURN, // - 457 // -1, //FRETURN, // - 458 // -2, //DRETURN, // - 459 // -1, //ARETURN, // - 460 // 0, //RETURN, // - 461 // NA, //GETSTATIC, // visitFieldInsn 462 // NA, //PUTSTATIC, // - 463 // NA, //GETFIELD, // - 464 // NA, //PUTFIELD, // - 465 // NA, //INVOKEVIRTUAL, // visitMethodInsn 466 // NA, //INVOKESPECIAL, // - 467 // NA, //INVOKESTATIC, // - 468 // NA, //INVOKEINTERFACE, // - 469 // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn 470 // 1, //NEW, // visitTypeInsn 471 // 0, //NEWARRAY, // visitIntInsn 472 // 0, //ANEWARRAY, // visitTypeInsn 473 // 0, //ARRAYLENGTH, // visitInsn 474 // NA, //ATHROW, // - 475 // 0, //CHECKCAST, // visitTypeInsn 476 // 0, //INSTANCEOF, // - 477 // -1, //MONITORENTER, // visitInsn 478 // -1, //MONITOREXIT, // - 479 // NA, //WIDE, // NOT VISITED 480 // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn 481 // -1, //IFNULL, // visitJumpInsn 482 // -1, //IFNONNULL, // - 483 // NA, //GOTO_W, // - 484 // NA, //JSR_W, // - 485 // }; 486 // for (i = 0; i < b.length; ++i) { 487 // System.err.print((char)('E' + b[i])); 488 // } 489 // System.err.println(); 490 } 491 492 /** 493 * The label (i.e. basic block) to which these input and output stack map 494 * frames correspond. 495 */ 496 Label owner; 497 498 /** 499 * The input stack map frame locals. 500 */ 501 int[] inputLocals; 502 503 /** 504 * The input stack map frame stack. 505 */ 506 int[] inputStack; 507 508 /** 509 * The output stack map frame locals. 510 */ 511 private int[] outputLocals; 512 513 /** 514 * The output stack map frame stack. 515 */ 516 private int[] outputStack; 517 518 /** 519 * Relative size of the output stack. The exact semantics of this field 520 * depends on the algorithm that is used. 521 * 522 * When only the maximum stack size is computed, this field is the size of 523 * the output stack relatively to the top of the input stack. 524 * 525 * When the stack map frames are completely computed, this field is the 526 * actual number of types in {@link #outputStack}. 527 */ 528 int outputStackTop; 529 530 /** 531 * Number of types that are initialized in the basic block. 532 * 533 * @see #initializations 534 */ 535 private int initializationCount; 536 537 /** 538 * The types that are initialized in the basic block. A constructor 539 * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace 540 * <i>every occurence</i> of this type in the local variables and in the 541 * operand stack. This cannot be done during the first phase of the 542 * algorithm since, during this phase, the local variables and the operand 543 * stack are not completely computed. It is therefore necessary to store the 544 * types on which constructors are invoked in the basic block, in order to 545 * do this replacement during the second phase of the algorithm, where the 546 * frames are fully computed. Note that this array can contain types that 547 * are relative to input locals or to the input stack (see below for the 548 * description of the algorithm). 549 */ 550 private int[] initializations; 551 552 /** 553 * Sets this frame to the given value. 554 * 555 * @param cw 556 * the ClassWriter to which this label belongs. 557 * @param nLocal 558 * the number of local variables. 559 * @param local 560 * the local variable types. Primitive types are represented by 561 * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, 562 * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, 563 * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or 564 * {@link Opcodes#UNINITIALIZED_THIS} (long and double are 565 * represented by a single element). Reference types are 566 * represented by String objects (representing internal names), 567 * and uninitialized types by Label objects (this label 568 * designates the NEW instruction that created this uninitialized 569 * value). 570 * @param nStack 571 * the number of operand stack elements. 572 * @param stack 573 * the operand stack types (same format as the "local" array). 574 */ 575 final void set(ClassWriter cw, final int nLocal, final Object[] local, 576 final int nStack, final Object[] stack) { 577 int i = convert(cw, nLocal, local, inputLocals); 578 while (i < local.length) { 579 inputLocals[i++] = TOP; 580 } 581 int nStackTop = 0; 582 for (int j = 0; j < nStack; ++j) { 583 if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) { 584 ++nStackTop; 585 } 586 } 587 inputStack = new int[nStack + nStackTop]; 588 convert(cw, nStack, stack, inputStack); 589 outputStackTop = 0; 590 initializationCount = 0; 591 } 592 593 /** 594 * Converts types from the MethodWriter.visitFrame() format to the Frame 595 * format. 596 * 597 * @param cw 598 * the ClassWriter to which this label belongs. 599 * @param nInput 600 * the number of types to convert. 601 * @param input 602 * the types to convert. Primitive types are represented by 603 * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, 604 * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, 605 * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or 606 * {@link Opcodes#UNINITIALIZED_THIS} (long and double are 607 * represented by a single element). Reference types are 608 * represented by String objects (representing internal names), 609 * and uninitialized types by Label objects (this label 610 * designates the NEW instruction that created this uninitialized 611 * value). 612 * @param output 613 * where to store the converted types. 614 * @return the number of output elements. 615 */ 616 private static int convert(ClassWriter cw, int nInput, Object[] input, 617 int[] output) { 618 int i = 0; 619 for (int j = 0; j < nInput; ++j) { 620 if (input[j] instanceof Integer) { 621 output[i++] = BASE | ((Integer) input[j]).intValue(); 622 if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) { 623 output[i++] = TOP; 624 } 625 } else if (input[j] instanceof String) { 626 output[i++] = type(cw, Type.getObjectType((String) input[j]) 627 .getDescriptor()); 628 } else { 629 output[i++] = UNINITIALIZED 630 | cw.addUninitializedType("", 631 ((Label) input[j]).position); 632 } 633 } 634 return i; 635 } 636 637 /** 638 * Sets this frame to the value of the given frame. WARNING: after this 639 * method is called the two frames share the same data structures. It is 640 * recommended to discard the given frame f to avoid unexpected side 641 * effects. 642 * 643 * @param f 644 * The new frame value. 645 */ 646 final void set(final Frame f) { 647 inputLocals = f.inputLocals; 648 inputStack = f.inputStack; 649 outputLocals = f.outputLocals; 650 outputStack = f.outputStack; 651 outputStackTop = f.outputStackTop; 652 initializationCount = f.initializationCount; 653 initializations = f.initializations; 654 } 655 656 /** 657 * Returns the output frame local variable type at the given index. 658 * 659 * @param local 660 * the index of the local that must be returned. 661 * @return the output frame local variable type at the given index. 662 */ 663 private int get(final int local) { 664 if (outputLocals == null || local >= outputLocals.length) { 665 // this local has never been assigned in this basic block, 666 // so it is still equal to its value in the input frame 667 return LOCAL | local; 668 } else { 669 int type = outputLocals[local]; 670 if (type == 0) { 671 // this local has never been assigned in this basic block, 672 // so it is still equal to its value in the input frame 673 type = outputLocals[local] = LOCAL | local; 674 } 675 return type; 676 } 677 } 678 679 /** 680 * Sets the output frame local variable type at the given index. 681 * 682 * @param local 683 * the index of the local that must be set. 684 * @param type 685 * the value of the local that must be set. 686 */ 687 private void set(final int local, final int type) { 688 // creates and/or resizes the output local variables array if necessary 689 if (outputLocals == null) { 690 outputLocals = new int[10]; 691 } 692 int n = outputLocals.length; 693 if (local >= n) { 694 int[] t = new int[Math.max(local + 1, 2 * n)]; 695 System.arraycopy(outputLocals, 0, t, 0, n); 696 outputLocals = t; 697 } 698 // sets the local variable 699 outputLocals[local] = type; 700 } 701 702 /** 703 * Pushes a new type onto the output frame stack. 704 * 705 * @param type 706 * the type that must be pushed. 707 */ 708 private void push(final int type) { 709 // creates and/or resizes the output stack array if necessary 710 if (outputStack == null) { 711 outputStack = new int[10]; 712 } 713 int n = outputStack.length; 714 if (outputStackTop >= n) { 715 int[] t = new int[Math.max(outputStackTop + 1, 2 * n)]; 716 System.arraycopy(outputStack, 0, t, 0, n); 717 outputStack = t; 718 } 719 // pushes the type on the output stack 720 outputStack[outputStackTop++] = type; 721 // updates the maximum height reached by the output stack, if needed 722 int top = owner.inputStackTop + outputStackTop; 723 if (top > owner.outputStackMax) { 724 owner.outputStackMax = top; 725 } 726 } 727 728 /** 729 * Pushes a new type onto the output frame stack. 730 * 731 * @param cw 732 * the ClassWriter to which this label belongs. 733 * @param desc 734 * the descriptor of the type to be pushed. Can also be a method 735 * descriptor (in this case this method pushes its return type 736 * onto the output frame stack). 737 */ 738 private void push(final ClassWriter cw, final String desc) { 739 int type = type(cw, desc); 740 if (type != 0) { 741 push(type); 742 if (type == LONG || type == DOUBLE) { 743 push(TOP); 744 } 745 } 746 } 747 748 /** 749 * Returns the int encoding of the given type. 750 * 751 * @param cw 752 * the ClassWriter to which this label belongs. 753 * @param desc 754 * a type descriptor. 755 * @return the int encoding of the given type. 756 */ 757 static int type(final ClassWriter cw, final String desc) { 758 String t; 759 int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; 760 switch (desc.charAt(index)) { 761 case 'V': 762 return 0; 763 case 'Z': 764 case 'C': 765 case 'B': 766 case 'S': 767 case 'I': 768 return INTEGER; 769 case 'F': 770 return FLOAT; 771 case 'J': 772 return LONG; 773 case 'D': 774 return DOUBLE; 775 case 'L': 776 case 'Q': 777 // stores the internal name, not the descriptor! 778 t = desc.substring(index + 1, desc.length() - 1); 779 return OBJECT | cw.addType(t); 780 // case '[': 781 default: 782 // extracts the dimensions and the element type 783 int data; 784 int dims = index + 1; 785 while (desc.charAt(dims) == '[') { 786 ++dims; 787 } 788 switch (desc.charAt(dims)) { 789 case 'Z': 790 data = BOOLEAN; 791 break; 792 case 'C': 793 data = CHAR; 794 break; 795 case 'B': 796 data = BYTE; 797 break; 798 case 'S': 799 data = SHORT; 800 break; 801 case 'I': 802 data = INTEGER; 803 break; 804 case 'F': 805 data = FLOAT; 806 break; 807 case 'J': 808 data = LONG; 809 break; 810 case 'D': 811 data = DOUBLE; 812 break; 813 // case 'L': 814 // case 'Q': 815 default: 816 // stores the internal name, not the descriptor 817 t = desc.substring(dims + 1, desc.length() - 1); 818 data = OBJECT | cw.addType(t); 819 } 820 return (dims - index) << 28 | data; 821 } 822 } 823 824 /** 825 * Pops a type from the output frame stack and returns its value. 826 * 827 * @return the type that has been popped from the output frame stack. 828 */ 829 private int pop() { 830 if (outputStackTop > 0) { 831 return outputStack[--outputStackTop]; 832 } else { 833 // if the output frame stack is empty, pops from the input stack 834 return STACK | -(--owner.inputStackTop); 835 } 836 } 837 838 /** 839 * Pops the given number of types from the output frame stack. 840 * 841 * @param elements 842 * the number of types that must be popped. 843 */ 844 private void pop(final int elements) { 845 if (outputStackTop >= elements) { 846 outputStackTop -= elements; 847 } else { 848 // if the number of elements to be popped is greater than the number 849 // of elements in the output stack, clear it, and pops the remaining 850 // elements from the input stack. 851 owner.inputStackTop -= elements - outputStackTop; 852 outputStackTop = 0; 853 } 854 } 855 856 /** 857 * Pops a type from the output frame stack. 858 * 859 * @param desc 860 * the descriptor of the type to be popped. Can also be a method 861 * descriptor (in this case this method pops the types 862 * corresponding to the method arguments). 863 */ 864 private void pop(final String desc) { 865 char c = desc.charAt(0); 866 if (c == '(') { 867 pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1); 868 } else if (c == 'J' || c == 'D') { 869 pop(2); 870 } else { 871 pop(1); 872 } 873 } 874 875 /** 876 * Adds a new type to the list of types on which a constructor is invoked in 877 * the basic block. 878 * 879 * @param var 880 * a type on a which a constructor is invoked. 881 */ 882 private void init(final int var) { 883 // creates and/or resizes the initializations array if necessary 884 if (initializations == null) { 885 initializations = new int[2]; 886 } 887 int n = initializations.length; 888 if (initializationCount >= n) { 889 int[] t = new int[Math.max(initializationCount + 1, 2 * n)]; 890 System.arraycopy(initializations, 0, t, 0, n); 891 initializations = t; 892 } 893 // stores the type to be initialized 894 initializations[initializationCount++] = var; 895 } 896 897 /** 898 * Replaces the given type with the appropriate type if it is one of the 899 * types on which a constructor is invoked in the basic block. 900 * 901 * @param cw 902 * the ClassWriter to which this label belongs. 903 * @param t 904 * a type 905 * @return t or, if t is one of the types on which a constructor is invoked 906 * in the basic block, the type corresponding to this constructor. 907 */ 908 private int init(final ClassWriter cw, final int t) { 909 int s; 910 if (t == UNINITIALIZED_THIS) { 911 s = OBJECT | cw.addType(cw.thisName); 912 } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) { 913 String type = cw.typeTable[t & BASE_VALUE].strVal1; 914 s = OBJECT | cw.addType(type); 915 } else { 916 return t; 917 } 918 for (int j = 0; j < initializationCount; ++j) { 919 int u = initializations[j]; 920 int dim = u & DIM; 921 int kind = u & KIND; 922 if (kind == LOCAL) { 923 u = dim + inputLocals[u & VALUE]; 924 } else if (kind == STACK) { 925 u = dim + inputStack[inputStack.length - (u & VALUE)]; 926 } 927 if (t == u) { 928 return s; 929 } 930 } 931 return t; 932 } 933 934 /** 935 * Initializes the input frame of the first basic block from the method 936 * descriptor. 937 * 938 * @param cw 939 * the ClassWriter to which this label belongs. 940 * @param access 941 * the access flags of the method to which this label belongs. 942 * @param args 943 * the formal parameter types of this method. 944 * @param maxLocals 945 * the maximum number of local variables of this method. 946 */ 947 final void initInputFrame(final ClassWriter cw, final int access, 948 final Type[] args, final int maxLocals) { 949 inputLocals = new int[maxLocals]; 950 inputStack = new int[0]; 951 int i = 0; 952 if ((access & Opcodes.ACC_STATIC) == 0) { 953 if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) { 954 inputLocals[i++] = OBJECT | cw.addType(cw.thisName); 955 } else { 956 inputLocals[i++] = UNINITIALIZED_THIS; 957 } 958 } 959 for (int j = 0; j < args.length; ++j) { 960 int t = type(cw, args[j].getDescriptor()); 961 inputLocals[i++] = t; 962 if (t == LONG || t == DOUBLE) { 963 inputLocals[i++] = TOP; 964 } 965 } 966 while (i < maxLocals) { 967 inputLocals[i++] = TOP; 968 } 969 } 970 971 /** 972 * Simulates the action of the given instruction on the output stack frame. 973 * 974 * @param opcode 975 * the opcode of the instruction. 976 * @param arg 977 * the operand of the instruction, if any. 978 * @param cw 979 * the class writer to which this label belongs. 980 * @param item 981 * the operand of the instructions, if any. 982 */ 983 void execute(final int opcode, final int arg, final ClassWriter cw, 984 final Item item) { 985 int t1, t2, t3, t4; 986 switch (opcode) { 987 case Opcodes.NOP: 988 case Opcodes.INEG: 989 case Opcodes.LNEG: 990 case Opcodes.FNEG: 991 case Opcodes.DNEG: 992 case Opcodes.I2B: 993 case Opcodes.I2C: 994 case Opcodes.I2S: 995 case Opcodes.GOTO: 996 case Opcodes.RETURN: 997 break; 998 case Opcodes.ACONST_NULL: 999 push(NULL); 1000 break; 1001 case Opcodes.ICONST_M1: 1002 case Opcodes.ICONST_0: 1003 case Opcodes.ICONST_1: 1004 case Opcodes.ICONST_2: 1005 case Opcodes.ICONST_3: 1006 case Opcodes.ICONST_4: 1007 case Opcodes.ICONST_5: 1008 case Opcodes.BIPUSH: 1009 case Opcodes.SIPUSH: 1010 case Opcodes.ILOAD: 1011 push(INTEGER); 1012 break; 1013 case Opcodes.LCONST_0: 1014 case Opcodes.LCONST_1: 1015 case Opcodes.LLOAD: 1016 push(LONG); 1017 push(TOP); 1018 break; 1019 case Opcodes.FCONST_0: 1020 case Opcodes.FCONST_1: 1021 case Opcodes.FCONST_2: 1022 case Opcodes.FLOAD: 1023 push(FLOAT); 1024 break; 1025 case Opcodes.DCONST_0: 1026 case Opcodes.DCONST_1: 1027 case Opcodes.DLOAD: 1028 push(DOUBLE); 1029 push(TOP); 1030 break; 1031 case Opcodes.LDC: 1032 switch (item.type) { 1033 case ClassWriter.INT: 1034 push(INTEGER); 1035 break; 1036 case ClassWriter.LONG: 1037 push(LONG); 1038 push(TOP); 1039 break; 1040 case ClassWriter.FLOAT: 1041 push(FLOAT); 1042 break; 1043 case ClassWriter.DOUBLE: 1044 push(DOUBLE); 1045 push(TOP); 1046 break; 1047 case ClassWriter.CLASS: 1048 push(OBJECT | cw.addType("java/lang/Class")); 1049 break; 1050 case ClassWriter.STR: 1051 push(OBJECT | cw.addType("java/lang/String")); 1052 break; 1053 case ClassWriter.MTYPE: 1054 push(OBJECT | cw.addType("java/lang/invoke/MethodType")); 1055 break; 1056 // case ClassWriter.HANDLE_BASE + [1..9]: 1057 default: 1058 push(OBJECT | cw.addType("java/lang/invoke/MethodHandle")); 1059 } 1060 break; 1061 case Opcodes.ALOAD: 1062 push(get(arg)); 1063 break; 1064 case Opcodes.IALOAD: 1065 case Opcodes.BALOAD: 1066 case Opcodes.CALOAD: 1067 case Opcodes.SALOAD: 1068 pop(2); 1069 push(INTEGER); 1070 break; 1071 case Opcodes.LALOAD: 1072 case Opcodes.D2L: 1073 pop(2); 1074 push(LONG); 1075 push(TOP); 1076 break; 1077 case Opcodes.FALOAD: 1078 pop(2); 1079 push(FLOAT); 1080 break; 1081 case Opcodes.DALOAD: 1082 case Opcodes.L2D: 1083 pop(2); 1084 push(DOUBLE); 1085 push(TOP); 1086 break; 1087 case Opcodes.AALOAD: 1088 pop(1); 1089 t1 = pop(); 1090 push(t1 == NULL ? t1 : ELEMENT_OF + t1); 1091 break; 1092 case Opcodes.ISTORE: 1093 case Opcodes.FSTORE: 1094 case Opcodes.ASTORE: 1095 t1 = pop(); 1096 set(arg, t1); 1097 if (arg > 0) { 1098 t2 = get(arg - 1); 1099 // if t2 is of kind STACK or LOCAL we cannot know its size! 1100 if (t2 == LONG || t2 == DOUBLE) { 1101 set(arg - 1, TOP); 1102 } else if ((t2 & KIND) != BASE) { 1103 set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); 1104 } 1105 } 1106 break; 1107 case Opcodes.LSTORE: 1108 case Opcodes.DSTORE: 1109 pop(1); 1110 t1 = pop(); 1111 set(arg, t1); 1112 set(arg + 1, TOP); 1113 if (arg > 0) { 1114 t2 = get(arg - 1); 1115 // if t2 is of kind STACK or LOCAL we cannot know its size! 1116 if (t2 == LONG || t2 == DOUBLE) { 1117 set(arg - 1, TOP); 1118 } else if ((t2 & KIND) != BASE) { 1119 set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); 1120 } 1121 } 1122 break; 1123 case Opcodes.IASTORE: 1124 case Opcodes.BASTORE: 1125 case Opcodes.CASTORE: 1126 case Opcodes.SASTORE: 1127 case Opcodes.FASTORE: 1128 case Opcodes.AASTORE: 1129 pop(3); 1130 break; 1131 case Opcodes.LASTORE: 1132 case Opcodes.DASTORE: 1133 pop(4); 1134 break; 1135 case Opcodes.POP: 1136 case Opcodes.IFEQ: 1137 case Opcodes.IFNE: 1138 case Opcodes.IFLT: 1139 case Opcodes.IFGE: 1140 case Opcodes.IFGT: 1141 case Opcodes.IFLE: 1142 case Opcodes.IRETURN: 1143 case Opcodes.FRETURN: 1144 case Opcodes.ARETURN: 1145 case Opcodes.TABLESWITCH: 1146 case Opcodes.LOOKUPSWITCH: 1147 case Opcodes.ATHROW: 1148 case Opcodes.MONITORENTER: 1149 case Opcodes.MONITOREXIT: 1150 case Opcodes.IFNULL: 1151 case Opcodes.IFNONNULL: 1152 pop(1); 1153 break; 1154 case Opcodes.POP2: 1155 case Opcodes.IF_ICMPEQ: 1156 case Opcodes.IF_ICMPNE: 1157 case Opcodes.IF_ICMPLT: 1158 case Opcodes.IF_ICMPGE: 1159 case Opcodes.IF_ICMPGT: 1160 case Opcodes.IF_ICMPLE: 1161 case Opcodes.IF_ACMPEQ: 1162 case Opcodes.IF_ACMPNE: 1163 case Opcodes.LRETURN: 1164 case Opcodes.DRETURN: 1165 pop(2); 1166 break; 1167 case Opcodes.DUP: 1168 t1 = pop(); 1169 push(t1); 1170 push(t1); 1171 break; 1172 case Opcodes.DUP_X1: 1173 t1 = pop(); 1174 t2 = pop(); 1175 push(t1); 1176 push(t2); 1177 push(t1); 1178 break; 1179 case Opcodes.DUP_X2: 1180 t1 = pop(); 1181 t2 = pop(); 1182 t3 = pop(); 1183 push(t1); 1184 push(t3); 1185 push(t2); 1186 push(t1); 1187 break; 1188 case Opcodes.DUP2: 1189 t1 = pop(); 1190 t2 = pop(); 1191 push(t2); 1192 push(t1); 1193 push(t2); 1194 push(t1); 1195 break; 1196 case Opcodes.DUP2_X1: 1197 t1 = pop(); 1198 t2 = pop(); 1199 t3 = pop(); 1200 push(t2); 1201 push(t1); 1202 push(t3); 1203 push(t2); 1204 push(t1); 1205 break; 1206 case Opcodes.DUP2_X2: 1207 t1 = pop(); 1208 t2 = pop(); 1209 t3 = pop(); 1210 t4 = pop(); 1211 push(t2); 1212 push(t1); 1213 push(t4); 1214 push(t3); 1215 push(t2); 1216 push(t1); 1217 break; 1218 case Opcodes.SWAP: 1219 t1 = pop(); 1220 t2 = pop(); 1221 push(t1); 1222 push(t2); 1223 break; 1224 case Opcodes.IADD: 1225 case Opcodes.ISUB: 1226 case Opcodes.IMUL: 1227 case Opcodes.IDIV: 1228 case Opcodes.IREM: 1229 case Opcodes.IAND: 1230 case Opcodes.IOR: 1231 case Opcodes.IXOR: 1232 case Opcodes.ISHL: 1233 case Opcodes.ISHR: 1234 case Opcodes.IUSHR: 1235 case Opcodes.L2I: 1236 case Opcodes.D2I: 1237 case Opcodes.FCMPL: 1238 case Opcodes.FCMPG: 1239 pop(2); 1240 push(INTEGER); 1241 break; 1242 case Opcodes.LADD: 1243 case Opcodes.LSUB: 1244 case Opcodes.LMUL: 1245 case Opcodes.LDIV: 1246 case Opcodes.LREM: 1247 case Opcodes.LAND: 1248 case Opcodes.LOR: 1249 case Opcodes.LXOR: 1250 pop(4); 1251 push(LONG); 1252 push(TOP); 1253 break; 1254 case Opcodes.FADD: 1255 case Opcodes.FSUB: 1256 case Opcodes.FMUL: 1257 case Opcodes.FDIV: 1258 case Opcodes.FREM: 1259 case Opcodes.L2F: 1260 case Opcodes.D2F: 1261 pop(2); 1262 push(FLOAT); 1263 break; 1264 case Opcodes.DADD: 1265 case Opcodes.DSUB: 1266 case Opcodes.DMUL: 1267 case Opcodes.DDIV: 1268 case Opcodes.DREM: 1269 pop(4); 1270 push(DOUBLE); 1271 push(TOP); 1272 break; 1273 case Opcodes.LSHL: 1274 case Opcodes.LSHR: 1275 case Opcodes.LUSHR: 1276 pop(3); 1277 push(LONG); 1278 push(TOP); 1279 break; 1280 case Opcodes.IINC: 1281 set(arg, INTEGER); 1282 break; 1283 case Opcodes.I2L: 1284 case Opcodes.F2L: 1285 pop(1); 1286 push(LONG); 1287 push(TOP); 1288 break; 1289 case Opcodes.I2F: 1290 pop(1); 1291 push(FLOAT); 1292 break; 1293 case Opcodes.I2D: 1294 case Opcodes.F2D: 1295 pop(1); 1296 push(DOUBLE); 1297 push(TOP); 1298 break; 1299 case Opcodes.F2I: 1300 case Opcodes.ARRAYLENGTH: 1301 case Opcodes.INSTANCEOF: 1302 pop(1); 1303 push(INTEGER); 1304 break; 1305 case Opcodes.LCMP: 1306 case Opcodes.DCMPL: 1307 case Opcodes.DCMPG: 1308 pop(4); 1309 push(INTEGER); 1310 break; 1311 case Opcodes.JSR: 1312 case Opcodes.RET: 1313 throw new RuntimeException( 1314 "JSR/RET are not supported with computeFrames option"); 1315 case Opcodes.GETSTATIC: 1316 push(cw, item.strVal3); 1317 break; 1318 case Opcodes.PUTSTATIC: 1319 pop(item.strVal3); 1320 break; 1321 case Opcodes.GETFIELD: 1322 pop(1); 1323 push(cw, item.strVal3); 1324 break; 1325 case Opcodes.PUTFIELD: 1326 pop(item.strVal3); 1327 pop(); 1328 break; 1329 case Opcodes.INVOKEVIRTUAL: 1330 case Opcodes.INVOKESPECIAL: 1331 case Opcodes.INVOKESTATIC: 1332 case Opcodes.INVOKEINTERFACE: 1333 pop(item.strVal3); 1334 if (opcode != Opcodes.INVOKESTATIC) { 1335 t1 = pop(); 1336 if (opcode == Opcodes.INVOKESPECIAL 1337 && item.strVal2.charAt(0) == '<') { 1338 init(t1); 1339 } 1340 } 1341 push(cw, item.strVal3); 1342 break; 1343 case Opcodes.INVOKEDYNAMIC: 1344 pop(item.strVal2); 1345 push(cw, item.strVal2); 1346 break; 1347 case Opcodes.NEW: 1348 push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg)); 1349 break; 1350 case Opcodes.NEWARRAY: 1351 pop(); 1352 switch (arg) { 1353 case Opcodes.T_BOOLEAN: 1354 push(ARRAY_OF | BOOLEAN); 1355 break; 1356 case Opcodes.T_CHAR: 1357 push(ARRAY_OF | CHAR); 1358 break; 1359 case Opcodes.T_BYTE: 1360 push(ARRAY_OF | BYTE); 1361 break; 1362 case Opcodes.T_SHORT: 1363 push(ARRAY_OF | SHORT); 1364 break; 1365 case Opcodes.T_INT: 1366 push(ARRAY_OF | INTEGER); 1367 break; 1368 case Opcodes.T_FLOAT: 1369 push(ARRAY_OF | FLOAT); 1370 break; 1371 case Opcodes.T_DOUBLE: 1372 push(ARRAY_OF | DOUBLE); 1373 break; 1374 // case Opcodes.T_LONG: 1375 default: 1376 push(ARRAY_OF | LONG); 1377 break; 1378 } 1379 break; 1380 case Opcodes.ANEWARRAY: 1381 String s = item.strVal1; 1382 pop(); 1383 if (s.charAt(0) == '[') { 1384 push(cw, '[' + s); 1385 } else { 1386 push(ARRAY_OF | OBJECT | cw.addType(s)); 1387 } 1388 break; 1389 case Opcodes.CHECKCAST: 1390 s = item.strVal1; 1391 pop(); 1392 if (s.charAt(0) == '[') { 1393 push(cw, s); 1394 } else { 1395 push(OBJECT | cw.addType(s)); 1396 } 1397 break; 1398 // case Opcodes.MULTIANEWARRAY: 1399 default: 1400 pop(arg); 1401 push(cw, item.strVal1); 1402 break; 1403 } 1404 } 1405 1406 /** 1407 * Merges the input frame of the given basic block with the input and output 1408 * frames of this basic block. Returns <tt>true</tt> if the input frame of 1409 * the given label has been changed by this operation. 1410 * 1411 * @param cw 1412 * the ClassWriter to which this label belongs. 1413 * @param frame 1414 * the basic block whose input frame must be updated. 1415 * @param edge 1416 * the kind of the {@link Edge} between this label and 'label'. 1417 * See {@link Edge#info}. 1418 * @return <tt>true</tt> if the input frame of the given label has been 1419 * changed by this operation. 1420 */ 1421 final boolean merge(final ClassWriter cw, final Frame frame, final int edge) { 1422 boolean changed = false; 1423 int i, s, dim, kind, t; 1424 1425 int nLocal = inputLocals.length; 1426 int nStack = inputStack.length; 1427 if (frame.inputLocals == null) { 1428 frame.inputLocals = new int[nLocal]; 1429 changed = true; 1430 } 1431 1432 for (i = 0; i < nLocal; ++i) { 1433 if (outputLocals != null && i < outputLocals.length) { 1434 s = outputLocals[i]; 1435 if (s == 0) { 1436 t = inputLocals[i]; 1437 } else { 1438 dim = s & DIM; 1439 kind = s & KIND; 1440 if (kind == BASE) { 1441 t = s; 1442 } else { 1443 if (kind == LOCAL) { 1444 t = dim + inputLocals[s & VALUE]; 1445 } else { 1446 t = dim + inputStack[nStack - (s & VALUE)]; 1447 } 1448 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 1449 && (t == LONG || t == DOUBLE)) { 1450 t = TOP; 1451 } 1452 } 1453 } 1454 } else { 1455 t = inputLocals[i]; 1456 } 1457 if (initializations != null) { 1458 t = init(cw, t); 1459 } 1460 changed |= merge(cw, t, frame.inputLocals, i); 1461 } 1462 1463 if (edge > 0) { 1464 for (i = 0; i < nLocal; ++i) { 1465 t = inputLocals[i]; 1466 changed |= merge(cw, t, frame.inputLocals, i); 1467 } 1468 if (frame.inputStack == null) { 1469 frame.inputStack = new int[1]; 1470 changed = true; 1471 } 1472 changed |= merge(cw, edge, frame.inputStack, 0); 1473 return changed; 1474 } 1475 1476 int nInputStack = inputStack.length + owner.inputStackTop; 1477 if (frame.inputStack == null) { 1478 frame.inputStack = new int[nInputStack + outputStackTop]; 1479 changed = true; 1480 } 1481 1482 for (i = 0; i < nInputStack; ++i) { 1483 t = inputStack[i]; 1484 if (initializations != null) { 1485 t = init(cw, t); 1486 } 1487 changed |= merge(cw, t, frame.inputStack, i); 1488 } 1489 for (i = 0; i < outputStackTop; ++i) { 1490 s = outputStack[i]; 1491 dim = s & DIM; 1492 kind = s & KIND; 1493 if (kind == BASE) { 1494 t = s; 1495 } else { 1496 if (kind == LOCAL) { 1497 t = dim + inputLocals[s & VALUE]; 1498 } else { 1499 t = dim + inputStack[nStack - (s & VALUE)]; 1500 } 1501 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 1502 && (t == LONG || t == DOUBLE)) { 1503 t = TOP; 1504 } 1505 } 1506 if (initializations != null) { 1507 t = init(cw, t); 1508 } 1509 changed |= merge(cw, t, frame.inputStack, nInputStack + i); 1510 } 1511 return changed; 1512 } 1513 1514 /** 1515 * Merges the type at the given index in the given type array with the given 1516 * type. Returns <tt>true</tt> if the type array has been modified by this 1517 * operation. 1518 * 1519 * @param cw 1520 * the ClassWriter to which this label belongs. 1521 * @param t 1522 * the type with which the type array element must be merged. 1523 * @param types 1524 * an array of types. 1525 * @param index 1526 * the index of the type that must be merged in 'types'. 1527 * @return <tt>true</tt> if the type array has been modified by this 1528 * operation. 1529 */ 1530 private static boolean merge(final ClassWriter cw, int t, 1531 final int[] types, final int index) { 1532 int u = types[index]; 1533 if (u == t) { 1534 // if the types are equal, merge(u,t)=u, so there is no change 1535 return false; 1536 } 1537 if ((t & ~DIM) == NULL) { 1538 if (u == NULL) { 1539 return false; 1540 } 1541 t = NULL; 1542 } 1543 if (u == 0) { 1544 // if types[index] has never been assigned, merge(u,t)=t 1545 types[index] = t; 1546 return true; 1547 } 1548 int v; 1549 if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) { 1550 // if u is a reference type of any dimension 1551 if (t == NULL) { 1552 // if t is the NULL type, merge(u,t)=u, so there is no change 1553 return false; 1554 } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) { 1555 // if t and u have the same dimension and same base kind 1556 if ((u & BASE_KIND) == OBJECT) { 1557 // if t is also a reference type, and if u and t have the 1558 // same dimension merge(u,t) = dim(t) | common parent of the 1559 // element types of u and t 1560 v = (t & DIM) | OBJECT 1561 | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); 1562 } else { 1563 // if u and t are array types, but not with the same element 1564 // type, merge(u,t) = dim(u) - 1 | java/lang/Object 1565 int vdim = ELEMENT_OF + (u & DIM); 1566 v = vdim | OBJECT | cw.addType("java/lang/Object"); 1567 } 1568 } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { 1569 // if t is any other reference or array type, the merged type 1570 // is min(udim, tdim) | java/lang/Object, where udim is the 1571 // array dimension of u, minus 1 if u is an array type with a 1572 // primitive element type (and similarly for tdim). 1573 int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 1574 : ELEMENT_OF) + (t & DIM); 1575 int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 1576 : ELEMENT_OF) + (u & DIM); 1577 v = Math.min(tdim, udim) | OBJECT 1578 | cw.addType("java/lang/Object"); 1579 } else { 1580 // if t is any other type, merge(u,t)=TOP 1581 v = TOP; 1582 } 1583 } else if (u == NULL) { 1584 // if u is the NULL type, merge(u,t)=t, 1585 // or TOP if t is not a reference type 1586 v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP; 1587 } else { 1588 // if u is any other type, merge(u,t)=TOP whatever t 1589 v = TOP; 1590 } 1591 if (u != v) { 1592 types[index] = v; 1593 return true; 1594 } 1595 return false; 1596 } 1597 }