aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-10-22 13:07:11 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-10-22 13:07:11 +0200
commitb103f6a6b9cc0ddf3df2788816a6fd98369b1b6d (patch)
treefc90bc070f0f50a2d8768db8fa1e16611d158f18 /src/qml/jsruntime
parent4867a49618e0d6a476e0549aeca5134b2e3c5892 (diff)
parent8ee3673e439b4499a8a4a4280637ee0270c4a54a (diff)
Merge remote-tracking branch 'origin/5.6' into origin/dev
Conflicts: src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h src/qml/debugger/qqmldebugserviceinterfaces.cpp src/qml/jsruntime/qv4debugging_p.h Change-Id: I82a4ce1bcd4579181df886558f55ad2b328d1682
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4context.cpp17
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp48
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h19
-rw-r--r--src/qml/jsruntime/qv4engine.cpp5
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
7 files changed, 64 insertions, 38 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 403beacf39..007bf92639 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -114,23 +114,32 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
Scope scope(this);
// find the right context to create the binding on
- ScopedObject activation(scope, d()->engine->globalObject);
+ ScopedObject activation(scope);
ScopedContext ctx(scope, this);
while (ctx) {
switch (ctx->d()->type) {
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
- if (!c->activation)
- c->activation = scope.engine->newObject();
- activation = c->activation;
+ if (!activation) {
+ if (!c->activation)
+ c->activation = scope.engine->newObject();
+ activation = c->activation;
+ }
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
+ // this is ugly, as it overrides the inner callcontext, but has to stay as long
+ // as bindings still get their own callcontext
Heap::QmlContext *qml = static_cast<Heap::QmlContext *>(ctx->d());
activation = qml->qml;
break;
}
+ case Heap::ExecutionContext::Type_GlobalContext: {
+ if (!activation)
+ activation = scope.engine->globalObject;
+ break;
+ }
default:
break;
}
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 79fd58f700..7706a40da6 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
using namespace QV4::Debugging;
-Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr,
+V4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr,
const QString &script)
: engine(engine)
, frameNr(frameNr)
@@ -62,7 +62,7 @@ Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr
, resultIsException(false)
{}
-void Debugger::JavaScriptJob::run()
+void V4Debugger::JavaScriptJob::run()
{
Scope scope(engine);
@@ -92,18 +92,18 @@ void Debugger::JavaScriptJob::run()
handleResult(result);
}
-bool Debugger::JavaScriptJob::hasExeption() const
+bool V4Debugger::JavaScriptJob::hasExeption() const
{
return resultIsException;
}
-class EvalJob: public Debugger::JavaScriptJob
+class EvalJob: public V4Debugger::JavaScriptJob
{
bool result;
public:
EvalJob(QV4::ExecutionEngine *engine, const QString &script)
- : Debugger::JavaScriptJob(engine, /*frameNr*/-1, script)
+ : V4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script)
, result(false)
{}
@@ -118,7 +118,7 @@ public:
}
};
-Debugger::Debugger(QV4::ExecutionEngine *engine)
+V4Debugger::V4Debugger(QV4::ExecutionEngine *engine)
: m_engine(engine)
, m_state(Running)
, m_stepping(NotStepping)
@@ -129,11 +129,11 @@ Debugger::Debugger(QV4::ExecutionEngine *engine)
, m_gatherSources(0)
, m_runningJob(0)
{
- qMetaTypeId<Debugger*>();
+ qMetaTypeId<V4Debugger*>();
qMetaTypeId<PauseReason>();
}
-void Debugger::pause()
+void V4Debugger::pause()
{
QMutexLocker locker(&m_lock);
if (m_state == Paused)
@@ -141,7 +141,7 @@ void Debugger::pause()
m_pauseRequested = true;
}
-void Debugger::resume(Speed speed)
+void V4Debugger::resume(Speed speed)
{
QMutexLocker locker(&m_lock);
if (m_state != Paused)
@@ -155,28 +155,28 @@ void Debugger::resume(Speed speed)
m_runningCondition.wakeAll();
}
-void Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition)
+void V4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition)
{
QMutexLocker locker(&m_lock);
m_breakPoints.insert(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber), condition);
m_haveBreakPoints = true;
}
-void Debugger::removeBreakPoint(const QString &fileName, int lineNumber)
+void V4Debugger::removeBreakPoint(const QString &fileName, int lineNumber)
{
QMutexLocker locker(&m_lock);
m_breakPoints.remove(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber));
m_haveBreakPoints = !m_breakPoints.isEmpty();
}
-void Debugger::setBreakOnThrow(bool onoff)
+void V4Debugger::setBreakOnThrow(bool onoff)
{
QMutexLocker locker(&m_lock);
m_breakOnThrow = onoff;
}
-Debugger::ExecutionState Debugger::currentExecutionState() const
+V4Debugger::ExecutionState V4Debugger::currentExecutionState() const
{
ExecutionState state;
state.fileName = getFunction()->sourceFile();
@@ -185,12 +185,12 @@ Debugger::ExecutionState Debugger::currentExecutionState() const
return state;
}
-QVector<StackFrame> Debugger::stackTrace(int frameLimit) const
+QVector<StackFrame> V4Debugger::stackTrace(int frameLimit) const
{
return m_engine->stackTrace(frameLimit);
}
-void Debugger::maybeBreakAtInstruction()
+void V4Debugger::maybeBreakAtInstruction()
{
if (m_runningJob) // do not re-enter when we're doing a job for the debugger.
return;
@@ -228,7 +228,7 @@ void Debugger::maybeBreakAtInstruction()
}
}
-void Debugger::enteringFunction()
+void V4Debugger::enteringFunction()
{
if (m_runningJob)
return;
@@ -239,7 +239,7 @@ void Debugger::enteringFunction()
}
}
-void Debugger::leavingFunction(const ReturnedValue &retVal)
+void V4Debugger::leavingFunction(const ReturnedValue &retVal)
{
if (m_runningJob)
return;
@@ -254,7 +254,7 @@ void Debugger::leavingFunction(const ReturnedValue &retVal)
}
}
-void Debugger::aboutToThrow()
+void V4Debugger::aboutToThrow()
{
if (!m_breakOnThrow)
return;
@@ -266,7 +266,7 @@ void Debugger::aboutToThrow()
pauseAndWait(Throwing);
}
-Function *Debugger::getFunction() const
+Function *V4Debugger::getFunction() const
{
Scope scope(m_engine);
ExecutionContext *context = m_engine->currentContext;
@@ -277,7 +277,7 @@ Function *Debugger::getFunction() const
return context->d()->engine->globalCode;
}
-void Debugger::pauseAndWait(PauseReason reason)
+void V4Debugger::pauseAndWait(PauseReason reason)
{
if (m_runningJob)
return;
@@ -298,7 +298,7 @@ void Debugger::pauseAndWait(PauseReason reason)
m_state = Running;
}
-bool Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
+bool V4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
{
BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr));
if (it == m_breakPoints.end())
@@ -316,13 +316,13 @@ bool Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
return evilJob.resultAsBoolean();
}
-void Debugger::runInEngine(Debugger::Job *job)
+void V4Debugger::runInEngine(V4Debugger::Job *job)
{
QMutexLocker locker(&m_lock);
runInEngine_havingLock(job);
}
-void Debugger::runInEngine_havingLock(Debugger::Job *job)
+void V4Debugger::runInEngine_havingLock(V4Debugger::Job *job)
{
Q_ASSERT(job);
Q_ASSERT(m_runningJob == 0);
@@ -333,7 +333,7 @@ void Debugger::runInEngine_havingLock(Debugger::Job *job)
m_runningJob = 0;
}
-Debugger::Job::~Job()
+V4Debugger::Job::~Job()
{
}
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index 14bff238cc..683036882e 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -93,6 +93,19 @@ typedef QHash<DebuggerBreakPoint, QString> BreakPoints;
class Q_QML_EXPORT Debugger : public QObject
{
Q_OBJECT
+
+public:
+ virtual ~Debugger() {}
+ virtual bool pauseAtNextOpportunity() const = 0;
+ virtual void maybeBreakAtInstruction() = 0;
+ virtual void enteringFunction() = 0;
+ virtual void leavingFunction(const ReturnedValue &retVal) = 0;
+ virtual void aboutToThrow() = 0;
+};
+
+class Q_QML_EXPORT V4Debugger : public Debugger
+{
+ Q_OBJECT
public:
class Q_QML_EXPORT Job
{
@@ -131,7 +144,7 @@ public:
NotStepping = FullThrottle
};
- Debugger(ExecutionEngine *engine);
+ V4Debugger(ExecutionEngine *engine);
ExecutionEngine *engine() const
{ return m_engine; }
@@ -173,13 +186,13 @@ public: // execution hooks
void aboutToThrow();
signals:
- void debuggerPaused(QV4::Debugging::Debugger *self, QV4::Debugging::PauseReason reason);
+ void debuggerPaused(QV4::Debugging::V4Debugger *self, QV4::Debugging::PauseReason reason);
private:
// requires lock to be held
void pauseAndWait(PauseReason reason);
bool reallyHitTheBreakPoint(const QString &filename, int linenr);
- void runInEngine_havingLock(Debugger::Job *job);
+ void runInEngine_havingLock(V4Debugger::Job *job);
private:
QV4::ExecutionEngine *m_engine;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 6fe14da850..82d94f569e 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -518,11 +518,10 @@ ExecutionEngine::~ExecutionEngine()
delete [] argumentsAccessors;
}
-void ExecutionEngine::enableDebugger()
+void ExecutionEngine::setDebugger(Debugging::Debugger *debugger_)
{
Q_ASSERT(!debugger);
- debugger = new Debugging::Debugger(this);
- iselFactory.reset(new Moth::ISelFactory);
+ debugger = debugger_;
}
void ExecutionEngine::enableProfiler()
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index e94b417908..4640f3f4cc 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -366,7 +366,7 @@ public:
ExecutionEngine(EvalISelFactory *iselFactory = 0);
~ExecutionEngine();
- void enableDebugger();
+ void setDebugger(Debugging::Debugger *debugger);
void enableProfiler();
ExecutionContext *pushGlobalContext();
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index f1face007c..3d3ac84576 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -277,10 +277,15 @@ Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
ReturnedValue MathObject::method_random(CallContext *context)
{
if (!seedCreatedStorage()->hasLocalData()) {
- qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) ^ reinterpret_cast<quintptr>(context));
+ int msecs = QTime(0,0,0).msecsTo(QTime::currentTime());
+ Q_ASSERT(msecs >= 0);
+ qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(context)));
seedCreatedStorage()->setLocalData(new bool(true));
}
- return Encode(qrand() / (double) RAND_MAX);
+ // rand()/qrand() return a value where the upperbound is RAND_MAX inclusive. So, instead of
+ // dividing by RAND_MAX (which would return 0..RAND_MAX inclusive), we divide by RAND_MAX + 1.
+ qint64 upperLimit = qint64(RAND_MAX) + 1;
+ return Encode(qrand() / double(upperLimit));
}
ReturnedValue MathObject::method_round(CallContext *context)
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index ee3539c176..ba29d52bc6 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1107,7 +1107,7 @@ void Object::copyArrayData(Object *other)
dd->len = other->d()->arrayData->len;
dd->offset = other->d()->arrayData->offset;
}
- memcpy(d()->arrayData->arrayData, other->d()->arrayData->arrayData, d()->arrayData->alloc*sizeof(Value));
+ memcpy(d()->arrayData->arrayData, other->d()->arrayData->arrayData, other->d()->arrayData->alloc*sizeof(Value));
}
setArrayLengthUnchecked(other->getLength());
}