View | Details | Raw Unified
Collapse All | Expand All

(-) jakarta-bsf/src/bsf-2.3/bsf/src/org/apache/bsf/engines/javascript/Attic/RhinoEngineDebugger.java (-650 / +597 lines)
 Lines 74-80    Link Here 
 * of script is sliced into compilation units.
 * of script is sliced into compilation units.
 * For instance, the script text may contain a function
 * For instance, the script text may contain a function
 * declaration and an expression to eval. The compilation
 * declaration and an expression to eval. The compilation
 * will result in two compilation units: the function and 
 * will result in two compilation units: the function and
 * the expression. Each compilation unit will correspond
 * the expression. Each compilation unit will correspond
 * to a range of the lines of the original script compiled.
 * to a range of the lines of the original script compiled.
 * All line numbers are global to the document the compiled
 * All line numbers are global to the document the compiled
 Lines 82-170    Link Here 
 * It is on compilation units that breakpoints can be set
 * It is on compilation units that breakpoints can be set
 * or removed, more exactly on the DebuggableScript attached
 * or removed, more exactly on the DebuggableScript attached
 * to them. See Rhino for more details.
 * to them. See Rhino for more details.
 * 
 *
 * @author: Olivier Gruber.
 * @author: Olivier Gruber.
 */ 
 */
public class CompilationUnit {
public class CompilationUnit {
	FnOrScript m_fnOrScript;
    FnOrScript m_fnOrScript;
	int m_firstLine;
    int m_firstLine;
	int m_lineCount;
    int m_lineCount;
	String m_fnName;
    String m_fnName;
	DebuggableScript m_dbgScript;
    DebuggableScript m_dbgScript;
	int m_validBrkptLines[];
    boolean[] m_breakpoints;
	/**
    /**
	 * CompilationUnit constructor comment.
     * CompilationUnit constructor comment.
	 */
     */
	public CompilationUnit(FnOrScript fnOrScript, DebuggableScript dbgScript) {
    public CompilationUnit(FnOrScript fnOrScript, DebuggableScript dbgScript) {
		int lastLine, lineno;
        m_fnOrScript = fnOrScript;
        m_dbgScript = dbgScript;
		m_fnOrScript = fnOrScript;
		m_dbgScript = dbgScript;
        int[] lines = dbgScript.getLineNumbers();
        if (lines.length != 0) {
		try {
            int lastLine;
			m_validBrkptLines = dbgScript.getLineNumbers();
            m_firstLine = lines[0];
			m_firstLine = 99999;
            lastLine = m_firstLine;
			lastLine = 0;
            for (int i = 1; i != lines.length; ++i) {
			for (int l = 0; l < m_validBrkptLines.length; l++) {
                int lineno = lines[i];
				lineno = m_validBrkptLines[l];
                if (m_firstLine > lineno) {
				if (m_firstLine > lineno)
                    m_firstLine = lineno;
					m_firstLine = lineno;
                } else if (lastLine < lineno) {
				if (lastLine < lineno)
                    lastLine = lineno;
					lastLine = lineno;
                }
			}
            }
			m_lineCount = lastLine - m_firstLine + 1;
            m_lineCount = lastLine - m_firstLine + 1;
		} catch (Throwable t) {
            m_breakpoints = new boolean[m_lineCount];
			DebugLog.stderrPrintln("\nWarning: can't get valid line numbers for breakpoints.", DebugLog.BSF_LOG_L2);
        }
			m_validBrkptLines = null;
		}
        String name = dbgScript.getFunctionName();
        if (name != null && name.length() != 0 && !name.equals("anonymous")) {
		Scriptable scriptable = dbgScript.getScriptable();
            m_fnName = name;
		if (scriptable instanceof NativeFunction) {
        }
			NativeFunction f = (NativeFunction) scriptable;
    }
			String name = f.getFunctionName();
    //----------------------------------------------------------
			if (name.length() > 0 && !name.equals("anonymous")) {
    boolean contains(int lineno) {
				m_fnName = name;
        return (m_firstLine <= lineno && lineno < m_firstLine + m_lineCount);
			}
    }
		}
    /**
	}
     * Returns true if the compilation unit contains
	//----------------------------------------------------------
     * the breakpoint.
	boolean contains(int lineno) {
     * Notice only breakpoint defined at a line number
		return (m_firstLine <= lineno && lineno < m_firstLine + m_lineCount);
     * are supported here.
	}
     */
	/**
    boolean contains(BreakPoint bp) {
	 * Returns true if the compilation unit contains
        try {
	 * the breakpoint. 
            return contains(bp.getLineNo());
	 * Notice only breakpoint defined at a line number
        } catch (BSFException ex) {
	 * are supported here.
            return false;
	 */
        }
	boolean contains(BreakPoint bp) {
    }
		try {
    /**
			return contains(bp.getLineNo());
     * Set a breakpoint at the given line if Rhino has provided us with the
		} catch (BSFException ex) {
     * valid lines information.
			return false;
     */
		}
    void propagate(int lineno) {
	}
        if (m_breakpoints != null) {
	/**
            int i = lineno - m_firstLine;
	 * Propagates (i.e. set) this breakpoint to the underlying Rhino
            if (0 <= i && i < m_lineCount) {
	 * engine if Rhino has provided us with the valid lines
                m_breakpoints[i] = true;
	 * information. Otherwise, Rhino crashes with a NullPointerException.
            }
	 */
        }
	void propagate(int lineno) {
    }
		if (m_validBrkptLines != null) {
    /**
			m_dbgScript.placeBreakpoint(lineno);
     * Clear a breakpoint at the given line if Rhino has provided us with the
		}
     * valid lines information.
	}
     */
	/**
    void unpropagate(int lineno) {
	 * Unpropagates (i.e. unset) this breakpoint to the underlying Rhino
        if (m_breakpoints != null) {
	 * engine if Rhino has provided us with the valid lines
            int i = lineno - m_firstLine;
	 * information. Otherwise, Rhino crashes with a NullPointerException.
            if (0 <= i && i < m_lineCount) {
	 */
                m_breakpoints[i] = false;
	void unpropagate(int lineno) {
            }
		if (m_validBrkptLines != null) {
        }
			m_dbgScript.removeBreakpoint(lineno);
    }
		}
	}
    boolean hasBreakpoint(int lineno) {
        if (m_breakpoints != null) {
            int i = lineno - m_firstLine;
            return 0 <= i && i < m_lineCount && m_breakpoints[i];
        }
        return false;
    }
}
}
 Lines 71-95    Link Here 
 * This class represents a function or script, that is,
 * This class represents a function or script, that is,
 * a piece of a document that is provided to the JavaScript
 * a piece of a document that is provided to the JavaScript
 * engine for evaluation, execution, or simply compilation.
 * engine for evaluation, execution, or simply compilation.
 * 
 *
 * A FnOrScript represents a range of lines or characters
 * A FnOrScript represents a range of lines or characters
 * in its document. For now, Rhino only supports ranges 
 * in its document. For now, Rhino only supports ranges
 * of lines, really, but the code for offsets is there anyway.
 * of lines, really, but the code for offsets is there anyway.
 *
 *
 * Warning: Offsets have never been quite tested yet...
 * Warning: Offsets have never been quite tested yet...
 * 
 *
 * A FnOrScript has compilation units. When Rhino compiles
 * A FnOrScript has compilation units. When Rhino compiles
 * a function or a script, even in interpreted mode where the
 * a function or a script, even in interpreted mode where the
 * compilation is done to JavaScript bytecode, it calls back
 * compilation is done to JavaScript bytecode, it calls back
 * its debugger with different compilation units; see 
 * its debugger with different compilation units; see
 * Debugger::handleCompilationDone method on the RhinoEngineDebugger
 * Debugger::handleCompilationDone method on the RhinoEngineDebugger
 * class.
 * class.
 *
 *
 * A FnOrScript also keeps track of the known breakpoints
 * A FnOrScript also keeps track of the known breakpoints
 * in its range of lines or characters. It makes sure
 * in its range of lines or characters. It makes sure
 * that they are propagated to the underlying Rhino 
 * that they are propagated to the underlying Rhino
 * engine (i.e. set) as well as unpropagated (i.e. unset).
 * engine (i.e. set) as well as unpropagated (i.e. unset).
 *  
 *
 * @author: Olivier Gruber
 * @author: Olivier Gruber
 */
 */
public class FnOrScript {
public class FnOrScript {
 Lines 103-111    Link Here 
    protected StringBuffer m_text;
    protected StringBuffer m_text;
    protected Vector m_units; // of CompilationUnit.
    protected Script m_script;
    protected Script m_script;
    private Vector m_units; // of CompilationUnit.
    private Hashtable m_functionToUnit;
    protected Hashtable m_functionMap;
    protected Hashtable m_functionMap;
    public FnOrScript(DocumentCell cell) {
    public FnOrScript(DocumentCell cell) {
 Lines 116-123    Link Here 
        m_lineCount = 0;
        m_lineCount = 0;
        m_breakpoints = new Vector();
        m_breakpoints = new Vector();
        m_text = new StringBuffer();
        m_text = new StringBuffer();
	
        m_units = new Vector();
        m_units = new Vector();
        m_functionToUnit = new Hashtable();
        m_functionMap = new Hashtable();
        m_functionMap = new Hashtable();
    }
    }
 Lines 131-137    Link Here 
        m_breakpoints.addElement(bp);
        m_breakpoints.addElement(bp);
        // now, look for a unit containing it and 
        // now, look for a unit containing it and
        // if one is found, set the breakpoint unit
        // if one is found, set the breakpoint unit
        // and propagate...
        // and propagate...
        Enumeration e;
        Enumeration e;
 Lines 147-153    Link Here 
        }
        }
        return bp;
        return bp;
    }
    }
	
    private BreakPoint _removeBreakpoint(int brkptId) {
    private BreakPoint _removeBreakpoint(int brkptId) {
        Enumeration e;
        Enumeration e;
        BreakPoint bp;
        BreakPoint bp;
 Lines 173-185    Link Here 
            bp = (BreakPoint) e.nextElement();
            bp = (BreakPoint) e.nextElement();
            if (bpid == bp.getId()) {
            if (bpid == bp.getId()) {
                m_breakpoints.removeElement(bp);
                m_breakpoints.removeElement(bp);
                bp.unpropagate();	
                bp.unpropagate();
                return bp;
                return bp;
            }
            }
        }
        }
        return null;
        return null;
    }
    }
	
    boolean contains(BreakPoint bp) throws BSFException {
    boolean contains(BreakPoint bp) throws BSFException {
        if (m_lineDefined) {
        if (m_lineDefined) {
            int line = bp.getLineNo();
            int line = bp.getLineNo();
 Lines 194-200    Link Here 
    // This protected method works as a factory
    // This protected method works as a factory
    // for language-specific breakpoints.
    // for language-specific breakpoints.
    // The default behavior is to use the provided
    // The default behavior is to use the provided
    // generic breakpoint. 
    // generic breakpoint.
    // See javascript for an example of language-specific
    // See javascript for an example of language-specific
    // breakpoints.
    // breakpoints.
 Lines 360-376    Link Here 
    public void addCompilationUnit(Context cx,
    public void addCompilationUnit(Context cx,
                                   DebuggableScript dbgScript,
                                   DebuggableScript dbgScript,
                                   StringBuffer source) {
                                   String source) {
        CompilationUnit unit;
        CompilationUnit unit;
        unit = new CompilationUnit(this, dbgScript);
        unit = new CompilationUnit(this, dbgScript);
        m_units.addElement(unit);
        m_units.addElement(unit);
        m_functionToUnit.put(dbgScript, unit);
        if (unit.m_fnName != null) {
        if (unit.m_fnName != null) {
            m_functionMap.put(unit.m_fnName, unit);
            m_functionMap.put(unit.m_fnName, unit);
        }
        }
        // Associate breakpoints to this unit if 
        // Associate breakpoints to this unit if
        // the unit contains them...
        // the unit contains them...
        Enumeration e;
        Enumeration e;
        BreakPoint bp;
        BreakPoint bp;
 Lines 383-395    Link Here 
        propagateAll();
        propagateAll();
    }
    }
    CompilationUnit getCompilationUnit(DebuggableScript dbgScript) {
        return (CompilationUnit)m_functionToUnit.get(dbgScript);
    }
    public void compile(Context cx, Scriptable global)
    public void compile(Context cx, Scriptable global)
        throws BSFException, IOException {
        throws BSFException, IOException {
        Enumeration e;
        Enumeration e;
        Reader reader = new StringReader(m_text.toString());
        Reader reader = new StringReader(m_text.toString());
        m_script =
        m_script =
            cx.compileReader(global, reader, m_cell.getName(), 
            cx.compileReader(global, reader, m_cell.getName(),
                             m_startLine, null);
                             m_startLine, null);
        if (m_script == null)
        if (m_script == null)
            throw new BSFException("Compilation of the script "
            throw new BSFException("Compilation of the script "
 Lines 104-110    Link Here 
    public void disconnectedDebuggerNotify() {
    public void disconnectedDebuggerNotify() {
        m_rhinoDbg.disconnectedDebuggerNotify();
        m_rhinoDbg.disconnectedDebuggerNotify();
    }
    }
	
    BSFDebugManagerImpl getDebugManager() {
    BSFDebugManagerImpl getDebugManager() {
        return dbgmgr;
        return dbgmgr;
    }
    }
 Lines 114-120    Link Here 
        m_rhinoDbg.placeBreakpointAtLine(brkptid, docname, lineno);
        m_rhinoDbg.placeBreakpointAtLine(brkptid, docname, lineno);
    }
    }
    public void placeBreakpointAtOffset(int brkptid, String docname, 
    public void placeBreakpointAtOffset(int brkptid, String docname,
                                        int offset) throws BSFException {
                                        int offset) throws BSFException {
        m_rhinoDbg.placeBreakpointAtOffset(brkptid, docname, offset);
        m_rhinoDbg.placeBreakpointAtOffset(brkptid, docname, offset);
    }
    }
 Lines 140-146    Link Here 
    public Object call(Object object, String method, Object[] args)
    public Object call(Object object, String method, Object[] args)
        throws BSFException {
        throws BSFException {
        Object theReturnValue = null;
        Object theReturnValue = null;
        DebuggableEngine engine;
        Context cx;
        Context cx;
        try {
        try {
 Lines 160-172    Link Here 
                cx.setOptimizationLevel(-1);
                cx.setOptimizationLevel(-1);
                engine = cx.getDebuggableEngine();
                cx.setDebugger(m_rhinoDbg, new RhinoContextProxy(m_rhinoDbg));
                engine.setDebugger(m_rhinoDbg);
                theReturnValue = ScriptRuntime.call(cx, fun, global, args, 
                theReturnValue = ScriptRuntime.call(cx, fun, global, args,
                                                    null);
                                                    null);
            } 
            }
            else {
            else {
                cx.setOptimizationLevel(-1);
                cx.setOptimizationLevel(-1);
 Lines 175-184    Link Here 
                cx.setOptimizationLevel(0);
                cx.setOptimizationLevel(0);
                engine = cx.getDebuggableEngine();
                cx.setDebugger(null, null);
                engine.setDebugger(null);
                theReturnValue = ScriptRuntime.call(cx, fun, global, args, 
                theReturnValue = ScriptRuntime.call(cx, fun, global, args,
                                                    null);
                                                    null);
            }
            }
            if (theReturnValue instanceof Wrapper) {
            if (theReturnValue instanceof Wrapper) {
 Lines 193-201    Link Here 
    }
    }
    public void declareBean(BSFDeclaredBean bean) throws BSFException {
    public void declareBean(BSFDeclaredBean bean) throws BSFException {
        // Must wrap non-scriptable objects before presenting to Rhino
        if ((bean.bean instanceof Number) ||
        Scriptable wrapped = Context.toObject(bean.bean, global);
            (bean.bean instanceof String) ||
        global.put(bean.name, global, wrapped);
            (bean.bean instanceof Boolean)) {
            global.put(bean.name, global, bean.bean);
        } else {
            // Must wrap non-scriptable objects before presenting to Rhino
            Scriptable wrapped = Context.toObject(bean.bean, global);
            global.put(bean.name, global, wrapped);
        }
    }
    }
    /**
    /**
 Lines 210-216    Link Here 
        DocumentCell cell;
        DocumentCell cell;
        FnOrScript fnOrScript;
        FnOrScript fnOrScript;
        Script script;
        Script script;
        DebuggableEngine engine;
        Context cx;
        Context cx;
        try {
        try {
 Lines 231-243    Link Here 
                cx.setOptimizationLevel(-1);
                cx.setOptimizationLevel(-1);
                engine = cx.getDebuggableEngine();
                cx.setDebugger(m_rhinoDbg, new RhinoContextProxy(m_rhinoDbg));
                engine.setDebugger(m_rhinoDbg);
                // Muck w/ this iff someone else hasn't already got it true
                if (!engine.getBreakNextLine()) {
                    engine.setBreakNextLine(cell.getEntryExit());
                }
                fnOrScript.compile(cx, global);
                fnOrScript.compile(cx, global);
                m_rhinoDbg.setCompilingFnOrScript(null);
                m_rhinoDbg.setCompilingFnOrScript(null);
 Lines 245-251    Link Here 
                if (script != null) retval = script.exec(cx, global);
                if (script != null) retval = script.exec(cx, global);
                else retval = null;
                else retval = null;
            } 
            }
            else {
            else {
                cx.setOptimizationLevel(-1);
                cx.setOptimizationLevel(-1);
 Lines 254-264    Link Here 
                cx.setOptimizationLevel(0);
                cx.setOptimizationLevel(0);
                engine = cx.getDebuggableEngine();
                cx.setDebugger(null, null);
                engine.setDebugger(null);
                retval = cx.evaluateString(global, scriptText,
                retval = cx.evaluateString(global, scriptText,
                                           source, lineNo, 
                                           source, lineNo,
                                           null);
                                           null);
            }
            }
 Lines 296-309    Link Here 
                // Display its stack trace as a diagnostic
                // Display its stack trace as a diagnostic
                target = (Throwable) value;
                target = (Throwable) value;
            }
            }
        } 
        }
        else if (t instanceof EvaluatorException || 
        else if (t instanceof EvaluatorException ||
                 t instanceof SecurityException) {
                 t instanceof SecurityException) {
            message = t.getLocalizedMessage();
            message = t.getLocalizedMessage();
        } 
        }
        else if (t instanceof RuntimeException) {
        else if (t instanceof RuntimeException) {
            message = "Internal Error: " + t.toString();
            message = "Internal Error: " + t.toString();
        } 
        }
        else if (t instanceof StackOverflowError) {
        else if (t instanceof StackOverflowError) {
            message = "Stack Overflow";
            message = "Stack Overflow";
        }
        }
 Lines 313-319    Link Here 
        }
        }
        //REMIND: can we recover the line number here?  I think
        //REMIND: can we recover the line number here?  I think
        // Rhino does this by looking up the stack for bytecode 
        // Rhino does this by looking up the stack for bytecode
        // see Context.getSourcePositionFromStack()
        // see Context.getSourcePositionFromStack()
        // but I don't think this would work in interpreted mode
        // but I don't think this would work in interpreted mode
 Lines 323-329    Link Here 
            // corrected the situation by aborting the loop and
            // corrected the situation by aborting the loop and
            // a long stacktrace would end up on the user's console
            // a long stacktrace would end up on the user's console
            throw (Error) t;
            throw (Error) t;
        } 
        }
        else {
        else {
            throw new BSFException(BSFException.REASON_OTHER_ERROR,
            throw new BSFException(BSFException.REASON_OTHER_ERROR,
                                   "JavaScript Error: " + message,
                                   "JavaScript Error: " + message,
 Lines 333-339    Link Here 
    /**
    /**
     * initialize the engine. put the manager into the context -> manager
     * initialize the engine. put the manager into the context -> manager
     * map hashtable too. 
     * map hashtable too.
     */
     */
    public void initialize(BSFManager mgr, String lang, Vector declaredBeans)
    public void initialize(BSFManager mgr, String lang, Vector declaredBeans)
        throws BSFException {
        throws BSFException {
 Lines 68-302    Link Here 
* @author: Administrator
* @author: Administrator
*/
*/
public class JsContextStub 
public class JsContextStub
extends org.apache.bsf.debug.util.Skeleton
extends org.apache.bsf.debug.util.Skeleton
   implements JsContext {
   implements JsContext {
	RhinoContextProxy m_rcp;
    RhinoContextProxy m_rcp;
	RhinoEngineDebugger m_rhinoDbg;
    RhinoEngineDebugger m_rhinoDbg;
	DebugFrame m_frame;
    int m_frameno;
	int m_frameno;
    int m_lineno;
	boolean m_atBreakpoint;
    boolean m_atBreakpoint;
	boolean m_invalid;
    boolean m_invalid;
	/**
    CompilationUnit m_unit;
	 * JsContextStub constructor comment.
    Scriptable m_variableObject;
	 */
    Scriptable m_thisObj;
	public JsContextStub(RhinoContextProxy rcp, DebugFrame frame, int frameno)
	throws RemoteException {
    /**
			super(org.apache.bsf.debug.util.DebugConstants.JS_CONTEXT_TID);
     * JsContextStub constructor comment.
		
     */
		m_rhinoDbg = rcp.getRhinoEngineDebugger();
    JsContextStub(RhinoContextProxy rcp, CompilationUnit unit)
		m_rcp = rcp;
    throws RemoteException {
		m_frame = frame;
        super(org.apache.bsf.debug.util.DebugConstants.JS_CONTEXT_TID);
		m_frameno = frameno;
		m_invalid = false;
        m_rhinoDbg = rcp.getRhinoEngineDebugger();
		m_atBreakpoint = true;
        m_rcp = rcp;
	}
        m_unit = unit;
	//--------------------------------------------------
        m_invalid = false;
	void atBreakpoint(boolean atbrkpt) {
        m_atBreakpoint = true;
		m_atBreakpoint = atbrkpt;
    }
	}
	public JsObject bind(String id) throws RemoteException {
    DebugFrame getRhinoDebugFrame() {
		try {
        return new RhinoDebugFrame(this);
			Context.enter();
    }
			Scriptable obj = m_frame.getVariableObject();
			Object prop;
    //--------------------------------------------------
			while (obj != null) {
    void atBreakpoint(boolean atbrkpt) {
				Scriptable m = obj;
        m_atBreakpoint = atbrkpt;
				do {
    }
					if (m.has(id, obj))
    public JsObject bind(String id) throws RemoteException {
						return m_rhinoDbg.marshallScriptable(obj);
        try {
					m = m.getPrototype();
            Context.enter();
				} while (m != null);
            Scriptable obj = m_variableObject;
				obj = obj.getParentScope();
            Object prop;
			}
            while (obj != null) {
			throw new JsdiException("Name not in scope.");
                Scriptable m = obj;
		} finally {
                do {
			Context.exit();
                    if (m.has(id, obj))
		}
                        return m_rhinoDbg.marshallScriptable(obj);
	}
                    m = m.getPrototype();
	//--------------------------------------------------
                } while (m != null);
	public JsCode getCode() {
                obj = obj.getParentScope();
		if (m_invalid)
            }
			throw new JsdiException("This context no longer exists.");
            throw new JsdiException("Name not in scope.");
		if (!m_atBreakpoint)
        } finally {
			throw new JsdiException("Resumed context, can't get the code.");
            Context.exit();
        }
		try {
    }
			Context.enter();
    //--------------------------------------------------
			return null;
    public JsCode getCode() {
		} finally {
        if (m_invalid)
			Context.exit();
            throw new JsdiException("This context no longer exists.");
		}
        if (!m_atBreakpoint)
	}
            throw new JsdiException("Resumed context, can't get the code.");
	public int getDepth() {
		return m_frameno;
        try {
	}
            Context.enter();
	//--------------------------------------------------
            return null;
	public JsEngine getEngine() {
        } finally {
		RhinoEngineDebugger redbg;
            Context.exit();
		redbg = m_rcp.getRhinoEngineDebugger();
        }
		return (JsEngine) redbg.getDebugInterface(); 
    }
		
    public int getDepth() {
	}
        return m_frameno;
	//--------------------------------------------------
    }
	public int getLineNumber() {
    //--------------------------------------------------
		if (m_invalid)
    public JsEngine getEngine() {
			throw new JsdiException("This context no longer exists.");
        RhinoEngineDebugger redbg;
		if (!m_atBreakpoint)
        redbg = m_rcp.getRhinoEngineDebugger();
			throw new JsdiException("Resumed context, can't get line number.");
        return (JsEngine) redbg.getDebugInterface();
		try {
    }
			Context.enter();
    //--------------------------------------------------
			return m_frame.getLineNumber();
    public int getLineNumber() {
		} finally {
        if (m_invalid)
			Context.exit();
            throw new JsdiException("This context no longer exists.");
		}
        if (!m_atBreakpoint)
	}
            throw new JsdiException("Resumed context, can't get line number.");
	//------------------------------------------------------  
	public JsObject getScope() throws RemoteException {
        return m_lineno;
    }
		if (m_invalid)
    //------------------------------------------------------
			throw new JsdiException("This context no longer exists.");
    public JsObject getScope() throws RemoteException {
		if (!m_atBreakpoint)
			throw new JsdiException("Resumed context, can't get line number.");
        if (m_invalid)
            throw new JsdiException("This context no longer exists.");
		try {
        if (!m_atBreakpoint)
			Context.enter();
            throw new JsdiException("Resumed context, can't get line number.");
			Scriptable varobj = m_frame.getVariableObject();
			JsObject scope = m_rhinoDbg.marshallScriptable(varobj);
        try {
			return scope;
            Context.enter();
		} finally {
            JsObject scope = m_rhinoDbg.marshallScriptable(m_variableObject);
			Context.exit();
            return scope;
		}
        } finally {
	}
            Context.exit();
	//------------------------------------------------------  
        }
	public String getSourceName() {
    }
		if (m_invalid)
    //------------------------------------------------------
			throw new JsdiException("This context no longer exists.");
    public String getSourceName() {
		if (!m_atBreakpoint)
        if (m_invalid)
			throw new JsdiException("Resumed context, can't get line number.");
            throw new JsdiException("This context no longer exists.");
        if (!m_atBreakpoint)
		try {
            throw new JsdiException("Resumed context, can't get line number.");
			Context.enter();
			return m_frame.getSourceName();
        return m_unit.m_dbgScript.getSourceName();
		} finally {
    }
			Context.exit();
    //------------------------------------------------------
		}
    public JsObject getThis() throws RemoteException {
	}
	//------------------------------------------------------  
        if (m_invalid)
	public JsObject getThis() throws RemoteException {
            throw new JsdiException("This context no longer exists.");
        if (!m_atBreakpoint)
		if (m_invalid)
            throw new JsdiException("Resumed context, can't get line number.");
			throw new JsdiException("This context no longer exists.");
		if (!m_atBreakpoint)
        try {
			throw new JsdiException("Resumed context, can't get line number.");
            Context.enter();
            JsObject thisobj = null;
		try {
            Scriptable obj = null;
			Context.enter();
            NativeCall call = null;
			JsObject thisobj = null;
            Scriptable varobj = m_variableObject;
			Scriptable obj = null;
            if (varobj instanceof NativeCall) {
			NativeCall call = null;
                call = (NativeCall) varobj;
			Scriptable varobj = m_frame.getVariableObject();
                obj = call.getThisObj();
			if (varobj instanceof NativeCall) {
                thisobj = m_rhinoDbg.marshallScriptable(varobj);
				call = (NativeCall) varobj;
            }
				obj = call.getThisObj();
            return thisobj;
				thisobj = m_rhinoDbg.marshallScriptable(varobj);
        } finally {
			}
            Context.exit();
			return thisobj;
        }
		} finally {
    }
			Context.exit();
    //--------------------------------------------------
		}
    void invalidate() {
	}
        m_invalid = true;
	//--------------------------------------------------
    }
	void invalidate() {
    //------------------------------------------------------
		m_invalid = true;
    public boolean isEvalContext() {
	}
        if (m_invalid)
	//------------------------------------------------------  
            throw new JsdiException("This context no longer exists.");
	public boolean isEvalContext() {
        if (!m_atBreakpoint)
		if (m_invalid)
            throw new JsdiException("Resumed context, can't get line number.");
			throw new JsdiException("This context no longer exists.");
		if (!m_atBreakpoint)
        try {
			throw new JsdiException("Resumed context, can't get line number.");
            Context.enter();
            return false;
		try {
        } finally {
			Context.enter();
            Context.exit();
			return false;
        }
		} finally {
    }
			Context.exit();
    //------------------------------------------------------
		}
    public boolean isFunctionContext() {
	}
        if (m_invalid)
	//------------------------------------------------------  
            throw new JsdiException("This context no longer exists.");
	public boolean isFunctionContext() {
        if (!m_atBreakpoint)
		if (m_invalid)
            throw new JsdiException("Resumed context, can't get line number.");
			throw new JsdiException("This context no longer exists.");
		if (!m_atBreakpoint)
        try {
			throw new JsdiException("Resumed context, can't get line number.");
            Context.enter();
            return false;
		try {
        } finally {
			Context.enter();
            Context.exit();
			return false;
        }
		} finally {
    }
			Context.exit();
    //------------------------------------------------------
		}
    public boolean isScriptContext() {
	}
        if (m_invalid)
	//------------------------------------------------------  
            throw new JsdiException("This context no longer exists.");
	public boolean isScriptContext() {
        if (!m_atBreakpoint)
		if (m_invalid)
            throw new JsdiException("Resumed context, can't get line number.");
			throw new JsdiException("This context no longer exists.");
        try {
		if (!m_atBreakpoint)
            Context.enter();
			throw new JsdiException("Resumed context, can't get line number.");
            return true;
		try {
        } finally {
			Context.enter();
            Context.exit();
			return true;
        }
		} finally {
    }
			Context.exit();
    public Object lookupName(String name) {
		}
	}
        try {
	public Object lookupName(String name) {
            Context.enter();
            Scriptable obj = m_variableObject;
		try {
            Object prop;
			Context.enter();
            while (obj != null) {
			Scriptable obj = m_frame.getVariableObject();
                Scriptable m = obj;
			Object prop;
                do {
			while (obj != null) {
                    Object result = m.get(name, obj);
				Scriptable m = obj;
                    if (result != Scriptable.NOT_FOUND)
				do {
                        return result;
					Object result = m.get(name, obj);
                    m = m.getPrototype();
					if (result != Scriptable.NOT_FOUND)
                } while (m != null);
						return result;
                obj = obj.getParentScope();
					m = m.getPrototype();
            }
				} while (m != null);
            throw new JsdiException("Name is not in scope.");
				obj = obj.getParentScope();
        } finally {
			}
            Context.exit();
			throw new JsdiException("Name is not in scope.");
        }
		} finally {
    }
			Context.exit();
    /**
		}
     * Looks up a name in the scope chain and returns its value.
	}
     */
	/**
    public Object lookupName(Scriptable scopeChain, String id) {
	 * Looks up a name in the scope chain and returns its value.
	 */
        try {
	public Object lookupName(Scriptable scopeChain, String id) {
            Context.enter();
            Scriptable obj = scopeChain;
		try {
            Object prop;
			Context.enter();
            while (obj != null) {
			Scriptable obj = scopeChain;
                Scriptable m = obj;
			Object prop;
                do {
			while (obj != null) {
                    Object result = m.get(id, obj);
				Scriptable m = obj;
                    if (result != Scriptable.NOT_FOUND)
				do {
                        return result;
					Object result = m.get(id, obj);
                    m = m.getPrototype();
					if (result != Scriptable.NOT_FOUND)
                } while (m != null);
						return result;
                obj = obj.getParentScope();
					m = m.getPrototype();
            }
				} while (m != null);
            return null;
				obj = obj.getParentScope();
        } finally {
			}
            Context.exit();
			return null;
        }
		} finally {
    }
			Context.exit();
}
		}
	}
class RhinoDebugFrame implements DebugFrame {
    JsContextStub m_stub;
    RhinoDebugFrame(JsContextStub stub) {
        m_stub = stub;
    }
    public void onEnter(Context cx, Scriptable activation,
                        Scriptable thisObj, Object[] args)
    {
        m_stub.m_variableObject = activation;
        m_stub.m_thisObj = thisObj;
        m_stub.m_frameno = m_stub.m_rcp.m_frameStack.size();
        m_stub.m_rcp.m_frameStack.push(m_stub);
    }
    public void onExit(Context cx, boolean byThrow, Object resultOrException)
    {
        m_stub.m_rcp.m_frameStack.pop();
        m_stub.invalidate();
    }
    public void onExceptionThrown(Context cx, Throwable ex) {
        m_stub.m_rcp.m_reDbg.handleExceptionThrown(cx, m_stub.m_rcp, ex);
    }
    public void onLineChange(Context cx, int lineNumber) {
        m_stub.m_lineno = lineNumber;
        if (m_stub.m_unit.hasBreakpoint(lineNumber)) {
            m_stub.m_rcp.m_reDbg.handleBreakpointHit(cx, m_stub.m_rcp);
        }
    }
}
}
 Lines 62-99    Link Here 
import org.apache.bsf.debug.jsdi.*;
import org.apache.bsf.debug.jsdi.*;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.debug.DebuggableEngine;
/**
/**
 * Insert the type's description here.
 * Insert the type's description here.
 * Creation date: (9/6/2001 1:21:46 PM)
 * Creation date: (9/6/2001 1:21:46 PM)
 * @author: Administrator
 * @author: Administrator
 */
 */
public class JsEngineStub 
public class JsEngineStub
    extends org.apache.bsf.debug.util.Skeleton
    extends org.apache.bsf.debug.util.Skeleton
    implements JsEngine {
    implements JsEngine {
    RhinoEngineDebugger m_rhinoDbg;
    RhinoEngineDebugger m_rhinoDbg;
    boolean m_inCallback;
    boolean m_inCallback;
    boolean m_resumeExecution;
    boolean m_resumeExecution;
    Object  m_lock;	
    Object  m_lock;
	
    /**
    /**
     * JsEngineStub constructor comment.
     * JsEngineStub constructor comment.
     */
     */
    public JsEngineStub(RhinoEngineDebugger rhinoDbg) 
    public JsEngineStub(RhinoEngineDebugger rhinoDbg)
        throws RemoteException {
        throws RemoteException {
        super(org.apache.bsf.debug.util.DebugConstants.JS_ENGINE_TID);
        super(org.apache.bsf.debug.util.DebugConstants.JS_ENGINE_TID);
        m_rhinoDbg = rhinoDbg;
        m_rhinoDbg = rhinoDbg;
        m_lock = new Object();
        m_lock = new Object();
    }
    }
	
    public boolean isSuspended() throws RemoteException {
    public boolean isSuspended() throws RemoteException {
        return m_inCallback;
        return m_inCallback;
    }
    }
	
    public boolean poll() { return true; }
    public boolean poll() { return true; }
	
    public Object eval(String docname, String exp, int lineNo)
    public Object eval(String docname, String exp, int lineNo)
        throws RemoteException {
        throws RemoteException {
 Lines 125-131    Link Here 
        try {
        try {
            Context.enter();
            Context.enter();
            count = m_rhinoDbg.getContextCount();
            count = m_rhinoDbg.getContextCount();
            DebugLog.stdoutPrintln("	count = "+count, 
            DebugLog.stdoutPrintln("    count = "+count,
                                   DebugLog.BSF_LOG_L3);
                                   DebugLog.BSF_LOG_L3);
            return count;
            return count;
        } finally {
        } finally {
 Lines 133-139    Link Here 
        }
        }
    }
    }
  
    public String getThread() throws RemoteException {
    public String getThread() throws RemoteException {
        return m_rhinoDbg.getThread();
        return m_rhinoDbg.getThread();
    }
    }
 Lines 203-209    Link Here 
    public void stepIn() throws RemoteException {
    public void stepIn() throws RemoteException {
        try {
        try {
            Context.enter();
            Context.enter();
            DebugLog.stdoutPrintln("Step In command on "+this, 
            DebugLog.stdoutPrintln("Step In command on "+this,
                                   DebugLog.BSF_LOG_L3);
                                   DebugLog.BSF_LOG_L3);
            m_rhinoDbg.stepIn(this);
            m_rhinoDbg.stepIn(this);
        } catch (Exception ex) {
        } catch (Exception ex) {
 Lines 225-231    Link Here 
    }
    }
    public void stepOver() throws RemoteException {
    public void stepOver() throws RemoteException {
        RhinoContextProxy rcp;
        try {
        try {
            Context.enter();
            Context.enter();
            m_rhinoDbg.stepOver(this);
            m_rhinoDbg.stepOver(this);
 Lines 70-202    Link Here 
import java.rmi.RemoteException;
import java.rmi.RemoteException;
public class RhinoContextProxy {
class RhinoContextProxy {
    RhinoEngineDebugger m_reDbg;
    RhinoEngineDebugger m_reDbg;
    Context m_context;
    JsContextStub m_contextStub;
    DebuggableEngine m_engine;
    ObjArray m_frameStack = new ObjArray();
    boolean m_atBreakpoint;
    int m_frameCount;
    JsContextStub m_frames[];
    private static final int NO_STEP = 0, STEP_IN = 1, STEP_OVER = 2,
    private static final int NO_STEP = 0, STEP_IN = 1, STEP_OVER = 2,
        STEP_OUT = 3, STOP_ENGINE = 4, RUNNING = 5;
        STEP_OUT = 3, STOP_ENGINE = 4, RUNNING = 5;
    private int m_stepCmd, m_stepDepth;
    private int m_stepCmd, m_stepDepth;
    RhinoContextProxy(RhinoEngineDebugger reDbg, Context cx) {
    RhinoContextProxy(RhinoEngineDebugger reDbg) {
        m_reDbg = reDbg;
        m_reDbg = reDbg;
        m_context = cx;
        m_engine = cx.getDebuggableEngine();
    }
    }
    public void cancelStepping() {
    static RhinoContextProxy getCurrent() {
        Context cx = Context.getCurrentContext();
        if (cx == null) { return null; }
        return (RhinoContextProxy)cx.getDebuggerContextData();
    }
    void cancelStepping() {
        m_stepCmd = NO_STEP;
        m_stepCmd = NO_STEP;
        m_stepDepth = -1;
        m_stepDepth = -1;
        m_engine.setBreakNextLine(false);
    }
    }
    public JsContextStub getContext(int depth) {
    int getContextCount() {
        return m_frames[depth];
        return m_frameStack.size();
    }
    }
    public int getContextCount() {
    JsContextStub getContextStub(int no) {
        return m_frameCount;
        if (!(0 <= no && no < m_frameStack.size())) { return null; }
        return (JsContextStub)m_frameStack.get(no);
    }
    }
    public JsContextStub getFrame(int no) {
    JsContextStub getTopContextStub() {
        if (no < 0 || no > m_frameCount)
        return getContextStub(m_frameStack.size() - 1);
            return null;
        if (no == m_frameCount)
            return m_contextStub;
        else
            return m_frames[no];
    }
    }
    public int getLineNumber() {
    int getLineNumber() {
        DebugFrame frame = m_engine.getFrame(0);
        JsContextStub stub = getTopContextStub();
        return stub.m_lineno;
        return frame.getLineNumber();
    }
    }
    public RhinoEngineDebugger getRhinoEngineDebugger() {
    RhinoEngineDebugger getRhinoEngineDebugger() {
        return m_reDbg;
        return m_reDbg;
    }
    }
    String getSourceName() {
    String getSourceName() {
        DebugFrame frame = m_engine.getFrame(0);
        JsContextStub stub = getTopContextStub();
        return stub.m_unit.m_dbgScript.getSourceName();
        return frame.getSourceName();
    }
    }
    // We hit a known breakpoint.
    // We hit a known breakpoint.
    // We need to update the stack.
    // We need to update the stack.
    // Also, cancel any pending stepping operation.
    // Also, cancel any pending stepping operation.
    public JsContextStub hitBreakpoint() throws RemoteException {
    JsContextStub hitBreakpoint() throws RemoteException {
        cancelStepping();
        cancelStepping();
        updateStack();
        return getTopContextStub();
        return m_frames[0];
    }
    }
    JsContextStub exceptionThrown() throws RemoteException {
    public JsContextStub exceptionThrown() throws RemoteException {
        cancelStepping();
        cancelStepping();
        updateStack();
        return getTopContextStub();
        return m_frames[0];
    }
    }
    public void resumed() {
    void resumed() {
        JsContextStub stub;
        for (int f = 0, N = getContextCount(); f != N; ++f) {
        DebugFrame frame;
            getContextStub(f).atBreakpoint(false);
        m_atBreakpoint = false;
        for (int f = 0; f < m_frameCount; f++) {
            stub = m_frames[f];
            stub.atBreakpoint(false);
        }
        }
    }
    }
    public void run() {
    void run() {
        m_engine.setBreakNextLine(false);
        m_stepCmd = RUNNING;
        m_stepCmd = RUNNING;
        m_stepDepth = -1;
        m_stepDepth = -1;
    }
    }
    public void stepIn() {
    void stepIn() {
        m_engine.setBreakNextLine(true);
        m_stepCmd = STEP_IN;
        m_stepCmd = STEP_IN;
        m_stepDepth = m_frameCount;
        m_stepDepth = getContextCount();
    }
    }
    public void stepOut() {
    void stepOut() {
        m_engine.setBreakNextLine(true);
        m_stepCmd = STEP_OUT;
        m_stepCmd = STEP_OUT;
        m_stepDepth = m_frameCount;
        m_stepDepth = getContextCount();
    }
    }
    public void stepOver() {
    void stepOver() {
        m_engine.setBreakNextLine(true);
        m_stepCmd = STEP_OVER;
        m_stepCmd = STEP_OVER;
        m_stepDepth = m_frameCount;
        m_stepDepth = getContextCount();
    }
    }
    public JsContextStub entry_exit_mode() throws RemoteException {
    JsContextStub entry_exit_mode() throws RemoteException {
        cancelStepping();
        cancelStepping();
        updateStack();
        return getTopContextStub();
        return m_frames[0];
    }
    }
    public JsContextStub stepping() {
    JsContextStub stepping() {
        // Did we hit a known breakpoint?
        // Did we hit a known breakpoint?
        int frameCount = m_engine.getFrameCount();
        int frameCount = getContextCount();
        try {
        try {
            switch (m_stepCmd) {
            switch (m_stepCmd) {
 Lines 204-242    Link Here 
                cancelStepping();
                cancelStepping();
                break;
                break;
            case STOP_ENGINE :
            case STOP_ENGINE :
                updateStack();
                cancelStepping();
                cancelStepping();
                return m_frames[0];
                return getTopContextStub();
            case STEP_IN :
            case STEP_IN :
                // OG if ((frameCount == m_stepDepth + 1) || 
                // OG if ((frameCount == m_stepDepth + 1) ||
                // (frameCount == m_stepDepth)) {
                // (frameCount == m_stepDepth)) {
                // step if we are in the same frame (nothing to step in... :-)
                // step if we are in the same frame (nothing to step in... :-)
                // if we are in a called frame...
                // if we are in a called frame...
                // but also if we stepped out of the current frame...
                // but also if we stepped out of the current frame...
                if ((frameCount >= m_stepDepth) 
                    || (frameCount < m_stepDepth)) {
                    updateStack();
                    cancelStepping();
                    cancelStepping();
                    return m_frames[0];
                    return getTopContextStub();
                }
                break;
            case STEP_OVER :
            case STEP_OVER :
                // OG if (frameCount == m_stepDepth) {
                // OG if (frameCount == m_stepDepth) {
                // step if we are in the same frame or above...
                // step if we are in the same frame or above...
                // this basically avoids any children frame but 
                // this basically avoids any children frame but
                // covers the return of the current frame.
                // covers the return of the current frame.
                if (frameCount <= m_stepDepth) {
                if (frameCount <= m_stepDepth) {
                    updateStack();
                    cancelStepping();
                    cancelStepping();
                    return m_frames[0];
                    return getTopContextStub();
                }
                }
                break;
                break;
            case STEP_OUT :
            case STEP_OUT :
                // OG if (frameCount == m_stepDepth - 1) {
                // OG if (frameCount == m_stepDepth - 1) {
                if (frameCount < m_stepDepth) {
                if (frameCount < m_stepDepth) {
                    updateStack();
                    cancelStepping();
                    cancelStepping();
                    return m_frames[0];
                    return getTopContextStub();
                }
                }
                break;
                break;
            default :
            default :
 Lines 249-303    Link Here 
        return null;
        return null;
    }
    }
    public void stopEngine() {
    void stopEngine() {
        m_engine.setBreakNextLine(true);
        m_stepCmd = STOP_ENGINE;
        m_stepCmd = STOP_ENGINE;
        m_stepDepth = -1;
        m_stepDepth = -1;
    }
    public void updateStack() throws RemoteException {
        JsContextStub frames[];
        JsContextStub stub;
        DebugFrame frame;
        int nf, of, frameCount;
        m_atBreakpoint = true;
        frameCount = m_engine.getFrameCount();
        frames = new JsContextStub[frameCount];
        // scan the stacks from the outer frame down
        // to the inner one of the shortest of the old
        // and the new known stack.
        // The goal is to recognize the DebugFrame objects
        // that are the sames so that we can reuse the 
        // stubs for those. 
        // As soon as a DebugFrame object is found different,
        // the rest of the stack is different, all the old
        // stubs can be dropped and invalidated, new ones
        // must be created.
        for (nf = frameCount - 1, of = m_frameCount - 1;
             nf >= 0 && of >= 0;
             nf--, of--) {
            frame = m_engine.getFrame(nf);
            if (frame == m_frames[of].m_frame) {
                frames[nf] = m_frames[of];
            } else
                break;
        }
        // now drop all old frames that diverged.
        // Also invalidate the frame stubs so to
        // tracked that they are no longer valid.
        for (; of >= 0; of--) {
            m_reDbg.dropStub(m_frames[of].m_frame);
            m_frames[of].invalidate();
        }
        for (; nf >= 0; nf--) {
            frame = m_engine.getFrame(nf);
            frames[nf] = new JsContextStub(this, frame, nf);
        }
        m_frames = frames;
        m_frameCount = frameCount;
    }
    }
}
}
 Lines 74-97    Link Here 
import org.apache.bsf.debug.*;
import org.apache.bsf.debug.*;
import org.apache.bsf.debug.jsdi.*;
import org.apache.bsf.debug.jsdi.*;
public class RhinoEngineDebugger implements Debugger {
class RhinoEngineDebugger implements Debugger {
    /** The global script object, where all embedded functions are defined,
    /** The global script object, where all embedded functions are defined,
     * as well as the standard ECMA "core" objects.
     * as well as the standard ECMA "core" objects.
     */	
     */
    private Scriptable global;
    private Scriptable global;
    private JsObject globalstub;
    private JsObject globalstub;
    private RhinoContextProxy m_rcp;
    private Scriptable undefined;
    private Scriptable undefined;
    private JsObject undefinedStub;
    private JsObject undefinedStub;
    /** 
    /**
     *  Hashtable allowing to find the stub for an object in the JavaScript
     *  Hashtable allowing to find the stub for an object in the JavaScript
     *  environment if one exists.
     *  environment if one exists.
     *  Typically: Scriptable, Function, Script, etc.
     *  Typically: Scriptable, Function, Script, etc.
     *  This is not used for Context and DebugFrame.
     *  This is not used for Context and DebugFrame.
     *  They typically contains JsObject associated to 
     *  They typically contains JsObject associated to
     *  org.mozilla.javascript.ScriptableObject
     *  org.mozilla.javascript.ScriptableObject
     */
     */
    private Hashtable stubs;
    private Hashtable stubs;
 Lines 102-117    Link Here 
    private FnOrScript m_compilingFnOrScript;
    private FnOrScript m_compilingFnOrScript;
    private JavaScriptEngine m_eng;
    private JavaScriptEngine m_eng;
    private Thread m_thread;
    private Hashtable m_documents;
    private Hashtable m_documents;
    BSFDebugManagerImpl dbgmgr;
    BSFDebugManagerImpl dbgmgr;
    public RhinoEngineDebugger(JavaScriptEngine eng) 
    RhinoEngineDebugger(JavaScriptEngine eng)
        throws RemoteException {
        throws RemoteException {
        super();
        super();
        m_thread = Thread.currentThread();
        m_eng = eng;
        m_eng = eng;
        dbgmgr = eng.getDebugManager();
        dbgmgr = eng.getDebugManager();
 Lines 127-171    Link Here 
    /**
    /**
     * Called when our debugger has been disconnected.
     * Called when our debugger has been disconnected.
     */
     */
    public void disconnectedDebuggerNotify() {
    void disconnectedDebuggerNotify() {
        m_callbacks = null;
        m_callbacks = null;
    }
    }
    void addStub(Context cx, RhinoContextProxy jscx) {
        stubs.put(cx, jscx);
    }
    void addStub(DebugFrame frame, JsContextStub stub) {
        stubs.put(frame, stub);
    }
    void addStub(Scriptable sobj, JsObject jsobj) {
    void addStub(Scriptable sobj, JsObject jsobj) {
        stubs.put(sobj, jsobj);
        stubs.put(sobj, jsobj);
    }
    }
    void dropStub(Object key) {
    void dropStub(Scriptable key) {
        stubs.remove(key);
        stubs.remove(key);
    }
    }
    public synchronized DocumentCell getDocumentCell(String name) {
    synchronized DocumentCell getDocumentCell(String name) {
        return (DocumentCell) m_documents.get(name);
        return (DocumentCell) m_documents.get(name);
    }
    }
    // Called upon creation of a BSFManager.
    // Called upon creation of a BSFManager.
    public synchronized DocumentCell loadDocumentNotify(String name) {
    synchronized DocumentCell loadDocumentNotify(String name) {
        DocumentCell cell;
        DocumentCell cell;
        cell = (DocumentCell) m_documents.get(name);
        cell = (DocumentCell) m_documents.get(name);
        if (cell == null) {
        if (cell == null) {
            cell = new DocumentCell(this, name);
            cell = new DocumentCell(this, name);
            m_documents.put(name, cell);
            m_documents.put(name, cell);
            if (dbgmgr!=null) 
            if (dbgmgr!=null)
                dbgmgr.loadDocumentNotify(m_eng, name);
                dbgmgr.loadDocumentNotify(m_eng, name);
        }
        }
        return cell;
        return cell;
    }
    }
    public synchronized void placeBreakpointAtLine(int brkptid,
    synchronized void placeBreakpointAtLine(int brkptid,
                                                   String docname,
                                                   String docname,
                                                   int lineno) {
                                                   int lineno) {
 Lines 174-180    Link Here 
        cell.addBreakpointAtLine(brkptid, lineno);
        cell.addBreakpointAtLine(brkptid, lineno);
    }
    }
    public synchronized void placeBreakpointAtOffset(int brkptid,
    synchronized void placeBreakpointAtOffset(int brkptid,
                                                     String docname,
                                                     String docname,
                                                     int offset) {
                                                     int offset) {
 Lines 183-189    Link Here 
        cell.addBreakpointAtOffset(brkptid, offset);
        cell.addBreakpointAtOffset(brkptid, offset);
    }
    }
    public void removeBreakpoint(String docname, int brkptid)
    void removeBreakpoint(String docname, int brkptid)
        throws BSFException {
        throws BSFException {
        DocumentCell cell;
        DocumentCell cell;
 Lines 191-197    Link Here 
        cell.removeBreakpoint(brkptid);
        cell.removeBreakpoint(brkptid);
    }
    }
    public void setEntryExit(String docname, boolean on)
    void setEntryExit(String docname, boolean on)
        throws BSFException {
        throws BSFException {
        DocumentCell cell;
        DocumentCell cell;
 Lines 199-205    Link Here 
        cell.setEntryExit(on);
        cell.setEntryExit(on);
    }
    }
    public Object eval(String docname, String fnOrScript, int lineno)
    Object eval(String docname, String fnOrScript, int lineno)
        throws RemoteException {
        throws RemoteException {
        Object retval;
        Object retval;
        try {
        try {
 Lines 210-222    Link Here 
        }
        }
    }
    }
    public JsContext getContext(int depth) {
    JsContext getContext(int depth) {
        if (m_rcp != null) return m_rcp.getContext(depth);
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        if (rcp != null) return rcp.getContextStub(depth);
        return null;
        return null;
    }
    }
    public int getContextCount() {
    int getContextCount() {
        if (m_rcp != null) return m_rcp.getContextCount();
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        if (rcp != null) return rcp.getContextCount();
        return -1;
        return -1;
    }
    }
 Lines 224-247    Link Here 
     * Return the current debugger.
     * Return the current debugger.
     * @return the debugger, or null if none is attached.
     * @return the debugger, or null if none is attached.
     */
     */
    public JsCallbacks getDebugger() {
    JsCallbacks getDebugger() {
        return m_callbacks;
        return m_callbacks;
    }
    }
    public Object getDebugInterface() {
    Object getDebugInterface() {
        return engineStub;
        return engineStub;
    }
    }
    public JsObject getGlobalObject() {
    JsObject getGlobalObject() {
        return globalstub;
        return globalstub;
    }
    }
    public RhinoContextProxy getRhinoContextProxy() {
        return m_rcp;
    }
    RhinoContextProxy getStub(Context cx) {
    RhinoContextProxy getStub(Context cx) {
        return (RhinoContextProxy) stubs.get(cx);
        return (RhinoContextProxy)cx.getDebuggerContextData();
    }
    }
    JsContextStub getStub(DebugFrame frame) {
    JsContextStub getStub(DebugFrame frame) {
 Lines 252-270    Link Here 
        return (JsObject) stubs.get(sobj);
        return (JsObject) stubs.get(sobj);
    }
    }
    public JsObject getUndefinedValue() {
    JsObject getUndefinedValue() {
        return undefinedStub;
        return undefinedStub;
    }
    }
    public String getThread() {
    String getThread() {
        Context cx = Context.getCurrentContext();
        String resultstr = "";
        String resultstr = "";
        if (m_thread != null) {
        if (cx != null) {
            try {
            try {
                final String resultstrf = (String)
                final String resultstrf = (String)
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                        public Object run() throws Exception {
                            return m_thread.getName();
                            return Thread.currentThread().getName();
                        }
                        }
                    });
                    });
            resultstr = resultstrf;
            resultstr = resultstrf;
 Lines 277-291    Link Here 
        return resultstr;
        return resultstr;
    }
    }
    public String getThreadGroup() {
    String getThreadGroup() {
        Context cx = Context.getCurrentContext();
        String resultstr = "";
        String resultstr = "";
        if (m_thread != null) {
        if (cx != null) {
            try {
            try {
                final String resultstrf = (String)
                final String resultstrf = (String)
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                        public Object run() throws Exception {
                            return m_thread.getThreadGroup().getName();
                            return Thread.currentThread().getThreadGroup().
                                        getName();
                        }
                        }
                    });
                    });
            resultstr = resultstrf;
            resultstr = resultstrf;
 Lines 305-311    Link Here 
    // to implement STEP_IN, STEP_OUT, and STEP_OVER.
    // to implement STEP_IN, STEP_OUT, and STEP_OVER.
    //---------------------------------------------------------
    //---------------------------------------------------------
    public void handleBreakpointHit(Context cx) {
    void handleBreakpointHit(Context cx, RhinoContextProxy rcp) {
        JsCallbacks debugger;
        JsCallbacks debugger;
        BreakPoint bp;
        BreakPoint bp;
        Enumeration e;
        Enumeration e;
 Lines 313-360    Link Here 
        boolean breakpointFound=false;
        boolean breakpointFound=false;
        String name;
        String name;
        int lineno;
        int lineno;
        boolean suspend=false;
		
        DebugLog.stdoutPrintln("**** Handling a breakpoint hit...",
        m_thread = Thread.currentThread();
        DebugLog.stdoutPrintln("**** Handling a breakpoint hit...", 
                               DebugLog.BSF_LOG_L3);
                               DebugLog.BSF_LOG_L3);
        m_rcp = getStub(cx);
        // if we have no callbacks... then just
        if (m_rcp == null) {
            m_rcp = new RhinoContextProxy(this, cx);
            addStub(cx, m_rcp);
        }
        // if we have no callbacks... then just 
        // ignore the breakpoint hit, do a run
        // ignore the breakpoint hit, do a run
        // so that execution resumes...
        // so that execution resumes...
        if (m_callbacks==null) {
        if (m_callbacks==null) {
            DebugLog.stdoutPrintln("	No callbacks, resuming...", DebugLog.BSF_LOG_L3);
            DebugLog.stdoutPrintln("    No callbacks, resuming...", DebugLog.BSF_LOG_L3);
            m_rcp.run();
            rcp.run();
        } else {
        } else {
            // First, check that we didn't hit a known breakpoint.
            // First, check that we didn't hit a known breakpoint.
            // First, search if we have breakpoints for the current documents
            // First, search if we have breakpoints for the current documents
            name = m_rcp.getSourceName();
            name = rcp.getSourceName();
            lineno = m_rcp.getLineNumber();
            lineno = rcp.getLineNumber();
            DebugLog.stdoutPrintln("	in "+name+" at "+lineno, DebugLog.BSF_LOG_L3);
            DebugLog.stdoutPrintln("    in "+name+" at "+lineno, DebugLog.BSF_LOG_L3);
            cell = getDocumentCell(name);
            cell = getDocumentCell(name);
            if (cell != null) 
            if (cell != null)
                _handleBreakpointHit(cell,lineno);
                _handleBreakpointHit(rcp,cell,lineno);
        } 
        }
        m_rcp = null;
    }
    }
    public void _handleBreakpointHit(DocumentCell cell, int lineno) {
    void _handleBreakpointHit(RhinoContextProxy rcp,
                              DocumentCell cell, int lineno)
    {
        JsCallbacks debugger;
        JsCallbacks debugger;
        BreakPoint bp;
        BreakPoint bp;
        Enumeration e;
        Enumeration e;
        JsContext stub=null;
        JsContext stub=null;
        boolean breakpointFound=false;
        boolean breakpointFound=false;
        boolean suspend=false;
        boolean suspend=false;
		
        try {
        try {
            bp = cell.findBreakpointAtLine(lineno);
            bp = cell.findBreakpointAtLine(lineno);
        } catch (BSFException bsfex) {
        } catch (BSFException bsfex) {
 Lines 363-381    Link Here 
        if (bp != null) {
        if (bp != null) {
            breakpointFound = true;
            breakpointFound = true;
            try {
            try {
                stub = m_rcp.hitBreakpoint();
                stub = rcp.hitBreakpoint();
                DebugLog.stdoutPrintln("	breakpoint callback...", DebugLog.BSF_LOG_L3);
                DebugLog.stdoutPrintln("    breakpoint callback...", DebugLog.BSF_LOG_L3);
             	m_callbacks.createFuture(m_rcp);
                 m_callbacks.createFuture(rcp);
                m_callbacks.handleBreakpointHit(stub);
                m_callbacks.handleBreakpointHit(stub);
                suspend = true;
                suspend = true;
            } catch (RemoteException rex) {
            } catch (RemoteException rex) {
                DebugLog.stderrPrintln("	EXCEPTION OCCURED DURING BREAKPOINT CALLBACK", DebugLog.BSF_LOG_L0);				
                DebugLog.stderrPrintln("    EXCEPTION OCCURED DURING BREAKPOINT CALLBACK", DebugLog.BSF_LOG_L0);
                DebugLog.stderrPrintln(rex.getMessage(), DebugLog.BSF_LOG_L0);
                DebugLog.stderrPrintln(rex.getMessage(), DebugLog.BSF_LOG_L0);
                rex.printStackTrace();
                rex.printStackTrace();
                suspend = false;
                suspend = false;
            }
            }
        } else {
        } else {
            DebugLog.stdoutPrintln("	didn't find a breakpoint...", DebugLog.BSF_LOG_L3);
            DebugLog.stdoutPrintln("    didn't find a breakpoint...", DebugLog.BSF_LOG_L3);
            breakpointFound = false;
            breakpointFound = false;
        }
        }
 Lines 384-470    Link Here 
            // line in the current document, we must be stepping
            // line in the current document, we must be stepping
            // or in entry/exit mode
            // or in entry/exit mode
            try {
            try {
                stub = m_rcp.stepping();
                stub = rcp.stepping();
                FnOrScript current = cell.findFnOrScriptContaining(lineno);
                FnOrScript current = cell.findFnOrScriptContaining(lineno);
                if (stub != null) {
                if (stub != null) {
                    cell.setLastFnOrScript(current);
                    cell.setLastFnOrScript(current);
                    DebugLog.stdoutPrintln("	stepping-done callback...", 
                    DebugLog.stdoutPrintln("    stepping-done callback...",
                                           DebugLog.BSF_LOG_L3);
                                           DebugLog.BSF_LOG_L3);
                	m_callbacks.createFuture(m_rcp);
                    m_callbacks.createFuture(rcp);
                    m_callbacks.handleSteppingDone(stub);
                    m_callbacks.handleSteppingDone(stub);
                    suspend = true;
                    suspend = true;
                } 
                }
                else if (cell.getEntryExit() &&
                else if (cell.getEntryExit() &&
                         (current != cell.getLastFnOrScript()) &&
                         (current != cell.getLastFnOrScript()) &&
                         (m_rcp.getContextCount() == 0)) {
                         (rcp.getContextCount() == 0)) {
                    cell.setLastFnOrScript(current);
                    cell.setLastFnOrScript(current);
                    stub = m_rcp.entry_exit_mode();
                    stub = rcp.entry_exit_mode();
                    DebugLog.stdoutPrintln("    entry/exit mode...", 
                    DebugLog.stdoutPrintln("    entry/exit mode...",
                                           DebugLog.BSF_LOG_L3);
                                           DebugLog.BSF_LOG_L3);
                	m_callbacks.createFuture(m_rcp);
                    m_callbacks.createFuture(rcp);
                    m_callbacks.handleSteppingDone(stub);
                    m_callbacks.handleSteppingDone(stub);
                    suspend = true;
                    suspend = true;
                }
                }
                else {
                else {
                    DebugLog.stdoutPrintln("	No reason to suspend execution.", DebugLog.BSF_LOG_L3);				
                    DebugLog.stdoutPrintln("    No reason to suspend execution.", DebugLog.BSF_LOG_L3);
                    suspend = false;
                    suspend = false;
                }
                }
            } catch (RemoteException rex) {
            } catch (RemoteException rex) {
                DebugLog.stderrPrintln("	EXCEPTION OCCURED DURING STEPPING-DONE CALLBACK", DebugLog.BSF_LOG_L0);				
                DebugLog.stderrPrintln("    EXCEPTION OCCURED DURING STEPPING-DONE CALLBACK", DebugLog.BSF_LOG_L0);
                DebugLog.stderrPrintln(rex.getMessage(), DebugLog.BSF_LOG_L0);
                DebugLog.stderrPrintln(rex.getMessage(), DebugLog.BSF_LOG_L0);
                rex.printStackTrace();
                rex.printStackTrace();
                suspend = false;
                suspend = false;
            }
            }
        }
        }
        if (suspend) {
        if (suspend) {
            // now, suspend this thread... until 
            // now, suspend this thread... until
            // we restart.
            // we restart.
            try {
            try {
                m_callbacks.suspendFuture(m_rcp);
                m_callbacks.suspendFuture(rcp);
            } catch (Exception ex) {
            } catch (Exception ex) {
                DebugLog.stdoutPrintln("Future creation failed... releasing the engine", DebugLog.BSF_LOG_L3);
                DebugLog.stdoutPrintln("Future creation failed... releasing the engine", DebugLog.BSF_LOG_L3);
                m_rcp.run();
                rcp.run();
            }
            }
        }			
        }
    }
    }
    public void run(JsEngineStub eng) throws Exception {
    void run(JsEngineStub eng) throws Exception {
        DebugLog.stdoutPrintln("RhinoEngineDebugger::run()...",
        DebugLog.stdoutPrintln("RhinoEngineDebugger::run()...",
                               DebugLog.BSF_LOG_L3);
                               DebugLog.BSF_LOG_L3);
        m_rcp.run(); 
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        m_callbacks.completeFuture(m_rcp);
        rcp.run();
        m_callbacks.completeFuture(rcp);
    }
    }
    public void stepIn(JsEngineStub eng) throws Exception {
    void stepIn(JsEngineStub eng) throws Exception {
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepIn()...",
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepIn()...",
                               DebugLog.BSF_LOG_L3);
                               DebugLog.BSF_LOG_L3);
        m_rcp.stepIn();
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        m_callbacks.completeFuture(m_rcp);
        rcp.stepIn();
        m_callbacks.completeFuture(rcp);
    }
    }
    public void stepOut(JsEngineStub eng) throws Exception {
    void stepOut(JsEngineStub eng) throws Exception {
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepOut()...",
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepOut()...",
                               DebugLog.BSF_LOG_L3);
                               DebugLog.BSF_LOG_L3);
        m_rcp.stepOut();
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        m_callbacks.completeFuture(m_rcp);
        rcp.stepOut();
        m_callbacks.completeFuture(rcp);
    }
    }
    public void stepOver(JsEngineStub eng) throws Exception {
    void stepOver(JsEngineStub eng) throws Exception {
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepOver()...",
        DebugLog.stdoutPrintln("RhinoEngineDebugger::stepOver()...",
                               DebugLog.BSF_LOG_L3);
                               DebugLog.BSF_LOG_L3);
        m_rcp.stepOver();
        RhinoContextProxy rcp = RhinoContextProxy.getCurrent();
        m_callbacks.completeFuture(m_rcp);
        rcp.stepOver();
        m_callbacks.completeFuture(rcp);
    }
    }
	
    public void handleCompilationDone(Context cx,
    public void handleCompilationDone(Context cx,
                                      DebuggableScript fnOrScript,
                                      DebuggableScript fnOrScript,
                                      StringBuffer source) {
                                      String source) {
        m_thread = Thread.currentThread();
        m_compilingFnOrScript.addCompilationUnit(cx, fnOrScript, source);
        m_compilingFnOrScript.addCompilationUnit(cx, fnOrScript, source);
    }
    }
    public void handleExceptionThrown(Context cx, Object exceptionThrown) {
    public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
        CompilationUnit unit;
        unit = m_compilingFnOrScript.getCompilationUnit(fnOrScript);
        RhinoContextProxy rcp = getStub(cx);
        try {
            JsContextStub stub = new JsContextStub(rcp, unit);
            return stub.getRhinoDebugFrame();
        } catch (RemoteException rex) {
            DebugLog.stderrPrintln("    EXCEPTION OCCURED DURING FRAME INITIALIZATION", DebugLog.BSF_LOG_L0);
            DebugLog.stderrPrintln(rex.getMessage(), DebugLog.BSF_LOG_L0);
            rex.printStackTrace();
            return null;
        }
    }
    void handleExceptionThrown(Context cx, RhinoContextProxy rcp,
                               Throwable exceptionThrown)
    {
        JsContext stub;
        JsContext stub;
        JsCallbacks debugger;
        JsCallbacks debugger;
        BreakPoint bp;
        BreakPoint bp;
 Lines 473-525    Link Here 
        String name,msg;
        String name,msg;
        Exception ex;
        Exception ex;
        int lineno;
        int lineno;
        NativeError error;
		
        // if we have no callbacks... then just
        m_thread = Thread.currentThread();
        // ignore the breakpoint hit, do a run
        m_rcp = getStub(cx);
        // so that execution resumes...
        if (m_rcp == null) {
        if (m_callbacks==null) {
            m_rcp = new RhinoContextProxy(this, cx);
            rcp.run();
            addStub(cx, m_rcp);
            return;
        }
        }
        try {
            // if we have no callbacks... then just 
            // ignore the breakpoint hit, do a run
            // so that execution resumes...
            if (m_callbacks==null) {
                m_rcp.run();
                return;
            }
            // First, check that we didn't hit a known breakpoint.
        // First, check that we didn't hit a known breakpoint.
            // First, search if we have breakpoints for the current documents
        // First, search if we have breakpoints for the current documents
            name = m_rcp.getSourceName();
        name = rcp.getSourceName();
            lineno = m_rcp.getLineNumber();
        lineno = rcp.getLineNumber();
            try {
        if (exceptionThrown instanceof EcmaError) {
                error = (NativeError)exceptionThrown;
            msg = ((EcmaError)exceptionThrown).getErrorObject().toString();
                msg = error.getName() + ": " + error.getMessage();
        } else {
            } catch (ClassCastException ccex) {
            msg = exceptionThrown.toString();
                msg = "Unknown JavaScript Exception";
        }
            }
        ex = new Exception(msg);
            ex = new Exception(msg);
            cell = getDocumentCell(name);
        cell = getDocumentCell(name);
            if (cell == null) return;
        if (cell == null) return;
            try {
        try {
                stub = m_rcp.exceptionThrown();	
            stub = rcp.exceptionThrown();
                m_callbacks.createFuture(m_rcp);
            m_callbacks.createFuture(rcp);
                m_callbacks.handleExceptionThrown(stub,ex);
            m_callbacks.handleExceptionThrown(stub,ex);
				
                // now, suspend this thread... until 
            // now, suspend this thread... until
                // we restart.
            // we restart.
                m_callbacks.suspendFuture(m_rcp);
            m_callbacks.suspendFuture(rcp);
				
            } catch (Exception ex2) {
        } catch (Exception ex2) {
                m_rcp.run();
            rcp.run();
				
            }
        } finally {
            m_rcp = null;
        }
        }
    }
    }
 Lines 568-577    Link Here 
     * The engine will call the attached debugger's handleBreakpointHit
     * The engine will call the attached debugger's handleBreakpointHit
     * method on the next line it executes if isLineStep is true.
     * method on the next line it executes if isLineStep is true.
     * May be used from another thread to interrupt execution.
     * May be used from another thread to interrupt execution.
     * 
     *
     * @param isLineStep if true, break next line
     * @param isLineStep if true, break next line
     */
     */
    public void setBreakNextLine(JsContext context, boolean isLineStep) {
    void setBreakNextLine(JsContext context, boolean isLineStep) {
    }
    }
    void setCompilingFnOrScript(FnOrScript fnOrScript) {
    void setCompilingFnOrScript(FnOrScript fnOrScript) {
 Lines 583-589    Link Here 
     * @param debugger the debugger to be used on callbacks from
     * @param debugger the debugger to be used on callbacks from
     * the engine.
     * the engine.
     */
     */
    public void setDebugger(JsCallbacks debugger) {
    void setDebugger(JsCallbacks debugger) {
        m_callbacks = debugger;
        m_callbacks = debugger;
    }
    }
}
}