< prev index next >

src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java

Print this page




  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 import java.lang.reflect.Constructor;

  62 import java.lang.reflect.Method;
  63 
  64 /**
  65  * A Java field or method type. This class can be used to make it easier to manipulate type and
  66  * method descriptors.
  67  *
  68  * @author Eric Bruneton
  69  * @author Chris Nokleberg
  70  */
  71 public final class Type {
  72 
  73     /** The sort of the {@code void} type. See {@link #getSort}. */
  74     public static final int VOID = 0;
  75 
  76     /** The sort of the {@code boolean} type. See {@link #getSort}. */
  77     public static final int BOOLEAN = 1;
  78 
  79     /** The sort of the {@code char} type. See {@link #getSort}. */
  80     public static final int CHAR = 2;
  81 


 317     }
 318 
 319     /**
 320       * Returns the {@link Type} values corresponding to the argument types of the given method
 321       * descriptor.
 322       *
 323       * @param methodDescriptor a method descriptor.
 324       * @return the {@link Type} values corresponding to the argument types of the given method
 325       *     descriptor.
 326       */
 327     public static Type[] getArgumentTypes(final String methodDescriptor) {
 328         // First step: compute the number of argument types in methodDescriptor.
 329         int numArgumentTypes = 0;
 330         // Skip the first character, which is always a '('.
 331         int currentOffset = 1;
 332         // Parse the argument types, one at a each loop iteration.
 333         while (methodDescriptor.charAt(currentOffset) != ')') {
 334             while (methodDescriptor.charAt(currentOffset) == '[') {
 335                 currentOffset++;
 336             }
 337             if (methodDescriptor.charAt(currentOffset++) == 'L') {

 338                 // Skip the argument descriptor content.
 339                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 340             }
 341             ++numArgumentTypes;
 342         }
 343 
 344         // Second step: create a Type instance for each argument type.
 345         Type[] argumentTypes = new Type[numArgumentTypes];
 346         // Skip the first character, which is always a '('.
 347         currentOffset = 1;
 348         // Parse and create the argument types, one at each loop iteration.
 349         int currentArgumentTypeIndex = 0;
 350         while (methodDescriptor.charAt(currentOffset) != ')') {
 351             final int currentArgumentTypeOffset = currentOffset;
 352             while (methodDescriptor.charAt(currentOffset) == '[') {
 353                 currentOffset++;
 354             }
 355             if (methodDescriptor.charAt(currentOffset++) == 'L') {

 356                 // Skip the argument descriptor content.
 357                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 358             }
 359             argumentTypes[currentArgumentTypeIndex++] =
 360                     getTypeInternal(methodDescriptor, currentArgumentTypeOffset, currentOffset);
 361         }
 362         return argumentTypes;
 363     }
 364 
 365     /**
 366       * Returns the {@link Type} values corresponding to the argument types of the given method.
 367       *
 368       * @param method a method.
 369       * @return the {@link Type} values corresponding to the argument types of the given method.
 370       */
 371     public static Type[] getArgumentTypes(final Method method) {
 372         Class<?>[] classes = method.getParameterTypes();
 373         Type[] types = new Type[classes.length];
 374         for (int i = classes.length - 1; i >= 0; --i) {
 375             types[i] = getType(classes[i]);


 384       * @return the return type of methods of this type.
 385       */
 386     public Type getReturnType() {
 387         return getReturnType(getDescriptor());
 388     }
 389 
 390     /**
 391       * Returns the {@link Type} corresponding to the return type of the given method descriptor.
 392       *
 393       * @param methodDescriptor a method descriptor.
 394       * @return the {@link Type} corresponding to the return type of the given method descriptor.
 395       */
 396     public static Type getReturnType(final String methodDescriptor) {
 397         // Skip the first character, which is always a '('.
 398         int currentOffset = 1;
 399         // Skip the argument types, one at a each loop iteration.
 400         while (methodDescriptor.charAt(currentOffset) != ')') {
 401             while (methodDescriptor.charAt(currentOffset) == '[') {
 402                 currentOffset++;
 403             }
 404             if (methodDescriptor.charAt(currentOffset++) == 'L') {

 405                 // Skip the argument descriptor content.
 406                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 407             }
 408         }
 409         return getTypeInternal(methodDescriptor, currentOffset + 1, methodDescriptor.length());
 410     }
 411 
 412     /**
 413       * Returns the {@link Type} corresponding to the return type of the given method.
 414       *
 415       * @param method a method.
 416       * @return the {@link Type} corresponding to the return type of the given method.
 417       */
 418     public static Type getReturnType(final Method method) {
 419         return getType(method.getReturnType());
 420     }
 421 
 422     /**
 423       * Returns the {@link Type} corresponding to the given field or method descriptor.
 424       *


 436                 return VOID_TYPE;
 437             case 'Z':
 438                 return BOOLEAN_TYPE;
 439             case 'C':
 440                 return CHAR_TYPE;
 441             case 'B':
 442                 return BYTE_TYPE;
 443             case 'S':
 444                 return SHORT_TYPE;
 445             case 'I':
 446                 return INT_TYPE;
 447             case 'F':
 448                 return FLOAT_TYPE;
 449             case 'J':
 450                 return LONG_TYPE;
 451             case 'D':
 452                 return DOUBLE_TYPE;
 453             case '[':
 454                 return new Type(ARRAY, descriptorBuffer, descriptorBegin, descriptorEnd);
 455             case 'L':

 456                 return new Type(OBJECT, descriptorBuffer, descriptorBegin + 1, descriptorEnd - 1);
 457             case '(':
 458                 return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
 459             default:
 460                 throw new IllegalArgumentException();
 461         }
 462     }
 463 
 464     // -----------------------------------------------------------------------------------------------
 465     // Methods to get class names, internal names or descriptors.
 466     // -----------------------------------------------------------------------------------------------
 467 
 468     /**
 469       * Returns the binary name of the class corresponding to this type. This method must not be used
 470       * on method types.
 471       *
 472       * @return the binary name of the class corresponding to this type.
 473       */
 474     public String getClassName() {
 475         switch (sort) {


 645                 descriptor = 'V';
 646             } else if (currentClass == Boolean.TYPE) {
 647                 descriptor = 'Z';
 648             } else if (currentClass == Byte.TYPE) {
 649                 descriptor = 'B';
 650             } else if (currentClass == Character.TYPE) {
 651                 descriptor = 'C';
 652             } else if (currentClass == Short.TYPE) {
 653                 descriptor = 'S';
 654             } else if (currentClass == Double.TYPE) {
 655                 descriptor = 'D';
 656             } else if (currentClass == Float.TYPE) {
 657                 descriptor = 'F';
 658             } else if (currentClass == Long.TYPE) {
 659                 descriptor = 'J';
 660             } else {
 661                 throw new AssertionError();
 662             }
 663             stringBuilder.append(descriptor);
 664         } else {
 665             stringBuilder.append('L');
 666             String name = currentClass.getName();






 667             int nameLength = name.length();
 668             for (int i = 0; i < nameLength; ++i) {
 669                 char car = name.charAt(i);
 670                 stringBuilder.append(car == '.' ? '/' : car);
 671             }
 672             stringBuilder.append(';');
 673         }
 674     }
 675 




























 676     // -----------------------------------------------------------------------------------------------
 677     // Methods to get the sort, dimension, size, and opcodes corresponding to a Type or descriptor.
 678     // -----------------------------------------------------------------------------------------------
 679 
 680     /**
 681       * Returns the sort of this type.
 682       *
 683       * @return {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE}, {@link #SHORT}, {@link
 684       *     #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY}, {@link #OBJECT} or
 685       *     {@link #METHOD}.
 686       */
 687     public int getSort() {
 688         return sort == INTERNAL ? OBJECT : sort;
 689     }
 690 
 691     /**
 692       * Returns the number of dimensions of this array type. This method should only be used for an
 693       * array type.
 694       *
 695       * @return the number of dimensions of this array type.


 749       * @param methodDescriptor a method descriptor.
 750       * @return the size of the arguments of the method (plus one for the implicit this argument),
 751       *     argumentsSize, and the size of its return value, returnSize, packed into a single int i =
 752       *     {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
 753       *     i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
 754       */
 755     public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
 756         int argumentsSize = 1;
 757         // Skip the first character, which is always a '('.
 758         int currentOffset = 1;
 759         int currentChar = methodDescriptor.charAt(currentOffset);
 760         // Parse the argument types and compute their size, one at a each loop iteration.
 761         while (currentChar != ')') {
 762             if (currentChar == 'J' || currentChar == 'D') {
 763                 currentOffset++;
 764                 argumentsSize += 2;
 765             } else {
 766                 while (methodDescriptor.charAt(currentOffset) == '[') {
 767                     currentOffset++;
 768                 }
 769                 if (methodDescriptor.charAt(currentOffset++) == 'L') {

 770                     // Skip the argument descriptor content.
 771                     currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 772                 }
 773                 argumentsSize += 1;
 774             }
 775             currentChar = methodDescriptor.charAt(currentOffset);
 776         }
 777         currentChar = methodDescriptor.charAt(currentOffset + 1);
 778         if (currentChar == 'V') {
 779             return argumentsSize << 2;
 780         } else {
 781             int returnSize = (currentChar == 'J' || currentChar == 'D') ? 2 : 1;
 782             return argumentsSize << 2 | returnSize;
 783         }
 784     }
 785 
 786     /**
 787       * Returns a JVM instruction opcode adapted to this {@link Type}. This method must not be used for
 788       * method types.
 789       *




  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 import java.lang.reflect.Constructor;
  62 import java.lang.reflect.InvocationTargetException;
  63 import java.lang.reflect.Method;
  64 
  65 /**
  66  * A Java field or method type. This class can be used to make it easier to manipulate type and
  67  * method descriptors.
  68  *
  69  * @author Eric Bruneton
  70  * @author Chris Nokleberg
  71  */
  72 public final class Type {
  73 
  74     /** The sort of the {@code void} type. See {@link #getSort}. */
  75     public static final int VOID = 0;
  76 
  77     /** The sort of the {@code boolean} type. See {@link #getSort}. */
  78     public static final int BOOLEAN = 1;
  79 
  80     /** The sort of the {@code char} type. See {@link #getSort}. */
  81     public static final int CHAR = 2;
  82 


 318     }
 319 
 320     /**
 321       * Returns the {@link Type} values corresponding to the argument types of the given method
 322       * descriptor.
 323       *
 324       * @param methodDescriptor a method descriptor.
 325       * @return the {@link Type} values corresponding to the argument types of the given method
 326       *     descriptor.
 327       */
 328     public static Type[] getArgumentTypes(final String methodDescriptor) {
 329         // First step: compute the number of argument types in methodDescriptor.
 330         int numArgumentTypes = 0;
 331         // Skip the first character, which is always a '('.
 332         int currentOffset = 1;
 333         // Parse the argument types, one at a each loop iteration.
 334         while (methodDescriptor.charAt(currentOffset) != ')') {
 335             while (methodDescriptor.charAt(currentOffset) == '[') {
 336                 currentOffset++;
 337             }
 338             char c = methodDescriptor.charAt(currentOffset++);
 339             if (c == 'L' || c == 'Q') {
 340                 // Skip the argument descriptor content.
 341                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 342             }
 343             ++numArgumentTypes;
 344         }
 345 
 346         // Second step: create a Type instance for each argument type.
 347         Type[] argumentTypes = new Type[numArgumentTypes];
 348         // Skip the first character, which is always a '('.
 349         currentOffset = 1;
 350         // Parse and create the argument types, one at each loop iteration.
 351         int currentArgumentTypeIndex = 0;
 352         while (methodDescriptor.charAt(currentOffset) != ')') {
 353             final int currentArgumentTypeOffset = currentOffset;
 354             while (methodDescriptor.charAt(currentOffset) == '[') {
 355                 currentOffset++;
 356             }
 357             char c = methodDescriptor.charAt(currentOffset++);
 358             if (c == 'L' || c == 'Q') {
 359                 // Skip the argument descriptor content.
 360                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 361             }
 362             argumentTypes[currentArgumentTypeIndex++] =
 363                     getTypeInternal(methodDescriptor, currentArgumentTypeOffset, currentOffset);
 364         }
 365         return argumentTypes;
 366     }
 367 
 368     /**
 369       * Returns the {@link Type} values corresponding to the argument types of the given method.
 370       *
 371       * @param method a method.
 372       * @return the {@link Type} values corresponding to the argument types of the given method.
 373       */
 374     public static Type[] getArgumentTypes(final Method method) {
 375         Class<?>[] classes = method.getParameterTypes();
 376         Type[] types = new Type[classes.length];
 377         for (int i = classes.length - 1; i >= 0; --i) {
 378             types[i] = getType(classes[i]);


 387       * @return the return type of methods of this type.
 388       */
 389     public Type getReturnType() {
 390         return getReturnType(getDescriptor());
 391     }
 392 
 393     /**
 394       * Returns the {@link Type} corresponding to the return type of the given method descriptor.
 395       *
 396       * @param methodDescriptor a method descriptor.
 397       * @return the {@link Type} corresponding to the return type of the given method descriptor.
 398       */
 399     public static Type getReturnType(final String methodDescriptor) {
 400         // Skip the first character, which is always a '('.
 401         int currentOffset = 1;
 402         // Skip the argument types, one at a each loop iteration.
 403         while (methodDescriptor.charAt(currentOffset) != ')') {
 404             while (methodDescriptor.charAt(currentOffset) == '[') {
 405                 currentOffset++;
 406             }
 407             char c = methodDescriptor.charAt(currentOffset++);
 408             if (c == 'L' || c == 'Q') {
 409                 // Skip the argument descriptor content.
 410                 currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 411             }
 412         }
 413         return getTypeInternal(methodDescriptor, currentOffset + 1, methodDescriptor.length());
 414     }
 415 
 416     /**
 417       * Returns the {@link Type} corresponding to the return type of the given method.
 418       *
 419       * @param method a method.
 420       * @return the {@link Type} corresponding to the return type of the given method.
 421       */
 422     public static Type getReturnType(final Method method) {
 423         return getType(method.getReturnType());
 424     }
 425 
 426     /**
 427       * Returns the {@link Type} corresponding to the given field or method descriptor.
 428       *


 440                 return VOID_TYPE;
 441             case 'Z':
 442                 return BOOLEAN_TYPE;
 443             case 'C':
 444                 return CHAR_TYPE;
 445             case 'B':
 446                 return BYTE_TYPE;
 447             case 'S':
 448                 return SHORT_TYPE;
 449             case 'I':
 450                 return INT_TYPE;
 451             case 'F':
 452                 return FLOAT_TYPE;
 453             case 'J':
 454                 return LONG_TYPE;
 455             case 'D':
 456                 return DOUBLE_TYPE;
 457             case '[':
 458                 return new Type(ARRAY, descriptorBuffer, descriptorBegin, descriptorEnd);
 459             case 'L':
 460             case 'Q':
 461                 return new Type(OBJECT, descriptorBuffer, descriptorBegin + 1, descriptorEnd - 1);
 462             case '(':
 463                 return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
 464             default:
 465                 throw new IllegalArgumentException();
 466         }
 467     }
 468 
 469     // -----------------------------------------------------------------------------------------------
 470     // Methods to get class names, internal names or descriptors.
 471     // -----------------------------------------------------------------------------------------------
 472 
 473     /**
 474       * Returns the binary name of the class corresponding to this type. This method must not be used
 475       * on method types.
 476       *
 477       * @return the binary name of the class corresponding to this type.
 478       */
 479     public String getClassName() {
 480         switch (sort) {


 650                 descriptor = 'V';
 651             } else if (currentClass == Boolean.TYPE) {
 652                 descriptor = 'Z';
 653             } else if (currentClass == Byte.TYPE) {
 654                 descriptor = 'B';
 655             } else if (currentClass == Character.TYPE) {
 656                 descriptor = 'C';
 657             } else if (currentClass == Short.TYPE) {
 658                 descriptor = 'S';
 659             } else if (currentClass == Double.TYPE) {
 660                 descriptor = 'D';
 661             } else if (currentClass == Float.TYPE) {
 662                 descriptor = 'F';
 663             } else if (currentClass == Long.TYPE) {
 664                 descriptor = 'J';
 665             } else {
 666                 throw new AssertionError();
 667             }
 668             stringBuilder.append(descriptor);
 669         } else {

 670             String name = currentClass.getName();
 671             if (Helper.isIndirectType(currentClass)) {
 672                 stringBuilder.append('L');
 673             } else {
 674                 stringBuilder.append('Q');
 675 
 676             }
 677             int nameLength = name.length();
 678             for (int i = 0; i < nameLength; ++i) {
 679                 char car = name.charAt(i);
 680                 stringBuilder.append(car == '.' ? '/' : car);
 681             }
 682             stringBuilder.append(';');
 683         }
 684     }
 685 
 686     // Workarounds nasgen build that depends on ASM but compiled with
 687     // the bootstrap JDK.  Can't reference Class::isIndirectType
 688     static class Helper {
 689         static final Method isIndirectTypeMethod = isIndirectTypeMethod();
 690         static Method isIndirectTypeMethod() {
 691             try {
 692                 return Class.class.getMethod("isIndirectType");
 693             } catch (NoSuchMethodException e) {
 694                 return null;
 695             }
 696         }
 697 
 698         static boolean isIndirectType(Class<?> clazz) {
 699             int mods = clazz.getModifiers();
 700             if ((mods & 0x00000100) != 0) {            // inline class
 701                 assert isIndirectTypeMethod != null;
 702                 try {
 703                     return (boolean) isIndirectTypeMethod.invoke(clazz);
 704                 } catch (InvocationTargetException e) {
 705                     throw new InternalError(e.getCause());
 706                 } catch (IllegalAccessException e) {
 707                     throw new InternalError(e);
 708                 }
 709             }
 710             return true;
 711         }
 712     }
 713 
 714     // -----------------------------------------------------------------------------------------------
 715     // Methods to get the sort, dimension, size, and opcodes corresponding to a Type or descriptor.
 716     // -----------------------------------------------------------------------------------------------
 717 
 718     /**
 719       * Returns the sort of this type.
 720       *
 721       * @return {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE}, {@link #SHORT}, {@link
 722       *     #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY}, {@link #OBJECT} or
 723       *     {@link #METHOD}.
 724       */
 725     public int getSort() {
 726         return sort == INTERNAL ? OBJECT : sort;
 727     }
 728 
 729     /**
 730       * Returns the number of dimensions of this array type. This method should only be used for an
 731       * array type.
 732       *
 733       * @return the number of dimensions of this array type.


 787       * @param methodDescriptor a method descriptor.
 788       * @return the size of the arguments of the method (plus one for the implicit this argument),
 789       *     argumentsSize, and the size of its return value, returnSize, packed into a single int i =
 790       *     {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
 791       *     i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
 792       */
 793     public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
 794         int argumentsSize = 1;
 795         // Skip the first character, which is always a '('.
 796         int currentOffset = 1;
 797         int currentChar = methodDescriptor.charAt(currentOffset);
 798         // Parse the argument types and compute their size, one at a each loop iteration.
 799         while (currentChar != ')') {
 800             if (currentChar == 'J' || currentChar == 'D') {
 801                 currentOffset++;
 802                 argumentsSize += 2;
 803             } else {
 804                 while (methodDescriptor.charAt(currentOffset) == '[') {
 805                     currentOffset++;
 806                 }
 807                 char c = methodDescriptor.charAt(currentOffset++);
 808                 if (c == 'L' || c == 'Q') {
 809                     // Skip the argument descriptor content.
 810                     currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1;
 811                 }
 812                 argumentsSize += 1;
 813             }
 814             currentChar = methodDescriptor.charAt(currentOffset);
 815         }
 816         currentChar = methodDescriptor.charAt(currentOffset + 1);
 817         if (currentChar == 'V') {
 818             return argumentsSize << 2;
 819         } else {
 820             int returnSize = (currentChar == 'J' || currentChar == 'D') ? 2 : 1;
 821             return argumentsSize << 2 | returnSize;
 822         }
 823     }
 824 
 825     /**
 826       * Returns a JVM instruction opcode adapted to this {@link Type}. This method must not be used for
 827       * method types.
 828       *


< prev index next >