001: /*
002: * @(#)CStubGenerator.java 1.15 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package runtime;
029:
030: import consts.Const;
031: import util.*;
032: import components.*;
033: import vm.*;
034: import java.io.PrintStream;
035: import java.util.Enumeration;
036: import java.util.Vector;
037: import java.util.Hashtable;
038:
039: public class CStubGenerator {
040: char CDelim = '_';
041: String exportPrefix = "";
042: boolean tracemode;
043: String outfileName;
044: final static char DIR_DELIM = '/';
045: final static char INNER_DELIM = '$';
046: PrintStream o;
047:
048: public CStubGenerator(boolean dotrace, PrintStream outfile) {
049: tracemode = dotrace;
050: o = outfile;
051: }
052:
053: // this data is really per-header.
054: // it is guarded by synchronous method access
055: String className;
056:
057: static String strsub(String src, char substitute) {
058: return src.replace(DIR_DELIM, substitute).replace(INNER_DELIM,
059: substitute);
060: }
061:
062: class StubGenerator extends util.SignatureIterator {
063: public String funcName;
064: public boolean tracemode;
065: public boolean isStatic;
066: public int argn;
067: public String retTypeWord = null;
068: public String params;
069: public String proto = "";
070: public String protoThis;
071: public String result = "";
072: String quotedClassFunc;
073: String methodName;
074:
075: public StubGenerator(String name, boolean isStaticMember,
076: String initialProto, String sig, boolean tm,
077: String mname) {
078: super (sig);
079: funcName = name;
080: isStatic = isStaticMember;
081: if (isStaticMember) {
082: params = "NULL";
083: argn = 0;
084: } else {
085: params = "_P_[0].p";
086: argn = 1;
087: }
088: protoThis = initialProto;
089: tracemode = tm;
090: methodName = mname;
091: }
092:
093: private void prefix(String returntype) {
094: result += " extern " + returntype + " " + funcName + "("
095: + protoThis + proto + ");\n";
096: if (tracemode) {
097: quotedClassFunc = "\"" + className + "\",\""
098: + methodName + "\"";
099: String this Param = isStatic ? ",%s,\"NULL\""
100: : ",0x%08x,_P_[0].p";
101: result += " ENTER_STUB(" + quotedClassFunc + this Param
102: + ",\"" + proto + "\");\n";
103: }
104: }
105:
106: private void suffix(String fmt, String val, String rtn) {
107: if (tracemode) {
108: if (fmt == null)
109: result += " EXIT_VOID_STUB(" + quotedClassFunc
110: + ");\n";
111: else
112: result += " EXIT_STUB(" + quotedClassFunc + ",\""
113: + fmt + "\"," + val + ");\n";
114: }
115: result += rtn;
116: }
117:
118: public void do_scalar(char t) {
119: // default scalar types: int, char, byte, short
120: if (isReturnType) {
121: prefix("long");
122: result += " _P_[0].i = " + funcName + "(" + params
123: + ");\n";
124: suffix("%d", "_P_[0].i", "\treturn _P_ + 1;\n");
125: } else {
126: params += ", _P_[" + argn + "].i";
127: proto += ",int";
128: argn += 1;
129: }
130: }
131:
132: public void do_float() {
133: if (isReturnType) {
134: prefix("float");
135: result += " _P_[0].f = " + funcName + "(" + params
136: + ");\n";
137: suffix("%f", "_P_[0].f", "\treturn _P_ + 1;\n");
138: } else {
139: params += ", _P_[" + argn + "].f";
140: proto += ",float";
141: argn += 1;
142: }
143: }
144:
145: public void do_double() {
146: if (isReturnType) {
147: result += " Java8 _tval;\n";
148: prefix("double");
149: result += " SET_DOUBLE(_tval, _P_, " + funcName + "("
150: + params + "));\n";
151: suffix(null, null, "\treturn _P_ + 2;\n");
152: } else {
153: result += " Java8 _t" + argn + ";\n";
154: params += ",GET_DOUBLE(_t" + argn + ", _P_+" + argn
155: + ") ";
156: proto += ",double";
157: argn += 2;
158: }
159: }
160:
161: public void do_long() {
162: if (isReturnType) {
163: result += " Java8 _tval;\n";
164: prefix("int64_t");
165: result += " SET_INT64(_tval, _P_, " + funcName + "("
166: + params + "));\n";
167: suffix(null, null, "\treturn _P_ + 2;\n");
168: } else {
169: result += " Java8 _t" + argn + ";\n";
170: params += ",GET_INT64(_t" + argn + ", _P_+" + argn
171: + ")";
172: proto += ",int64_t";
173: argn += 2;
174: }
175: }
176:
177: public void do_void() {
178: if (isReturnType) {
179: prefix("void");
180: result += " (void) " + funcName + "(" + params + ");\n";
181: suffix(null, null, "\treturn _P_;\n");
182: } else {
183: System.out
184: .println(Localizer
185: .getString("cstubgenerator.void_parameter_type"));
186: }
187: }
188:
189: public void do_boolean() {
190: if (isReturnType) {
191: prefix("long");
192: result += " _P_[0].i = " + funcName + "(" + params
193: + ")? TRUE : FALSE;\n";
194: suffix("%d", "_P_[0].i", "\treturn _P_ + 1;\n");
195: } else {
196: params += ", _P_[" + argn + "].i";
197: proto += ",int";
198: argn += 1;
199: }
200: }
201:
202: public void do_object(int startname, int endname) {
203: if (isReturnType) {
204: prefix("void*");
205: result += " _P_[0].p = " + funcName + "(" + params
206: + ");\n";
207: suffix("0x%08x", "_P_[0].p", "\treturn _P_ + 1;\n");
208: } else {
209: params += ", _P_[" + argn + "].p";
210: proto += ",void *";
211: argn += 1;
212: }
213: }
214:
215: public void do_array(int depth, int startname, int endname) {
216: if (isReturnType) {
217: prefix("void*");
218: result += " _P_[0].p = " + funcName + "(" + params
219: + ");\n";
220: suffix("0x%08x", "_P_[0].p", "\treturn _P_ + 1;\n");
221: } else {
222: params += ", _P_[" + argn + "].p";
223: proto += ",void *";
224: argn += 1;
225: }
226: }
227: }
228:
229: private boolean printStub(MethodInfo m) {
230: if ((m.access & Const.ACC_NATIVE) == 0)
231: return false; // we're here in error.
232: String mName = strsub(m.name.string, CDelim);
233: String funcName = className + "_" + mName;
234: String stubName = "Java_" + funcName + "_stub";
235:
236: StubGenerator g = new StubGenerator(funcName, m
237: .isStaticMember(), "void *", m.type.string, tracemode,
238: mName);
239: try {
240: g.iterate_parameters();
241: g.iterate_returntype();
242: } catch (DataFormatException e) {
243: e.printStackTrace();
244: return false;
245: }
246:
247: o.println(exportPrefix + "stack_item *" + stubName
248: + "(stack_item *_P_,struct execenv *_EE_) {");
249: o.print(g.result);
250: o.println("}");
251: return true;
252: }
253:
254: private void prolog() {
255: o.println("/* Stubs for class " + className + " */");
256: }
257:
258: private void epilog() {
259: }
260:
261: void fileProlog() {
262: o
263: .println("/* DO NOT EDIT THIS FILE - it is machine generated */");
264: o.println("#include <StubPreamble.h>");
265: if (tracemode) {
266: o.println("#include <threads.h>\n");
267: o.println("#ifndef ENTER_STUB");
268: o.println("#define ENTER_STUB(n,fcn,fmt,s,p)\\");
269: o
270: .println(" printf(\"0x%08x: %s_%s(\" #fmt \"%s)\\n\", threadSelf(), n, fcn, s, p);");
271: o.println("#endif");
272: o.println("#ifndef EXIT_STUB");
273: o.println("#define EXIT_STUB(n,f,fmt,r)\\");
274: o
275: .println(" printf(\"0x%08x: %s_%s returned \" #fmt \"\\n\", threadSelf(), n, f, r);");
276: o.println("#define EXIT_VOID_STUB(n,f)\\");
277: o
278: .println(" printf(\"0x%08x: %s_%s returned\\n\", threadSelf(), n, f);");
279: o.println("#endif");
280: }
281: }
282:
283: private void dumpStubs(ClassInfo c) {
284: className = strsub(c.className, CDelim);
285: if ((c.methods == null) || (c.methods.length == 0))
286: return;
287: prolog();
288: MethodInfo t[] = c.methods;
289: for (int i = 0; i < t.length; i++) {
290: if ((t[i].access & Const.ACC_NATIVE) != 0)
291: printStub(t[i]);
292: }
293: epilog();
294: }
295:
296: synchronized public void writeStubs(ClassInfo c[], int nclasses,
297: ClassnameFilterList nativeTypes) {
298: fileProlog();
299: for (int i = 0; i < nclasses; i++) {
300: String[] types = nativeTypes.getTypes(c[i].className);
301: for (int j = 0; j < types.length; ++j) {
302: String type = types[j];
303: if (type.substring(0, 3).equals("JDK")) {
304: dumpStubs(c[i]);
305: break;
306: }
307: }
308: }
309: }
310:
311: }
|