PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/com.amd.aparapi/src/java/com/amd/aparapi/ClassModel.java

http://aparapi.googlecode.com/
Java | 1873 lines | 1448 code | 326 blank | 99 comment | 186 complexity | 2db70388dceeb4ea73301753a7351d24 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. Copyright (c) 2010-2011, Advanced Micro Devices, Inc.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
  5. following conditions are met:
  6. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
  7. disclaimer.
  8. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
  9. disclaimer in the documentation and/or other materials provided with the distribution.
  10. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
  11. derived from this software without specific prior written permission.
  12. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  13. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  14. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  15. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  16. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  17. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  18. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  19. If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export
  20. laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 through
  21. 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR,
  22. you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of
  23. Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration
  24. Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1,
  25. E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups
  26. D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject
  27. to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774
  28. of EAR). For the most current Country Group listings, or for additional information about the EAR or your obligations
  29. under those regulations, please refer to the U.S. Bureau of Industry and Security's website at http://www.bis.doc.gov/.
  30. */
  31. package com.amd.aparapi;
  32. import java.util.ArrayList;
  33. import java.util.Iterator;
  34. import java.util.List;
  35. import java.util.Stack;
  36. import java.util.logging.Level;
  37. import java.util.logging.Logger;
  38. import com.amd.aparapi.ClassModel.AttributePool.CodeEntry;
  39. import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry;
  40. import com.amd.aparapi.ClassModel.ConstantPool.FieldEntry;
  41. import com.amd.aparapi.ClassModel.ConstantPool.MethodEntry;
  42. import com.amd.aparapi.InstructionSet.TypeSpec;
  43. /**
  44. * Class represents a ClassFile (MyClass.class).
  45. *
  46. * A ClassModel is constructed from an instance of a <code>java.lang.Class</code>.
  47. *
  48. * If the java class mode changes we may need to modify this to accommodate.
  49. *
  50. * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf">Java 5 Class File Format</a>
  51. *
  52. * @author gfrost
  53. *
  54. */
  55. class ClassModel{
  56. static final char SIGC_VOID = 'V';
  57. static final char SIGC_BOOLEAN = 'Z';
  58. static final char SIGC_BYTE = 'B';
  59. static final char SIGC_CHAR = 'C';
  60. static final char SIGC_SHORT = 'S';
  61. static final char SIGC_INT = 'I';
  62. static final char SIGC_LONG = 'J';
  63. static final char SIGC_FLOAT = 'F';
  64. static final char SIGC_DOUBLE = 'D';
  65. static final char SIGC_ARRAY = '[';
  66. static final char SIGC_CLASS = 'L';
  67. static final char SIGC_START_METHOD = '(';
  68. static final char SIGC_END_CLASS = ';';
  69. static final char SIGC_END_METHOD = ')';
  70. static final char SIGC_PACKAGE = '/';
  71. private static Logger logger = Logger.getLogger(Config.getLoggerName());
  72. private ClassModel superClazz = null;
  73. /**
  74. * Create a ClassModel representing a given Class.
  75. *
  76. * The class's classfile must be available from the class's classloader via <code>getClassLoader().getResourceAsStream(name))</code>.
  77. * For dynamic languages creating classes on the fly we may need another approach.
  78. *
  79. * @param _class The class we will extract the model from
  80. * @throws ClassParseException
  81. */
  82. ClassModel(Class<?> _class) throws ClassParseException {
  83. parse(_class);
  84. Class<?> mySuper = _class.getSuperclass();
  85. // Find better way to do this check
  86. // The java.lang.Object test is for unit test framework to succeed - should
  87. // not occur in normal use
  88. if ((mySuper != null) && (!mySuper.getName().equals(Kernel.class.getName()))
  89. && (!mySuper.getName().equals("java.lang.Object"))) {
  90. superClazz = new ClassModel(mySuper);
  91. }
  92. }
  93. /**
  94. * Determine if this is the superclass of some other named class.
  95. *
  96. * @param otherClassName The name of the class to compare against
  97. * @return true if 'this' a superclass of another named class
  98. */
  99. boolean isSuperClass(String otherClassName) {
  100. if (getClassWeAreModelling().getName().equals(otherClassName)) {
  101. return true;
  102. } else if (superClazz != null) {
  103. return superClazz.isSuperClass(otherClassName);
  104. } else {
  105. return false;
  106. }
  107. }
  108. /**
  109. * Determine if this is the superclass of some other class.
  110. *
  111. * @param otherClass The class to compare against
  112. * @return true if 'this' a superclass of another class
  113. */
  114. boolean isSuperClass(Class<?> other) {
  115. Class<?> s = other.getSuperclass();
  116. while (s != null) {
  117. if (this.getClassWeAreModelling() == s || (this.getClassWeAreModelling().getName().equals(s.getName()))) {
  118. return true;
  119. }
  120. s = s.getSuperclass();
  121. }
  122. return false;
  123. }
  124. /**
  125. * Getter for superClazz
  126. *
  127. * @return the superClazz ClassModel
  128. */
  129. ClassModel getSuperClazz() {
  130. return superClazz;
  131. }
  132. @Annotations.DocMe void replaceSuperClazz(ClassModel c) {
  133. if (this.superClazz != null) {
  134. assert c.isSuperClass(this.getClassWeAreModelling()) == true : "not my super";
  135. if (this.superClazz.getClassWeAreModelling().getName().equals(c.getClassWeAreModelling().getName())) {
  136. this.superClazz = c;
  137. } else {
  138. this.superClazz.replaceSuperClazz(c);
  139. }
  140. }
  141. }
  142. /**
  143. * Convert a given JNI character type (say 'I') to its type name ('int').
  144. *
  145. * @param _typeChar
  146. * @return either a mapped type name or null if no mapping exists.
  147. */
  148. static String typeName(char _typeChar) {
  149. String returnName = null;
  150. switch (_typeChar) {
  151. case SIGC_VOID:
  152. returnName = "void";
  153. break;
  154. case SIGC_INT:
  155. returnName = "int";
  156. break;
  157. case SIGC_DOUBLE:
  158. returnName = "double";
  159. break;
  160. case SIGC_FLOAT:
  161. returnName = "float";
  162. break;
  163. case SIGC_SHORT:
  164. returnName = "short";
  165. break;
  166. case SIGC_CHAR:
  167. returnName = "char";
  168. break;
  169. case SIGC_BYTE:
  170. returnName = "byte";
  171. break;
  172. case SIGC_LONG:
  173. returnName = "long";
  174. break;
  175. case SIGC_BOOLEAN:
  176. returnName = "boolean";
  177. break;
  178. }
  179. return (returnName);
  180. }
  181. static String convert(String _string) {
  182. return (convert(_string, "", false));
  183. }
  184. static String convert(String _string, String _insert) {
  185. return (convert(_string, _insert, false));
  186. }
  187. static String convert(String _string, String _insert, boolean _showFullClassName) {
  188. Stack<String> stringStack = new Stack<String>();
  189. Stack<String> methodStack = null;
  190. int length = _string.length();
  191. char[] chars = _string.toCharArray();
  192. int i = 0;
  193. boolean inArray = false;
  194. boolean inMethod = false;
  195. boolean inArgs = false;
  196. int args = 0;
  197. while (i < length) {
  198. switch (chars[i]) {
  199. case SIGC_CLASS: {
  200. StringBuilder classNameBuffer = new StringBuilder();
  201. i++;
  202. while ((i < length) && chars[i] != SIGC_END_CLASS) {
  203. if (chars[i] == SIGC_PACKAGE) {
  204. classNameBuffer.append('.');
  205. } else {
  206. classNameBuffer.append(chars[i]);
  207. }
  208. i++;
  209. }
  210. i++; // step over SIGC_ENDCLASS
  211. String className = classNameBuffer.toString();
  212. if (_showFullClassName) {
  213. if (className.startsWith("java.lang")) {
  214. className = className.substring("java.lang.".length());
  215. }
  216. } else {
  217. int lastDot = className.lastIndexOf('.');
  218. if (lastDot > 0) {
  219. className = className.substring(lastDot + 1);
  220. }
  221. }
  222. if (inArray) {
  223. // swap the stack items
  224. String popped = stringStack.pop();
  225. if (inArgs && args > 0) {
  226. stringStack.push(", ");
  227. }
  228. stringStack.push(className);
  229. stringStack.push(popped);
  230. inArray = false;
  231. } else {
  232. if (inArgs && args > 0) {
  233. stringStack.push(", ");
  234. }
  235. stringStack.push(className);
  236. }
  237. args++;
  238. }
  239. break;
  240. case SIGC_ARRAY: {
  241. StringBuilder arrayDims = new StringBuilder();
  242. while ((i < length) && chars[i] == SIGC_ARRAY) {
  243. arrayDims.append("[]");
  244. i++;
  245. }
  246. stringStack.push(arrayDims.toString());
  247. inArray = true;
  248. }
  249. break;
  250. case SIGC_VOID:
  251. case SIGC_INT:
  252. case SIGC_DOUBLE:
  253. case SIGC_FLOAT:
  254. case SIGC_SHORT:
  255. case SIGC_CHAR:
  256. case SIGC_BYTE:
  257. case SIGC_LONG:
  258. case SIGC_BOOLEAN: {
  259. if (inArray) {
  260. // swap the stack items
  261. String popped = stringStack.pop();
  262. if (inArgs && args > 0) {
  263. stringStack.push(", ");
  264. }
  265. stringStack.push(typeName(chars[i]));
  266. stringStack.push(popped);
  267. inArray = false;
  268. } else {
  269. if (inArgs && args > 0) {
  270. stringStack.push(", ");
  271. }
  272. stringStack.push(typeName(chars[i]));
  273. }
  274. i++; // step over this
  275. }
  276. break;
  277. case SIGC_START_METHOD: {
  278. stringStack.push("(");
  279. i++; // step over this
  280. inArgs = true;
  281. args = 0;
  282. }
  283. break;
  284. case SIGC_END_METHOD: {
  285. inMethod = true;
  286. inArgs = false;
  287. stringStack.push(")");
  288. methodStack = stringStack;
  289. stringStack = new Stack<String>();
  290. i++; // step over this
  291. }
  292. break;
  293. }
  294. }
  295. StringBuilder returnValue = new StringBuilder();
  296. for (String s : stringStack) {
  297. returnValue.append(s);
  298. returnValue.append(" ");
  299. }
  300. if (inMethod) {
  301. for (String s : methodStack) {
  302. returnValue.append(s);
  303. returnValue.append(" ");
  304. }
  305. } else {
  306. returnValue.append(_insert);
  307. }
  308. return (returnValue.toString());
  309. }
  310. static class MethodDescription{
  311. private String className;
  312. private String methodName;
  313. private String type;
  314. private String[] args;
  315. MethodDescription(String _className, String _methodName, String _type, String[] _args) {
  316. methodName = _methodName;
  317. className = _className;
  318. type = _type;
  319. args = _args;
  320. }
  321. String[] getArgs() {
  322. return (args);
  323. }
  324. String getType() {
  325. return (type);
  326. }
  327. String getClassName() {
  328. return (className);
  329. }
  330. String getMethodName() {
  331. return (methodName);
  332. }
  333. }
  334. static MethodDescription getMethodDescription(String _string) {
  335. String className = null;
  336. String methodName = null;
  337. String descriptor = null;
  338. MethodDescription methodDescription = null;
  339. if (_string.startsWith("(")) {
  340. className = "?";
  341. methodName = "?";
  342. descriptor = _string;
  343. } else {
  344. int parenIndex = _string.indexOf("(");
  345. int dotIndex = _string.indexOf(".");
  346. descriptor = _string.substring(parenIndex);
  347. className = _string.substring(0, dotIndex);
  348. methodName = _string.substring(dotIndex + 1, parenIndex);
  349. }
  350. Stack<String> stringStack = new Stack<String>();
  351. Stack<String> methodStack = null;
  352. int length = descriptor.length();
  353. char[] chars = new char[descriptor.length()];
  354. descriptor.getChars(0, descriptor.length(), chars, 0);
  355. int i = 0;
  356. boolean inArray = false;
  357. boolean inMethod = false;
  358. while (i < length) {
  359. switch (chars[i]) {
  360. case SIGC_CLASS: {
  361. StringBuilder stringBuffer = null;
  362. if (inArray) {
  363. stringBuffer = new StringBuilder(stringStack.pop());
  364. } else {
  365. stringBuffer = new StringBuilder();
  366. }
  367. while ((i < length) && chars[i] != SIGC_END_CLASS) {
  368. stringBuffer.append(chars[i]);
  369. i++;
  370. }
  371. stringBuffer.append(chars[i]);
  372. i++; // step over SIGC_ENDCLASS
  373. stringStack.push(stringBuffer.toString());
  374. inArray = false;
  375. }
  376. break;
  377. case SIGC_ARRAY: {
  378. StringBuilder stringBuffer = new StringBuilder();
  379. while ((i < length) && chars[i] == SIGC_ARRAY) {
  380. stringBuffer.append(chars[i]);
  381. i++;
  382. }
  383. stringStack.push(stringBuffer.toString());
  384. inArray = true;
  385. }
  386. break;
  387. case SIGC_VOID:
  388. case SIGC_INT:
  389. case SIGC_DOUBLE:
  390. case SIGC_FLOAT:
  391. case SIGC_SHORT:
  392. case SIGC_CHAR:
  393. case SIGC_BYTE:
  394. case SIGC_LONG:
  395. case SIGC_BOOLEAN: {
  396. StringBuilder stringBuffer = null;
  397. if (inArray) {
  398. stringBuffer = new StringBuilder(stringStack.pop());
  399. } else {
  400. stringBuffer = new StringBuilder();
  401. }
  402. stringBuffer.append(chars[i]);
  403. i++; // step over this
  404. stringStack.push(stringBuffer.toString());
  405. inArray = false;
  406. }
  407. break;
  408. case SIGC_START_METHOD: {
  409. i++; // step over this
  410. }
  411. break;
  412. case SIGC_END_METHOD: {
  413. inMethod = true;
  414. inArray = false;
  415. methodStack = stringStack;
  416. stringStack = new Stack<String>();
  417. i++; // step over this
  418. }
  419. break;
  420. }
  421. }
  422. if (inMethod) {
  423. methodDescription = new MethodDescription(className, methodName, stringStack.toArray(new String[0])[0], methodStack
  424. .toArray(new String[0]));
  425. } else {
  426. System.out.println("can't convert to a description");
  427. }
  428. return (methodDescription);
  429. }
  430. private int magic;
  431. private int minorVersion;
  432. private int majorVersion;
  433. private ConstantPool constantPool;
  434. private int accessFlags;
  435. private int thisClassConstantPoolIndex;
  436. private int superClassConstantPoolIndex;
  437. private List<ClassModelInterface> interfaces = new ArrayList<ClassModelInterface>();
  438. private List<ClassModelField> fields = new ArrayList<ClassModelField>();
  439. private List<ClassModelMethod> methods = new ArrayList<ClassModelMethod>();
  440. private AttributePool attributePool;
  441. enum ConstantPoolType {
  442. EMPTY,
  443. UTF8,
  444. UNICODE,
  445. INTEGER,
  446. FLOAT,
  447. LONG,
  448. DOUBLE,
  449. CLASS,
  450. STRING,
  451. FIELD,
  452. METHOD,
  453. INTERFACEMETHOD,
  454. NAMEANDTYPE
  455. };
  456. enum Access {
  457. PUBLIC(0x00000001),
  458. PRIVATE(0x00000002),
  459. PROTECTED(0x00000004),
  460. STATIC(0x00000008),
  461. FINAL(0x00000010),
  462. ACC_SYNCHRONIZED(0x00000020),
  463. ACC_VOLATILE(0x00000040),
  464. BRIDGE(0x00000040),
  465. TRANSIENT(0x00000080),
  466. VARARGS(0x00000080),
  467. NATIVE(0x00000100),
  468. INTERFACE(0x00000200),
  469. ABSTRACT(0x00000400),
  470. SUPER(0x00000020),
  471. STRICT(0x00000800),
  472. ANNOTATION(0x00002000),
  473. ACC_ENUM(0x00004000);
  474. int bits;
  475. Access(int _bits) {
  476. bits = _bits;
  477. }
  478. boolean bitIsSet(int _accessFlags) {
  479. return ((bits & _accessFlags) == bits);
  480. }
  481. String convert(int _accessFlags) {
  482. StringBuffer stringBuffer = new StringBuffer();
  483. for (Access access : Access.values()) {
  484. if (access.bitIsSet(_accessFlags)) {
  485. stringBuffer.append(" " + access.name().toLowerCase());
  486. }
  487. }
  488. return (stringBuffer.toString());
  489. }
  490. }
  491. private static enum SignatureParseState {
  492. skipping,
  493. counting,
  494. inclass,
  495. inArray,
  496. done;
  497. };
  498. class ConstantPool implements Iterable<ConstantPool.Entry>{
  499. private List<Entry> entries = new ArrayList<Entry>();
  500. abstract class Entry{
  501. private ConstantPoolType constantPoolType;
  502. private int slot;
  503. Entry(ByteReader _byteReader, int _slot, ConstantPoolType _constantPoolType) {
  504. constantPoolType = _constantPoolType;
  505. slot = _slot;
  506. }
  507. ConstantPoolType getConstantPoolType() {
  508. return (constantPoolType);
  509. }
  510. int getSlot() {
  511. return (slot);
  512. }
  513. }
  514. class ClassEntry extends Entry{
  515. private int nameIndex;
  516. ClassEntry(ByteReader _byteReader, int _slot) {
  517. super(_byteReader, _slot, ConstantPoolType.CLASS);
  518. nameIndex = _byteReader.u2();
  519. }
  520. int getNameIndex() {
  521. return (nameIndex);
  522. }
  523. UTF8Entry getNameUTF8Entry() {
  524. return (ConstantPool.this.getUTF8Entry(nameIndex));
  525. }
  526. }
  527. class DoubleEntry extends Entry{
  528. private double doubleValue;
  529. DoubleEntry(ByteReader _byteReader, int _slot) {
  530. super(_byteReader, _slot, ConstantPoolType.DOUBLE);
  531. doubleValue = _byteReader.d8();
  532. }
  533. double getDoubleValue() {
  534. return (doubleValue);
  535. }
  536. }
  537. class EmptyEntry extends Entry{
  538. EmptyEntry(ByteReader _byteReader, int _slot) {
  539. super(_byteReader, _slot, ConstantPoolType.EMPTY);
  540. }
  541. }
  542. class FieldEntry extends ReferenceEntry{
  543. FieldEntry(ByteReader _byteReader, int _slot) {
  544. super(_byteReader, _slot, ConstantPoolType.FIELD);
  545. }
  546. }
  547. class FloatEntry extends Entry{
  548. private float floatValue;
  549. FloatEntry(ByteReader _byteReader, int _slot) {
  550. super(_byteReader, _slot, ConstantPoolType.FLOAT);
  551. floatValue = _byteReader.f4();
  552. }
  553. float getFloatValue() {
  554. return (floatValue);
  555. }
  556. }
  557. class IntegerEntry extends Entry{
  558. private int intValue;
  559. IntegerEntry(ByteReader _byteReader, int _slot) {
  560. super(_byteReader, _slot, ConstantPoolType.INTEGER);
  561. intValue = _byteReader.u4();
  562. }
  563. int getIntValue() {
  564. return (intValue);
  565. }
  566. }
  567. class InterfaceMethodEntry extends MethodReferenceEntry{
  568. InterfaceMethodEntry(ByteReader _byteReader, int _slot) {
  569. super(_byteReader, _slot, ConstantPoolType.INTERFACEMETHOD);
  570. }
  571. }
  572. class LongEntry extends Entry{
  573. private long longValue;
  574. LongEntry(ByteReader _byteReader, int _slot) {
  575. super(_byteReader, _slot, ConstantPoolType.LONG);
  576. longValue = _byteReader.u8();
  577. }
  578. long getLongValue() {
  579. return (longValue);
  580. }
  581. }
  582. class MethodEntry extends MethodReferenceEntry{
  583. MethodEntry(ByteReader _byteReader, int _slot) {
  584. super(_byteReader, _slot, ConstantPoolType.METHOD);
  585. }
  586. @Override public String toString() {
  587. StringBuilder sb = new StringBuilder();
  588. sb.append(getClassEntry().getNameUTF8Entry().getUTF8());
  589. sb.append(".");
  590. sb.append(getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
  591. sb.append(getNameAndTypeEntry().getDescriptorUTF8Entry().getUTF8());
  592. return (sb.toString());
  593. }
  594. }
  595. class NameAndTypeEntry extends Entry{
  596. private int descriptorIndex;
  597. private int nameIndex;
  598. NameAndTypeEntry(ByteReader _byteReader, int _slot) {
  599. super(_byteReader, _slot, ConstantPoolType.NAMEANDTYPE);
  600. nameIndex = _byteReader.u2();
  601. descriptorIndex = _byteReader.u2();
  602. }
  603. int getDescriptorIndex() {
  604. return (descriptorIndex);
  605. }
  606. UTF8Entry getDescriptorUTF8Entry() {
  607. return (ConstantPool.this.getUTF8Entry(descriptorIndex));
  608. }
  609. int getNameIndex() {
  610. return (nameIndex);
  611. }
  612. UTF8Entry getNameUTF8Entry() {
  613. return (ConstantPool.this.getUTF8Entry(nameIndex));
  614. }
  615. }
  616. abstract class MethodReferenceEntry extends ReferenceEntry{
  617. class Arg extends Type{
  618. Arg(String _signature, int _start, int _pos, int _argc) {
  619. super(_signature.substring(_start, _pos + 1));
  620. argc = _argc;
  621. }
  622. private int argc;
  623. int getArgc() {
  624. return (argc);
  625. }
  626. }
  627. private Arg[] args = null;
  628. private Type returnType = null;
  629. @Override public int hashCode() {
  630. NameAndTypeEntry nameAndTypeEntry = getNameAndTypeEntry();
  631. return ((nameAndTypeEntry.getNameIndex() * 31 + nameAndTypeEntry.getDescriptorIndex()) * 31 + getClassIndex());
  632. }
  633. @Override public boolean equals(Object _other) {
  634. if (_other == null || !(_other instanceof MethodReferenceEntry)) {
  635. return (false);
  636. } else {
  637. MethodReferenceEntry otherMethodReferenceEntry = (MethodReferenceEntry) _other;
  638. return (otherMethodReferenceEntry.getNameAndTypeEntry().getNameIndex() == getNameAndTypeEntry().getNameIndex()
  639. && otherMethodReferenceEntry.getNameAndTypeEntry().getDescriptorIndex() == getNameAndTypeEntry()
  640. .getDescriptorIndex() && otherMethodReferenceEntry.getClassIndex() == getClassIndex());
  641. }
  642. }
  643. MethodReferenceEntry(ByteReader byteReader, int slot, ConstantPoolType constantPoolType) {
  644. super(byteReader, slot, constantPoolType);
  645. }
  646. int getStackProduceCount() {
  647. return (getReturnType().isVoid() ? 0 : 1);
  648. }
  649. Type getReturnType() {
  650. if (returnType == null) {
  651. getArgs();
  652. }
  653. return (returnType);
  654. }
  655. Arg[] getArgs() {
  656. if (args == null || returnType == null) {
  657. List<Arg> argList = new ArrayList<Arg>();
  658. NameAndTypeEntry nameAndTypeEntry = getNameAndTypeEntry();
  659. String signature = nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8();// "([[IF)V" for a method that takes an int[][], float and returns void.
  660. // Sadly we need to parse this, we need the # of arguments for the call
  661. SignatureParseState state = SignatureParseState.skipping;
  662. int start = 0;
  663. for (int pos = 0; state != SignatureParseState.done; pos++) {
  664. char ch = signature.charAt(pos);
  665. switch (ch) {
  666. case '(':
  667. state = SignatureParseState.counting;
  668. break;
  669. case ')':
  670. state = SignatureParseState.done;
  671. returnType = new Type(signature.substring(pos + 1));
  672. break;
  673. case '[':
  674. switch (state) {
  675. case counting:
  676. state = SignatureParseState.inArray;
  677. start = pos;
  678. break;
  679. }
  680. // we don't care about arrays
  681. break;
  682. case 'L':
  683. // beginning of Ljava/lang/String; or something
  684. switch (state) {
  685. case counting:
  686. start = pos;
  687. // fallthrough intended!!
  688. case inArray:
  689. state = SignatureParseState.inclass;
  690. break;
  691. }
  692. break;
  693. case ';':
  694. // note we will only be in 'inclass' if we were previously counting, so this is safe
  695. switch (state) {
  696. case inclass:
  697. argList.add(new Arg(signature, start, pos, argList.size()));
  698. state = SignatureParseState.counting;
  699. break;
  700. }
  701. break;
  702. default:
  703. // we have IJBZDF so inc counter if we are still counting
  704. switch (state) {
  705. case counting:
  706. start = pos;
  707. // fallthrough intended!!
  708. case inArray:
  709. argList.add(new Arg(signature, start, pos, argList.size()));
  710. break;
  711. }
  712. break;
  713. }
  714. }
  715. // System.out.println("method "+name+" has signature of "+signature+" which has "+count+" args");
  716. args = argList.toArray(new Arg[0]);
  717. }
  718. return (args);
  719. }
  720. int getStackConsumeCount() {
  721. return (getArgs().length);
  722. }
  723. }
  724. abstract class ReferenceEntry extends Entry{
  725. protected int referenceClassIndex;
  726. protected int nameAndTypeIndex;
  727. protected int argCount = -1;
  728. ReferenceEntry(ByteReader _byteReader, int _slot, ConstantPoolType _constantPoolType) {
  729. super(_byteReader, _slot, _constantPoolType);
  730. referenceClassIndex = _byteReader.u2();
  731. nameAndTypeIndex = _byteReader.u2();
  732. }
  733. ClassEntry getClassEntry() {
  734. return (ConstantPool.this.getClassEntry(referenceClassIndex));
  735. }
  736. int getClassIndex() {
  737. return (referenceClassIndex);
  738. }
  739. NameAndTypeEntry getNameAndTypeEntry() {
  740. return (ConstantPool.this.getNameAndTypeEntry(nameAndTypeIndex));
  741. }
  742. int getNameAndTypeIndex() {
  743. return (nameAndTypeIndex);
  744. }
  745. boolean same(Entry _entry) {
  746. if (_entry instanceof ReferenceEntry) {
  747. ReferenceEntry entry = (ReferenceEntry) _entry;
  748. return ((referenceClassIndex == entry.referenceClassIndex) && (nameAndTypeIndex == entry.nameAndTypeIndex));
  749. }
  750. return (false);
  751. }
  752. class Type{
  753. private int arrayDimensions = 0;
  754. Type(String _type) {
  755. type = _type;
  756. while (type.charAt(arrayDimensions) == '[') {
  757. arrayDimensions++;
  758. }
  759. type = type.substring(arrayDimensions);
  760. }
  761. String getType() {
  762. return (type);
  763. }
  764. boolean isVoid() {
  765. return (type.equals("V"));
  766. }
  767. private String type;
  768. final boolean isArray() {
  769. return (arrayDimensions > 0);
  770. }
  771. final int getArrayDimensions() {
  772. return (arrayDimensions);
  773. }
  774. }
  775. }
  776. class StringEntry extends Entry{
  777. private int utf8Index;
  778. StringEntry(ByteReader _byteReader, int _slot) {
  779. super(_byteReader, _slot, ConstantPoolType.STRING);
  780. utf8Index = _byteReader.u2();
  781. }
  782. int getUTF8Index() {
  783. return (utf8Index);
  784. }
  785. UTF8Entry getStringUTF8Entry() {
  786. return (ConstantPool.this.getUTF8Entry(utf8Index));
  787. }
  788. }
  789. class UTF8Entry extends Entry{
  790. private String UTF8;
  791. UTF8Entry(ByteReader _byteReader, int _slot) {
  792. super(_byteReader, _slot, ConstantPoolType.UTF8);
  793. UTF8 = _byteReader.utf8();
  794. }
  795. String getUTF8() {
  796. return (UTF8);
  797. }
  798. }
  799. ConstantPool(ByteReader _byteReader) {
  800. int size = _byteReader.u2();
  801. add(new EmptyEntry(_byteReader, 0)); // slot 0
  802. for (int i = 1; i < size; i++) {
  803. ConstantPoolType constantPoolType = ConstantPoolType.values()[_byteReader.u1()];
  804. switch (constantPoolType) {
  805. case UTF8:
  806. add(new UTF8Entry(_byteReader, i));
  807. break;
  808. case INTEGER:
  809. add(new IntegerEntry(_byteReader, i));
  810. break;
  811. case FLOAT:
  812. add(new FloatEntry(_byteReader, i));
  813. break;
  814. case LONG:
  815. add(new LongEntry(_byteReader, i));
  816. i++;// Longs take two slots in the ConstantPool
  817. add(new EmptyEntry(_byteReader, i));
  818. break;
  819. case DOUBLE:
  820. add(new DoubleEntry(_byteReader, i));
  821. i++; // Doubles take two slots in the ConstantPool
  822. add(new EmptyEntry(_byteReader, i));
  823. break;
  824. case CLASS:
  825. add(new ClassEntry(_byteReader, i));
  826. break;
  827. case STRING:
  828. add(new StringEntry(_byteReader, i));
  829. break;
  830. case FIELD:
  831. add(new FieldEntry(_byteReader, i));
  832. break;
  833. case METHOD:
  834. add(new MethodEntry(_byteReader, i));
  835. break;
  836. case INTERFACEMETHOD:
  837. add(new InterfaceMethodEntry(_byteReader, i));
  838. break;
  839. case NAMEANDTYPE:
  840. add(new NameAndTypeEntry(_byteReader, i));
  841. break;
  842. default:
  843. System.out.printf("slot %04x unexpected Constant constantPoolType = %s\n", i, constantPoolType);
  844. }
  845. }
  846. }
  847. ClassEntry getClassEntry(int _index) {
  848. try {
  849. return ((ClassEntry) entries.get(_index));
  850. } catch (ClassCastException e) {
  851. return (null);
  852. }
  853. }
  854. DoubleEntry getDoubleEntry(int _index) {
  855. try {
  856. return ((DoubleEntry) entries.get(_index));
  857. } catch (ClassCastException e) {
  858. return (null);
  859. }
  860. }
  861. FieldEntry getFieldEntry(int _index) {
  862. try {
  863. return ((FieldEntry) entries.get(_index));
  864. } catch (ClassCastException e) {
  865. return (null);
  866. }
  867. }
  868. FloatEntry getFloatEntry(int _index) {
  869. try {
  870. return ((FloatEntry) entries.get(_index));
  871. } catch (ClassCastException e) {
  872. return (null);
  873. }
  874. }
  875. IntegerEntry getIntegerEntry(int _index) {
  876. try {
  877. return ((IntegerEntry) entries.get(_index));
  878. } catch (ClassCastException e) {
  879. return (null);
  880. }
  881. }
  882. InterfaceMethodEntry getInterfaceMethodEntry(int _index) {
  883. try {
  884. return ((InterfaceMethodEntry) entries.get(_index));
  885. } catch (ClassCastException e) {
  886. return (null);
  887. }
  888. }
  889. LongEntry getLongEntry(int _index) {
  890. try {
  891. return ((LongEntry) entries.get(_index));
  892. } catch (ClassCastException e) {
  893. return (null);
  894. }
  895. }
  896. MethodEntry getMethodEntry(int _index) {
  897. try {
  898. return ((MethodEntry) entries.get(_index));
  899. } catch (ClassCastException e) {
  900. return (null);
  901. }
  902. }
  903. NameAndTypeEntry getNameAndTypeEntry(int _index) {
  904. try {
  905. return ((NameAndTypeEntry) entries.get(_index));
  906. } catch (ClassCastException e) {
  907. return (null);
  908. }
  909. }
  910. StringEntry getStringEntry(int _index) {
  911. try {
  912. return ((StringEntry) entries.get(_index));
  913. } catch (ClassCastException e) {
  914. return (null);
  915. }
  916. }
  917. UTF8Entry getUTF8Entry(int _index) {
  918. try {
  919. return ((UTF8Entry) entries.get(_index));
  920. } catch (ClassCastException e) {
  921. return (null);
  922. }
  923. }
  924. void add(Entry _entry) {
  925. entries.add(_entry);
  926. }
  927. @Override public Iterator<Entry> iterator() {
  928. return (entries.iterator());
  929. }
  930. Entry get(int _index) {
  931. return (entries.get(_index));
  932. }
  933. String getDescription(ConstantPool.Entry _entry) {
  934. StringBuilder sb = new StringBuilder();
  935. if (_entry instanceof ConstantPool.EmptyEntry) {
  936. ;
  937. } else if (_entry instanceof ConstantPool.DoubleEntry) {
  938. ConstantPool.DoubleEntry doubleEntry = (ConstantPool.DoubleEntry) _entry;
  939. sb.append(doubleEntry.getDoubleValue());
  940. } else if (_entry instanceof ConstantPool.FloatEntry) {
  941. ConstantPool.FloatEntry floatEntry = (ConstantPool.FloatEntry) _entry;
  942. sb.append(floatEntry.getFloatValue());
  943. } else if (_entry instanceof ConstantPool.IntegerEntry) {
  944. ConstantPool.IntegerEntry integerEntry = (ConstantPool.IntegerEntry) _entry;
  945. sb.append(integerEntry.getIntValue());
  946. } else if (_entry instanceof ConstantPool.LongEntry) {
  947. ConstantPool.LongEntry longEntry = (ConstantPool.LongEntry) _entry;
  948. sb.append(longEntry.getLongValue());
  949. } else if (_entry instanceof ConstantPool.UTF8Entry) {
  950. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) _entry;
  951. sb.append(utf8Entry.getUTF8());
  952. } else if (_entry instanceof ConstantPool.StringEntry) {
  953. ConstantPool.StringEntry stringEntry = (ConstantPool.StringEntry) _entry;
  954. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(stringEntry.getUTF8Index());
  955. sb.append(utf8Entry.getUTF8());
  956. } else if (_entry instanceof ConstantPool.ClassEntry) {
  957. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) _entry;
  958. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  959. sb.append(utf8Entry.getUTF8());
  960. } else if (_entry instanceof ConstantPool.NameAndTypeEntry) {
  961. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) _entry;
  962. ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getNameIndex());
  963. ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getDescriptorIndex());
  964. sb.append(utf8NameEntry.getUTF8() + "." + utf8DescriptorEntry.getUTF8());
  965. } else if (_entry instanceof ConstantPool.MethodEntry) {
  966. ConstantPool.MethodEntry methodEntry = (ConstantPool.MethodEntry) _entry;
  967. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(methodEntry.getClassIndex());
  968. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  969. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(methodEntry.getNameAndTypeIndex());
  970. ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getNameIndex());
  971. ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getDescriptorIndex());
  972. sb.append(convert(utf8DescriptorEntry.getUTF8(), utf8Entry.getUTF8() + "." + utf8NameEntry.getUTF8()));
  973. } else if (_entry instanceof ConstantPool.InterfaceMethodEntry) {
  974. ConstantPool.InterfaceMethodEntry interfaceMethodEntry = (ConstantPool.InterfaceMethodEntry) _entry;
  975. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(interfaceMethodEntry.getClassIndex());
  976. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  977. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(interfaceMethodEntry
  978. .getNameAndTypeIndex());
  979. ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getNameIndex());
  980. ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getDescriptorIndex());
  981. sb.append(convert(utf8DescriptorEntry.getUTF8(), utf8Entry.getUTF8() + "." + utf8NameEntry.getUTF8()));
  982. } else if (_entry instanceof ConstantPool.FieldEntry) {
  983. ConstantPool.FieldEntry fieldEntry = (ConstantPool.FieldEntry) _entry;
  984. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(fieldEntry.getClassIndex());
  985. ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  986. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(fieldEntry.getNameAndTypeIndex());
  987. ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getNameIndex());
  988. ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry.getDescriptorIndex());
  989. sb.append(convert(utf8DescriptorEntry.getUTF8(), utf8Entry.getUTF8() + "." + utf8NameEntry.getUTF8()));
  990. }
  991. return (sb.toString());
  992. }
  993. int[] getConstantPoolReferences(ConstantPool.Entry _entry) {
  994. int[] references = new int[0];
  995. if (_entry instanceof ConstantPool.StringEntry) {
  996. ConstantPool.StringEntry stringEntry = (ConstantPool.StringEntry) _entry;
  997. references = new int[] {
  998. stringEntry.getUTF8Index()
  999. };
  1000. } else if (_entry instanceof ConstantPool.ClassEntry) {
  1001. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) _entry;
  1002. references = new int[] {
  1003. classEntry.getNameIndex()
  1004. };
  1005. } else if (_entry instanceof ConstantPool.NameAndTypeEntry) {
  1006. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) _entry;
  1007. references = new int[] {
  1008. nameAndTypeEntry.getNameIndex(),
  1009. nameAndTypeEntry.getDescriptorIndex()
  1010. };
  1011. } else if (_entry instanceof ConstantPool.MethodEntry) {
  1012. ConstantPool.MethodEntry methodEntry = (ConstantPool.MethodEntry) _entry;
  1013. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(methodEntry.getClassIndex());
  1014. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  1015. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(methodEntry.getNameAndTypeIndex());
  1016. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1017. .getNameIndex());
  1018. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1019. .getDescriptorIndex());
  1020. references = new int[] {
  1021. methodEntry.getClassIndex(),
  1022. classEntry.getNameIndex(),
  1023. nameAndTypeEntry.getNameIndex(),
  1024. nameAndTypeEntry.getDescriptorIndex()
  1025. };
  1026. } else if (_entry instanceof ConstantPool.InterfaceMethodEntry) {
  1027. ConstantPool.InterfaceMethodEntry interfaceMethodEntry = (ConstantPool.InterfaceMethodEntry) _entry;
  1028. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(interfaceMethodEntry.getClassIndex());
  1029. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  1030. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(interfaceMethodEntry
  1031. .getNameAndTypeIndex());
  1032. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1033. .getNameIndex());
  1034. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1035. .getDescriptorIndex());
  1036. references = new int[] {
  1037. interfaceMethodEntry.getClassIndex(),
  1038. classEntry.getNameIndex(),
  1039. nameAndTypeEntry.getNameIndex(),
  1040. nameAndTypeEntry.getDescriptorIndex()
  1041. };
  1042. } else if (_entry instanceof ConstantPool.FieldEntry) {
  1043. ConstantPool.FieldEntry fieldEntry = (ConstantPool.FieldEntry) _entry;
  1044. ConstantPool.ClassEntry classEntry = (ConstantPool.ClassEntry) get(fieldEntry.getClassIndex());
  1045. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8Entry = (ConstantPool.UTF8Entry) get(classEntry.getNameIndex());
  1046. ConstantPool.NameAndTypeEntry nameAndTypeEntry = (ConstantPool.NameAndTypeEntry) get(fieldEntry.getNameAndTypeIndex());
  1047. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8NameEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1048. .getNameIndex());
  1049. @SuppressWarnings("unused") ConstantPool.UTF8Entry utf8DescriptorEntry = (ConstantPool.UTF8Entry) get(nameAndTypeEntry
  1050. .getDescriptorIndex());
  1051. references = new int[] {
  1052. fieldEntry.getClassIndex(),
  1053. classEntry.getNameIndex(),
  1054. nameAndTypeEntry.getNameIndex(),
  1055. nameAndTypeEntry.getDescriptorIndex()
  1056. };
  1057. }
  1058. return (references);
  1059. }
  1060. String getType(ConstantPool.Entry _entry) {
  1061. StringBuffer sb = new StringBuffer();
  1062. if (_entry instanceof ConstantPool.EmptyEntry) {
  1063. sb.append("empty");
  1064. } else if (_entry instanceof ConstantPool.DoubleEntry) {
  1065. sb.append("double");
  1066. } else if (_entry instanceof ConstantPool.FloatEntry) {
  1067. sb.append("float");
  1068. } else if (_entry instanceof ConstantPool.IntegerEntry) {
  1069. sb.append("int");
  1070. } else if (_entry instanceof ConstantPool.LongEntry) {
  1071. sb.append("long");
  1072. } else if (_entry instanceof ConstantPool.UTF8Entry) {
  1073. sb.append("utf8");
  1074. } else if (_entry instanceof ConstantPool.StringEntry) {
  1075. sb.append("string");
  1076. } else if (_entry instanceof ConstantPool.ClassEntry) {
  1077. sb.append("class");
  1078. } else if (_entry instanceof ConstantPool.NameAndTypeEntry) {
  1079. sb.append("name/type");
  1080. } else if (_entry instanceof ConstantPool.MethodEntry) {
  1081. sb.append("method");
  1082. } else if (_entry instanceof ConstantPool.InterfaceMethodEntry) {
  1083. sb.append("interface method");
  1084. } else if (_entry instanceof ConstantPool.FieldEntry) {
  1085. sb.append("field");
  1086. }
  1087. return (sb.toString());
  1088. }
  1089. Object getConstantEntry(int _constantPoolIndex) {
  1090. Entry entry = get(_constantPoolIndex);
  1091. Object object = null;
  1092. switch (entry.getConstantPoolType()) {
  1093. case FLOAT:
  1094. object = ((FloatEntry) entry).getFloatValue();
  1095. break;
  1096. case DOUBLE:
  1097. object = ((DoubleEntry) entry).getDoubleValue();
  1098. break;
  1099. case INTEGER:
  1100. object = ((IntegerEntry) entry).getIntValue();
  1101. break;
  1102. case LONG:
  1103. object = ((LongEntry) entry).getLongValue();
  1104. break;
  1105. case STRING:
  1106. object = ((StringEntry) entry).getStringUTF8Entry().getUTF8();
  1107. break;
  1108. }
  1109. return (object);
  1110. }
  1111. }
  1112. class AttributePool{
  1113. private List<AttributePoolEntry> attributePoolEntries = new ArrayList<AttributePoolEntry>();
  1114. class CodeEntry extends AttributePoolEntry{
  1115. class ExceptionPoolEntry{
  1116. private int exceptionClassIndex;
  1117. private int end;
  1118. private int handler;
  1119. private int start;
  1120. ExceptionPoolEntry(ByteReader _byteReader) {
  1121. start = _byteReader.u2();
  1122. end = _byteReader.u2();
  1123. handler = _byteReader.u2();
  1124. exceptionClassIndex = _byteReader.u2();
  1125. }
  1126. ConstantPool.ClassEntry getClassEntry() {
  1127. return (constantPool.getClassEntry(exceptionClassIndex));
  1128. }
  1129. int getClassIndex() {
  1130. return (exceptionClassIndex);
  1131. }
  1132. int getEnd() {
  1133. return (end);
  1134. }
  1135. int getHandler() {
  1136. return (handler);
  1137. }
  1138. int getStart() {
  1139. return (start);
  1140. }
  1141. }
  1142. private List<ExceptionPoolEntry> exceptionPoolEntries = new ArrayList<ExceptionPoolEntry>();
  1143. private AttributePool codeEntryAttributePool;
  1144. private byte[] code;
  1145. private int maxLocals;
  1146. private int maxStack;
  1147. CodeEntry(ByteReader _byteReader, int _nameIndex, int _length) {
  1148. super(_byteReader, _nameIndex, _length);
  1149. maxStack = _byteReader.u2();
  1150. maxLocals = _byteReader.u2();
  1151. int codeLength = _byteReader.u4();
  1152. code = _byteReader.bytes(codeLength);
  1153. int exceptionTableLength = _byteReader.u2();
  1154. for (int i = 0; i < exceptionTableLength; i++) {
  1155. exceptionPoolEntries.add(new ExceptionPoolEntry(_byteReader));
  1156. }
  1157. codeEntryAttributePool = new AttributePool(_byteReader);
  1158. }
  1159. @Override AttributePool getAttributePool() {
  1160. return (codeEntryAttributePool);
  1161. }
  1162. LineNumberTableEntry getLineNumberTableEntry() {
  1163. return (codeEntryAttributePo

Large files files are truncated, but you can click here to view the full file