001: /*
002: Copyright (c) 2003, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.binding.classes;
030:
031: import java.security.InvalidParameterException;
032:
033: import org.apache.bcel.Constants;
034: import org.apache.bcel.generic.*;
035:
036: /**
037: * Instruction builder. Extends the basic instruction construction tools in
038: * BCEL with some convenience methods.
039: *
040: * @author Dennis M. Sosnoski
041: * @version 1.0
042: */
043:
044: public class InstructionBuilder extends InstructionFactory {
045: /**
046: * Constructor.
047: *
048: * @param cg class generation information
049: * @param cp constant pool generator
050: */
051:
052: public InstructionBuilder(ClassGen cg, ConstantPoolGen cp) {
053: super (cg, cp);
054: }
055:
056: /**
057: * Get constant pool generator.
058: *
059: * @return constant pool generator for class
060: */
061:
062: public ConstantPoolGen getConstantPoolGen() {
063: return cp;
064: }
065:
066: /**
067: * Create load constant instruction. Builds the most appropriate type of
068: * instruction for the value.
069: *
070: * @param value constant value to be loaded
071: * @return generated instruction information
072: */
073:
074: public CompoundInstruction createLoadConstant(int value) {
075: return new PUSH(cp, value);
076: }
077:
078: /**
079: * Create load constant instruction. Loads a <code>String</code> reference
080: * from the constant pool.
081: *
082: * @param value constant value to be loaded
083: * @return generated instruction information
084: */
085:
086: public CompoundInstruction createLoadConstant(String value) {
087: return new PUSH(cp, value);
088: }
089:
090: /**
091: * Create load constant instruction. Loads an unwrapped primitive value or
092: * String from the constant pool.
093: *
094: * @param value constant value to be loaded
095: * @return generated instruction information
096: */
097:
098: public CompoundInstruction createLoadConstant(Object value) {
099: if (value instanceof Boolean) {
100: return new PUSH(cp, (Boolean) value);
101: } else if (value instanceof Character) {
102: return new PUSH(cp, (Character) value);
103: } else if (value instanceof Number) {
104: return new PUSH(cp, (Number) value);
105: } else if (value instanceof String) {
106: return new PUSH(cp, (String) value);
107: } else {
108: throw new InvalidParameterException(
109: "Internal code generation error!");
110: }
111: }
112:
113: /**
114: * Create getfield instruction. Uses the field information to generate
115: * the instruction.
116: *
117: * @param item information for field to be set
118: * @return generated instruction information
119: */
120:
121: public FieldInstruction createGetField(ClassItem item) {
122: String cname = item.getClassFile().getName();
123: String fname = item.getName();
124: return new GETFIELD(cp.addFieldref(cname, fname, item
125: .getSignature()));
126: }
127:
128: /**
129: * Create putfield instruction. Uses the field information to generate
130: * the instruction.
131: *
132: * @param item information for field to be set
133: * @return generated instruction information
134: */
135:
136: public FieldInstruction createPutField(ClassItem item) {
137: String cname = item.getClassFile().getName();
138: String fname = item.getName();
139: return new PUTFIELD(cp.addFieldref(cname, fname, item
140: .getSignature()));
141: }
142:
143: /**
144: * Create getstatic instruction. Uses the field information to generate
145: * the instruction.
146: *
147: * @param item information for field to be set
148: * @return generated instruction information
149: */
150:
151: public FieldInstruction createGetStatic(ClassItem item) {
152: String cname = item.getClassFile().getName();
153: String fname = item.getName();
154: return new GETSTATIC(cp.addFieldref(cname, fname, item
155: .getSignature()));
156: }
157:
158: /**
159: * Create putstatic instruction. Uses the field information to generate
160: * the instruction.
161: *
162: * @param item information for field to be set
163: * @return generated instruction information
164: */
165:
166: public FieldInstruction createPutStatic(ClassItem item) {
167: String cname = item.getClassFile().getName();
168: String fname = item.getName();
169: return new PUTSTATIC(cp.addFieldref(cname, fname, item
170: .getSignature()));
171: }
172:
173: /**
174: * Create invoke instruction for static method. Uses the method information
175: * to generate the instruction.
176: *
177: * @param item information for method to be called
178: * @return generated instruction information
179: */
180:
181: public InvokeInstruction createCallStatic(ClassItem item) {
182: String cname = item.getClassFile().getName();
183: String mname = item.getName();
184: int index = cp.addMethodref(cname, mname, item.getSignature());
185: return new INVOKESTATIC(index);
186: }
187:
188: /**
189: * Create invoke instruction for virtual method. Uses the method information
190: * to generate the instruction.
191: *
192: * @param item information for method to be called
193: * @return generated instruction information
194: */
195:
196: public InvokeInstruction createCallVirtual(ClassItem item) {
197: String cname = item.getClassFile().getName();
198: String mname = item.getName();
199: int index = cp.addMethodref(cname, mname, item.getSignature());
200: return new INVOKEVIRTUAL(index);
201: }
202:
203: /**
204: * Create invoke instruction for interface method. Uses the method
205: * information to generate the instruction.
206: *
207: * @param item information for method to be called
208: * @return generated instruction information
209: */
210:
211: public InvokeInstruction createCallInterface(ClassItem item) {
212: String cname = item.getClassFile().getName();
213: String mname = item.getName();
214: String signature = item.getSignature();
215: return createInvoke(cname, mname,
216: Type.getReturnType(signature), Type
217: .getArgumentTypes(signature),
218: Constants.INVOKEINTERFACE);
219: }
220:
221: /**
222: * Create invoke static method instruction from signature.
223: *
224: * @param method fully qualified class and method name
225: * @param signature method signature in standard form
226: * @return generated instruction information
227: */
228:
229: public InvokeInstruction createCallStatic(String method,
230: String signature) {
231: int split = method.lastIndexOf('.');
232: String cname = method.substring(0, split);
233: String mname = method.substring(split + 1);
234: int index = cp.addMethodref(cname, mname, signature);
235: return new INVOKESTATIC(index);
236: }
237:
238: /**
239: * Create invoke virtual method instruction from signature.
240: *
241: * @param method fully qualified class and method name
242: * @param signature method signature in standard form
243: * @return generated instruction information
244: */
245:
246: public InvokeInstruction createCallVirtual(String method,
247: String signature) {
248: int split = method.lastIndexOf('.');
249: String cname = method.substring(0, split);
250: String mname = method.substring(split + 1);
251: int index = cp.addMethodref(cname, mname, signature);
252: return new INVOKEVIRTUAL(index);
253: }
254:
255: /**
256: * Create invoke interface method instruction from signature.
257: *
258: * @param method fully qualified interface and method name
259: * @param signature method signature in standard form
260: * @return generated instruction information
261: */
262:
263: public InvokeInstruction createCallInterface(String method,
264: String signature) {
265: int split = method.lastIndexOf('.');
266: String cname = method.substring(0, split);
267: String mname = method.substring(split + 1);
268: return createInvoke(cname, mname,
269: Type.getReturnType(signature), Type
270: .getArgumentTypes(signature),
271: Constants.INVOKEINTERFACE);
272: }
273:
274: /**
275: * Create invoke initializer instruction from signature.
276: *
277: * @param name fully qualified class name
278: * @param signature method signature in standard form
279: * @return generated instruction information
280: */
281:
282: public InvokeInstruction createCallInit(String name,
283: String signature) {
284: int index = cp.addMethodref(name, "<init>", signature);
285: return new INVOKESPECIAL(index);
286: }
287: }
|