diff options
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/jsruntime.pri | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4dataview.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4dateobject.cpp | 48 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4dateobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4debugging.cpp | 286 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4debugging_p.h | 159 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifier_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4include_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4math_p.h | 73 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mathobject.cpp | 42 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject.cpp | 48 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject_p.h | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4serialize_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 2 |
17 files changed, 103 insertions, 589 deletions
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index 5ffdebe328..503b40e8ae 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -112,5 +112,3 @@ valgrind { } ios: DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1 - -include(../../3rdparty/double-conversion/double-conversion.pri) diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 8901834e76..cd28c03fa3 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -285,7 +285,7 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx) return scope.engine->throwTypeError(); idx += v->d()->byteOffset; - double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qSNaN(); + double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qQNaN(); bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean(); if (sizeof(T) == 4) { diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index a6e1f47d91..d414ec2084 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -198,7 +198,7 @@ static inline double MonthFromTime(double t) else if (d < 365.0 + l) return 11; - return qSNaN(); // ### assert? + return qQNaN(); // ### assert? } static inline double DateFromTime(double t) @@ -222,7 +222,7 @@ static inline double DateFromTime(double t) case 11: return d - 333.0 - l; } - return qSNaN(); // ### assert + return qQNaN(); // ### assert } static inline double WeekDay(double t) @@ -254,7 +254,7 @@ static inline double DayFromMonth(double month, double leap) case 11: return 334.0 + leap; } - return qSNaN(); // ### assert? + return qQNaN(); // ### assert? } static double MakeDay(double year, double month, double day) @@ -333,7 +333,7 @@ static inline double currentTime() static inline double TimeClip(double t) { if (! qIsFinite(t) || fabs(t) > 8.64e15) - return qSNaN(); + return qQNaN(); return Primitive::toInteger(t); } @@ -538,7 +538,7 @@ static inline double ParseString(const QString &s) } } if (!dt.isValid()) - return qSNaN(); + return qQNaN(); return dt.toMSecsSinceEpoch(); } @@ -630,7 +630,7 @@ DEFINE_OBJECT_VTABLE(DateObject); Heap::DateObject::DateObject(const QDateTime &date) { - this->date = date.isValid() ? date.toMSecsSinceEpoch() : qSNaN(); + this->date = date.isValid() ? date.toMSecsSinceEpoch() : qQNaN(); } QDateTime DateObject::toQDateTime() const @@ -764,7 +764,7 @@ double DatePrototype::getThisDate(ExecutionContext *ctx) ReturnedValue DatePrototype::method_parse(CallContext *ctx) { if (!ctx->argc()) - return Encode(qSNaN()); + return Encode(qQNaN()); return Encode(ParseString(ctx->args()[0].toQString())); } @@ -994,7 +994,7 @@ ReturnedValue DatePrototype::method_setTime(CallContext *ctx) if (!self) return ctx->engine()->throwTypeError(); - double t = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double t = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(t)); return Encode(self->date()); } @@ -1007,7 +1007,7 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))))); return Encode(self->date()); } @@ -1019,7 +1019,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))); return Encode(self->date()); } @@ -1031,7 +1031,7 @@ ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); self->setDate(t); @@ -1045,7 +1045,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))); self->setDate(t); @@ -1059,7 +1059,7 @@ ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber(); double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); @@ -1074,7 +1074,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber(); double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))); @@ -1089,7 +1089,7 @@ ReturnedValue DatePrototype::method_setHours(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber(); double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber(); double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber(); @@ -1105,7 +1105,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber(); double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber(); double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber(); @@ -1121,7 +1121,7 @@ ReturnedValue DatePrototype::method_setDate(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)))); self->setDate(t); return Encode(self->date()); @@ -1134,7 +1134,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))); self->setDate(t); return Encode(self->date()); @@ -1147,7 +1147,7 @@ ReturnedValue DatePrototype::method_setMonth(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); self->setDate(t); @@ -1161,7 +1161,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))); self->setDate(t); @@ -1179,10 +1179,10 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx) t = 0; else t = LocalTime(t); - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double r; if (std::isnan(year)) { - r = qSNaN(); + r = qQNaN(); } else { if ((Primitive::toInteger(year) >= 0) && (Primitive::toInteger(year) <= 99)) year += 1900; @@ -1201,7 +1201,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber(); double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))); @@ -1218,7 +1218,7 @@ ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx) double t = LocalTime(self->date()); if (std::isnan(t)) t = 0; - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber(); double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index 2eaa837666..eb048b1e99 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -59,7 +59,7 @@ namespace Heap { struct DateObject : Object { DateObject() { - date = qSNaN(); + date = qQNaN(); } DateObject(const Value &date) diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 7706a40da6..b04bcd33e7 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -51,290 +51,4 @@ QT_BEGIN_NAMESPACE -using namespace QV4; -using namespace QV4::Debugging; - -V4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, - const QString &script) - : engine(engine) - , frameNr(frameNr) - , script(script) - , resultIsException(false) -{} - -void V4Debugger::JavaScriptJob::run() -{ - Scope scope(engine); - - ExecutionContextSaver saver(scope); - - ExecutionContext *ctx = engine->currentContext; - if (frameNr > 0) { - for (int i = 0; i < frameNr; ++i) { - ctx = engine->parentContext(ctx); - } - engine->pushContext(ctx); - } - - QV4::Script script(ctx, this->script); - script.strictMode = ctx->d()->strictMode; - // In order for property lookups in QML to work, we need to disable fast v4 lookups. That - // is a side-effect of inheritContext. - script.inheritContext = true; - script.parse(); - QV4::ScopedValue result(scope); - if (!scope.engine->hasException) - result = script.run(); - if (scope.engine->hasException) { - result = scope.engine->catchException(); - resultIsException = true; - } - handleResult(result); -} - -bool V4Debugger::JavaScriptJob::hasExeption() const -{ - return resultIsException; -} - -class EvalJob: public V4Debugger::JavaScriptJob -{ - bool result; - -public: - EvalJob(QV4::ExecutionEngine *engine, const QString &script) - : V4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script) - , result(false) - {} - - virtual void handleResult(QV4::ScopedValue &result) - { - this->result = result->toBoolean(); - } - - bool resultAsBoolean() const - { - return result; - } -}; - -V4Debugger::V4Debugger(QV4::ExecutionEngine *engine) - : m_engine(engine) - , m_state(Running) - , m_stepping(NotStepping) - , m_pauseRequested(false) - , m_haveBreakPoints(false) - , m_breakOnThrow(false) - , m_returnedValue(engine, Primitive::undefinedValue()) - , m_gatherSources(0) - , m_runningJob(0) -{ - qMetaTypeId<V4Debugger*>(); - qMetaTypeId<PauseReason>(); -} - -void V4Debugger::pause() -{ - QMutexLocker locker(&m_lock); - if (m_state == Paused) - return; - m_pauseRequested = true; -} - -void V4Debugger::resume(Speed speed) -{ - QMutexLocker locker(&m_lock); - if (m_state != Paused) - return; - - if (!m_returnedValue.isUndefined()) - m_returnedValue.set(m_engine, Encode::undefined()); - - m_currentContext.set(m_engine, *m_engine->currentContext); - m_stepping = speed; - m_runningCondition.wakeAll(); -} - -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 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 V4Debugger::setBreakOnThrow(bool onoff) -{ - QMutexLocker locker(&m_lock); - - m_breakOnThrow = onoff; -} - -V4Debugger::ExecutionState V4Debugger::currentExecutionState() const -{ - ExecutionState state; - state.fileName = getFunction()->sourceFile(); - state.lineNumber = engine()->current->lineNumber; - - return state; -} - -QVector<StackFrame> V4Debugger::stackTrace(int frameLimit) const -{ - return m_engine->stackTrace(frameLimit); -} - -void V4Debugger::maybeBreakAtInstruction() -{ - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - - if (m_gatherSources) { - m_gatherSources->run(); - delete m_gatherSources; - m_gatherSources = 0; - } - - switch (m_stepping) { - case StepOver: - if (m_currentContext.asManaged()->d() != m_engine->current) - break; - // fall through - case StepIn: - pauseAndWait(Step); - return; - case StepOut: - case NotStepping: - break; - } - - if (m_pauseRequested) { // Serve debugging requests from the agent - m_pauseRequested = false; - pauseAndWait(PauseRequest); - } else if (m_haveBreakPoints) { - if (Function *f = getFunction()) { - const int lineNumber = engine()->current->lineNumber; - if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber)) - pauseAndWait(BreakPoint); - } - } -} - -void V4Debugger::enteringFunction() -{ - if (m_runningJob) - return; - QMutexLocker locker(&m_lock); - - if (m_stepping == StepIn) { - m_currentContext.set(m_engine, *m_engine->currentContext); - } -} - -void V4Debugger::leavingFunction(const ReturnedValue &retVal) -{ - if (m_runningJob) - return; - Q_UNUSED(retVal); // TODO - - QMutexLocker locker(&m_lock); - - if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) { - m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext)); - m_stepping = StepOver; - m_returnedValue.set(m_engine, retVal); - } -} - -void V4Debugger::aboutToThrow() -{ - if (!m_breakOnThrow) - return; - - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - pauseAndWait(Throwing); -} - -Function *V4Debugger::getFunction() const -{ - Scope scope(m_engine); - ExecutionContext *context = m_engine->currentContext; - ScopedFunctionObject function(scope, context->getFunctionObject()); - if (function) - return function->function(); - else - return context->d()->engine->globalCode; -} - -void V4Debugger::pauseAndWait(PauseReason reason) -{ - if (m_runningJob) - return; - - m_state = Paused; - emit debuggerPaused(this, reason); - - while (true) { - m_runningCondition.wait(&m_lock); - if (m_runningJob) { - m_runningJob->run(); - m_jobIsRunning.wakeAll(); - } else { - break; - } - } - - m_state = Running; -} - -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()) - return false; - QString condition = it.value(); - if (condition.isEmpty()) - return true; - - Q_ASSERT(m_runningJob == 0); - EvalJob evilJob(m_engine, condition); - m_runningJob = &evilJob; - m_runningJob->run(); - m_runningJob = 0; - - return evilJob.resultAsBoolean(); -} - -void V4Debugger::runInEngine(V4Debugger::Job *job) -{ - QMutexLocker locker(&m_lock); - runInEngine_havingLock(job); -} - -void V4Debugger::runInEngine_havingLock(V4Debugger::Job *job) -{ - Q_ASSERT(job); - Q_ASSERT(m_runningJob == 0); - - m_runningJob = job; - m_runningCondition.wakeAll(); - m_jobIsRunning.wait(&m_lock); - m_runningJob = 0; -} - -V4Debugger::Job::~Job() -{ -} - QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index fdc9cac24f..3a3ecef918 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef DEBUGGING_H -#define DEBUGGING_H +#ifndef QV4DEBUGGING_H +#define QV4DEBUGGING_H // // W A R N I N G @@ -46,50 +46,13 @@ // #include "qv4global_p.h" -#include "qv4engine_p.h" -#include "qv4context_p.h" -#include "qv4scopedvalue_p.h" - -#include <QHash> -#include <QThread> -#include <QMutex> -#include <QWaitCondition> - -#include <QtCore/QJsonObject> +#include <QtCore/qobject.h> QT_BEGIN_NAMESPACE namespace QV4 { - -struct Function; - namespace Debugging { -enum PauseReason { - PauseRequest, - BreakPoint, - Throwing, - Step -}; - -struct DebuggerBreakPoint { - DebuggerBreakPoint(const QString &fileName, int line) - : fileName(fileName), lineNumber(line) - {} - QString fileName; - int lineNumber; -}; -inline uint qHash(const DebuggerBreakPoint &b, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(b.fileName, seed) ^ b.lineNumber; -} -inline bool operator==(const DebuggerBreakPoint &a, const DebuggerBreakPoint &b) -{ - return a.lineNumber == b.lineNumber && a.fileName == b.fileName; -} - -typedef QHash<DebuggerBreakPoint, QString> BreakPoints; - class Q_QML_EXPORT Debugger : public QObject { Q_OBJECT @@ -103,123 +66,9 @@ public: virtual void aboutToThrow() = 0; }; -class Q_QML_EXPORT V4Debugger : public Debugger -{ - Q_OBJECT -public: - class Q_QML_EXPORT Job - { - public: - virtual ~Job() = 0; - virtual void run() = 0; - }; - - class Q_QML_EXPORT JavaScriptJob: public Job - { - QV4::ExecutionEngine *engine; - int frameNr; - const QString &script; - bool resultIsException; - - public: - JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script); - void run(); - bool hasExeption() const; - - protected: - virtual void handleResult(QV4::ScopedValue &result) = 0; - }; - - enum State { - Running, - Paused - }; - - enum Speed { - FullThrottle = 0, - StepOut, - StepOver, - StepIn, - - NotStepping = FullThrottle - }; - - V4Debugger(ExecutionEngine *engine); - - ExecutionEngine *engine() const - { return m_engine; } - - void pause(); - void resume(Speed speed); - - State state() const { return m_state; } - - void addBreakPoint(const QString &fileName, int lineNumber, const QString &condition = QString()); - void removeBreakPoint(const QString &fileName, int lineNumber); - - void setBreakOnThrow(bool onoff); - - // used for testing - struct ExecutionState - { - QString fileName; - int lineNumber; - }; - ExecutionState currentExecutionState() const; - - bool pauseAtNextOpportunity() const { - return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver; - } - - QVector<StackFrame> stackTrace(int frameLimit = -1) const; - QVector<Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const; - - Function *getFunction() const; - void runInEngine(Job *job); - -public: // compile-time interface - void maybeBreakAtInstruction(); - -public: // execution hooks - void enteringFunction(); - void leavingFunction(const ReturnedValue &retVal); - void aboutToThrow(); - -signals: - void sourcesCollected(QV4::Debugging::V4Debugger *self, const QStringList &sources, int seq); - 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(V4Debugger::Job *job); - -private: - QV4::ExecutionEngine *m_engine; - QV4::PersistentValue m_currentContext; - QMutex m_lock; - QWaitCondition m_runningCondition; - State m_state; - Speed m_stepping; - bool m_pauseRequested; - bool m_haveBreakPoints; - bool m_breakOnThrow; - - BreakPoints m_breakPoints; - QV4::PersistentValue m_returnedValue; - - Job *m_gatherSources; - Job *m_runningJob; - QWaitCondition m_jobIsRunning; -}; - } // namespace Debugging } // namespace QV4 QT_END_NAMESPACE -Q_DECLARE_METATYPE(QV4::Debugging::Debugger*) -Q_DECLARE_METATYPE(QV4::Debugging::PauseReason) - -#endif // DEBUGGING_H +#endif // QV4DEBUGGING_H diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 110a2c9089..b4733356ac 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -302,7 +302,7 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok) ++r; } if (*r) - output.append(input.mid(start, i - start + 1)); + output.append(input.midRef(start, i - start + 1)); else output.append(QChar(b)); } else { diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h index 605b06c685..ff93b70ff9 100644 --- a/src/qml/jsruntime/qv4identifier_p.h +++ b/src/qml/jsruntime/qv4identifier_p.h @@ -103,8 +103,6 @@ struct IdentifierHashBase inline IdentifierHashBase &operator=(const IdentifierHashBase &other); bool isEmpty() const { return !d; } - // ### - void reserve(int) {} inline int count() const; bool contains(const Identifier *i) const; diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h index 3e3cf5e770..497566e7eb 100644 --- a/src/qml/jsruntime/qv4include_p.h +++ b/src/qml/jsruntime/qv4include_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE class QQmlEngine; class QNetworkAccessManager; class QNetworkReply; -class QV8Engine; class QV4Include : public QObject { Q_OBJECT diff --git a/src/qml/jsruntime/qv4math_p.h b/src/qml/jsruntime/qv4math_p.h index cf627bcc5d..51031356bc 100644 --- a/src/qml/jsruntime/qv4math_p.h +++ b/src/qml/jsruntime/qv4math_p.h @@ -47,6 +47,7 @@ #include <qglobal.h> #include <QtCore/qnumeric.h> +#include <QtCore/private/qnumeric_p.h> #include <cmath> #if defined(Q_CC_GNU) @@ -59,84 +60,30 @@ QT_BEGIN_NAMESPACE namespace QV4 { -#if defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86) - static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("addl %2, %1\n" - "seto %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(add_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("subl %2, %1\n" - "seto %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(sub_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("imul %2, %1\n" - "setc %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(mul_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); -} - -#else - -static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) + b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } -static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) - b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); -} - -static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) * b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); -} - -#endif - } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 3d3ac84576..ada073fbd4 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -96,7 +96,7 @@ static double copySign(double x, double y) ReturnedValue MathObject::method_abs(CallContext *context) { if (!context->argc()) - return Encode(qSNaN()); + return Encode(qQNaN()); if (context->args()[0].isInteger()) { int i = context->args()[0].integerValue(); @@ -114,7 +114,7 @@ ReturnedValue MathObject::method_acos(CallContext *context) { double v = context->argc() ? context->args()[0].toNumber() : 2; if (v > 1) - return Encode(qSNaN()); + return Encode(qQNaN()); return Encode(std::acos(v)); } @@ -123,14 +123,14 @@ ReturnedValue MathObject::method_asin(CallContext *context) { double v = context->argc() ? context->args()[0].toNumber() : 2; if (v > 1) - return Encode(qSNaN()); + return Encode(qQNaN()); else return Encode(std::asin(v)); } ReturnedValue MathObject::method_atan(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v == 0.0) return Encode(v); else @@ -139,8 +139,8 @@ ReturnedValue MathObject::method_atan(CallContext *context) ReturnedValue MathObject::method_atan2(CallContext *context) { - double v1 = context->argc() ? context->args()[0].toNumber() : qSNaN(); - double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN(); + double v1 = context->argc() ? context->args()[0].toNumber() : qQNaN(); + double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN(); if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0)) return Encode(copySign(0, -1.0)); @@ -157,7 +157,7 @@ ReturnedValue MathObject::method_atan2(CallContext *context) ReturnedValue MathObject::method_ceil(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v < 0.0 && v > -1.0) return Encode(copySign(0, -1.0)); else @@ -166,13 +166,13 @@ ReturnedValue MathObject::method_ceil(CallContext *context) ReturnedValue MathObject::method_cos(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::cos(v)); } ReturnedValue MathObject::method_exp(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (qIsInf(v)) { if (copySign(1.0, v) == -1.0) return Encode(0); @@ -185,15 +185,15 @@ ReturnedValue MathObject::method_exp(CallContext *context) ReturnedValue MathObject::method_floor(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::floor(v)); } ReturnedValue MathObject::method_log(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v < 0) - return Encode(qSNaN()); + return Encode(qQNaN()); else return Encode(std::log(v)); } @@ -224,16 +224,16 @@ ReturnedValue MathObject::method_min(CallContext *context) ReturnedValue MathObject::method_pow(CallContext *context) { - double x = context->argc() > 0 ? context->args()[0].toNumber() : qSNaN(); - double y = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN(); + double x = context->argc() > 0 ? context->args()[0].toNumber() : qQNaN(); + double y = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN(); if (std::isnan(y)) - return Encode(qSNaN()); + return Encode(qQNaN()); if (y == 0) { return Encode(1); } else if (((x == 1) || (x == -1)) && std::isinf(y)) { - return Encode(qSNaN()); + return Encode(qQNaN()); } else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) { return Encode(qInf()); } else if ((x == 0) && copySign(1.0, x) == -1.0) { @@ -269,7 +269,7 @@ ReturnedValue MathObject::method_pow(CallContext *context) return Encode(std::pow(x, y)); } // ### - return Encode(qSNaN()); + return Encode(qQNaN()); } Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage); @@ -290,26 +290,26 @@ ReturnedValue MathObject::method_random(CallContext *context) ReturnedValue MathObject::method_round(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); v = copySign(std::floor(v + 0.5), v); return Encode(v); } ReturnedValue MathObject::method_sin(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::sin(v)); } ReturnedValue MathObject::method_sqrt(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::sqrt(v)); } ReturnedValue MathObject::method_tan(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v == 0.0) return Encode(v); else diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 4ae30a7f35..5006c8c2cd 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -39,13 +39,31 @@ #include <QtCore/qmath.h> #include <QtCore/QDebug> #include <cassert> -#include <double-conversion.h> using namespace QV4; DEFINE_OBJECT_VTABLE(NumberCtor); DEFINE_OBJECT_VTABLE(NumberObject); +struct NumberLocaleHolder : public NumberLocale +{ + NumberLocaleHolder() {} +}; + +Q_GLOBAL_STATIC(NumberLocaleHolder, numberLocaleHolder) + +NumberLocale::NumberLocale() : QLocale(QLocale::C), + // -128 means shortest string that can accurately represent the number. + defaultDoublePrecision(0xffffff80) +{ + setNumberOptions(QLocale::OmitGroupSeparator | QLocale::OmitLeadingZeroInExponent); +} + +const NumberLocale *NumberLocale::instance() +{ + return numberLocaleHolder(); +} + Heap::NumberCtor::NumberCtor(QV4::ExecutionContext *scope) : Heap::FunctionObject(scope, QStringLiteral("Number")) { @@ -71,7 +89,7 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor) ctor->defineReadonlyProperty(engine->id_prototype(), (o = this)); ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1)); - ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qSNaN())); + ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qQNaN())); ctor->defineReadonlyProperty(QStringLiteral("NEGATIVE_INFINITY"), Primitive::fromDouble(-qInf())); ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf())); ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308)); @@ -201,15 +219,9 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx) str = QStringLiteral("NaN"); else if (qIsInf(v)) str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity"); - else if (v < 1.e21) { - char buf[100]; - double_conversion::StringBuilder builder(buf, sizeof(buf)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToFixed(v, fdigits, &builder); - str = QString::fromLatin1(builder.Finalize()); - // At some point, the 3rd party double-conversion code should be moved to qtcore. - // When that's done, we can use: -// str = QString::number(v, 'f', int (fdigits)); - } else + else if (v < 1.e21) + str = NumberLocale::instance()->toString(v, 'f', int(fdigits)); + else return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue(); return scope.engine->newString(str)->asReturnedValue(); } @@ -221,7 +233,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx) if (scope.engine->hasException) return Encode::undefined(); - int fdigits = -1; + int fdigits = NumberLocale::instance()->defaultDoublePrecision; if (ctx->argc() && !ctx->args()[0].isUndefined()) { fdigits = ctx->args()[0].toInt32(); @@ -231,11 +243,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx) } } - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToExponential(d, fdigits, &builder); - QString result = QString::fromLatin1(builder.Finalize()); - + QString result = NumberLocale::instance()->toString(d, 'e', fdigits); return scope.engine->newString(result)->asReturnedValue(); } @@ -255,10 +263,6 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx) return ctx->engine()->throwRangeError(error); } - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToPrecision(v->asDouble(), precision, &builder); - QString result = QString::fromLatin1(builder.Finalize()); - + QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision); return scope.engine->newString(result)->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index cc5033531e..bd6fe3febb 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -60,6 +60,15 @@ struct NumberCtor : FunctionObject { } +class NumberLocale : public QLocale +{ +public: + static const NumberLocale *instance(); + const int defaultDoublePrecision; +protected: + NumberLocale(); +}; + struct NumberCtor: FunctionObject { V4_OBJECT2(NumberCtor, FunctionObject) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2cb8991055..594df67f44 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1452,7 +1452,8 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const const QQmlPropertyData *candidate = &data; while (candidate) { error += QLatin1String("\n ") + - QString::fromUtf8(object.metaObject()->method(candidate->coreIndex).methodSignature().constData()); + QString::fromUtf8(object.metaObject()->method(candidate->coreIndex) + .methodSignature()); candidate = RelatedMethod(object, candidate, dummy, propertyCache); } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a988313f5f..2d0eac079f 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -43,6 +43,7 @@ #include "qv4dateobject_p.h" #include "qv4lookup_p.h" #include "qv4function_p.h" +#include "qv4numberobject_p.h" #include "private/qlocale_tools_p.h" #include "qv4scopedvalue_p.h" #include <private/qqmlcontextwrapper_p.h> @@ -60,8 +61,6 @@ #include <wtf/MathExtras.h> -#include "../../3rdparty/double-conversion/double-conversion.h" - #ifdef QV4_COUNT_RUNTIME_FUNCTIONS # include <QtCore/QBuffer> # include <QtCore/QDebug> @@ -226,10 +225,8 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix) } if (radix == 10) { - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToShortest(num, &builder); - *result = QString::fromLatin1(builder.Finalize()); + const NumberLocale *locale = NumberLocale::instance(); + *result = locale->toString(num, 'g', locale->defaultDoublePrecision); return; } diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h index d5d48edee7..e364477a19 100644 --- a/src/qml/jsruntime/qv4serialize_p.h +++ b/src/qml/jsruntime/qv4serialize_p.h @@ -50,8 +50,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - namespace QV4 { class Serialize { diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 757ec6c6bf..8433582215 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -264,7 +264,7 @@ ReturnedValue StringPrototype::method_charCodeAt(CallContext *context) if (pos >= 0 && pos < str.length()) return Encode(str.at(pos).unicode()); - return Encode(qSNaN()); + return Encode(qQNaN()); } ReturnedValue StringPrototype::method_concat(CallContext *context) |