From 40c54d32e287b7f043dd0d94ad43c250082c7172 Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 11 Aug 2009 21:09:14 +0200 Subject: Implement connection between JSC::Debugger and QScriptEngineAgent. Complete reimplementation of QScriptEngineAgentPrivate. New QScriptEngineAgentPrivate implementation makes conversion from different JSC::Debuger types and events to corresponding QScriptEngineAgent. contextPush and contextPop events are created in QScriptEngine each time contextPush or contextPop is ordered from public API --- src/script/api/qscriptengine.cpp | 17 ++++----- src/script/api/qscriptengineagent.cpp | 57 ++++++++++++++++++++++-------- src/script/api/qscriptengineagent_p.h | 65 ++++++++++++++++++++++++++++++++--- 3 files changed, 113 insertions(+), 26 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index cc7ead3..dfdfdac 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -44,6 +44,7 @@ #include "qnumeric.h" #include "qscriptengine_p.h" +#include "qscriptengineagent_p.h" #include "qscriptcontext_p.h" #include "qscriptstring_p.h" #include "qscriptvalue_p.h" @@ -2252,11 +2253,10 @@ QScriptContext *QScriptEngine::pushContext() previousFrame, 0, argCount, 0); QScriptContext *ctx = d->contextForFrame(d->currentFrame); ctx->setThisObject(globalObject()); + + if (agent()) + agent()->contextPush(); return ctx; - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY -// notifyContextPush(); TODO -#endif } /*! @@ -2267,6 +2267,8 @@ QScriptContext *QScriptEngine::pushContext() */ void QScriptEngine::popContext() { + if (agent()) + agent()->contextPop(); Q_D(QScriptEngine); if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0 || d->currentFrame->returnValueRegister() != 0 || !currentContext()->parentContext()) { @@ -2278,9 +2280,6 @@ void QScriptEngine::popContext() d->currentFrame->scopeChain()->pop()->deref(); d->currentFrame = d->currentFrame->callerFrame(); registerFile.shrink(newEnd); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY -// notifyContextPop(); TODO -#endif } /*! @@ -3530,9 +3529,11 @@ QT_END_INCLUDE_NAMESPACE */ void QScriptEngine::setAgent(QScriptEngineAgent *agent) { - qWarning("QScriptEngine::setAgent() not implemented"); Q_D(QScriptEngine); + if (d->agent) + QScriptEngineAgentPrivate::get(d->agent)->detach(); d->agent = agent; + QScriptEngineAgentPrivate::get(d->agent)->attach(); } /*! diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index 3d96725..b958f2b 100644 --- a/src/script/api/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -40,6 +40,10 @@ ****************************************************************************/ #include "qscriptengineagent.h" +#include "qscriptengineagent_p.h" + +#include "CodeBlock.h" +#include "Instruction.h" QT_BEGIN_NAMESPACE @@ -122,29 +126,51 @@ QT_BEGIN_NAMESPACE \sa extension() */ -class QScriptEngineAgent; -class Q_SCRIPT_EXPORT QScriptEngineAgentPrivate + +void QScriptEngineAgentPrivate::attach() { - Q_DECLARE_PUBLIC(QScriptEngineAgent) -public: - QScriptEngineAgentPrivate(); - virtual ~QScriptEngineAgentPrivate(); + QScriptEnginePrivate *d = QScriptEnginePrivate::get(engine); + if (d->originalGlobalObject()->debugger()) + d->originalGlobalObject()->setDebugger(0); + JSC::Debugger::attach(d->originalGlobalObject()); +} - QScriptEngine *engine; +void QScriptEngineAgentPrivate::detach() +{ + JSC::Debugger::detach(QScriptEnginePrivate::get(engine)->originalGlobalObject()); +} - QScriptEngineAgent *q_ptr; +void QScriptEngineAgentPrivate::exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler) +{ + QScriptValue value(QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue(frame.exception())); + q_ptr->exceptionThrow(sourceID, value, hasHandler); }; -QScriptEngineAgentPrivate::QScriptEngineAgentPrivate() +void QScriptEngineAgentPrivate::exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID) { + QScriptValue value(QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue(frame.exception())); + q_ptr->exceptionCatch(sourceID, value); } -QScriptEngineAgentPrivate::~QScriptEngineAgentPrivate() +void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column) { -// ### QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); -// ### eng_p->agentDeleted(q_ptr); + q_ptr->positionChange(sourceID, lineno, column); } +void QScriptEngineAgentPrivate::functionExit(const JSC::JSValue& returnValue, intptr_t sourceID) +{ + QScriptValue result = QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue(returnValue); + q_ptr->functionExit(sourceID, result); + q_ptr->contextPop(); +} + +void QScriptEngineAgentPrivate::evaluateStop(const JSC::JSValue& returnValue, intptr_t sourceID) +{ + QScriptValue result = QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue(returnValue); + q_ptr->functionExit(sourceID, result); +} + + /*! Constructs a QScriptEngineAgent object for the given \a engine. @@ -154,10 +180,13 @@ QScriptEngineAgentPrivate::~QScriptEngineAgentPrivate() agent. */ QScriptEngineAgent::QScriptEngineAgent(QScriptEngine *engine) - : d_ptr(new QScriptEngineAgentPrivate) + : d_ptr(new QScriptEngineAgentPrivate()) { - d_ptr->q_ptr = this; d_ptr->engine = engine; + d_ptr->q_ptr = this; + if (engine) { + d_ptr->engine->setAgent(this); + } } /*! diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h index 9d1f798..da3eef5 100644 --- a/src/script/api/qscriptengineagent_p.h +++ b/src/script/api/qscriptengineagent_p.h @@ -54,21 +54,78 @@ // #include +#include "Debugger.h" +#include "qscriptengineagent.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" + +#include "CallFrame.h" +#include "SourceCode.h" +#include "UString.h" +#include "DebuggerCallFrame.h" QT_BEGIN_NAMESPACE class QScriptEngine; class QScriptEngineAgent; -class Q_SCRIPT_EXPORT QScriptEngineAgentPrivate +class Q_SCRIPT_EXPORT QScriptEngineAgentPrivate : public JSC::Debugger { Q_DECLARE_PUBLIC(QScriptEngineAgent) public: - QScriptEngineAgentPrivate(); - virtual ~QScriptEngineAgentPrivate(); + static QScriptEngineAgent* get(QScriptEngineAgentPrivate* p) {return p->q_func();} + static QScriptEngineAgentPrivate* get(QScriptEngineAgent* p) {return p->d_func();} - QScriptEngine *engine; + QScriptEngineAgentPrivate(){} + virtual ~QScriptEngineAgentPrivate(){}; + + void attach(); + void detach(); + + //scripts + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {}; + virtual void scriptUnload(qint64 id) + { + q_ptr->scriptUnload(id); + }; + virtual void scriptLoad(qint64 id, const JSC::UString &program, + const JSC::UString &fileName, int baseLineNumber) + { + q_ptr->scriptLoad(id,program.toQString(), fileName.toQString(), baseLineNumber); + }; + //exceptions + virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) {}; + virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler); + virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID); + + //statements + virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column); + virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int /*lineno*/) + { + q_ptr->contextPush(); + q_ptr->functionEntry(sourceID); + }; + virtual void returnEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int /*lineno*/) {} + virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno) {}; + virtual void didExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) {}; + virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID); + //others + virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column) + { + QList args; + args << sourceID << lineno << column; + if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) + q_ptr->extension(QScriptEngineAgent::DebuggerInvocationRequest, args); + }; + + virtual void evaluateStart(intptr_t sourceID) + { + q_ptr->functionEntry(sourceID); + } + virtual void evaluateStop(const JSC::JSValue& returnValue, intptr_t sourceID); + + QScriptEngine *engine; QScriptEngineAgent *q_ptr; }; -- cgit v0.12