PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/asm/Type.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 331 lines | 122 code | 38 blank | 171 comment | 42 complexity | 79f86f6972f15cdc8092e32142ca96a2 MD5 | raw file
  1. /***
  2. * ASM: a very small and fast Java bytecode manipulation framework
  3. * Copyright (c) 2000-2007 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.alibaba.fastjson.asm;
  31. /**
  32. * A Java type. This class can be used to make it easier to manipulate type and method descriptors.
  33. *
  34. * @author Eric Bruneton
  35. * @author Chris Nokleberg
  36. */
  37. public class Type {
  38. /**
  39. * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
  40. */
  41. public static final int VOID = 0;
  42. /**
  43. * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
  44. */
  45. public static final int BOOLEAN = 1;
  46. /**
  47. * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
  48. */
  49. public static final int CHAR = 2;
  50. /**
  51. * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
  52. */
  53. public static final int BYTE = 3;
  54. /**
  55. * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
  56. */
  57. public static final int SHORT = 4;
  58. /**
  59. * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
  60. */
  61. public static final int INT = 5;
  62. /**
  63. * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
  64. */
  65. public static final int FLOAT = 6;
  66. /**
  67. * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
  68. */
  69. public static final int LONG = 7;
  70. /**
  71. * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
  72. */
  73. public static final int DOUBLE = 8;
  74. /**
  75. * The sort of array reference types. See {@link #getSort getSort}.
  76. */
  77. public static final int ARRAY = 9;
  78. /**
  79. * The sort of object reference type. See {@link #getSort getSort}.
  80. */
  81. public static final int OBJECT = 10;
  82. /**
  83. * The <tt>void</tt> type.
  84. */
  85. public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
  86. /**
  87. * The <tt>boolean</tt> type.
  88. */
  89. public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
  90. /**
  91. * The <tt>char</tt> type.
  92. */
  93. public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
  94. /**
  95. * The <tt>byte</tt> type.
  96. */
  97. public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
  98. /**
  99. * The <tt>short</tt> type.
  100. */
  101. public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
  102. /**
  103. * The <tt>int</tt> type.
  104. */
  105. public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
  106. /**
  107. * The <tt>float</tt> type.
  108. */
  109. public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
  110. /**
  111. * The <tt>long</tt> type.
  112. */
  113. public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
  114. /**
  115. * The <tt>double</tt> type.
  116. */
  117. public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
  118. // ------------------------------------------------------------------------
  119. // Fields
  120. // ------------------------------------------------------------------------
  121. /**
  122. * The sort of this Java type.
  123. */
  124. private final int sort;
  125. /**
  126. * A buffer containing the internal name of this Java type. This field is only used for reference types.
  127. */
  128. private final char[] buf;
  129. /**
  130. * The offset of the internal name of this Java type in {@link #buf buf} or, for primitive types, the size,
  131. * descriptor and getOpcode offsets for this type (byte 0 contains the size, byte 1 the descriptor, byte 2 the
  132. * offset for IALOAD or IASTORE, byte 3 the offset for all other instructions).
  133. */
  134. private final int off;
  135. /**
  136. * The length of the internal name of this Java type.
  137. */
  138. private final int len;
  139. // ------------------------------------------------------------------------
  140. // Constructors
  141. // ------------------------------------------------------------------------
  142. /**
  143. * Constructs a reference type.
  144. *
  145. * @param sort the sort of the reference type to be constructed.
  146. * @param buf a buffer containing the descriptor of the previous type.
  147. * @param off the offset of this descriptor in the previous buffer.
  148. * @param len the length of this descriptor.
  149. */
  150. private Type(final int sort, final char[] buf, final int off, final int len){
  151. this.sort = sort;
  152. this.buf = buf;
  153. this.off = off;
  154. this.len = len;
  155. }
  156. /**
  157. * Returns the Java type corresponding to the given type descriptor.
  158. *
  159. * @param typeDescriptor a type descriptor.
  160. * @return the Java type corresponding to the given type descriptor.
  161. */
  162. public static Type getType(final String typeDescriptor) {
  163. return getType(typeDescriptor.toCharArray(), 0);
  164. }
  165. /**
  166. * Computes the size of the arguments and of the return value of a method.
  167. *
  168. * @param desc the descriptor of a method.
  169. * @return the size of the arguments of the method (plus one for the implicit this argument), argSize, and the size
  170. * of its return value, retSize, packed into a single int i = <tt>(argSize << 2) | retSize</tt> (argSize is
  171. * therefore equal to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
  172. */
  173. public static int getArgumentsAndReturnSizes(final String desc) {
  174. int n = 1;
  175. int c = 1;
  176. while (true) {
  177. char car = desc.charAt(c++);
  178. if (car == ')') {
  179. car = desc.charAt(c);
  180. return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
  181. } else if (car == 'L') {
  182. while (desc.charAt(c++) != ';') {
  183. }
  184. n += 1;
  185. } else if (car == '[') {
  186. while ((car = desc.charAt(c)) == '[') {
  187. ++c;
  188. }
  189. if (car == 'D' || car == 'J') {
  190. n -= 1;
  191. }
  192. } else if (car == 'D' || car == 'J') {
  193. n += 2;
  194. } else {
  195. n += 1;
  196. }
  197. }
  198. }
  199. /**
  200. * Returns the Java type corresponding to the given type descriptor.
  201. *
  202. * @param buf a buffer containing a type descriptor.
  203. * @param off the offset of this descriptor in the previous buffer.
  204. * @return the Java type corresponding to the given type descriptor.
  205. */
  206. private static Type getType(final char[] buf, final int off) {
  207. int len;
  208. switch (buf[off]) {
  209. case 'V':
  210. return VOID_TYPE;
  211. case 'Z':
  212. return BOOLEAN_TYPE;
  213. case 'C':
  214. return CHAR_TYPE;
  215. case 'B':
  216. return BYTE_TYPE;
  217. case 'S':
  218. return SHORT_TYPE;
  219. case 'I':
  220. return INT_TYPE;
  221. case 'F':
  222. return FLOAT_TYPE;
  223. case 'J':
  224. return LONG_TYPE;
  225. case 'D':
  226. return DOUBLE_TYPE;
  227. case '[':
  228. len = 1;
  229. while (buf[off + len] == '[') {
  230. ++len;
  231. }
  232. if (buf[off + len] == 'L') {
  233. ++len;
  234. while (buf[off + len] != ';') {
  235. ++len;
  236. }
  237. }
  238. return new Type(ARRAY, buf, off, len + 1);
  239. // case 'L':
  240. default:
  241. len = 1;
  242. while (buf[off + len] != ';') {
  243. ++len;
  244. }
  245. return new Type(OBJECT, buf, off + 1, len - 1);
  246. }
  247. }
  248. // ------------------------------------------------------------------------
  249. // Accessors
  250. // ------------------------------------------------------------------------
  251. /**
  252. * Returns the sort of this Java type.
  253. *
  254. * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT
  255. * SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY}
  256. * or {@link #OBJECT OBJECT}.
  257. */
  258. public int getSort() {
  259. return sort;
  260. }
  261. /**
  262. * Returns the internal name of the class corresponding to this object or array type. The internal name of a class
  263. * is its fully qualified name (as returned by Class.getName(), where '.' are replaced by '/'. This method should
  264. * only be used for an object or array type.
  265. *
  266. * @return the internal name of the class corresponding to this object type.
  267. */
  268. public String getInternalName() {
  269. return new String(buf, off, len);
  270. }
  271. // ------------------------------------------------------------------------
  272. // Conversion to type descriptors
  273. // ------------------------------------------------------------------------
  274. /**
  275. * Returns the descriptor corresponding to this Java type.
  276. *
  277. * @return the descriptor corresponding to this Java type.
  278. */
  279. public String getDescriptor() {
  280. StringBuffer buf = new StringBuffer();
  281. if (this.buf == null) {
  282. // descriptor is in byte 3 of 'off' for primitive types (buf == null)
  283. buf.append((char) ((off & 0xFF000000) >>> 24));
  284. } else if (sort == ARRAY) {
  285. buf.append(this.buf, off, len);
  286. } else { // sort == OBJECT
  287. buf.append('L');
  288. buf.append(this.buf, off, len);
  289. buf.append(';');
  290. }
  291. return buf.toString();
  292. }
  293. }