aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/debugger/qv8debugservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/debugger/qv8debugservice.cpp')
-rw-r--r--src/declarative/debugger/qv8debugservice.cpp135
1 files changed, 74 insertions, 61 deletions
diff --git a/src/declarative/debugger/qv8debugservice.cpp b/src/declarative/debugger/qv8debugservice.cpp
index 2f7ca348fd..f708f592b4 100644
--- a/src/declarative/debugger/qv8debugservice.cpp
+++ b/src/declarative/debugger/qv8debugservice.cpp
@@ -45,7 +45,6 @@
#include <private/qv8engine_p.h>
#include <private/qdeclarativeengine_p.h>
-#include <QtCore/QEventLoop>
#include <QtCore/QHash>
#include <QtCore/QFileInfo>
@@ -72,12 +71,9 @@ void DebugMessageHandler(const v8::Debug::Message& message)
message.GetJSON()));
QV8DebugService *service = QV8DebugService::instance();
- service->debugMessageHandler(response);
+ service->debugMessageHandler(response, message.WillStartRunning());
- if ((event == v8::Break || event == v8::Exception) &&
- !message.WillStartRunning()) {
- service->executionStopped();
- } else if (event == v8::AfterCompile) {
+ if (event == v8::AfterCompile) {
service->appendSourcePath(response);
} //TODO::v8::Exception
}
@@ -87,32 +83,41 @@ class QV8DebugServicePrivate : public QDeclarativeDebugServicePrivate
public:
QV8DebugServicePrivate()
:initialized(false)
+ , scheduleBreak(false)
+ , debuggerThreadIsolate(0)
+ , debuggerThreadEngine(0)
+ , isRunning(true)
{
- //Create a new isolate
- isolate = v8::Isolate::New();
-
- //Enter the isolate and initialize
- v8::Isolate::Scope i_scope(isolate);
+ //Create an isolate & engine in GUI thread
+ guiThreadIsolate = v8::Isolate::New();
+ v8::Isolate::Scope i_scope(guiThreadIsolate);
v8::V8::Initialize();
-
- //Create an instance in the new isolate
- engine = new QJSEngine();
+ guiThreadEngine = new QJSEngine();
}
~QV8DebugServicePrivate()
{
- delete engine;
- isolate->Dispose();
+ delete debuggerThreadEngine;
+ if (debuggerThreadIsolate)
+ debuggerThreadIsolate->Dispose();
+ delete guiThreadEngine;
+ if (guiThreadIsolate)
+ guiThreadIsolate->Dispose();
}
void sendDebugMessage(const QString &message);
static QByteArray packMessage(const QString &message);
bool initialized;
- QJSEngine *engine;
- v8::Isolate *isolate;
+ bool scheduleBreak;
+
+ v8::Isolate *debuggerThreadIsolate;
+ QJSEngine *debuggerThreadEngine;
+ v8::Isolate *guiThreadIsolate;
+ QJSEngine *guiThreadEngine;
+
QList<QDeclarativeEngine *> engines;
- QEventLoop loop;
+ bool isRunning;
QHash<QString, QString> sourcePath;
QHash<QString, QString> requestCache;
QHash<int, SignalHandlerData> handlersList;
@@ -166,20 +171,18 @@ void QV8DebugService::removeEngine(QDeclarativeEngine *engine)
d->engines.removeAll(engine);
}
-void QV8DebugService::debugMessageHandler(const QString &message)
-{
- sendMessage(QV8DebugServicePrivate::packMessage(message));
-}
-
-void QV8DebugService::executionStopped()
+void QV8DebugService::debugMessageHandler(const QString &message, bool willStartRunning)
{
Q_D(QV8DebugService);
+ d->isRunning = willStartRunning;
- if (!d->loop.isRunning()) {
- d->loop.exec(QEventLoop::ExcludeUserInputEvents);
- }
+ if (d->scheduleBreak)
+ scheduledDebugBreak();
+
+ sendMessage(QV8DebugServicePrivate::packMessage(message));
}
+
void QV8DebugService::appendSourcePath(const QString &message)
{
Q_D(QV8DebugService);
@@ -189,8 +192,8 @@ void QV8DebugService::appendSourcePath(const QString &message)
This will ensure that the debug message handler does not
receive any messages related to this operation */
{
- v8::Isolate::Scope i_scope(d->isolate);
- QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
+ v8::Isolate::Scope scope(d->guiThreadIsolate);
+ QJSValue parser = d->guiThreadEngine->evaluate(QLatin1String("JSON.parse"));
QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(message));
msgMap = out.toVariant().toMap();
}
@@ -220,18 +223,26 @@ void QV8DebugService::signalEmitted(const QString &signal)
//is no need for additional check.
Q_D(QV8DebugService);
- bool debugBreak = false;
//Parse just the name and remove the class info
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1String("("))).toLower();
foreach (const SignalHandlerData &data, d->handlersList) {
if (data.functionName == signalName
&& data.enabled) {
- debugBreak = true;
+ d->scheduleBreak = true;
}
}
- if (debugBreak)
+ if (d->scheduleBreak)
+ scheduledDebugBreak();
+}
+
+void QV8DebugService::scheduledDebugBreak()
+{
+ Q_D(QV8DebugService);
+ if (d->scheduleBreak) {
v8::Debug::DebugBreak();
+ d->scheduleBreak = false;
+ }
}
void QV8DebugService::messageReceived(const QByteArray &message)
@@ -243,6 +254,16 @@ void QV8DebugService::messageReceived(const QByteArray &message)
ds >> command;
if (command == "V8DEBUG") {
+
+ if (!d->debuggerThreadEngine) {
+ //Create an isolate & engine in debugger thread
+ d->debuggerThreadIsolate = v8::Isolate::New();
+ v8::Isolate::Scope i_scope(d->debuggerThreadIsolate);
+ v8::V8::Initialize();
+ d->debuggerThreadEngine = new QJSEngine();
+ }
+
+
QString request;
{
QByteArray requestArray;
@@ -251,12 +272,9 @@ void QV8DebugService::messageReceived(const QByteArray &message)
}
QVariantMap reqMap;
- /* Parse the byte string in a separate isolate
- This will ensure that the debug message handler does not
- receive any messages related to this operation */
{
- v8::Isolate::Scope i_scope(d->isolate);
- QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
+ v8::Isolate::Scope i_scope(d->debuggerThreadIsolate);
+ QJSValue parser = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.parse"));
QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(request));
reqMap = out.toVariant().toMap();
}
@@ -276,9 +294,9 @@ void QV8DebugService::messageReceived(const QByteArray &message)
// "success" : true
// }
{
- v8::Isolate::Scope i_scope(d->isolate);
const QString obj(QLatin1String("{}"));
- QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
+ v8::Isolate::Scope i_scope(d->debuggerThreadIsolate);
+ QJSValue parser = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.parse"));
QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj);
jsonVal.setProperty(QLatin1String("type"), QJSValue(QLatin1String("response")));
@@ -286,16 +304,14 @@ void QV8DebugService::messageReceived(const QByteArray &message)
jsonVal.setProperty(QLatin1String("request_seq"), QJSValue(sequence));
jsonVal.setProperty(QLatin1String("command"), QJSValue(debugCommand));
jsonVal.setProperty(QLatin1String("success"), QJSValue(true));
- jsonVal.setProperty(QLatin1String("running"), QJSValue(!d->loop.isRunning()));
+ jsonVal.setProperty(QLatin1String("running"), QJSValue(d->isRunning));
- QJSValue stringify = d->engine->evaluate(QLatin1String("JSON.stringify"));
+ QJSValue stringify = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.stringify"));
QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
- debugMessageHandler(json.toString());
-
+ sendMessage(QV8DebugServicePrivate::packMessage(json.toString()));
}
} else if (debugCommand == QLatin1String("interrupt")) {
- v8::Debug::DebugBreak();
//Prepare the response string
//Create a json message using v8 debugging protocol
//and send it to client
@@ -307,9 +323,9 @@ void QV8DebugService::messageReceived(const QByteArray &message)
// "success" : true
// }
{
- v8::Isolate::Scope i_scope(d->isolate);
const QString obj(QLatin1String("{}"));
- QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
+ v8::Isolate::Scope i_scope(d->debuggerThreadIsolate);
+ QJSValue parser = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.parse"));
QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj);
jsonVal.setProperty(QLatin1String("type"), QJSValue(QLatin1String("response")));
@@ -317,14 +333,15 @@ void QV8DebugService::messageReceived(const QByteArray &message)
jsonVal.setProperty(QLatin1String("request_seq"), QJSValue(sequence));
jsonVal.setProperty(QLatin1String("command"), QJSValue(debugCommand));
jsonVal.setProperty(QLatin1String("success"), QJSValue(true));
- jsonVal.setProperty(QLatin1String("running"), QJSValue(!d->loop.isRunning()));
+ jsonVal.setProperty(QLatin1String("running"), QJSValue(d->isRunning));
- QJSValue stringify = d->engine->evaluate(QLatin1String("JSON.stringify"));
+ QJSValue stringify = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.stringify"));
QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
- debugMessageHandler(json.toString());
-
+ sendMessage(QV8DebugServicePrivate::packMessage(json.toString()));
}
-
+ // break has to be executed in gui thread
+ d->scheduleBreak = true;
+ QMetaObject::invokeMethod(this, "scheduledDebugBreak", Qt::QueuedConnection);
} else {
bool forwardRequestToV8 = true;
@@ -363,9 +380,9 @@ void QV8DebugService::messageReceived(const QByteArray &message)
// "success" : true
// }
{
- v8::Isolate::Scope i_scope(d->isolate);
const QString obj(QLatin1String("{}"));
- QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
+ v8::Isolate::Scope i_scope(d->debuggerThreadIsolate);
+ QJSValue parser = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.parse"));
QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj);
jsonVal.setProperty(QLatin1String("type"), QJSValue(QLatin1String("response")));
@@ -398,12 +415,11 @@ void QV8DebugService::messageReceived(const QByteArray &message)
}
- jsonVal.setProperty(QLatin1String("running"), QJSValue(!d->loop.isRunning()));
+ jsonVal.setProperty(QLatin1String("running"), QJSValue(d->isRunning));
- QJSValue stringify = d->engine->evaluate(QLatin1String("JSON.stringify"));
+ QJSValue stringify = d->debuggerThreadEngine->evaluate(QLatin1String("JSON.stringify"));
QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
- debugMessageHandler(json.toString());
-
+ sendMessage(QV8DebugServicePrivate::packMessage(json.toString()));
}
}
} else if (debugCommand == QLatin1String("changebreakpoint")) {
@@ -440,9 +456,6 @@ void QV8DebugService::messageReceived(const QByteArray &message)
void QV8DebugServicePrivate::sendDebugMessage(const QString &message)
{
- if (loop.isRunning())
- loop.exit();
-
v8::Debug::SendCommand(message.utf16(), message.size());
}