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 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 // stores the internal name, not the descriptor! 777 t = desc.substring(index + 1, desc.length() - 1); 778 return OBJECT | cw.addType(t); 779 // case '[': 780 default: 781 // extracts the dimensions and the element type 782 int data; 783 int dims = index + 1; 784 while (desc.charAt(dims) == '[') { 785 ++dims; 786 } 787 switch (desc.charAt(dims)) { 788 case 'Z': 789 data = BOOLEAN; 790 break; 791 case 'C': 792 data = CHAR; 793 break; 794 case 'B': 795 data = BYTE; 796 break; 797 case 'S': 798 data = SHORT; 799 break; 800 case 'I': 801 data = INTEGER; 802 break; 803 case 'F': 804 data = FLOAT; 805 break; 806 case 'J': 807 data = LONG; 808 break; 809 case 'D': 810 data = DOUBLE; 811 break; 812 // case 'L': 813 default: 814 // stores the internal name, not the descriptor 815 t = desc.substring(dims + 1, desc.length() - 1); 816 data = OBJECT | cw.addType(t); 817 } 818 return (dims - index) << 28 | data; 819 } 820 } 821 822 /** 823 * Pops a type from the output frame stack and returns its value. 824 * 825 * @return the type that has been popped from the output frame stack. 826 */ 827 private int pop() { 828 if (outputStackTop > 0) { 829 return outputStack[--outputStackTop]; 830 } else { 831 // if the output frame stack is empty, pops from the input stack 832 return STACK | -(--owner.inputStackTop); 833 } 834 } 835 836 /** 837 * Pops the given number of types from the output frame stack. 838 * 839 * @param elements 840 * the number of types that must be popped. 841 */ 842 private void pop(final int elements) { 843 if (outputStackTop >= elements) { 844 outputStackTop -= elements; 845 } else { 846 // if the number of elements to be popped is greater than the number 847 // of elements in the output stack, clear it, and pops the remaining 848 // elements from the input stack. 849 owner.inputStackTop -= elements - outputStackTop; 850 outputStackTop = 0; 851 } 852 } 853 854 /** 855 * Pops a type from the output frame stack. 856 * 857 * @param desc 858 * the descriptor of the type to be popped. Can also be a method 859 * descriptor (in this case this method pops the types 860 * corresponding to the method arguments). 861 */ 862 private void pop(final String desc) { 863 char c = desc.charAt(0); 864 if (c == '(') { 865 pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1); 866 } else if (c == 'J' || c == 'D') { 867 pop(2); 868 } else { 869 pop(1); 870 } 871 } 872 873 /** 874 * Adds a new type to the list of types on which a constructor is invoked in 875 * the basic block. 876 * 877 * @param var 878 * a type on a which a constructor is invoked. 879 */ 880 private void init(final int var) { 881 // creates and/or resizes the initializations array if necessary 882 if (initializations == null) { 883 initializations = new int[2]; 884 } 885 int n = initializations.length; 886 if (initializationCount >= n) { 887 int[] t = new int[Math.max(initializationCount + 1, 2 * n)]; 888 System.arraycopy(initializations, 0, t, 0, n); 889 initializations = t; 890 } 891 // stores the type to be initialized 892 initializations[initializationCount++] = var; 893 } 894 895 /** 896 * Replaces the given type with the appropriate type if it is one of the 897 * types on which a constructor is invoked in the basic block. 898 * 899 * @param cw 900 * the ClassWriter to which this label belongs. 901 * @param t 902 * a type 903 * @return t or, if t is one of the types on which a constructor is invoked 904 * in the basic block, the type corresponding to this constructor. 905 */ 906 private int init(final ClassWriter cw, final int t) { 907 int s; 908 if (t == UNINITIALIZED_THIS) { 909 s = OBJECT | cw.addType(cw.thisName); 910 } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) { 911 String type = cw.typeTable[t & BASE_VALUE].strVal1; 912 s = OBJECT | cw.addType(type); 913 } else { 914 return t; 915 } 916 for (int j = 0; j < initializationCount; ++j) { 917 int u = initializations[j]; 918 int dim = u & DIM; 919 int kind = u & KIND; 920 if (kind == LOCAL) { 921 u = dim + inputLocals[u & VALUE]; 922 } else if (kind == STACK) { 923 u = dim + inputStack[inputStack.length - (u & VALUE)]; 924 } 925 if (t == u) { 926 return s; 927 } 928 } 929 return t; 930 } 931 932 /** 933 * Initializes the input frame of the first basic block from the method 934 * descriptor. 935 * 936 * @param cw 937 * the ClassWriter to which this label belongs. 938 * @param access 939 * the access flags of the method to which this label belongs. 940 * @param args 941 * the formal parameter types of this method. 942 * @param maxLocals 943 * the maximum number of local variables of this method. 944 */ 945 final void initInputFrame(final ClassWriter cw, final int access, 946 final Type[] args, final int maxLocals) { 947 inputLocals = new int[maxLocals]; 948 inputStack = new int[0]; 949 int i = 0; 950 if ((access & Opcodes.ACC_STATIC) == 0) { 951 if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) { 952 inputLocals[i++] = OBJECT | cw.addType(cw.thisName); 953 } else { 954 inputLocals[i++] = UNINITIALIZED_THIS; 955 } 956 } 957 for (int j = 0; j < args.length; ++j) { 958 int t = type(cw, args[j].getDescriptor()); 959 inputLocals[i++] = t; 960 if (t == LONG || t == DOUBLE) { 961 inputLocals[i++] = TOP; 962 } 963 } 964 while (i < maxLocals) { 965 inputLocals[i++] = TOP; 966 } 967 } 968 969 /** 970 * Simulates the action of the given instruction on the output stack frame. 971 * 972 * @param opcode 973 * the opcode of the instruction. 974 * @param arg 975 * the operand of the instruction, if any. 976 * @param cw 977 * the class writer to which this label belongs. 978 * @param item 979 * the operand of the instructions, if any. 980 */ 981 void execute(final int opcode, final int arg, final ClassWriter cw, 982 final Item item) { 983 int t1, t2, t3, t4; 984 switch (opcode) { 985 case Opcodes.NOP: 986 case Opcodes.INEG: 987 case Opcodes.LNEG: 988 case Opcodes.FNEG: 989 case Opcodes.DNEG: 990 case Opcodes.I2B: 991 case Opcodes.I2C: 992 case Opcodes.I2S: 993 case Opcodes.GOTO: 994 case Opcodes.RETURN: 995 break; 996 case Opcodes.ACONST_NULL: 997 push(NULL); 998 break; 999 case Opcodes.ICONST_M1: 1000 case Opcodes.ICONST_0: 1001 case Opcodes.ICONST_1: 1002 case Opcodes.ICONST_2: 1003 case Opcodes.ICONST_3: 1004 case Opcodes.ICONST_4: 1005 case Opcodes.ICONST_5: 1006 case Opcodes.BIPUSH: 1007 case Opcodes.SIPUSH: 1008 case Opcodes.ILOAD: 1009 push(INTEGER); 1010 break; 1011 case Opcodes.LCONST_0: 1012 case Opcodes.LCONST_1: 1013 case Opcodes.LLOAD: 1014 push(LONG); 1015 push(TOP); 1016 break; 1017 case Opcodes.FCONST_0: 1018 case Opcodes.FCONST_1: 1019 case Opcodes.FCONST_2: 1020 case Opcodes.FLOAD: 1021 push(FLOAT); 1022 break; 1023 case Opcodes.DCONST_0: 1024 case Opcodes.DCONST_1: 1025 case Opcodes.DLOAD: 1026 push(DOUBLE); 1027 push(TOP); 1028 break; 1029 case Opcodes.LDC: 1030 switch (item.type) { 1031 case ClassWriter.INT: 1032 push(INTEGER); 1033 break; 1034 case ClassWriter.LONG: 1035 push(LONG); 1036 push(TOP); 1037 break; 1038 case ClassWriter.FLOAT: 1039 push(FLOAT); 1040 break; 1041 case ClassWriter.DOUBLE: 1042 push(DOUBLE); 1043 push(TOP); 1044 break; 1045 case ClassWriter.CLASS: 1046 push(OBJECT | cw.addType("java/lang/Class")); 1047 break; 1048 case ClassWriter.STR: 1049 push(OBJECT | cw.addType("java/lang/String")); 1050 break; 1051 case ClassWriter.MTYPE: 1052 push(OBJECT | cw.addType("java/lang/invoke/MethodType")); 1053 break; 1054 // case ClassWriter.HANDLE_BASE + [1..9]: 1055 default: 1056 push(OBJECT | cw.addType("java/lang/invoke/MethodHandle")); 1057 } 1058 break; 1059 case Opcodes.ALOAD: 1060 push(get(arg)); 1061 break; 1062 case Opcodes.IALOAD: 1063 case Opcodes.BALOAD: 1064 case Opcodes.CALOAD: 1065 case Opcodes.SALOAD: 1066 pop(2); 1067 push(INTEGER); 1068 break; 1069 case Opcodes.LALOAD: 1070 case Opcodes.D2L: 1071 pop(2); 1072 push(LONG); 1073 push(TOP); 1074 break; 1075 case Opcodes.FALOAD: 1076 pop(2); 1077 push(FLOAT); 1078 break; 1079 case Opcodes.DALOAD: 1080 case Opcodes.L2D: 1081 pop(2); 1082 push(DOUBLE); 1083 push(TOP); 1084 break; 1085 case Opcodes.AALOAD: 1086 pop(1); 1087 t1 = pop(); 1088 push(t1 == NULL ? t1 : ELEMENT_OF + t1); 1089 break; 1090 case Opcodes.ISTORE: 1091 case Opcodes.FSTORE: 1092 case Opcodes.ASTORE: 1093 t1 = pop(); 1094 set(arg, t1); 1095 if (arg > 0) { 1096 t2 = get(arg - 1); 1097 // if t2 is of kind STACK or LOCAL we cannot know its size! 1098 if (t2 == LONG || t2 == DOUBLE) { 1099 set(arg - 1, TOP); 1100 } else if ((t2 & KIND) != BASE) { 1101 set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); 1102 } 1103 } 1104 break; 1105 case Opcodes.LSTORE: 1106 case Opcodes.DSTORE: 1107 pop(1); 1108 t1 = pop(); 1109 set(arg, t1); 1110 set(arg + 1, TOP); 1111 if (arg > 0) { 1112 t2 = get(arg - 1); 1113 // if t2 is of kind STACK or LOCAL we cannot know its size! 1114 if (t2 == LONG || t2 == DOUBLE) { 1115 set(arg - 1, TOP); 1116 } else if ((t2 & KIND) != BASE) { 1117 set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); 1118 } 1119 } 1120 break; 1121 case Opcodes.IASTORE: 1122 case Opcodes.BASTORE: 1123 case Opcodes.CASTORE: 1124 case Opcodes.SASTORE: 1125 case Opcodes.FASTORE: 1126 case Opcodes.AASTORE: 1127 pop(3); 1128 break; 1129 case Opcodes.LASTORE: 1130 case Opcodes.DASTORE: 1131 pop(4); 1132 break; 1133 case Opcodes.POP: 1134 case Opcodes.IFEQ: 1135 case Opcodes.IFNE: 1136 case Opcodes.IFLT: 1137 case Opcodes.IFGE: 1138 case Opcodes.IFGT: 1139 case Opcodes.IFLE: 1140 case Opcodes.IRETURN: 1141 case Opcodes.FRETURN: 1142 case Opcodes.ARETURN: 1143 case Opcodes.TABLESWITCH: 1144 case Opcodes.LOOKUPSWITCH: 1145 case Opcodes.ATHROW: 1146 case Opcodes.MONITORENTER: 1147 case Opcodes.MONITOREXIT: 1148 case Opcodes.IFNULL: 1149 case Opcodes.IFNONNULL: 1150 pop(1); 1151 break; 1152 case Opcodes.POP2: 1153 case Opcodes.IF_ICMPEQ: 1154 case Opcodes.IF_ICMPNE: 1155 case Opcodes.IF_ICMPLT: 1156 case Opcodes.IF_ICMPGE: 1157 case Opcodes.IF_ICMPGT: 1158 case Opcodes.IF_ICMPLE: 1159 case Opcodes.IF_ACMPEQ: 1160 case Opcodes.IF_ACMPNE: 1161 case Opcodes.LRETURN: 1162 case Opcodes.DRETURN: 1163 pop(2); 1164 break; 1165 case Opcodes.DUP: 1166 t1 = pop(); 1167 push(t1); 1168 push(t1); 1169 break; 1170 case Opcodes.DUP_X1: 1171 t1 = pop(); 1172 t2 = pop(); 1173 push(t1); 1174 push(t2); 1175 push(t1); 1176 break; 1177 case Opcodes.DUP_X2: 1178 t1 = pop(); 1179 t2 = pop(); 1180 t3 = pop(); 1181 push(t1); 1182 push(t3); 1183 push(t2); 1184 push(t1); 1185 break; 1186 case Opcodes.DUP2: 1187 t1 = pop(); 1188 t2 = pop(); 1189 push(t2); 1190 push(t1); 1191 push(t2); 1192 push(t1); 1193 break; 1194 case Opcodes.DUP2_X1: 1195 t1 = pop(); 1196 t2 = pop(); 1197 t3 = pop(); 1198 push(t2); 1199 push(t1); 1200 push(t3); 1201 push(t2); 1202 push(t1); 1203 break; 1204 case Opcodes.DUP2_X2: 1205 t1 = pop(); 1206 t2 = pop(); 1207 t3 = pop(); 1208 t4 = pop(); 1209 push(t2); 1210 push(t1); 1211 push(t4); 1212 push(t3); 1213 push(t2); 1214 push(t1); 1215 break; 1216 case Opcodes.SWAP: 1217 t1 = pop(); 1218 t2 = pop(); 1219 push(t1); 1220 push(t2); 1221 break; 1222 case Opcodes.IADD: 1223 case Opcodes.ISUB: 1224 case Opcodes.IMUL: 1225 case Opcodes.IDIV: 1226 case Opcodes.IREM: 1227 case Opcodes.IAND: 1228 case Opcodes.IOR: 1229 case Opcodes.IXOR: 1230 case Opcodes.ISHL: 1231 case Opcodes.ISHR: 1232 case Opcodes.IUSHR: 1233 case Opcodes.L2I: 1234 case Opcodes.D2I: 1235 case Opcodes.FCMPL: 1236 case Opcodes.FCMPG: 1237 pop(2); 1238 push(INTEGER); 1239 break; 1240 case Opcodes.LADD: 1241 case Opcodes.LSUB: 1242 case Opcodes.LMUL: 1243 case Opcodes.LDIV: 1244 case Opcodes.LREM: 1245 case Opcodes.LAND: 1246 case Opcodes.LOR: 1247 case Opcodes.LXOR: 1248 pop(4); 1249 push(LONG); 1250 push(TOP); 1251 break; 1252 case Opcodes.FADD: 1253 case Opcodes.FSUB: 1254 case Opcodes.FMUL: 1255 case Opcodes.FDIV: 1256 case Opcodes.FREM: 1257 case Opcodes.L2F: 1258 case Opcodes.D2F: 1259 pop(2); 1260 push(FLOAT); 1261 break; 1262 case Opcodes.DADD: 1263 case Opcodes.DSUB: 1264 case Opcodes.DMUL: 1265 case Opcodes.DDIV: 1266 case Opcodes.DREM: 1267 pop(4); 1268 push(DOUBLE); 1269 push(TOP); 1270 break; 1271 case Opcodes.LSHL: 1272 case Opcodes.LSHR: 1273 case Opcodes.LUSHR: 1274 pop(3); 1275 push(LONG); 1276 push(TOP); 1277 break; 1278 case Opcodes.IINC: 1279 set(arg, INTEGER); 1280 break; 1281 case Opcodes.I2L: 1282 case Opcodes.F2L: 1283 pop(1); 1284 push(LONG); 1285 push(TOP); 1286 break; 1287 case Opcodes.I2F: 1288 pop(1); 1289 push(FLOAT); 1290 break; 1291 case Opcodes.I2D: 1292 case Opcodes.F2D: 1293 pop(1); 1294 push(DOUBLE); 1295 push(TOP); 1296 break; 1297 case Opcodes.F2I: 1298 case Opcodes.ARRAYLENGTH: 1299 case Opcodes.INSTANCEOF: 1300 pop(1); 1301 push(INTEGER); 1302 break; 1303 case Opcodes.LCMP: 1304 case Opcodes.DCMPL: 1305 case Opcodes.DCMPG: 1306 pop(4); 1307 push(INTEGER); 1308 break; 1309 case Opcodes.JSR: 1310 case Opcodes.RET: 1311 throw new RuntimeException( 1312 "JSR/RET are not supported with computeFrames option"); 1313 case Opcodes.GETSTATIC: 1314 push(cw, item.strVal3); 1315 break; 1316 case Opcodes.PUTSTATIC: 1317 pop(item.strVal3); 1318 break; 1319 case Opcodes.GETFIELD: 1320 pop(1); 1321 push(cw, item.strVal3); 1322 break; 1323 case Opcodes.PUTFIELD: 1324 pop(item.strVal3); 1325 pop(); 1326 break; 1327 case Opcodes.INVOKEVIRTUAL: 1328 case Opcodes.INVOKESPECIAL: 1329 case Opcodes.INVOKESTATIC: 1330 case Opcodes.INVOKEINTERFACE: 1331 pop(item.strVal3); 1332 if (opcode != Opcodes.INVOKESTATIC) { 1333 t1 = pop(); 1334 if (opcode == Opcodes.INVOKESPECIAL 1335 && item.strVal2.charAt(0) == '<') { 1336 init(t1); 1337 } 1338 } 1339 push(cw, item.strVal3); 1340 break; 1341 case Opcodes.INVOKEDYNAMIC: 1342 pop(item.strVal2); 1343 push(cw, item.strVal2); 1344 break; 1345 case Opcodes.NEW: 1346 push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg)); 1347 break; 1348 case Opcodes.NEWARRAY: 1349 pop(); 1350 switch (arg) { 1351 case Opcodes.T_BOOLEAN: 1352 push(ARRAY_OF | BOOLEAN); 1353 break; 1354 case Opcodes.T_CHAR: 1355 push(ARRAY_OF | CHAR); 1356 break; 1357 case Opcodes.T_BYTE: 1358 push(ARRAY_OF | BYTE); 1359 break; 1360 case Opcodes.T_SHORT: 1361 push(ARRAY_OF | SHORT); 1362 break; 1363 case Opcodes.T_INT: 1364 push(ARRAY_OF | INTEGER); 1365 break; 1366 case Opcodes.T_FLOAT: 1367 push(ARRAY_OF | FLOAT); 1368 break; 1369 case Opcodes.T_DOUBLE: 1370 push(ARRAY_OF | DOUBLE); 1371 break; 1372 // case Opcodes.T_LONG: 1373 default: 1374 push(ARRAY_OF | LONG); 1375 break; 1376 } 1377 break; 1378 case Opcodes.ANEWARRAY: 1379 String s = item.strVal1; 1380 pop(); 1381 if (s.charAt(0) == '[') { 1382 push(cw, '[' + s); 1383 } else { 1384 push(ARRAY_OF | OBJECT | cw.addType(s)); 1385 } 1386 break; 1387 case Opcodes.CHECKCAST: 1388 s = item.strVal1; 1389 pop(); 1390 if (s.charAt(0) == '[') { 1391 push(cw, s); 1392 } else { 1393 push(OBJECT | cw.addType(s)); 1394 } 1395 break; 1396 // case Opcodes.MULTIANEWARRAY: 1397 default: 1398 pop(arg); 1399 push(cw, item.strVal1); 1400 break; 1401 } 1402 } 1403 1404 /** 1405 * Merges the input frame of the given basic block with the input and output 1406 * frames of this basic block. Returns <tt>true</tt> if the input frame of 1407 * the given label has been changed by this operation. 1408 * 1409 * @param cw 1410 * the ClassWriter to which this label belongs. 1411 * @param frame 1412 * the basic block whose input frame must be updated. 1413 * @param edge 1414 * the kind of the {@link Edge} between this label and 'label'. 1415 * See {@link Edge#info}. 1416 * @return <tt>true</tt> if the input frame of the given label has been 1417 * changed by this operation. 1418 */ 1419 final boolean merge(final ClassWriter cw, final Frame frame, final int edge) { 1420 boolean changed = false; 1421 int i, s, dim, kind, t; 1422 1423 int nLocal = inputLocals.length; 1424 int nStack = inputStack.length; 1425 if (frame.inputLocals == null) { 1426 frame.inputLocals = new int[nLocal]; 1427 changed = true; 1428 } 1429 1430 for (i = 0; i < nLocal; ++i) { 1431 if (outputLocals != null && i < outputLocals.length) { 1432 s = outputLocals[i]; 1433 if (s == 0) { 1434 t = inputLocals[i]; 1435 } else { 1436 dim = s & DIM; 1437 kind = s & KIND; 1438 if (kind == BASE) { 1439 t = s; 1440 } else { 1441 if (kind == LOCAL) { 1442 t = dim + inputLocals[s & VALUE]; 1443 } else { 1444 t = dim + inputStack[nStack - (s & VALUE)]; 1445 } 1446 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 1447 && (t == LONG || t == DOUBLE)) { 1448 t = TOP; 1449 } 1450 } 1451 } 1452 } else { 1453 t = inputLocals[i]; 1454 } 1455 if (initializations != null) { 1456 t = init(cw, t); 1457 } 1458 changed |= merge(cw, t, frame.inputLocals, i); 1459 } 1460 1461 if (edge > 0) { 1462 for (i = 0; i < nLocal; ++i) { 1463 t = inputLocals[i]; 1464 changed |= merge(cw, t, frame.inputLocals, i); 1465 } 1466 if (frame.inputStack == null) { 1467 frame.inputStack = new int[1]; 1468 changed = true; 1469 } 1470 changed |= merge(cw, edge, frame.inputStack, 0); 1471 return changed; 1472 } 1473 1474 int nInputStack = inputStack.length + owner.inputStackTop; 1475 if (frame.inputStack == null) { 1476 frame.inputStack = new int[nInputStack + outputStackTop]; 1477 changed = true; 1478 } 1479 1480 for (i = 0; i < nInputStack; ++i) { 1481 t = inputStack[i]; 1482 if (initializations != null) { 1483 t = init(cw, t); 1484 } 1485 changed |= merge(cw, t, frame.inputStack, i); 1486 } 1487 for (i = 0; i < outputStackTop; ++i) { 1488 s = outputStack[i]; 1489 dim = s & DIM; 1490 kind = s & KIND; 1491 if (kind == BASE) { 1492 t = s; 1493 } else { 1494 if (kind == LOCAL) { 1495 t = dim + inputLocals[s & VALUE]; 1496 } else { 1497 t = dim + inputStack[nStack - (s & VALUE)]; 1498 } 1499 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 1500 && (t == LONG || t == DOUBLE)) { 1501 t = TOP; 1502 } 1503 } 1504 if (initializations != null) { 1505 t = init(cw, t); 1506 } 1507 changed |= merge(cw, t, frame.inputStack, nInputStack + i); 1508 } 1509 return changed; 1510 } 1511 1512 /** 1513 * Merges the type at the given index in the given type array with the given 1514 * type. Returns <tt>true</tt> if the type array has been modified by this 1515 * operation. 1516 * 1517 * @param cw 1518 * the ClassWriter to which this label belongs. 1519 * @param t 1520 * the type with which the type array element must be merged. 1521 * @param types 1522 * an array of types. 1523 * @param index 1524 * the index of the type that must be merged in 'types'. 1525 * @return <tt>true</tt> if the type array has been modified by this 1526 * operation. 1527 */ 1528 private static boolean merge(final ClassWriter cw, int t, 1529 final int[] types, final int index) { 1530 int u = types[index]; 1531 if (u == t) { 1532 // if the types are equal, merge(u,t)=u, so there is no change 1533 return false; 1534 } 1535 if ((t & ~DIM) == NULL) { 1536 if (u == NULL) { 1537 return false; 1538 } 1539 t = NULL; 1540 } 1541 if (u == 0) { 1542 // if types[index] has never been assigned, merge(u,t)=t 1543 types[index] = t; 1544 return true; 1545 } 1546 int v; 1547 if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) { 1548 // if u is a reference type of any dimension 1549 if (t == NULL) { 1550 // if t is the NULL type, merge(u,t)=u, so there is no change 1551 return false; 1552 } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) { 1553 // if t and u have the same dimension and same base kind 1554 if ((u & BASE_KIND) == OBJECT) { 1555 // if t is also a reference type, and if u and t have the 1556 // same dimension merge(u,t) = dim(t) | common parent of the 1557 // element types of u and t 1558 v = (t & DIM) | OBJECT 1559 | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); 1560 } else { 1561 // if u and t are array types, but not with the same element 1562 // type, merge(u,t) = dim(u) - 1 | java/lang/Object 1563 int vdim = ELEMENT_OF + (u & DIM); 1564 v = vdim | OBJECT | cw.addType("java/lang/Object"); 1565 } 1566 } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { 1567 // if t is any other reference or array type, the merged type 1568 // is min(udim, tdim) | java/lang/Object, where udim is the 1569 // array dimension of u, minus 1 if u is an array type with a 1570 // primitive element type (and similarly for tdim). 1571 int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 1572 : ELEMENT_OF) + (t & DIM); 1573 int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 1574 : ELEMENT_OF) + (u & DIM); 1575 v = Math.min(tdim, udim) | OBJECT 1576 | cw.addType("java/lang/Object"); 1577 } else { 1578 // if t is any other type, merge(u,t)=TOP 1579 v = TOP; 1580 } 1581 } else if (u == NULL) { 1582 // if u is the NULL type, merge(u,t)=t, 1583 // or TOP if t is not a reference type 1584 v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP; 1585 } else { 1586 // if u is any other type, merge(u,t)=TOP whatever t 1587 v = TOP; 1588 } 1589 if (u != v) { 1590 types[index] = v; 1591 return true; 1592 } 1593 return false; 1594 } 1595 }