From d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 8 Jun 2010 08:22:05 +0200 Subject: reverted folder structure change for better mergeing with upstream --- .../org/mozilla/javascript/tools/debugger/Dim.java | 1560 -------------------- 1 file changed, 1560 deletions(-) delete mode 100644 infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java (limited to 'infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java') diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java deleted file mode 100644 index de8fcde..0000000 --- a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java +++ /dev/null @@ -1,1560 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Rhino JavaScript Debugger code, released - * November 21, 2000. - * - * The Initial Developer of the Original Code is - * SeeBeyond Corporation. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * Matt Gould - * Christopher Oliver - * Cameron McCormack - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 or later (the "GPL"), in which - * case the provisions of the GPL are applicable instead of those above. If - * you wish to allow use of your version of this file only under the terms of - * the GPL and not to allow others to use your version of this file under the - * MPL, indicate your decision by deleting the provisions above and replacing - * them with the notice and other provisions required by the GPL. If you do - * not delete the provisions above, a recipient may use your version of this - * file under either the MPL or the GPL. - * - * ***** END LICENSE BLOCK ***** */ -package org.mozilla.javascript.tools.debugger; - -import org.mozilla.javascript.*; -import org.mozilla.javascript.debug.*; -import java.util.*; -import java.io.*; -import java.net.URL; - -/** - * Dim or Debugger Implementation for Rhino. - */ -public class Dim { - - // Constants for instructing the debugger what action to perform - // to end interruption. Used by 'returnValue'. - public static final int STEP_OVER = 0; - public static final int STEP_INTO = 1; - public static final int STEP_OUT = 2; - public static final int GO = 3; - public static final int BREAK = 4; - public static final int EXIT = 5; - - // Constants for the DimIProxy interface implementation class. - private static final int IPROXY_DEBUG = 0; - private static final int IPROXY_LISTEN = 1; - private static final int IPROXY_COMPILE_SCRIPT = 2; - private static final int IPROXY_EVAL_SCRIPT = 3; - private static final int IPROXY_STRING_IS_COMPILABLE = 4; - private static final int IPROXY_OBJECT_TO_STRING = 5; - private static final int IPROXY_OBJECT_PROPERTY = 6; - private static final int IPROXY_OBJECT_IDS = 7; - - /** - * Interface to the debugger GUI. - */ - private GuiCallback callback; - - /** - * Whether the debugger should break. - */ - private boolean breakFlag; - - /** - * The ScopeProvider object that provides the scope in which to - * evaluate script. - */ - private ScopeProvider scopeProvider; - - /** - * The index of the current stack frame. - */ - private int frameIndex = -1; - - /** - * Information about the current stack at the point of interruption. - */ - private volatile ContextData interruptedContextData; - - /** - * The ContextFactory to listen to for debugging information. - */ - private ContextFactory contextFactory; - - /** - * Synchronization object used to allow script evaluations to - * happen when a thread is resumed. - */ - private Object monitor = new Object(); - - /** - * Synchronization object used to wait for valid - * {@link #interruptedContextData}. - */ - private Object eventThreadMonitor = new Object(); - - /** - * The action to perform to end the interruption loop. - */ - private volatile int returnValue = -1; - - /** - * Whether the debugger is inside the interruption loop. - */ - private boolean insideInterruptLoop; - - /** - * The requested script string to be evaluated when the thread - * has been resumed. - */ - private String evalRequest; - - /** - * The stack frame in which to evaluate {@link #evalRequest}. - */ - private StackFrame evalFrame; - - /** - * The result of evaluating {@link #evalRequest}. - */ - private String evalResult; - - /** - * Whether the debugger should break when a script exception is thrown. - */ - private boolean breakOnExceptions; - - /** - * Whether the debugger should break when a script function is entered. - */ - private boolean breakOnEnter; - - /** - * Whether the debugger should break when a script function is returned - * from. - */ - private boolean breakOnReturn; - - /** - * Table mapping URLs to information about the script source. - */ - private final Hashtable urlToSourceInfo = new Hashtable(); - - /** - * Table mapping function names to information about the function. - */ - private final Hashtable functionNames = new Hashtable(); - - /** - * Table mapping functions to information about the function. - */ - private final Hashtable functionToSource = new Hashtable(); - - /** - * ContextFactory.Listener instance attached to {@link #contextFactory}. - */ - private DimIProxy listener; - - /** - * Sets the GuiCallback object to use. - */ - public void setGuiCallback(GuiCallback callback) { - this.callback = callback; - } - - /** - * Tells the debugger to break at the next opportunity. - */ - public void setBreak() { - this.breakFlag = true; - } - - /** - * Sets the ScopeProvider to be used. - */ - public void setScopeProvider(ScopeProvider scopeProvider) { - this.scopeProvider = scopeProvider; - } - - /** - * Switches context to the stack frame with the given index. - */ - public void contextSwitch(int frameIndex) { - this.frameIndex = frameIndex; - } - - /** - * Sets whether the debugger should break on exceptions. - */ - public void setBreakOnExceptions(boolean breakOnExceptions) { - this.breakOnExceptions = breakOnExceptions; - } - - /** - * Sets whether the debugger should break on function entering. - */ - public void setBreakOnEnter(boolean breakOnEnter) { - this.breakOnEnter = breakOnEnter; - } - - /** - * Sets whether the debugger should break on function return. - */ - public void setBreakOnReturn(boolean breakOnReturn) { - this.breakOnReturn = breakOnReturn; - } - - /** - * Attaches the debugger to the given ContextFactory. - */ - public void attachTo(ContextFactory factory) { - detach(); - this.contextFactory = factory; - this.listener = new DimIProxy(this, IPROXY_LISTEN); - factory.addListener(this.listener); - } - - /** - * Detaches the debugger from the current ContextFactory. - */ - public void detach() { - if (listener != null) { - contextFactory.removeListener(listener); - contextFactory = null; - listener = null; - } - } - - /** - * Releases resources associated with this debugger. - */ - public void dispose() { - detach(); - } - - /** - * Returns the FunctionSource object for the given script or function. - */ - private FunctionSource getFunctionSource(DebuggableScript fnOrScript) { - FunctionSource fsource = functionSource(fnOrScript); - if (fsource == null) { - String url = getNormalizedUrl(fnOrScript); - SourceInfo si = sourceInfo(url); - if (si == null) { - if (!fnOrScript.isGeneratedScript()) { - // Not eval or Function, try to load it from URL - String source = loadSource(url); - if (source != null) { - DebuggableScript top = fnOrScript; - for (;;) { - DebuggableScript parent = top.getParent(); - if (parent == null) { - break; - } - top = parent; - } - registerTopScript(top, source); - fsource = functionSource(fnOrScript); - } - } - } - } - return fsource; - } - - /** - * Loads the script at the given URL. - */ - private String loadSource(String sourceUrl) { - String source = null; - int hash = sourceUrl.indexOf('#'); - if (hash >= 0) { - sourceUrl = sourceUrl.substring(0, hash); - } - try { - InputStream is; - openStream: - { - if (sourceUrl.indexOf(':') < 0) { - // Can be a file name - try { - if (sourceUrl.startsWith("~/")) { - String home = SecurityUtilities.getSystemProperty("user.home"); - if (home != null) { - String pathFromHome = sourceUrl.substring(2); - File f = new File(new File(home), pathFromHome); - if (f.exists()) { - is = new FileInputStream(f); - break openStream; - } - } - } - File f = new File(sourceUrl); - if (f.exists()) { - is = new FileInputStream(f); - break openStream; - } - } catch (SecurityException ex) { } - // No existing file, assume missed http:// - if (sourceUrl.startsWith("//")) { - sourceUrl = "http:" + sourceUrl; - } else if (sourceUrl.startsWith("/")) { - sourceUrl = "http://127.0.0.1" + sourceUrl; - } else { - sourceUrl = "http://" + sourceUrl; - } - } - - is = (new URL(sourceUrl)).openStream(); - } - - try { - source = Kit.readReader(new InputStreamReader(is)); - } finally { - is.close(); - } - } catch (IOException ex) { - System.err.println - ("Failed to load source from "+sourceUrl+": "+ ex); - } - return source; - } - - /** - * Registers the given script as a top-level script in the debugger. - */ - private void registerTopScript(DebuggableScript topScript, String source) { - if (!topScript.isTopLevel()) { - throw new IllegalArgumentException(); - } - String url = getNormalizedUrl(topScript); - DebuggableScript[] functions = getAllFunctions(topScript); - final SourceInfo sourceInfo = new SourceInfo(source, functions, url); - - synchronized (urlToSourceInfo) { - SourceInfo old = (SourceInfo)urlToSourceInfo.get(url); - if (old != null) { - sourceInfo.copyBreakpointsFrom(old); - } - urlToSourceInfo.put(url, sourceInfo); - for (int i = 0; i != sourceInfo.functionSourcesTop(); ++i) { - FunctionSource fsource = sourceInfo.functionSource(i); - String name = fsource.name(); - if (name.length() != 0) { - functionNames.put(name, fsource); - } - } - } - - synchronized (functionToSource) { - for (int i = 0; i != functions.length; ++i) { - FunctionSource fsource = sourceInfo.functionSource(i); - functionToSource.put(functions[i], fsource); - } - } - - callback.updateSourceText(sourceInfo); - } - - /** - * Returns the FunctionSource object for the given function or script. - */ - private FunctionSource functionSource(DebuggableScript fnOrScript) { - return (FunctionSource)functionToSource.get(fnOrScript); - } - - /** - * Returns an array of all function names. - */ - public String[] functionNames() { - String[] a; - synchronized (urlToSourceInfo) { - Enumeration e = functionNames.keys(); - a = new String[functionNames.size()]; - int i = 0; - while (e.hasMoreElements()) { - a[i++] = (String)e.nextElement(); - } - } - return a; - } - - /** - * Returns the FunctionSource object for the function with the given name. - */ - public FunctionSource functionSourceByName(String functionName) { - return (FunctionSource)functionNames.get(functionName); - } - - /** - * Returns the SourceInfo object for the given URL. - */ - public SourceInfo sourceInfo(String url) { - return (SourceInfo)urlToSourceInfo.get(url); - } - - /** - * Returns the source URL for the given script or function. - */ - private String getNormalizedUrl(DebuggableScript fnOrScript) { - String url = fnOrScript.getSourceName(); - if (url == null) { url = ""; } - else { - // Not to produce window for eval from different lines, - // strip line numbers, i.e. replace all #[0-9]+\(eval\) by - // (eval) - // Option: similar teatment for Function? - char evalSeparator = '#'; - StringBuffer sb = null; - int urlLength = url.length(); - int cursor = 0; - for (;;) { - int searchStart = url.indexOf(evalSeparator, cursor); - if (searchStart < 0) { - break; - } - String replace = null; - int i = searchStart + 1; - while (i != urlLength) { - int c = url.charAt(i); - if (!('0' <= c && c <= '9')) { - break; - } - ++i; - } - if (i != searchStart + 1) { - // i points after #[0-9]+ - if ("(eval)".regionMatches(0, url, i, 6)) { - cursor = i + 6; - replace = "(eval)"; - } - } - if (replace == null) { - break; - } - if (sb == null) { - sb = new StringBuffer(); - sb.append(url.substring(0, searchStart)); - } - sb.append(replace); - } - if (sb != null) { - if (cursor != urlLength) { - sb.append(url.substring(cursor)); - } - url = sb.toString(); - } - } - return url; - } - - /** - * Returns an array of all functions in the given script. - */ - private static DebuggableScript[] getAllFunctions - (DebuggableScript function) { - ObjArray functions = new ObjArray(); - collectFunctions_r(function, functions); - DebuggableScript[] result = new DebuggableScript[functions.size()]; - functions.toArray(result); - return result; - } - - /** - * Helper function for {@link #getAllFunctions(DebuggableScript)}. - */ - private static void collectFunctions_r(DebuggableScript function, - ObjArray array) { - array.add(function); - for (int i = 0; i != function.getFunctionCount(); ++i) { - collectFunctions_r(function.getFunction(i), array); - } - } - - /** - * Clears all breakpoints. - */ - public void clearAllBreakpoints() { - Enumeration e = urlToSourceInfo.elements(); - while (e.hasMoreElements()) { - SourceInfo si = (SourceInfo)e.nextElement(); - si.removeAllBreakpoints(); - } - } - - /** - * Called when a breakpoint has been hit. - */ - private void handleBreakpointHit(StackFrame frame, Context cx) { - breakFlag = false; - interrupted(cx, frame, null); - } - - /** - * Called when a script exception has been thrown. - */ - private void handleExceptionThrown(Context cx, Throwable ex, - StackFrame frame) { - if (breakOnExceptions) { - ContextData cd = frame.contextData(); - if (cd.lastProcessedException != ex) { - interrupted(cx, frame, ex); - cd.lastProcessedException = ex; - } - } - } - - /** - * Returns the current ContextData object. - */ - public ContextData currentContextData() { - return interruptedContextData; - } - - /** - * Sets the action to perform to end interruption. - */ - public void setReturnValue(int returnValue) { - synchronized (monitor) { - this.returnValue = returnValue; - monitor.notify(); - } - } - - /** - * Resumes execution of script. - */ - public void go() { - synchronized (monitor) { - this.returnValue = GO; - monitor.notifyAll(); - } - } - - /** - * Evaluates the given script. - */ - public String eval(String expr) { - String result = "undefined"; - if (expr == null) { - return result; - } - ContextData contextData = currentContextData(); - if (contextData == null || frameIndex >= contextData.frameCount()) { - return result; - } - StackFrame frame = contextData.getFrame(frameIndex); - if (contextData.eventThreadFlag) { - Context cx = Context.getCurrentContext(); - result = do_eval(cx, frame, expr); - } else { - synchronized (monitor) { - if (insideInterruptLoop) { - evalRequest = expr; - evalFrame = frame; - monitor.notify(); - do { - try { - monitor.wait(); - } catch (InterruptedException exc) { - Thread.currentThread().interrupt(); - break; - } - } while (evalRequest != null); - result = evalResult; - } - } - } - return result; - } - - /** - * Compiles the given script. - */ - public void compileScript(String url, String text) { - DimIProxy action = new DimIProxy(this, IPROXY_COMPILE_SCRIPT); - action.url = url; - action.text = text; - action.withContext(); - } - - /** - * Evaluates the given script. - */ - public void evalScript(final String url, final String text) { - DimIProxy action = new DimIProxy(this, IPROXY_EVAL_SCRIPT); - action.url = url; - action.text = text; - action.withContext(); - } - - /** - * Converts the given script object to a string. - */ - public String objectToString(Object object) { - DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_TO_STRING); - action.object = object; - action.withContext(); - return action.stringResult; - } - - /** - * Returns whether the given string is syntactically valid script. - */ - public boolean stringIsCompilableUnit(String str) { - DimIProxy action = new DimIProxy(this, IPROXY_STRING_IS_COMPILABLE); - action.text = str; - action.withContext(); - return action.booleanResult; - } - - /** - * Returns the value of a property on the given script object. - */ - public Object getObjectProperty(Object object, Object id) { - DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_PROPERTY); - action.object = object; - action.id = id; - action.withContext(); - return action.objectResult; - } - - /** - * Returns an array of the property names on the given script object. - */ - public Object[] getObjectIds(Object object) { - DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_IDS); - action.object = object; - action.withContext(); - return action.objectArrayResult; - } - - /** - * Returns the value of a property on the given script object. - */ - private Object getObjectPropertyImpl(Context cx, Object object, - Object id) { - Scriptable scriptable = (Scriptable)object; - Object result; - if (id instanceof String) { - String name = (String)id; - if (name.equals("this")) { - result = scriptable; - } else if (name.equals("__proto__")) { - result = scriptable.getPrototype(); - } else if (name.equals("__parent__")) { - result = scriptable.getParentScope(); - } else { - result = ScriptableObject.getProperty(scriptable, name); - if (result == ScriptableObject.NOT_FOUND) { - result = Undefined.instance; - } - } - } else { - int index = ((Integer)id).intValue(); - result = ScriptableObject.getProperty(scriptable, index); - if (result == ScriptableObject.NOT_FOUND) { - result = Undefined.instance; - } - } - return result; - } - - /** - * Returns an array of the property names on the given script object. - */ - private Object[] getObjectIdsImpl(Context cx, Object object) { - if (!(object instanceof Scriptable) || object == Undefined.instance) { - return Context.emptyArgs; - } - - Object[] ids; - Scriptable scriptable = (Scriptable)object; - if (scriptable instanceof DebuggableObject) { - ids = ((DebuggableObject)scriptable).getAllIds(); - } else { - ids = scriptable.getIds(); - } - - Scriptable proto = scriptable.getPrototype(); - Scriptable parent = scriptable.getParentScope(); - int extra = 0; - if (proto != null) { - ++extra; - } - if (parent != null) { - ++extra; - } - if (extra != 0) { - Object[] tmp = new Object[extra + ids.length]; - System.arraycopy(ids, 0, tmp, extra, ids.length); - ids = tmp; - extra = 0; - if (proto != null) { - ids[extra++] = "__proto__"; - } - if (parent != null) { - ids[extra++] = "__parent__"; - } - } - - return ids; - } - - /** - * Interrupts script execution. - */ - private void interrupted(Context cx, final StackFrame frame, - Throwable scriptException) { - ContextData contextData = frame.contextData(); - boolean eventThreadFlag = callback.isGuiEventThread(); - contextData.eventThreadFlag = eventThreadFlag; - - boolean recursiveEventThreadCall = false; - -interruptedCheck: - synchronized (eventThreadMonitor) { - if (eventThreadFlag) { - if (interruptedContextData != null) { - recursiveEventThreadCall = true; - break interruptedCheck; - } - } else { - while (interruptedContextData != null) { - try { - eventThreadMonitor.wait(); - } catch (InterruptedException exc) { - return; - } - } - } - interruptedContextData = contextData; - } - - if (recursiveEventThreadCall) { - // XXX: For now the following is commented out as on Linux - // too deep recursion of dispatchNextGuiEvent causes GUI lockout. - // Note: it can make GUI unresponsive if long-running script - // will be called on GUI thread while processing another interrupt - if (false) { - // Run event dispatch until gui sets a flag to exit the initial - // call to interrupted. - while (this.returnValue == -1) { - try { - callback.dispatchNextGuiEvent(); - } catch (InterruptedException exc) { - } - } - } - return; - } - - if (interruptedContextData == null) Kit.codeBug(); - - try { - do { - int frameCount = contextData.frameCount(); - this.frameIndex = frameCount -1; - - final String threadTitle = Thread.currentThread().toString(); - final String alertMessage; - if (scriptException == null) { - alertMessage = null; - } else { - alertMessage = scriptException.toString(); - } - - int returnValue = -1; - if (!eventThreadFlag) { - synchronized (monitor) { - if (insideInterruptLoop) Kit.codeBug(); - this.insideInterruptLoop = true; - this.evalRequest = null; - this.returnValue = -1; - callback.enterInterrupt(frame, threadTitle, - alertMessage); - try { - for (;;) { - try { - monitor.wait(); - } catch (InterruptedException exc) { - Thread.currentThread().interrupt(); - break; - } - if (evalRequest != null) { - this.evalResult = null; - try { - evalResult = do_eval(cx, evalFrame, - evalRequest); - } finally { - evalRequest = null; - evalFrame = null; - monitor.notify(); - } - continue; - } - if (this.returnValue != -1) { - returnValue = this.returnValue; - break; - } - } - } finally { - insideInterruptLoop = false; - } - } - } else { - this.returnValue = -1; - callback.enterInterrupt(frame, threadTitle, alertMessage); - while (this.returnValue == -1) { - try { - callback.dispatchNextGuiEvent(); - } catch (InterruptedException exc) { - } - } - returnValue = this.returnValue; - } - switch (returnValue) { - case STEP_OVER: - contextData.breakNextLine = true; - contextData.stopAtFrameDepth = contextData.frameCount(); - break; - case STEP_INTO: - contextData.breakNextLine = true; - contextData.stopAtFrameDepth = -1; - break; - case STEP_OUT: - if (contextData.frameCount() > 1) { - contextData.breakNextLine = true; - contextData.stopAtFrameDepth - = contextData.frameCount() -1; - } - break; - } - } while (false); - } finally { - synchronized (eventThreadMonitor) { - interruptedContextData = null; - eventThreadMonitor.notifyAll(); - } - } - - } - - /** - * Evaluates script in the given stack frame. - */ - private static String do_eval(Context cx, StackFrame frame, String expr) { - String resultString; - Debugger saved_debugger = cx.getDebugger(); - Object saved_data = cx.getDebuggerContextData(); - int saved_level = cx.getOptimizationLevel(); - - cx.setDebugger(null, null); - cx.setOptimizationLevel(-1); - cx.setGeneratingDebug(false); - try { - Callable script = (Callable)cx.compileString(expr, "", 0, null); - Object result = script.call(cx, frame.scope, frame.thisObj, - ScriptRuntime.emptyArgs); - if (result == Undefined.instance) { - resultString = ""; - } else { - resultString = ScriptRuntime.toString(result); - } - } catch (Exception exc) { - resultString = exc.getMessage(); - } finally { - cx.setGeneratingDebug(true); - cx.setOptimizationLevel(saved_level); - cx.setDebugger(saved_debugger, saved_data); - } - if (resultString == null) { - resultString = "null"; - } - return resultString; - } - - /** - * Proxy class to implement debug interfaces without bloat of class - * files. - */ - private static class DimIProxy - implements ContextAction, ContextFactory.Listener, Debugger { - - /** - * The debugger. - */ - private Dim dim; - - /** - * The interface implementation type. One of the IPROXY_* constants - * defined in {@link Dim}. - */ - private int type; - - /** - * The URL origin of the script to compile or evaluate. - */ - private String url; - - /** - * The text of the script to compile, evaluate or test for compilation. - */ - private String text; - - /** - * The object to convert, get a property from or enumerate. - */ - private Object object; - - /** - * The property to look up in {@link #object}. - */ - private Object id; - - /** - * The boolean result of the action. - */ - private boolean booleanResult; - - /** - * The String result of the action. - */ - private String stringResult; - - /** - * The Object result of the action. - */ - private Object objectResult; - - /** - * The Object[] result of the action. - */ - private Object[] objectArrayResult; - - /** - * Creates a new DimIProxy. - */ - private DimIProxy(Dim dim, int type) { - this.dim = dim; - this.type = type; - } - - // ContextAction - - /** - * Performs the action given by {@link #type}. - */ - public Object run(Context cx) { - switch (type) { - case IPROXY_COMPILE_SCRIPT: - cx.compileString(text, url, 1, null); - break; - - case IPROXY_EVAL_SCRIPT: - { - Scriptable scope = null; - if (dim.scopeProvider != null) { - scope = dim.scopeProvider.getScope(); - } - if (scope == null) { - scope = new ImporterTopLevel(cx); - } - cx.evaluateString(scope, text, url, 1, null); - } - break; - - case IPROXY_STRING_IS_COMPILABLE: - booleanResult = cx.stringIsCompilableUnit(text); - break; - - case IPROXY_OBJECT_TO_STRING: - if (object == Undefined.instance) { - stringResult = "undefined"; - } else if (object == null) { - stringResult = "null"; - } else if (object instanceof NativeCall) { - stringResult = "[object Call]"; - } else { - stringResult = Context.toString(object); - } - break; - - case IPROXY_OBJECT_PROPERTY: - objectResult = dim.getObjectPropertyImpl(cx, object, id); - break; - - case IPROXY_OBJECT_IDS: - objectArrayResult = dim.getObjectIdsImpl(cx, object); - break; - - default: - throw Kit.codeBug(); - } - return null; - } - - /** - * Performs the action given by {@link #type} with the attached - * {@link ContextFactory}. - */ - private void withContext() { - dim.contextFactory.call(this); - } - - // ContextFactory.Listener - - /** - * Called when a Context is created. - */ - public void contextCreated(Context cx) { - if (type != IPROXY_LISTEN) Kit.codeBug(); - ContextData contextData = new ContextData(); - Debugger debugger = new DimIProxy(dim, IPROXY_DEBUG); - cx.setDebugger(debugger, contextData); - cx.setGeneratingDebug(true); - cx.setOptimizationLevel(-1); - } - - /** - * Called when a Context is destroyed. - */ - public void contextReleased(Context cx) { - if (type != IPROXY_LISTEN) Kit.codeBug(); - } - - // Debugger - - /** - * Returns a StackFrame for the given function or script. - */ - public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) { - if (type != IPROXY_DEBUG) Kit.codeBug(); - - FunctionSource item = dim.getFunctionSource(fnOrScript); - if (item == null) { - // Can not debug if source is not available - return null; - } - return new StackFrame(cx, dim, item); - } - - /** - * Called when compilation is finished. - */ - public void handleCompilationDone(Context cx, - DebuggableScript fnOrScript, - String source) { - if (type != IPROXY_DEBUG) Kit.codeBug(); - - if (!fnOrScript.isTopLevel()) { - return; - } - dim.registerTopScript(fnOrScript, source); - } - } - - /** - * Class to store information about a stack. - */ - public static class ContextData { - - /** - * The stack frames. - */ - private ObjArray frameStack = new ObjArray(); - - /** - * Whether the debugger should break at the next line in this context. - */ - private boolean breakNextLine; - - /** - * The frame depth the debugger should stop at. Used to implement - * "step over" and "step out". - */ - private int stopAtFrameDepth = -1; - - /** - * Whether this context is in the event thread. - */ - private boolean eventThreadFlag; - - /** - * The last exception that was processed. - */ - private Throwable lastProcessedException; - - /** - * Returns the ContextData for the given Context. - */ - public static ContextData get(Context cx) { - return (ContextData) cx.getDebuggerContextData(); - } - - /** - * Returns the number of stack frames. - */ - public int frameCount() { - return frameStack.size(); - } - - /** - * Returns the stack frame with the given index. - */ - public StackFrame getFrame(int frameNumber) { - int num = frameStack.size() - frameNumber - 1; - return (StackFrame) frameStack.get(num); - } - - /** - * Pushes a stack frame on to the stack. - */ - private void pushFrame(StackFrame frame) { - frameStack.push(frame); - } - - /** - * Pops a stack frame from the stack. - */ - private void popFrame() { - frameStack.pop(); - } - } - - /** - * Object to represent one stack frame. - */ - public static class StackFrame implements DebugFrame { - - /** - * The debugger. - */ - private Dim dim; - - /** - * The ContextData for the Context being debugged. - */ - private ContextData contextData; - - /** - * The scope. - */ - private Scriptable scope; - - /** - * The 'this' object. - */ - private Scriptable thisObj; - - /** - * Information about the function. - */ - private FunctionSource fsource; - - /** - * Array of breakpoint state for each source line. - */ - private boolean[] breakpoints; - - /** - * Current line number. - */ - private int lineNumber; - - /** - * Creates a new StackFrame. - */ - private StackFrame(Context cx, Dim dim, FunctionSource fsource) { - this.dim = dim; - this.contextData = ContextData.get(cx); - this.fsource = fsource; - this.breakpoints = fsource.sourceInfo().breakpoints; - this.lineNumber = fsource.firstLine(); - } - - /** - * Called when the stack frame is entered. - */ - public void onEnter(Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) { - contextData.pushFrame(this); - this.scope = scope; - this.thisObj = thisObj; - if (dim.breakOnEnter) { - dim.handleBreakpointHit(this, cx); - } - } - - /** - * Called when the current position has changed. - */ - public void onLineChange(Context cx, int lineno) { - this.lineNumber = lineno; - - if (!breakpoints[lineno] && !dim.breakFlag) { - boolean lineBreak = contextData.breakNextLine; - if (lineBreak && contextData.stopAtFrameDepth >= 0) { - lineBreak = (contextData.frameCount() - <= contextData.stopAtFrameDepth); - } - if (!lineBreak) { - return; - } - contextData.stopAtFrameDepth = -1; - contextData.breakNextLine = false; - } - - dim.handleBreakpointHit(this, cx); - } - - /** - * Called when an exception has been thrown. - */ - public void onExceptionThrown(Context cx, Throwable exception) { - dim.handleExceptionThrown(cx, exception, this); - } - - /** - * Called when the stack frame has been left. - */ - public void onExit(Context cx, boolean byThrow, - Object resultOrException) { - if (dim.breakOnReturn && !byThrow) { - dim.handleBreakpointHit(this, cx); - } - contextData.popFrame(); - } - - /** - * Called when a 'debugger' statement is executed. - */ - public void onDebuggerStatement(Context cx) { - dim.handleBreakpointHit(this, cx); - } - - /** - * Returns the SourceInfo object for the function. - */ - public SourceInfo sourceInfo() { - return fsource.sourceInfo(); - } - - /** - * Returns the ContextData object for the Context. - */ - public ContextData contextData() { - return contextData; - } - - /** - * Returns the scope object for this frame. - */ - public Object scope() { - return scope; - } - - /** - * Returns the 'this' object for this frame. - */ - public Object thisObj() { - return thisObj; - } - - /** - * Returns the source URL. - */ - public String getUrl() { - return fsource.sourceInfo().url(); - } - - /** - * Returns the current line number. - */ - public int getLineNumber() { - return lineNumber; - } - } - - /** - * Class to store information about a function. - */ - public static class FunctionSource { - - /** - * Information about the source of the function. - */ - private SourceInfo sourceInfo; - - /** - * Line number of the first line of the function. - */ - private int firstLine; - - /** - * The function name. - */ - private String name; - - /** - * Creates a new FunctionSource. - */ - private FunctionSource(SourceInfo sourceInfo, int firstLine, - String name) { - if (name == null) throw new IllegalArgumentException(); - this.sourceInfo = sourceInfo; - this.firstLine = firstLine; - this.name = name; - } - - /** - * Returns the SourceInfo object that describes the source of the - * function. - */ - public SourceInfo sourceInfo() { - return sourceInfo; - } - - /** - * Returns the line number of the first line of the function. - */ - public int firstLine() { - return firstLine; - } - - /** - * Returns the name of the function. - */ - public String name() { - return name; - } - } - - /** - * Class to store information about a script source. - */ - public static class SourceInfo { - - /** - * An empty array of booleans. - */ - private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; - - /** - * The script. - */ - private String source; - - /** - * The URL of the script. - */ - private String url; - - /** - * Array indicating which lines can have breakpoints set. - */ - private boolean[] breakableLines; - - /** - * Array indicating whether a breakpoint is set on the line. - */ - private boolean[] breakpoints; - - /** - * Array of FunctionSource objects for the functions in the script. - */ - private FunctionSource[] functionSources; - - /** - * Creates a new SourceInfo object. - */ - private SourceInfo(String source, DebuggableScript[] functions, - String normilizedUrl) { - this.source = source; - this.url = normilizedUrl; - - int N = functions.length; - int[][] lineArrays = new int[N][]; - for (int i = 0; i != N; ++i) { - lineArrays[i] = functions[i].getLineNumbers(); - } - - int minAll = 0, maxAll = -1; - int[] firstLines = new int[N]; - for (int i = 0; i != N; ++i) { - int[] lines = lineArrays[i]; - if (lines == null || lines.length == 0) { - firstLines[i] = -1; - } else { - int min, max; - min = max = lines[0]; - for (int j = 1; j != lines.length; ++j) { - int line = lines[j]; - if (line < min) { - min = line; - } else if (line > max) { - max = line; - } - } - firstLines[i] = min; - if (minAll > maxAll) { - minAll = min; - maxAll = max; - } else { - if (min < minAll) { - minAll = min; - } - if (max > maxAll) { - maxAll = max; - } - } - } - } - - if (minAll > maxAll) { - // No line information - this.breakableLines = EMPTY_BOOLEAN_ARRAY; - this.breakpoints = EMPTY_BOOLEAN_ARRAY; - } else { - if (minAll < 0) { - // Line numbers can not be negative - throw new IllegalStateException(String.valueOf(minAll)); - } - int linesTop = maxAll + 1; - this.breakableLines = new boolean[linesTop]; - this.breakpoints = new boolean[linesTop]; - for (int i = 0; i != N; ++i) { - int[] lines = lineArrays[i]; - if (lines != null && lines.length != 0) { - for (int j = 0; j != lines.length; ++j) { - int line = lines[j]; - this.breakableLines[line] = true; - } - } - } - } - this.functionSources = new FunctionSource[N]; - for (int i = 0; i != N; ++i) { - String name = functions[i].getFunctionName(); - if (name == null) { - name = ""; - } - this.functionSources[i] - = new FunctionSource(this, firstLines[i], name); - } - } - - /** - * Returns the source text. - */ - public String source() { - return this.source; - } - - /** - * Returns the script's origin URL. - */ - public String url() { - return this.url; - } - - /** - * Returns the number of FunctionSource objects stored in this object. - */ - public int functionSourcesTop() { - return functionSources.length; - } - - /** - * Returns the FunctionSource object with the given index. - */ - public FunctionSource functionSource(int i) { - return functionSources[i]; - } - - /** - * Copies the breakpoints from the given SourceInfo object into this - * one. - */ - private void copyBreakpointsFrom(SourceInfo old) { - int end = old.breakpoints.length; - if (end > this.breakpoints.length) { - end = this.breakpoints.length; - } - for (int line = 0; line != end; ++line) { - if (old.breakpoints[line]) { - this.breakpoints[line] = true; - } - } - } - - /** - * Returns whether the given line number can have a breakpoint set on - * it. - */ - public boolean breakableLine(int line) { - return (line < this.breakableLines.length) - && this.breakableLines[line]; - } - - /** - * Returns whether there is a breakpoint set on the given line. - */ - public boolean breakpoint(int line) { - if (!breakableLine(line)) { - throw new IllegalArgumentException(String.valueOf(line)); - } - return line < this.breakpoints.length && this.breakpoints[line]; - } - - /** - * Sets or clears the breakpoint flag for the given line. - */ - public boolean breakpoint(int line, boolean value) { - if (!breakableLine(line)) { - throw new IllegalArgumentException(String.valueOf(line)); - } - boolean changed; - synchronized (breakpoints) { - if (breakpoints[line] != value) { - breakpoints[line] = value; - changed = true; - } else { - changed = false; - } - } - return changed; - } - - /** - * Removes all breakpoints from the script. - */ - public void removeAllBreakpoints() { - synchronized (breakpoints) { - for (int line = 0; line != breakpoints.length; ++line) { - breakpoints[line] = false; - } - } - } - } -} -- cgit v1.2.3