diff options
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 95 |
1 files changed, 66 insertions, 29 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 26f473a7aa..a9284f2e69 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -86,7 +86,9 @@ #include "qv4isel_masm_p.h" #endif // V4_ENABLE_JIT +#if QT_CONFIG(qml_interpreter) #include "qv4isel_moth_p.h" +#endif #if USE(PTHREADS) # include <pthread.h> @@ -136,8 +138,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , currentContext(0) , bumperPointerAllocator(new WTF::BumpPointerAllocator) , jsStack(new WTF::PageAllocation) - , debugger(0) - , profiler(0) , globalCode(0) , v8Engine(0) , argumentsAccessors(0) @@ -145,6 +145,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , m_engineId(engineSerial.fetchAndAddOrdered(1)) , regExpCache(0) , m_multiplyWrappedQObjects(0) +#ifndef QT_NO_QML_DEBUGGER + , m_debugger(0) + , m_profiler(0) +#endif { if (maxCallDepth == -1) { bool ok = false; @@ -158,6 +162,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) MemoryManager::GCBlocker gcBlocker(memoryManager); if (!factory) { +#if QT_CONFIG(qml_interpreter) bool jitDisabled = true; #ifdef V4_ENABLE_JIT @@ -178,6 +183,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) "very slow. Visit https://wiki.qt.io/V4 to learn about possible " "solutions for your platform."); } +#else + factory = new JIT::ISelFactory; +#endif } iselFactory.reset(factory); @@ -442,10 +450,12 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) ExecutionEngine::~ExecutionEngine() { - delete debugger; - debugger = 0; - delete profiler; - profiler = 0; +#ifndef QT_NO_QML_DEBUGGER + delete m_debugger; + m_debugger = 0; + delete m_profiler; + m_profiler = 0; +#endif delete m_multiplyWrappedQObjects; m_multiplyWrappedQObjects = 0; delete identifierTable; @@ -467,23 +477,26 @@ ExecutionEngine::~ExecutionEngine() delete [] argumentsAccessors; } -void ExecutionEngine::setDebugger(Debugging::Debugger *debugger_) +#ifndef QT_NO_QML_DEBUGGER +void ExecutionEngine::setDebugger(Debugging::Debugger *debugger) { - Q_ASSERT(!debugger); - debugger = debugger_; + Q_ASSERT(!m_debugger); + m_debugger = debugger; } -void ExecutionEngine::enableProfiler() +void ExecutionEngine::setProfiler(Profiling::Profiler *profiler) { - Q_ASSERT(!profiler); - profiler = new QV4::Profiling::Profiler(this); + Q_ASSERT(!m_profiler); + m_profiler = profiler; } +#endif // QT_NO_QML_DEBUGGER void ExecutionEngine::initRootContext() { Scope scope(this); - Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(sizeof(GlobalContext::Data) + sizeof(CallData))); - new (r->d()) GlobalContext::Data(this); + Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>( + sizeof(GlobalContext::Data) + sizeof(CallData))); + r->d_unchecked()->init(this); r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1); r->d()->callData->tag = QV4::Value::Integer_Type_Internal; r->d()->callData->argc = 0; @@ -566,7 +579,7 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int leng if (length) { size_t size = sizeof(Heap::ArrayData) + (length-1)*sizeof(Value); Heap::SimpleArrayData *d = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size); - new (d) Heap::SimpleArrayData; + d->init(); d->alloc = length; d->type = Heap::ArrayData::Simple; d->offset = 0; @@ -615,6 +628,13 @@ Heap::DateObject *ExecutionEngine::newDateObject(const QDateTime &dt) return object->d(); } +Heap::DateObject *ExecutionEngine::newDateObjectFromTime(const QTime &t) +{ + Scope scope(this); + Scoped<DateObject> object(scope, memoryManager->allocObject<DateObject>(t)); + return object->d(); +} + Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags) { bool global = (flags & IR::RegExp::RegExp_Global); @@ -730,7 +750,7 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const if (!ctx) return 0; - return ctx->qml->context.contextData(); + return ctx->qml->context->contextData(); } QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const @@ -906,12 +926,12 @@ ReturnedValue ExecutionEngine::throwError(const Value &value) QV4::Scope scope(this); QV4::Scoped<ErrorObject> error(scope, value); if (!!error) - exceptionStackTrace = error->d()->stackTrace; + exceptionStackTrace = *error->d()->stackTrace; else exceptionStackTrace = stackTrace(); - if (debugger) - debugger->aboutToThrow(); + if (QV4::Debugging::Debugger *debug = debugger()) + debug->aboutToThrow(); return Encode::undefined(); } @@ -969,7 +989,7 @@ ReturnedValue ExecutionEngine::throwReferenceError(const Value &value) { Scope scope(this); ScopedString s(scope, value.toString(this)); - QString msg = s->toQString() + QStringLiteral(" is not defined"); + QString msg = s->toQString() + QLatin1String(" is not defined"); ScopedObject error(scope, newReferenceErrorObject(msg)); return throwError(error); } @@ -993,7 +1013,7 @@ ReturnedValue ExecutionEngine::throwRangeError(const Value &value) { Scope scope(this); ScopedString s(scope, value.toString(this)); - QString msg = s->toQString() + QStringLiteral(" out of range"); + QString msg = s->toQString() + QLatin1String(" out of range"); ScopedObject error(scope, newRangeErrorObject(msg)); return throwError(error); } @@ -1065,7 +1085,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int QV4::Scope scope(e); if (const QV4::VariantObject *v = value.as<QV4::VariantObject>()) - return v->d()->data; + return v->d()->data(); if (typeHint == QVariant::Bool) return QVariant(value.toBoolean()); @@ -1124,7 +1144,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int if (value.isUndefined()) return QVariant(); if (value.isNull()) - return QVariant(QMetaType::VoidStar, (void *)0); + return QVariant::fromValue(nullptr); if (value.isBoolean()) return value.booleanValue(); if (value.isInteger()) @@ -1139,10 +1159,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return str; } if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) - return ld->d()->locale; + return *ld->d()->locale; if (const QV4::DateObject *d = value.as<DateObject>()) return d->toQDateTime(); - if (const QV4::ArrayBuffer *d = value.as<ArrayBuffer>()) + if (const ArrayBuffer *d = value.as<ArrayBuffer>()) return d->asByteArray(); // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! @@ -1254,6 +1274,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::UnknownType: case QMetaType::Void: return QV4::Encode::undefined(); + case QMetaType::Nullptr: case QMetaType::VoidStar: return QV4::Encode::null(); case QMetaType::Bool: @@ -1270,6 +1291,8 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) return QV4::Encode(*reinterpret_cast<const double*>(ptr)); case QMetaType::QString: return newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue(); + case QMetaType::QByteArray: + return newArrayBuffer(*reinterpret_cast<const QByteArray*>(ptr))->asReturnedValue(); case QMetaType::Float: return QV4::Encode(*reinterpret_cast<const float*>(ptr)); case QMetaType::Short: @@ -1287,7 +1310,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::QDate: return QV4::Encode(newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr)))); case QMetaType::QTime: - return QV4::Encode(newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr)))); + return QV4::Encode(newDateObjectFromTime(*reinterpret_cast<const QTime *>(ptr))); case QMetaType::QRegExp: return QV4::Encode(newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr))); case QMetaType::QObjectStar: @@ -1423,6 +1446,7 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) case QMetaType::UnknownType: case QMetaType::Void: return QV4::Encode::undefined(); + case QMetaType::Nullptr: case QMetaType::VoidStar: return QV4::Encode::null(); case QMetaType::Bool: @@ -1446,6 +1470,8 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return QV4::Encode(*reinterpret_cast<const double*>(data)); case QMetaType::QString: return newString(*reinterpret_cast<const QString*>(data))->asReturnedValue(); + case QMetaType::QByteArray: + return newArrayBuffer(*reinterpret_cast<const QByteArray*>(data))->asReturnedValue(); case QMetaType::Float: return QV4::Encode(*reinterpret_cast<const float*>(data)); case QMetaType::Short: @@ -1507,6 +1533,11 @@ void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject) Q_UNUSED(baseObject); } +void ExecutionEngine::failStackLimitCheck(Scope &scope) +{ + scope.result = throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); +} + // Converts a JS value to a meta-type. // data must point to a place that can store a value of the given type. // Returns true if conversion succeeded, false otherwise. @@ -1538,6 +1569,12 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) else *reinterpret_cast<QString*>(data) = value->toQString(); return true; + case QMetaType::QByteArray: + if (const ArrayBuffer *ab = value->as<ArrayBuffer>()) + *reinterpret_cast<QByteArray*>(data) = ab->asByteArray(); + else + *reinterpret_cast<QByteArray*>(data) = QByteArray(); + return true; case QMetaType::Float: *reinterpret_cast<float*>(data) = value->toNumber(); return true; @@ -1662,7 +1699,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) return true; if (value->as<QV4::VariantObject>() && name.endsWith('*')) { int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = value->as<QV4::VariantObject>()->d()->data; + QVariant &var = value->as<QV4::VariantObject>()->d()->data(); if (valueType == var.userType()) { // We have T t, T* is requested, so return &t. *reinterpret_cast<void* *>(data) = var.data(); @@ -1674,7 +1711,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) while (proto) { bool canCast = false; if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) { - const QVariant &v = vo->d()->data; + const QVariant &v = vo->d()->data(); canCast = (type == v.userType()) || (valueType && (valueType == v.userType())); } else if (proto->as<QV4::QObjectWrapper>()) { @@ -1729,7 +1766,7 @@ static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const Value &value) QV4::Scoped<QV4::VariantObject> v(scope, value); if (v) { - QVariant variant = v->d()->data; + QVariant variant = v->d()->data(); int type = variant.userType(); if (type == QMetaType::QObjectStar) return *reinterpret_cast<QObject* const *>(variant.constData()); |