001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.bytecode;
031:
032: import com.caucho.log.Log;
033: import com.caucho.vfs.TempBuffer;
034: import com.caucho.vfs.TempStream;
035: import com.caucho.vfs.WriteStream;
036:
037: import java.io.*;
038: import java.util.ArrayList;
039: import java.util.logging.Logger;
040:
041: /**
042: * Represents a generic attribute
043: */
044: public class CodeWriterAttribute extends CodeAttribute {
045: static private final Logger log = Logger
046: .getLogger(CodeAttribute.class.getName());
047:
048: private int _stack;
049: private ByteArrayOutputStream _bos;
050:
051: public CodeWriterAttribute(JavaClass jClass) {
052: setJavaClass(jClass);
053:
054: addUTF8("Code");
055:
056: _bos = new ByteArrayOutputStream();
057: }
058:
059: public void cast(String className) {
060: int index = addClass(className);
061:
062: write(CodeVisitor.CHECKCAST);
063: write(index >> 8);
064: write(index);
065: }
066:
067: public void getField(String className, String fieldName, String sig) {
068: int index = addFieldRef(className, fieldName, sig);
069:
070: write(CodeVisitor.GETFIELD);
071: write(index >> 8);
072: write(index);
073: }
074:
075: public void putField(String className, String fieldName, String sig) {
076: int index = addFieldRef(className, fieldName, sig);
077:
078: write(CodeVisitor.PUTFIELD);
079: write(index >> 8);
080: write(index);
081: }
082:
083: public void getStatic(String className, String fieldName, String sig) {
084: int index = addFieldRef(className, fieldName, sig);
085:
086: write(CodeVisitor.GETSTATIC);
087: write(index >> 8);
088: write(index);
089: }
090:
091: public void putStatic(String className, String fieldName, String sig) {
092: int index = addFieldRef(className, fieldName, sig);
093:
094: write(CodeVisitor.PUTSTATIC);
095: write(index >> 8);
096: write(index);
097: }
098:
099: public void getArrayObject() {
100: write(CodeVisitor.AALOAD);
101: }
102:
103: public void setArrayObject() {
104: write(CodeVisitor.AASTORE);
105: }
106:
107: public void pushObjectVar(int index) {
108: _stack++;
109:
110: if (index <= 3) {
111: write(CodeVisitor.ALOAD_0 + index);
112: } else {
113: write(CodeVisitor.ALOAD);
114: write(index >> 8);
115: write(index);
116: }
117: }
118:
119: public void pushIntVar(int index) {
120: _stack++;
121:
122: if (index <= 3) {
123: write(CodeVisitor.ILOAD_0 + index);
124: } else {
125: write(CodeVisitor.ILOAD);
126: write(index >> 8);
127: write(index);
128: }
129: }
130:
131: public void pushLongVar(int index) {
132: _stack += 2;
133:
134: if (index <= 3) {
135: write(CodeVisitor.LLOAD_0 + index);
136: } else {
137: write(CodeVisitor.LLOAD);
138: write(index >> 8);
139: write(index);
140: }
141: }
142:
143: public void pushFloatVar(int index) {
144: _stack += 1;
145:
146: if (index <= 3) {
147: write(CodeVisitor.FLOAD_0 + index);
148: } else {
149: write(CodeVisitor.FLOAD);
150: write(index >> 8);
151: write(index);
152: }
153: }
154:
155: public void pushDoubleVar(int index) {
156: _stack += 2;
157:
158: if (index <= 3) {
159: write(CodeVisitor.DLOAD_0 + index);
160: } else {
161: write(CodeVisitor.DLOAD);
162: write(index >> 8);
163: write(index);
164: }
165: }
166:
167: public void pushNull() {
168: _stack += 1;
169:
170: write(CodeVisitor.ACONST_NULL);
171: }
172:
173: public void pushInt(int value) {
174: _stack += 1;
175:
176: write(CodeVisitor.SIPUSH);
177: write(value >> 8);
178: write(value);
179: }
180:
181: public void invoke(String className, String methodName,
182: String signature, int argStack, int returnStack) {
183: _stack += returnStack - argStack;
184:
185: int index = addMethodRef(className, methodName, signature);
186:
187: write(CodeVisitor.INVOKEVIRTUAL);
188: write(index >> 8);
189: write(index);
190: }
191:
192: public void newInstance(String className) {
193: _stack += 1;
194:
195: int index = addClass(className);
196:
197: write(CodeVisitor.NEW);
198: write(index >> 8);
199: write(index);
200: }
201:
202: public void newObjectArray(String className) {
203: _stack += 1;
204:
205: int index = addClass(className);
206:
207: write(CodeVisitor.ANEWARRAY);
208: write(index >> 8);
209: write(index);
210: }
211:
212: public void dup() {
213: _stack += 1;
214:
215: write(CodeVisitor.DUP);
216: }
217:
218: public void invokespecial(String className, String methodName,
219: String signature, int argStack, int returnStack) {
220: _stack += returnStack - argStack;
221:
222: int index = addMethodRef(className, methodName, signature);
223:
224: write(CodeVisitor.INVOKESPECIAL);
225: write(index >> 8);
226: write(index);
227: }
228:
229: public void addReturn() {
230: write(CodeVisitor.RETURN);
231: }
232:
233: public void addIntReturn() {
234: write(CodeVisitor.IRETURN);
235: }
236:
237: public void addLongReturn() {
238: write(CodeVisitor.LRETURN);
239: }
240:
241: public void addFloatReturn() {
242: write(CodeVisitor.FRETURN);
243: }
244:
245: public void addDoubleReturn() {
246: write(CodeVisitor.DRETURN);
247: }
248:
249: public void addObjectReturn() {
250: write(CodeVisitor.ARETURN);
251: }
252:
253: public int addFieldRef(String className, String fieldName,
254: String sig) {
255: FieldRefConstant ref = getConstantPool().addFieldRef(className,
256: fieldName, sig);
257:
258: return ref.getIndex();
259: }
260:
261: public int addMethodRef(String className, String methodName,
262: String sig) {
263: MethodRefConstant ref = getConstantPool().addMethodRef(
264: className, methodName, sig);
265:
266: return ref.getIndex();
267: }
268:
269: public int addUTF8(String code) {
270: Utf8Constant value = getConstantPool().addUTF8(code);
271:
272: return value.getIndex();
273: }
274:
275: public int addClass(String className) {
276: ClassConstant value = getConstantPool().addClass(className);
277:
278: return value.getIndex();
279: }
280:
281: public ConstantPool getConstantPool() {
282: return getJavaClass().getConstantPool();
283: }
284:
285: private void write(int v) {
286: _bos.write(v);
287: }
288:
289: public void close() {
290: if (_bos != null) {
291: setCode(_bos.toByteArray());
292: _bos = null;
293: }
294: }
295: }
|