aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsundar <none@none>2014-06-11 17:41:52 +0530
committersundar <none@none>2014-06-11 17:41:52 +0530
commitfdd645c487a49b6d4757d89468f442daf2094c6a (patch)
treef496287755925fadfc5a43038d2ca4f4b34f2aef /src
parent3766722d463fcc909607d0d52e5500df9b28e7df (diff)
downloadnashorn-fdd645c487a49b6d4757d89468f442daf2094c6a.tar.gz
8044798: API for debugging Nashorn
Reviewed-by: jlaskey, hannesw
Diffstat (limited to 'src')
-rw-r--r--src/jdk/nashorn/internal/runtime/DebuggerSupport.java65
-rw-r--r--src/jdk/nashorn/internal/runtime/ScriptFunctionData.java4
-rw-r--r--src/jdk/nashorn/internal/runtime/Source.java5
3 files changed, 72 insertions, 2 deletions
diff --git a/src/jdk/nashorn/internal/runtime/DebuggerSupport.java b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
index 261bc020..38e5d858 100644
--- a/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
+++ b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
@@ -25,12 +25,20 @@
package jdk.nashorn.internal.runtime;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Field;
+import java.net.URL;
import java.util.HashSet;
import java.util.Set;
+import jdk.nashorn.internal.scripts.JS;
/**
* This class provides support for external debuggers. Its primary purpose is
* is to simplify the debugger tasks and provide better performance.
+ * Even though the methods are not public, there are still part of the
+ * external debugger interface.
*/
final class DebuggerSupport {
/**
@@ -46,6 +54,11 @@ final class DebuggerSupport {
*/
@SuppressWarnings("unused")
DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null);
+
+ // Hook to force the loading of the SourceInfo class
+ @SuppressWarnings("unused")
+ final
+ SourceInfo srcInfo = new SourceInfo(null, 0, null, null);
}
/** This class is used to send a bulk description of a value. */
@@ -70,6 +83,54 @@ final class DebuggerSupport {
}
}
+ static class SourceInfo {
+ final String name;
+ final URL url;
+ final int hash;
+ final char[] content;
+
+ SourceInfo(final String name, final int hash, final URL url, final char[] content) {
+ this.name = name;
+ this.hash = hash;
+ this.url = url;
+ this.content = content;
+ }
+ }
+
+ /**
+ * Hook that is called just before invoking method handle
+ * from ScriptFunctionData via invoke, constructor method calls.
+ *
+ * @param mh script class method about to be invoked.
+ */
+ static void notifyInvoke(final MethodHandle mh) {
+ // Do nothing here. This is placeholder method on which a
+ // debugger can place a breakpoint so that it can access the
+ // (script class) method handle that is about to be invoked.
+ // See ScriptFunctionData.invoke and ScriptFunctionData.construct.
+ }
+
+ /**
+ * Return the script source info for the given script class.
+ *
+ * @param clazz compiled script class
+ * @return SourceInfo
+ */
+ static SourceInfo getSourceInfo(final Class<?> clazz) {
+ if (JS.class.isAssignableFrom(clazz)) {
+ try {
+ final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
+ sourceField.setAccessible(true);
+ final Source src = (Source) sourceField.get(null);
+ return src.getSourceInfo();
+ } catch (final IllegalAccessException | NoSuchFieldException ignored) {
+ return null;
+ }
+ }
+
+ return null;
+ }
+
/**
* Return the current context global.
* @return context global.
@@ -84,7 +145,7 @@ final class DebuggerSupport {
* @param self Receiver to use.
* @param string String to evaluate.
* @param returnException true if exceptions are to be returned.
- * @return Result of eval as string, or, an exception or null depending on returnException.
+ * @return Result of eval, or, an exception or null depending on returnException.
*/
static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
final ScriptObject global = Context.getGlobal();
@@ -235,7 +296,7 @@ final class DebuggerSupport {
* @param value Arbitrary value to be displayed by the debugger.
* @return A string representation of the value or an array of DebuggerValueDesc.
*/
- private static String valueAsString(final Object value) {
+ static String valueAsString(final Object value) {
final JSType type = JSType.of(value);
switch (type) {
diff --git a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
index ad40d622..001996b7 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -519,6 +519,8 @@ public abstract class ScriptFunctionData implements Serializable {
final Object selfObj = convertThisObject(self);
final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+ DebuggerSupport.notifyInvoke(mh);
+
if (isVarArg(mh)) {
if (needsCallee(mh)) {
return mh.invokeExact(fn, selfObj, args);
@@ -572,6 +574,8 @@ public abstract class ScriptFunctionData implements Serializable {
final MethodHandle mh = getGenericConstructor();
final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+ DebuggerSupport.notifyInvoke(mh);
+
if (isVarArg(mh)) {
if (needsCallee(mh)) {
return mh.invokeExact(fn, args);
diff --git a/src/jdk/nashorn/internal/runtime/Source.java b/src/jdk/nashorn/internal/runtime/Source.java
index f7e890ff..1423c163 100644
--- a/src/jdk/nashorn/internal/runtime/Source.java
+++ b/src/jdk/nashorn/internal/runtime/Source.java
@@ -124,6 +124,11 @@ public final class Source {
}
}
+ /* package-private */
+ DebuggerSupport.SourceInfo getSourceInfo() {
+ return new DebuggerSupport.SourceInfo(getName(), data.hashCode(), data.url(), data.array());
+ }
+
// Wrapper to manage lazy loading
private static interface Data {