
jdk.nashorn.internal.runtime.DebuggerSupport Maven / Gradle / Ivy
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
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 {
/**
* Hook to force the loading of the DebuggerSupport class so that it is
* available to external debuggers.
*/
static boolean FORCELOAD = true;
static {
/**
* Hook to force the loading of the DebuggerValueDesc class so that it is
* available to external debuggers.
*/
@SuppressWarnings("unused")
final
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. */
static class DebuggerValueDesc {
/** Property key (or index) or field name. */
final String key;
/** If the value is expandable. */
final boolean expandable;
/** Property or field value as object. */
final Object valueAsObject;
/** Property or field value as string. */
final String valueAsString;
DebuggerValueDesc(final String key, final boolean expandable, final Object valueAsObject, final String valueAsString) {
this.key = key;
this.expandable = expandable;
this.valueAsObject = valueAsObject;
this.valueAsString = valueAsString;
}
}
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.
*/
static Object getGlobal() {
return Context.getGlobal();
}
/**
* Call eval on the current global.
* @param scope Scope to use.
* @param self Receiver to use.
* @param string String to evaluate.
* @param returnException true if exceptions are to be returned.
* @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();
final ScriptObject initialScope = scope != null ? scope : global;
final Object callThis = self != null ? self : global;
final Context context = global.getContext();
try {
return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED);
} catch (final Throwable ex) {
return returnException ? ex : null;
}
}
/**
* This method returns a bulk description of an object's properties.
* @param object Script object to be displayed by the debugger.
* @param all true if to include non-enumerable values.
* @return An array of DebuggerValueDesc.
*/
static DebuggerValueDesc[] valueInfos(final Object object, final boolean all) {
assert object instanceof ScriptObject;
return getDebuggerValueDescs((ScriptObject)object, all, new HashSet<>());
}
/**
* This method returns a debugger description of the value.
* @param name Name of value (property name).
* @param value Data value.
* @param all true if to include non-enumerable values.
* @return A DebuggerValueDesc.
*/
static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all) {
return valueInfo(name, value, all, new HashSet<>());
}
/**
* This method returns a debugger description of the value.
* @param name Name of value (property name).
* @param value Data value.
* @param all true if to include non-enumerable values.
* @param duplicates Duplication set to avoid cycles.
* @return A DebuggerValueDesc.
*/
private static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all, final Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy