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