annotate agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaScriptEngine.java @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
2 * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.utilities.soql;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import javax.script.Invocable;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 import javax.script.ScriptContext;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 import javax.script.ScriptEngine;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 import javax.script.ScriptEngineManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 import javax.script.ScriptException;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 import sun.jvm.hotspot.oops.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 import sun.jvm.hotspot.runtime.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 import sun.jvm.hotspot.utilities.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 import sun.jvm.hotspot.tools.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 import sun.jvm.hotspot.tools.jcore.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 import java.lang.reflect.Method;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 import java.lang.reflect.Modifier;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
44 * Simple wrapper around jsr-223 JavaScript script engine.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 * In addition to wrapping useful functionality of jsr-223 engine,
a61af66fc99e Initial load
duke
parents:
diff changeset
46 * this class exposed certain "global" functions to the script.
a61af66fc99e Initial load
duke
parents:
diff changeset
47 */
a61af66fc99e Initial load
duke
parents:
diff changeset
48 public abstract class JSJavaScriptEngine extends MapScriptObject {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
50 * Start a read-eval-print loop with this engine.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 */
a61af66fc99e Initial load
duke
parents:
diff changeset
52 public void startConsole() {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 start(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
57 * Initialize the engine so that we can "eval" strings
a61af66fc99e Initial load
duke
parents:
diff changeset
58 * and files later.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 */
a61af66fc99e Initial load
duke
parents:
diff changeset
60 public void start() {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 start(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
65 * Define a global function that invokes given Method.
a61af66fc99e Initial load
duke
parents:
diff changeset
66 */
a61af66fc99e Initial load
duke
parents:
diff changeset
67 public void defineFunction(Object target, Method method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 putFunction(target, method, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
72 * Call the script function of given name passing the
a61af66fc99e Initial load
duke
parents:
diff changeset
73 * given arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 */
a61af66fc99e Initial load
duke
parents:
diff changeset
75 public Object call(String name, Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 Invocable invocable = (Invocable)engine;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 return invocable.invokeFunction(name, args);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 } catch (RuntimeException re) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 throw re;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 } catch (Exception exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 throw new RuntimeException(exp);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
87 address function returns address of JSJavaObject as String. For other
a61af66fc99e Initial load
duke
parents:
diff changeset
88 type of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 */
a61af66fc99e Initial load
duke
parents:
diff changeset
90 public Object address(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (args.length != 1) return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if (o != null && o instanceof JSJavaObject) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 return ((JSJavaObject)o).getOop().getHandle().toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
102 classof function gets type of given JSJavaInstance or JSJavaArray. Or
a61af66fc99e Initial load
duke
parents:
diff changeset
103 given a string class name, this function gets the class object. For
a61af66fc99e Initial load
duke
parents:
diff changeset
104 other type of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 */
a61af66fc99e Initial load
duke
parents:
diff changeset
106 public Object classof(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (args.length != 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (o != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 if (o instanceof JSJavaObject) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (o instanceof JSJavaInstance) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return ((JSJavaInstance)o).getJSJavaClass();
a61af66fc99e Initial load
duke
parents:
diff changeset
115 } else if (o instanceof JSJavaArray) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return ((JSJavaArray)o).getJSJavaClass();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 } else if (o instanceof String) {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass((String) o);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return getJSJavaFactory().newJSJavaKlass(ik).getJSJavaClass();
a61af66fc99e Initial load
duke
parents:
diff changeset
123 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
132 * dumpClass function creates a .class file for a given Class object.
a61af66fc99e Initial load
duke
parents:
diff changeset
133 * On success, returns true. Else, returns false. Second optional argument
a61af66fc99e Initial load
duke
parents:
diff changeset
134 * specifies the directory in which .class content is dumped. This defaults
a61af66fc99e Initial load
duke
parents:
diff changeset
135 * to '.'
a61af66fc99e Initial load
duke
parents:
diff changeset
136 */
a61af66fc99e Initial load
duke
parents:
diff changeset
137 public Object dumpClass(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (args.length == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 Object clazz = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if (clazz == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 InstanceKlass ik = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (clazz instanceof String) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 String name = (String) clazz;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (name.startsWith("0x")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // treat it as address
a61af66fc99e Initial load
duke
parents:
diff changeset
150 VM vm = VM.getVM();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 Address addr = vm.getDebugger().parseAddress(name);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
152 Metadata metadata = Metadata.instantiateWrapperFor(addr.addOffsetTo(0));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
153 if (metadata instanceof InstanceKlass) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
154 ik = (InstanceKlass) metadata;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
155 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 ik = SystemDictionaryHelper.findInstanceKlass((String) clazz);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 } else if (clazz instanceof JSJavaClass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 JSJavaKlass jk = ((JSJavaClass)clazz).getJSJavaKlass();
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (jk != null && jk instanceof JSJavaInstanceKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (ik == null) return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 StringBuffer buf = new StringBuffer();
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if (args.length > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 buf.append(args[1].toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
174 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 buf.append('.');
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 buf.append(File.separatorChar);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 buf.append(ik.getName().asString().replace('/', File.separatorChar));
a61af66fc99e Initial load
duke
parents:
diff changeset
180 buf.append(".class");
a61af66fc99e Initial load
duke
parents:
diff changeset
181 String fileName = buf.toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
182 File file = new File(fileName);
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 int index = fileName.lastIndexOf(File.separatorChar);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 File dir = new File(fileName.substring(0, index));
a61af66fc99e Initial load
duke
parents:
diff changeset
187 dir.mkdirs();
a61af66fc99e Initial load
duke
parents:
diff changeset
188 FileOutputStream fos = new FileOutputStream(file);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 ClassWriter cw = new ClassWriter(ik, fos);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 cw.write();
a61af66fc99e Initial load
duke
parents:
diff changeset
191 fos.close();
a61af66fc99e Initial load
duke
parents:
diff changeset
192 } catch (IOException exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 printError(exp.toString(), exp);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 return Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return Boolean.TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
201 * dumpHeap function creates a heap dump file.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 * On success, returns true. Else, returns false.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 */
a61af66fc99e Initial load
duke
parents:
diff changeset
204 public Object dumpHeap(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 String fileName = "heap.bin";
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if (args.length > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 fileName = args[0].toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return new JMap().writeHeapHprofBin(fileName)? Boolean.TRUE: Boolean.FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
213 help function prints help message for global functions and variables.
a61af66fc99e Initial load
duke
parents:
diff changeset
214 */
a61af66fc99e Initial load
duke
parents:
diff changeset
215 public void help(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 println("Function/Variable Description");
a61af66fc99e Initial load
duke
parents:
diff changeset
217 println("================= ===========");
a61af66fc99e Initial load
duke
parents:
diff changeset
218 println("address(jobject) returns the address of the Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
219 println("classof(jobject) returns the class object of the Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
220 println("dumpClass(jclass,[dir]) writes .class for the given Java Class");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 println("dumpHeap([file]) writes heap in hprof binary format");
a61af66fc99e Initial load
duke
parents:
diff changeset
222 println("help() prints this help message");
a61af66fc99e Initial load
duke
parents:
diff changeset
223 println("identityHash(jobject) returns the hashCode of the Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
224 println("mirror(jobject) returns a local mirror of the Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 println("load([file1, file2,...]) loads JavaScript file(s). With no files, reads <stdin>");
a61af66fc99e Initial load
duke
parents:
diff changeset
226 println("object(string) converts a string address into Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
227 println("owner(jobject) returns the owner thread of this monitor or null");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 println("sizeof(jobject) returns the size of Java object in bytes");
a61af66fc99e Initial load
duke
parents:
diff changeset
229 println("staticof(jclass, field) returns a static field of the given Java class");
a61af66fc99e Initial load
duke
parents:
diff changeset
230 println("read([prompt]) reads a single line from standard input");
a61af66fc99e Initial load
duke
parents:
diff changeset
231 println("quit() quits the interactive load call");
a61af66fc99e Initial load
duke
parents:
diff changeset
232 println("jvm the target jvm that is being debugged");
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
236 identityHash function gets identity hash code value of given
a61af66fc99e Initial load
duke
parents:
diff changeset
237 JSJavaObject. For other type of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 */
a61af66fc99e Initial load
duke
parents:
diff changeset
239 public Object identityHash(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 if (args.length != 1) return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (o != null && o instanceof JSJavaObject) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 return new Long(((JSJavaObject)o).getOop().identityHash());
a61af66fc99e Initial load
duke
parents:
diff changeset
244 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
251 * Load and execute a set of JavaScript source files.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 * This method is defined as a JavaScript function.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 */
a61af66fc99e Initial load
duke
parents:
diff changeset
254 public void load(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 for (int i = 0; i < args.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 processSource(args[i].toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
261 mirror function creats local copy of the Oop wrapper supplied.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if mirror can not be created, return undefined. For other types,
a61af66fc99e Initial load
duke
parents:
diff changeset
263 mirror is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 */
a61af66fc99e Initial load
duke
parents:
diff changeset
265 public Object mirror(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 Object o = args[0];
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
267 Object res = UNDEFINED;
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
268 if (o != null) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
269 if (o instanceof JSJavaObject) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 Oop oop = ((JSJavaObject)o).getOop();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 res = getObjectReader().readObject(oop);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
273 } catch (Exception e) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
274 if (debug) e.printStackTrace(getErrorStream());
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
275 }
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
276 } else if (o instanceof JSMetadata) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
277 Metadata metadata = ((JSMetadata)o).getMetadata();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
278 try {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
279 if (metadata instanceof InstanceKlass) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
280 res = getObjectReader().readClass((InstanceKlass) metadata);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 } catch (Exception e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if (debug) e.printStackTrace(getErrorStream());
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
287 return res;
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 1552
diff changeset
288 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
291 owner function gets owning thread of given JSJavaObjec, if any, else
a61af66fc99e Initial load
duke
parents:
diff changeset
292 returns null. For other type of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 */
a61af66fc99e Initial load
duke
parents:
diff changeset
294 public Object owner(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
296 if (o != null && o instanceof JSJavaObject) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 return getOwningThread((JSJavaObject)o);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
304 object function takes a string address and returns a JSJavaObject.
a61af66fc99e Initial load
duke
parents:
diff changeset
305 For other type of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 */
a61af66fc99e Initial load
duke
parents:
diff changeset
307 public Object object(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (o != null && o instanceof String) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 VM vm = VM.getVM();
a61af66fc99e Initial load
duke
parents:
diff changeset
311 Address addr = vm.getDebugger().parseAddress((String)o);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 Oop oop = vm.getObjectHeap().newOop(addr.addOffsetToAsOopHandle(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
313 return getJSJavaFactory().newJSJavaObject(oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
314 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
320 sizeof function returns size of a Java object in bytes. For other type
a61af66fc99e Initial load
duke
parents:
diff changeset
321 of objects, the result is undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
322 */
a61af66fc99e Initial load
duke
parents:
diff changeset
323 public Object sizeof(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 if (args.length != 1) return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 Object o = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if (o != null && o instanceof JSJavaObject) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 return new Long(((JSJavaObject)o).getOop().getObjectSize());
a61af66fc99e Initial load
duke
parents:
diff changeset
328 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
334 staticof function gets static field of given class. Both class and
a61af66fc99e Initial load
duke
parents:
diff changeset
335 field name are specified as strings. undefined is returned if there is
a61af66fc99e Initial load
duke
parents:
diff changeset
336 no such named field.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 */
a61af66fc99e Initial load
duke
parents:
diff changeset
338 public Object staticof(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
339 Object classname = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Object fieldname = args[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
341 if (fieldname == null || classname == null ||
a61af66fc99e Initial load
duke
parents:
diff changeset
342 !(fieldname instanceof String)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 InstanceKlass ik = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 if (classname instanceof JSJavaClass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 JSJavaClass jclass = (JSJavaClass) classname;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 JSJavaKlass jk = jclass.getJSJavaKlass();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (jk != null && jk instanceof JSJavaInstanceKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 } else if (classname instanceof String) {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 ik = SystemDictionaryHelper.findInstanceKlass((String)classname);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (ik == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 JSJavaFactory factory = getJSJavaFactory();
a61af66fc99e Initial load
duke
parents:
diff changeset
363 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 return ((JSJavaInstanceKlass) factory.newJSJavaKlass(ik)).getStaticFieldValue((String)fieldname);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 } catch (NoSuchFieldException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 return UNDEFINED;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
371 * read function reads a single line of input from standard input
a61af66fc99e Initial load
duke
parents:
diff changeset
372 */
a61af66fc99e Initial load
duke
parents:
diff changeset
373 public Object read(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 BufferedReader in = getInputReader();
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if (in == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if (args.length > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 print(args[0].toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
380 print(":");
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 return in.readLine();
a61af66fc99e Initial load
duke
parents:
diff changeset
384 } catch (IOException exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 exp.printStackTrace();
a61af66fc99e Initial load
duke
parents:
diff changeset
386 throw new RuntimeException(exp);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
391 * Quit the shell.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 * This only affects the interactive mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 */
a61af66fc99e Initial load
duke
parents:
diff changeset
394 public void quit(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 quit();
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 public void writeln(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 for (int i = 0; i < args.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 print(args[i].toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
401 print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 println("");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 public void write(Object[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 for (int i = 0; i < args.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 print(args[i].toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
409 print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 //-- Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
414 protected void start(boolean console) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 ScriptContext context = engine.getContext();
a61af66fc99e Initial load
duke
parents:
diff changeset
416 OutputStream out = getOutputStream();
a61af66fc99e Initial load
duke
parents:
diff changeset
417 if (out != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 context.setWriter(new PrintWriter(out));
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 OutputStream err = getErrorStream();
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (err != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 context.setErrorWriter(new PrintWriter(err));
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // load "sa.js" initialization file
a61af66fc99e Initial load
duke
parents:
diff changeset
425 loadInitFile();
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // load "~/jsdb.js" (if found) to perform user specific
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // initialization steps, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
428 loadUserInitFile();
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 JSJavaFactory fac = getJSJavaFactory();
a61af66fc99e Initial load
duke
parents:
diff changeset
431 JSJavaVM jvm = (fac != null)? fac.newJSJavaVM() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // call "main" function from "sa.js" -- main expects
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // 'this' object and jvm object
a61af66fc99e Initial load
duke
parents:
diff changeset
434 call("main", new Object[] { this, jvm });
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // if asked, start read-eval-print console
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (console) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 processSource(null);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 protected JSJavaScriptEngine(boolean debug) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 this.debug = debug;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 ScriptEngineManager manager = new ScriptEngineManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
445 engine = manager.getEngineByName("javascript");
a61af66fc99e Initial load
duke
parents:
diff changeset
446 if (engine == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 throw new RuntimeException("can't load JavaScript engine");
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449 Method[] methods = getClass().getMethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
450 for (int i = 0; i < methods.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 Method m = methods[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
452 if (! Modifier.isPublic(m.getModifiers())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455 Class[] argTypes = m.getParameterTypes();
a61af66fc99e Initial load
duke
parents:
diff changeset
456 if (argTypes.length == 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
457 argTypes[0] == Object[].class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 putFunction(this, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 protected JSJavaScriptEngine() {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 this(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 protected abstract ObjectReader getObjectReader();
a61af66fc99e Initial load
duke
parents:
diff changeset
468 protected abstract JSJavaFactory getJSJavaFactory();
a61af66fc99e Initial load
duke
parents:
diff changeset
469 protected void printPrompt(String str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 System.err.print(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 System.err.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 protected void loadInitFile() {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 InputStream is = JSJavaScriptEngine.class.getResourceAsStream("sa.js");
a61af66fc99e Initial load
duke
parents:
diff changeset
476 BufferedReader reader = new BufferedReader(new InputStreamReader(is));
a61af66fc99e Initial load
duke
parents:
diff changeset
477 evalReader(reader, "sa.js");
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 protected void loadUserInitFile() {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 File initFile = new File(getUserInitFileDir(), getUserInitFileName());
a61af66fc99e Initial load
duke
parents:
diff changeset
482 if (initFile.exists() && initFile.isFile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // load the init script
a61af66fc99e Initial load
duke
parents:
diff changeset
484 processSource(initFile.getAbsolutePath());
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 protected String getUserInitFileDir() {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 return System.getProperty("user.home");
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 protected String getUserInitFileName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 return "jsdb.js";
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 protected BufferedReader getInputReader() {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (inReader == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 inReader = new BufferedReader(new InputStreamReader(System.in));
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500 return inReader;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 protected PrintStream getOutputStream() {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 return System.out;
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 protected PrintStream getErrorStream() {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return System.err;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 protected void print(String name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
512 getOutputStream().print(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 protected void println(String name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 getOutputStream().println(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 protected void printError(String message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 printError(message, null);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 protected void printError(String message, Exception exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 getErrorStream().println(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 if (exp != null && debug) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 exp.printStackTrace(getErrorStream());
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 protected boolean isQuitting() {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 return quitting;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 protected void quit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 quitting = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 protected ScriptEngine getScriptEngine() {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 return engine;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 private JSJavaThread getOwningThread(JSJavaObject jo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 Oop oop = jo.getOop();
a61af66fc99e Initial load
duke
parents:
diff changeset
544 Mark mark = oop.getMark();
a61af66fc99e Initial load
duke
parents:
diff changeset
545 ObjectMonitor mon = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 Address owner = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 JSJavaThread owningThread = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // check for heavyweight monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (! mark.hasMonitor()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // check for lightweight monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if (mark.hasLocker()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 owner = mark.locker().getAddress(); // save the address of the Lock word
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // implied else: no owner
a61af66fc99e Initial load
duke
parents:
diff changeset
555 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // this object has a heavyweight monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
557 mon = mark.monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // The owner field of a heavyweight monitor may be NULL for no
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // owner, a JavaThread * or it may still be the address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // Lock word in a JavaThread's stack. A monitor can be inflated
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // by a non-owning JavaThread, but only the owning JavaThread
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // can change the owner field from the Lock word to the
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // JavaThread * and it may not have done that yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
565 owner = mon.owner();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // find the owning thread
a61af66fc99e Initial load
duke
parents:
diff changeset
569 if (owner != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 JSJavaFactory factory = getJSJavaFactory();
a61af66fc99e Initial load
duke
parents:
diff changeset
571 owningThread = (JSJavaThread) factory.newJSJavaThread(VM.getVM().getThreads().owningThreadFromMonitor(owner));
a61af66fc99e Initial load
duke
parents:
diff changeset
572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
573 return owningThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
577 * Evaluate JavaScript source.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 * @param filename the name of the file to compile, or null
a61af66fc99e Initial load
duke
parents:
diff changeset
579 * for interactive mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
580 */
a61af66fc99e Initial load
duke
parents:
diff changeset
581 private void processSource(String filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (filename == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 BufferedReader in = getInputReader();
a61af66fc99e Initial load
duke
parents:
diff changeset
584 String sourceName = "<stdin>";
a61af66fc99e Initial load
duke
parents:
diff changeset
585 int lineno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 boolean hitEOF = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
587 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 int startline = lineno;
a61af66fc99e Initial load
duke
parents:
diff changeset
589 printPrompt("jsdb> ");
a61af66fc99e Initial load
duke
parents:
diff changeset
590 Object source = read(EMPTY_ARRAY);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 if (source == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 hitEOF = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
593 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595 lineno++;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 Object result = evalString(source.toString(), sourceName, startline);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 if (result != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 printError(result.toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 if (isQuitting()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // The user executed the quit() function.
a61af66fc99e Initial load
duke
parents:
diff changeset
602 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604 } while (!hitEOF);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 Reader in = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
607 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 in = new BufferedReader(new FileReader(filename));
a61af66fc99e Initial load
duke
parents:
diff changeset
609 evalReader(in, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 } catch (FileNotFoundException ex) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 println("File '" + filename + "' not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
612 throw new RuntimeException(ex);
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 protected Object evalString(String source, String filename, int lineNum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 engine.put(ScriptEngine.FILENAME, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
620 return engine.eval(source);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 } catch (ScriptException sexp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 printError(sexp.toString(), sexp);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 } catch (Exception exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 printError(exp.toString(), exp);
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 private Object evalReader(Reader in, String filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 engine.put(ScriptEngine.FILENAME, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 return engine.eval(in);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 } catch (ScriptException sexp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 System.err.println(sexp);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 printError(sexp.toString(), sexp);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 } finally {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 in.close();
a61af66fc99e Initial load
duke
parents:
diff changeset
639 } catch (IOException ioe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 printError(ioe.toString(), ioe);
a61af66fc99e Initial load
duke
parents:
diff changeset
641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // lazily initialized input reader
a61af66fc99e Initial load
duke
parents:
diff changeset
647 private BufferedReader inReader;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // debug mode or not
a61af66fc99e Initial load
duke
parents:
diff changeset
649 protected final boolean debug;
a61af66fc99e Initial load
duke
parents:
diff changeset
650 private boolean quitting;
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // underlying jsr-223 script engine
a61af66fc99e Initial load
duke
parents:
diff changeset
652 private ScriptEngine engine;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }