/src/main/java/com/alibaba/fastjson/asm/Type.java
Java | 331 lines | 122 code | 38 blank | 171 comment | 42 complexity | 79f86f6972f15cdc8092e32142ca96a2 MD5 | raw file
- /***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
- package com.alibaba.fastjson.asm;
- /**
- * A Java type. This class can be used to make it easier to manipulate type and method descriptors.
- *
- * @author Eric Bruneton
- * @author Chris Nokleberg
- */
- public class Type {
- /**
- * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
- */
- public static final int VOID = 0;
- /**
- * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
- */
- public static final int BOOLEAN = 1;
- /**
- * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
- */
- public static final int CHAR = 2;
- /**
- * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
- */
- public static final int BYTE = 3;
- /**
- * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
- */
- public static final int SHORT = 4;
- /**
- * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
- */
- public static final int INT = 5;
- /**
- * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
- */
- public static final int FLOAT = 6;
- /**
- * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
- */
- public static final int LONG = 7;
- /**
- * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
- */
- public static final int DOUBLE = 8;
- /**
- * The sort of array reference types. See {@link #getSort getSort}.
- */
- public static final int ARRAY = 9;
- /**
- * The sort of object reference type. See {@link #getSort getSort}.
- */
- public static final int OBJECT = 10;
- /**
- * The <tt>void</tt> type.
- */
- public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
- /**
- * The <tt>boolean</tt> type.
- */
- public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
- /**
- * The <tt>char</tt> type.
- */
- public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
- /**
- * The <tt>byte</tt> type.
- */
- public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
- /**
- * The <tt>short</tt> type.
- */
- public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
- /**
- * The <tt>int</tt> type.
- */
- public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
- /**
- * The <tt>float</tt> type.
- */
- public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
- /**
- * The <tt>long</tt> type.
- */
- public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
- /**
- * The <tt>double</tt> type.
- */
- public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
- // ------------------------------------------------------------------------
- // Fields
- // ------------------------------------------------------------------------
- /**
- * The sort of this Java type.
- */
- private final int sort;
- /**
- * A buffer containing the internal name of this Java type. This field is only used for reference types.
- */
- private final char[] buf;
- /**
- * The offset of the internal name of this Java type in {@link #buf buf} or, for primitive types, the size,
- * descriptor and getOpcode offsets for this type (byte 0 contains the size, byte 1 the descriptor, byte 2 the
- * offset for IALOAD or IASTORE, byte 3 the offset for all other instructions).
- */
- private final int off;
- /**
- * The length of the internal name of this Java type.
- */
- private final int len;
- // ------------------------------------------------------------------------
- // Constructors
- // ------------------------------------------------------------------------
- /**
- * Constructs a reference type.
- *
- * @param sort the sort of the reference type to be constructed.
- * @param buf a buffer containing the descriptor of the previous type.
- * @param off the offset of this descriptor in the previous buffer.
- * @param len the length of this descriptor.
- */
- private Type(final int sort, final char[] buf, final int off, final int len){
- this.sort = sort;
- this.buf = buf;
- this.off = off;
- this.len = len;
- }
- /**
- * Returns the Java type corresponding to the given type descriptor.
- *
- * @param typeDescriptor a type descriptor.
- * @return the Java type corresponding to the given type descriptor.
- */
- public static Type getType(final String typeDescriptor) {
- return getType(typeDescriptor.toCharArray(), 0);
- }
- /**
- * Computes the size of the arguments and of the return value of a method.
- *
- * @param desc the descriptor of a method.
- * @return the size of the arguments of the method (plus one for the implicit this argument), argSize, and the size
- * of its return value, retSize, packed into a single int i = <tt>(argSize << 2) | retSize</tt> (argSize is
- * therefore equal to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
- */
- public static int getArgumentsAndReturnSizes(final String desc) {
- int n = 1;
- int c = 1;
- while (true) {
- char car = desc.charAt(c++);
- if (car == ')') {
- car = desc.charAt(c);
- return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
- } else if (car == 'L') {
- while (desc.charAt(c++) != ';') {
- }
- n += 1;
- } else if (car == '[') {
- while ((car = desc.charAt(c)) == '[') {
- ++c;
- }
- if (car == 'D' || car == 'J') {
- n -= 1;
- }
- } else if (car == 'D' || car == 'J') {
- n += 2;
- } else {
- n += 1;
- }
- }
- }
- /**
- * Returns the Java type corresponding to the given type descriptor.
- *
- * @param buf a buffer containing a type descriptor.
- * @param off the offset of this descriptor in the previous buffer.
- * @return the Java type corresponding to the given type descriptor.
- */
- private static Type getType(final char[] buf, final int off) {
- int len;
- switch (buf[off]) {
- case 'V':
- return VOID_TYPE;
- case 'Z':
- return BOOLEAN_TYPE;
- case 'C':
- return CHAR_TYPE;
- case 'B':
- return BYTE_TYPE;
- case 'S':
- return SHORT_TYPE;
- case 'I':
- return INT_TYPE;
- case 'F':
- return FLOAT_TYPE;
- case 'J':
- return LONG_TYPE;
- case 'D':
- return DOUBLE_TYPE;
- case '[':
- len = 1;
- while (buf[off + len] == '[') {
- ++len;
- }
- if (buf[off + len] == 'L') {
- ++len;
- while (buf[off + len] != ';') {
- ++len;
- }
- }
- return new Type(ARRAY, buf, off, len + 1);
- // case 'L':
- default:
- len = 1;
- while (buf[off + len] != ';') {
- ++len;
- }
- return new Type(OBJECT, buf, off + 1, len - 1);
- }
- }
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
- /**
- * Returns the sort of this Java type.
- *
- * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT
- * SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY}
- * or {@link #OBJECT OBJECT}.
- */
- public int getSort() {
- return sort;
- }
- /**
- * Returns the internal name of the class corresponding to this object or array type. The internal name of a class
- * is its fully qualified name (as returned by Class.getName(), where '.' are replaced by '/'. This method should
- * only be used for an object or array type.
- *
- * @return the internal name of the class corresponding to this object type.
- */
- public String getInternalName() {
- return new String(buf, off, len);
- }
- // ------------------------------------------------------------------------
- // Conversion to type descriptors
- // ------------------------------------------------------------------------
- /**
- * Returns the descriptor corresponding to this Java type.
- *
- * @return the descriptor corresponding to this Java type.
- */
- public String getDescriptor() {
- StringBuffer buf = new StringBuffer();
- if (this.buf == null) {
- // descriptor is in byte 3 of 'off' for primitive types (buf == null)
- buf.append((char) ((off & 0xFF000000) >>> 24));
- } else if (sort == ARRAY) {
- buf.append(this.buf, off, len);
- } else { // sort == OBJECT
- buf.append('L');
- buf.append(this.buf, off, len);
- buf.append(';');
- }
- return buf.toString();
- }
- }