1. package com.sun.org.apache.bcel.internal.generic;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <http://www.apache.org/>.
  54. */
  55. import com.sun.org.apache.bcel.internal.Constants;
  56. /**
  57. * Instances of this class may be used, e.g., to generate typed
  58. * versions of instructions. Its main purpose is to be used as the
  59. * byte code generating backend of a compiler. You can subclass it to
  60. * add your own create methods.
  61. *
  62. * @version $Id: InstructionFactory.java,v 1.1.1.1 2001/10/29 20:00:19 jvanzyl Exp $
  63. * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  64. * @see Constants
  65. */
  66. public class InstructionFactory implements InstructionConstants {
  67. protected ClassGen cg;
  68. protected ConstantPoolGen cp;
  69. public InstructionFactory(ClassGen cg, ConstantPoolGen cp) {
  70. this.cg = cg;
  71. this.cp = cp;
  72. }
  73. /** Initialize with ClassGen object
  74. */
  75. public InstructionFactory(ClassGen cg) {
  76. this(cg, cg.getConstantPool());
  77. }
  78. /** Initialize just with ConstantPoolGen object
  79. */
  80. public InstructionFactory(ConstantPoolGen cp) {
  81. this(null, cp);
  82. }
  83. /** Create an invoke instruction.
  84. *
  85. * @param class_name name of the called class
  86. * @param name name of the called method
  87. * @param ret_type return type of method
  88. * @param arg_types argument types of method
  89. * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL,
  90. * or INVOKESPECIAL
  91. * @see Constants
  92. */
  93. public InvokeInstruction createInvoke(String class_name, String name, Type ret_type,
  94. Type[] arg_types, short kind) {
  95. int index;
  96. int nargs = 0;
  97. String signature = Type.getMethodSignature(ret_type, arg_types);
  98. for(int i=0; i < arg_types.length; i++) // Count size of arguments
  99. nargs += arg_types[i].getSize();
  100. if(kind == Constants.INVOKEINTERFACE)
  101. index = cp.addInterfaceMethodref(class_name, name, signature);
  102. else
  103. index = cp.addMethodref(class_name, name, signature);
  104. switch(kind) {
  105. case Constants.INVOKESPECIAL: return new INVOKESPECIAL(index);
  106. case Constants.INVOKEVIRTUAL: return new INVOKEVIRTUAL(index);
  107. case Constants.INVOKESTATIC: return new INVOKESTATIC(index);
  108. case Constants.INVOKEINTERFACE: return new INVOKEINTERFACE(index, nargs + 1);
  109. default:
  110. throw new RuntimeException("Oops: Unknown invoke kind:" + kind);
  111. }
  112. }
  113. /** Create a call to the most popular System.out.println() method.
  114. *
  115. * @param s the string to print
  116. */
  117. public InstructionList createPrintln(String s) {
  118. InstructionList il = new InstructionList();
  119. int out = cp.addFieldref("java.lang.System", "out",
  120. "Ljava/io/PrintStream;");
  121. int println = cp.addMethodref("java.io.PrintStream", "println",
  122. "(Ljava/lang/String;)V");
  123. il.append(new GETSTATIC(out));
  124. il.append(new PUSH(cp, s));
  125. il.append(new INVOKEVIRTUAL(println));
  126. return il;
  127. }
  128. private static class MethodObject {
  129. Type[] arg_types;
  130. Type result_type;
  131. String[] arg_names;
  132. String class_name;
  133. String name;
  134. int access;
  135. MethodObject(String c, String n, Type r, Type[] a, int acc) {
  136. class_name = c;
  137. name = n;
  138. result_type = r;
  139. arg_types = a;
  140. access = acc;
  141. }
  142. }
  143. private InvokeInstruction createInvoke(MethodObject m, short kind) {
  144. return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind);
  145. }
  146. private static MethodObject[] append_mos = {
  147. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  148. new Type[] { Type.STRING }, Constants.ACC_PUBLIC),
  149. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  150. new Type[] { Type.OBJECT }, Constants.ACC_PUBLIC),
  151. null, null, // indices 2, 3
  152. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  153. new Type[] { Type.BOOLEAN }, Constants.ACC_PUBLIC),
  154. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  155. new Type[] { Type.CHAR }, Constants.ACC_PUBLIC),
  156. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  157. new Type[] { Type.FLOAT }, Constants.ACC_PUBLIC),
  158. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  159. new Type[] { Type.DOUBLE }, Constants.ACC_PUBLIC),
  160. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  161. new Type[] { Type.INT }, Constants.ACC_PUBLIC),
  162. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte)
  163. new Type[] { Type.INT }, Constants.ACC_PUBLIC),
  164. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short)
  165. new Type[] { Type.INT }, Constants.ACC_PUBLIC),
  166. new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER,
  167. new Type[] { Type.LONG }, Constants.ACC_PUBLIC)
  168. };
  169. private static final boolean isString(Type type) {
  170. return ((type instanceof ObjectType) &&
  171. ((ObjectType)type).getClassName().equals("java.lang.String"));
  172. }
  173. public Instruction createAppend(Type type) {
  174. byte t = type.getType();
  175. if(isString(type))
  176. return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL);
  177. switch(t) {
  178. case Constants.T_BOOLEAN:
  179. case Constants.T_CHAR:
  180. case Constants.T_FLOAT:
  181. case Constants.T_DOUBLE:
  182. case Constants.T_BYTE:
  183. case Constants.T_SHORT:
  184. case Constants.T_INT:
  185. case Constants.T_LONG
  186. : return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL);
  187. case Constants.T_ARRAY:
  188. case Constants.T_OBJECT:
  189. return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL);
  190. default:
  191. throw new RuntimeException("Oops: No append for this type? " + type);
  192. }
  193. }
  194. /** Create a field instruction.
  195. *
  196. * @param class_name name of the accessed class
  197. * @param name name of the referenced field
  198. * @param type type of field
  199. * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC
  200. * @see Constants
  201. */
  202. public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) {
  203. int index;
  204. String signature = type.getSignature();
  205. index = cp.addFieldref(class_name, name, signature);
  206. switch(kind) {
  207. case Constants.GETFIELD: return new GETFIELD(index);
  208. case Constants.PUTFIELD: return new PUTFIELD(index);
  209. case Constants.GETSTATIC: return new GETSTATIC(index);
  210. case Constants.PUTSTATIC: return new PUTSTATIC(index);
  211. default:
  212. throw new RuntimeException("Oops: Unknown getfield kind:" + kind);
  213. }
  214. }
  215. /** Create reference to `this'
  216. */
  217. public static Instruction createThis() {
  218. return new ALOAD(0);
  219. }
  220. /** Create typed return
  221. */
  222. public static ReturnInstruction createReturn(Type type) {
  223. switch(type.getType()) {
  224. case Constants.T_ARRAY:
  225. case Constants.T_OBJECT: return ARETURN;
  226. case Constants.T_INT:
  227. case Constants.T_SHORT:
  228. case Constants.T_BOOLEAN:
  229. case Constants.T_CHAR:
  230. case Constants.T_BYTE: return IRETURN;
  231. case Constants.T_FLOAT: return FRETURN;
  232. case Constants.T_DOUBLE: return DRETURN;
  233. case Constants.T_LONG: return LRETURN;
  234. case Constants.T_VOID: return RETURN;
  235. default:
  236. throw new RuntimeException("Invalid type: " + type);
  237. }
  238. }
  239. private static final ArithmeticInstruction createBinaryIntOp(char first, String op) {
  240. switch(first) {
  241. case '-' : return ISUB;
  242. case '+' : return IADD;
  243. case '%' : return IREM;
  244. case '*' : return IMUL;
  245. case '/' : return IDIV;
  246. case '&' : return IAND;
  247. case '|' : return IOR;
  248. case '^' : return IXOR;
  249. case '<' : return ISHL;
  250. case '>' : return op.equals(">>>")? (ArithmeticInstruction)IUSHR :
  251. (ArithmeticInstruction)ISHR;
  252. default: throw new RuntimeException("Invalid operand " + op);
  253. }
  254. }
  255. private static final ArithmeticInstruction createBinaryLongOp(char first, String op) {
  256. switch(first) {
  257. case '-' : return LSUB;
  258. case '+' : return LADD;
  259. case '%' : return LREM;
  260. case '*' : return LMUL;
  261. case '/' : return LDIV;
  262. case '&' : return LAND;
  263. case '|' : return LOR;
  264. case '^' : return LXOR;
  265. case '<' : return LSHL;
  266. case '>' : return op.equals(">>>")? (ArithmeticInstruction)LUSHR :
  267. (ArithmeticInstruction)LSHR;
  268. default: throw new RuntimeException("Invalid operand " + op);
  269. }
  270. }
  271. private static final ArithmeticInstruction createBinaryFloatOp(char op) {
  272. switch(op) {
  273. case '-' : return FSUB;
  274. case '+' : return FADD;
  275. case '*' : return FMUL;
  276. case '/' : return FDIV;
  277. default: throw new RuntimeException("Invalid operand " + op);
  278. }
  279. }
  280. private static final ArithmeticInstruction createBinaryDoubleOp(char op) {
  281. switch(op) {
  282. case '-' : return DSUB;
  283. case '+' : return DADD;
  284. case '*' : return DMUL;
  285. case '/' : return DDIV;
  286. default: throw new RuntimeException("Invalid operand " + op);
  287. }
  288. }
  289. /**
  290. * Create binary operation for simple basic types, such as int and float.
  291. *
  292. * @param op operation, such as "+", "*", "<<", etc.
  293. */
  294. public static ArithmeticInstruction createBinaryOperation(String op, Type type) {
  295. char first = op.toCharArray()[0];
  296. switch(type.getType()) {
  297. case Constants.T_BYTE:
  298. case Constants.T_SHORT:
  299. case Constants.T_INT:
  300. case Constants.T_CHAR: return createBinaryIntOp(first, op);
  301. case Constants.T_LONG: return createBinaryLongOp(first, op);
  302. case Constants.T_FLOAT: return createBinaryFloatOp(first);
  303. case Constants.T_DOUBLE: return createBinaryDoubleOp(first);
  304. default: throw new RuntimeException("Invalid type " + type);
  305. }
  306. }
  307. /**
  308. * @param size size of operand, either 1 (int, e.g.) or 2 (double)
  309. */
  310. public static StackInstruction createPop(int size) {
  311. return (size == 2)? (StackInstruction)POP2 :
  312. (StackInstruction)POP;
  313. }
  314. /**
  315. * @param size size of operand, either 1 (int, e.g.) or 2 (double)
  316. */
  317. public static StackInstruction createDup(int size) {
  318. return (size == 2)? (StackInstruction)DUP2 :
  319. (StackInstruction)DUP;
  320. }
  321. /**
  322. * @param size size of operand, either 1 (int, e.g.) or 2 (double)
  323. */
  324. public static StackInstruction createDup_2(int size) {
  325. return (size == 2)? (StackInstruction)DUP2_X2 :
  326. (StackInstruction)DUP_X2;
  327. }
  328. /**
  329. * @param size size of operand, either 1 (int, e.g.) or 2 (double)
  330. */
  331. public static StackInstruction createDup_1(int size) {
  332. return (size == 2)? (StackInstruction)DUP2_X1 :
  333. (StackInstruction)DUP_X1;
  334. }
  335. /**
  336. * @param index index of local variable
  337. */
  338. public static LocalVariableInstruction createStore(Type type, int index) {
  339. switch(type.getType()) {
  340. case Constants.T_BOOLEAN:
  341. case Constants.T_CHAR:
  342. case Constants.T_BYTE:
  343. case Constants.T_SHORT:
  344. case Constants.T_INT: return new ISTORE(index);
  345. case Constants.T_FLOAT: return new FSTORE(index);
  346. case Constants.T_DOUBLE: return new DSTORE(index);
  347. case Constants.T_LONG: return new LSTORE(index);
  348. case Constants.T_ARRAY:
  349. case Constants.T_OBJECT: return new ASTORE(index);
  350. default: throw new RuntimeException("Invalid type " + type);
  351. }
  352. }
  353. /**
  354. * @param index index of local variable
  355. */
  356. public static LocalVariableInstruction createLoad(Type type, int index) {
  357. switch(type.getType()) {
  358. case Constants.T_BOOLEAN:
  359. case Constants.T_CHAR:
  360. case Constants.T_BYTE:
  361. case Constants.T_SHORT:
  362. case Constants.T_INT: return new ILOAD(index);
  363. case Constants.T_FLOAT: return new FLOAD(index);
  364. case Constants.T_DOUBLE: return new DLOAD(index);
  365. case Constants.T_LONG: return new LLOAD(index);
  366. case Constants.T_ARRAY:
  367. case Constants.T_OBJECT: return new ALOAD(index);
  368. default: throw new RuntimeException("Invalid type " + type);
  369. }
  370. }
  371. /**
  372. * @param type type of elements of array, i.e., array.getElementType()
  373. */
  374. public static ArrayInstruction createArrayLoad(Type type) {
  375. switch(type.getType()) {
  376. case Constants.T_BOOLEAN:
  377. case Constants.T_BYTE: return BALOAD;
  378. case Constants.T_CHAR: return CALOAD;
  379. case Constants.T_SHORT: return SALOAD;
  380. case Constants.T_INT: return IALOAD;
  381. case Constants.T_FLOAT: return FALOAD;
  382. case Constants.T_DOUBLE: return DALOAD;
  383. case Constants.T_LONG: return LALOAD;
  384. case Constants.T_ARRAY:
  385. case Constants.T_OBJECT: return AALOAD;
  386. default: throw new RuntimeException("Invalid type " + type);
  387. }
  388. }
  389. /**
  390. * @param type type of elements of array, i.e., array.getElementType()
  391. */
  392. public static ArrayInstruction createArrayStore(Type type) {
  393. switch(type.getType()) {
  394. case Constants.T_BOOLEAN:
  395. case Constants.T_BYTE: return BASTORE;
  396. case Constants.T_CHAR: return CASTORE;
  397. case Constants.T_SHORT: return SASTORE;
  398. case Constants.T_INT: return IASTORE;
  399. case Constants.T_FLOAT: return FASTORE;
  400. case Constants.T_DOUBLE: return DASTORE;
  401. case Constants.T_LONG: return LASTORE;
  402. case Constants.T_ARRAY:
  403. case Constants.T_OBJECT: return AASTORE;
  404. default: throw new RuntimeException("Invalid type " + type);
  405. }
  406. }
  407. /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g.,
  408. * if the operands are basic types and CHECKCAST if they are reference types.
  409. */
  410. public Instruction createCast(Type src_type, Type dest_type) {
  411. if((src_type instanceof BasicType) && (dest_type instanceof BasicType)) {
  412. byte dest = dest_type.getType();
  413. byte src = src_type.getType();
  414. if(dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE ||
  415. src == Constants.T_SHORT))
  416. src = Constants.T_INT;
  417. String[] short_names = { "C", "F", "D", "B", "S", "I", "L" };
  418. String name = "com.sun.org.apache.bcel.internal.generic." + short_names[src - Constants.T_CHAR] +
  419. "2" + short_names[dest - Constants.T_CHAR];
  420. Instruction i = null;
  421. try {
  422. i = (Instruction)java.lang.Class.forName(name).newInstance();
  423. } catch(Exception e) {
  424. throw new RuntimeException("Could not find instruction: " + name);
  425. }
  426. return i;
  427. } else if((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) {
  428. if(dest_type instanceof ArrayType)
  429. return new CHECKCAST(cp.addArrayClass((ArrayType)dest_type));
  430. else
  431. return new CHECKCAST(cp.addClass(((ObjectType)dest_type).getClassName()));
  432. }
  433. else
  434. throw new RuntimeException("Can not cast " + src_type + " to " + dest_type);
  435. }
  436. public GETFIELD createGetField(String class_name, String name, Type t) {
  437. return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature()));
  438. }
  439. public GETSTATIC createGetStatic(String class_name, String name, Type t) {
  440. return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
  441. }
  442. public PUTFIELD createPutField(String class_name, String name, Type t) {
  443. return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature()));
  444. }
  445. public PUTSTATIC createPutStatic(String class_name, String name, Type t) {
  446. return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
  447. }
  448. public CHECKCAST createCheckCast(ReferenceType t) {
  449. if(t instanceof ArrayType)
  450. return new CHECKCAST(cp.addArrayClass((ArrayType)t));
  451. else
  452. return new CHECKCAST(cp.addClass((ObjectType)t));
  453. }
  454. public NEW createNew(ObjectType t) {
  455. return new NEW(cp.addClass(t));
  456. }
  457. public NEW createNew(String s) {
  458. return createNew(new ObjectType(s));
  459. }
  460. /** Create new array of given size and type.
  461. */
  462. public AllocationInstruction createNewArray(Type t, short dim) {
  463. if(dim == 1) {
  464. if(t instanceof ObjectType)
  465. return new ANEWARRAY(cp.addClass((ObjectType)t));
  466. else if(t instanceof ArrayType)
  467. return new ANEWARRAY(cp.addArrayClass((ArrayType)t));
  468. else
  469. return new NEWARRAY(((BasicType)t).getType());
  470. } else {
  471. ArrayType at;
  472. if(t instanceof ArrayType)
  473. at = (ArrayType)t;
  474. else
  475. at = new ArrayType(t, dim);
  476. return new MULTIANEWARRAY(cp.addArrayClass(at), dim);
  477. }
  478. }
  479. /** Create "null" value for reference types, 0 for basic types like int
  480. */
  481. public static Instruction createNull(Type type) {
  482. switch(type.getType()) {
  483. case Constants.T_ARRAY:
  484. case Constants.T_OBJECT: return ACONST_NULL;
  485. case Constants.T_INT:
  486. case Constants.T_SHORT:
  487. case Constants.T_BOOLEAN:
  488. case Constants.T_CHAR:
  489. case Constants.T_BYTE: return ICONST_0;
  490. case Constants.T_FLOAT: return FCONST_0;
  491. case Constants.T_DOUBLE: return DCONST_0;
  492. case Constants.T_LONG: return LCONST_0;
  493. case Constants.T_VOID: return NOP;
  494. default:
  495. throw new RuntimeException("Invalid type: " + type);
  496. }
  497. }
  498. /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH.
  499. * For those you should use the SWITCH compeund instruction.
  500. */
  501. public static BranchInstruction createBranchInstruction(short opcode, InstructionHandle target) {
  502. switch(opcode) {
  503. case Constants.IFEQ: return new IFEQ(target);
  504. case Constants.IFNE: return new IFNE(target);
  505. case Constants.IFLT: return new IFLT(target);
  506. case Constants.IFGE: return new IFGE(target);
  507. case Constants.IFGT: return new IFGT(target);
  508. case Constants.IFLE: return new IFLE(target);
  509. case Constants.IF_ICMPEQ: return new IF_ICMPEQ(target);
  510. case Constants.IF_ICMPNE: return new IF_ICMPNE(target);
  511. case Constants.IF_ICMPLT: return new IF_ICMPLT(target);
  512. case Constants.IF_ICMPGE: return new IF_ICMPGE(target);
  513. case Constants.IF_ICMPGT: return new IF_ICMPGT(target);
  514. case Constants.IF_ICMPLE: return new IF_ICMPLE(target);
  515. case Constants.IF_ACMPEQ: return new IF_ACMPEQ(target);
  516. case Constants.IF_ACMPNE: return new IF_ACMPNE(target);
  517. case Constants.GOTO: return new GOTO(target);
  518. case Constants.JSR: return new JSR(target);
  519. case Constants.IFNULL: return new IFNULL(target);
  520. case Constants.IFNONNULL: return new IFNONNULL(target);
  521. case Constants.GOTO_W: return new GOTO_W(target);
  522. case Constants.JSR_W: return new JSR_W(target);
  523. default:
  524. throw new RuntimeException("Invalid opcode: " + opcode);
  525. }
  526. }
  527. public void setClassGen(ClassGen c) { cg = c; }
  528. public ClassGen getClassGen() { return cg; }
  529. public void setConstantPool(ConstantPoolGen c) { cp = c; }
  530. public ConstantPoolGen getConstantPool() { return cp; }
  531. }