diff options
author | Ulf Hermann <[email protected]> | 2019-04-05 09:59:10 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2019-05-08 12:05:36 +0000 |
commit | fd6321c03e2d63997078bfa41332dbddefbb86b0 (patch) | |
tree | 12c92e0def97d5f704efb4a19c6f92d0f928375c | |
parent | a8b3536d6e5e7eb1c51fb20df071185dbce317a2 (diff) |
Remove last traces of QV8Engine
Change-Id: I59f738402d51e39188bbbca2ef1fbc8a61612372
Reviewed-by: Simon Hausmann <[email protected]>
27 files changed, 404 insertions, 687 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 0aad0d7c16..9004d1ee6f 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE } -class QQmlSqlDatabaseData : public QV8Engine::Deletable +class QQmlSqlDatabaseData : public QV4::ExecutionEngine::Deletable { public: QQmlSqlDatabaseData(QV4::ExecutionEngine *engine); diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp index 383444a808..459797f977 100644 --- a/src/particles/qquickv4particledata.cpp +++ b/src/particles/qquickv4particledata.cpp @@ -290,7 +290,7 @@ struct QV4ParticleData : public QV4::Object DEFINE_OBJECT_VTABLE(QV4ParticleData); -class QV4ParticleDataDeletable : public QV8Engine::Deletable +class QV4ParticleDataDeletable : public QV4::ExecutionEngine::Deletable { public: QV4ParticleDataDeletable(QV4::ExecutionEngine *engine); diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index db57d38c24..996b2f16ae 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -146,7 +146,7 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile() document->jsModule.fileName = typeData->urlString(); document->jsModule.finalUrl = typeData->finalUrlString(); QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine, - document->program, &document->jsGenerator.stringTable, engine->v8engine()->illegalNames()); + document->program, &document->jsGenerator.stringTable, engine->v4engine()->illegalNames()); QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator); if (!jsCodeGen.generateCodeForComponents()) return nullptr; @@ -298,7 +298,7 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlTypeCompiler *typeCompiler) , qmlObjects(*typeCompiler->qmlObjects()) , imports(typeCompiler->imports()) , customParsers(typeCompiler->customParserCache()) - , illegalNames(typeCompiler->enginePrivate()->v8engine()->illegalNames()) + , illegalNames(typeCompiler->enginePrivate()->v4engine()->illegalNames()) , propertyCaches(typeCompiler->propertyCaches()) { } diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 45ea79d31a..7bf2a4d004 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -41,7 +41,6 @@ #include "qjsengine_p.h" #include "qjsvalue.h" #include "qjsvalue_p.h" -#include "private/qv8engine_p.h" #include "private/qv4engine_p.h" #include "private/qv4mm_p.h" @@ -348,7 +347,6 @@ QJSEngine::QJSEngine(QObject *parent) : QObject(*new QJSEnginePrivate, parent) , m_v4Engine(new QV4::ExecutionEngine(this)) { - m_v4Engine->v8Engine = new QV8Engine(m_v4Engine); checkForApplicationInstance(); QJSEnginePrivate::addToDebugServer(this); @@ -361,7 +359,6 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent) : QObject(dd, parent) , m_v4Engine(new QV4::ExecutionEngine(this)) { - m_v4Engine->v8Engine = new QV8Engine(m_v4Engine); checkForApplicationInstance(); } @@ -375,7 +372,6 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent) QJSEngine::~QJSEngine() { QJSEnginePrivate::removeFromDebugServer(this); - delete m_v4Engine->v8Engine; delete m_v4Engine; } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index b65a2f2dad..b04a879c7f 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -102,7 +102,6 @@ #include "qv4dataview_p.h" #include "qv4promiseobject_p.h" #include "qv4typedarray_p.h" -#include <private/qv8engine_p.h> #include <private/qjsvalue_p.h> #include <private/qqmltypewrapper_p.h> #include <private/qqmlvaluetypewrapper_p.h> @@ -110,9 +109,16 @@ #include <private/qqmllistwrapper_p.h> #include <private/qqmllist_p.h> #include <private/qqmltypeloader_p.h> +#include <private/qqmlmemoryprofiler_p.h> +#include <private/qqmlbuiltinfunctions_p.h> #if QT_CONFIG(qml_locale) #include <private/qqmllocale_p.h> #endif +#if QT_CONFIG(qml_xml_http_request) +#include <private/qv4domerrors_p.h> +#include <private/qqmlxmlhttprequest_p.h> +#endif +#include <private/qv4sqlerrors_p.h> #include <qqmlfile.h> #if USE(PTHREADS) @@ -129,6 +135,8 @@ #include <valgrind/memcheck.h> #endif +Q_DECLARE_METATYPE(QList<int>) + QT_BEGIN_NAMESPACE using namespace QV4; @@ -142,6 +150,43 @@ ReturnedValue throwTypeError(const FunctionObject *b, const QV4::Value *, const qint32 ExecutionEngine::maxCallDepth = -1; +template <typename ReturnType> +ReturnType convertJSValueToVariantType(const QJSValue &value) +{ + return value.toVariant().value<ReturnType>(); +} + +static void saveJSValue(QDataStream &stream, const void *data) +{ + const QJSValue *jsv = reinterpret_cast<const QJSValue *>(data); + quint32 isNullOrUndefined = 0; + if (jsv->isNull()) + isNullOrUndefined |= 0x1; + if (jsv->isUndefined()) + isNullOrUndefined |= 0x2; + stream << isNullOrUndefined; + if (!isNullOrUndefined) + reinterpret_cast<const QJSValue*>(data)->toVariant().save(stream); +} + +static void restoreJSValue(QDataStream &stream, void *data) +{ + QJSValue *jsv = reinterpret_cast<QJSValue*>(data); + + quint32 isNullOrUndefined; + stream >> isNullOrUndefined; + + if (isNullOrUndefined & 0x1) { + *jsv = QJSValue(QJSValue::NullValue); + } else if (isNullOrUndefined & 0x2) { + *jsv = QJSValue(); + } else { + QVariant v; + v.load(stream); + QJSValuePrivate::setVariant(jsv, v); + } +} + ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) : executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) @@ -149,7 +194,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) , jsStack(new WTF::PageAllocation) , gcStack(new WTF::PageAllocation) , globalCode(nullptr) - , v8Engine(nullptr) , publicEngine(jsEngine) , m_engineId(engineSerial.fetchAndAddOrdered(1)) , regExpCache(nullptr) @@ -157,6 +201,10 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) #if QT_CONFIG(qml_jit) , m_canAllocateExecutableMemory(OSAllocator::canAllocateExecutableMemory()) #endif +#if QT_CONFIG(qml_xml_http_request) + , m_xmlHttpRequestData(nullptr) +#endif + , m_qmlEngine(nullptr) { memoryManager = new QV4::MemoryManager(this); @@ -643,11 +691,28 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) pd->set = thrower(); functionPrototype()->insertMember(id_caller(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable); functionPrototype()->insertMember(id_arguments(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable); + + QML_MEMORY_SCOPE_STRING("QV4Engine::QV4Engine"); + qMetaTypeId<QJSValue>(); + qMetaTypeId<QList<int> >(); + + if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QVariantMap>()) + QMetaType::registerConverter<QJSValue, QVariantMap>(convertJSValueToVariantType<QVariantMap>); + if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QVariantList>()) + QMetaType::registerConverter<QJSValue, QVariantList>(convertJSValueToVariantType<QVariantList>); + if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QStringList>()) + QMetaType::registerConverter<QJSValue, QStringList>(convertJSValueToVariantType<QStringList>); + QMetaType::registerStreamOperators(qMetaTypeId<QJSValue>(), saveJSValue, restoreJSValue); + + QV4::QObjectWrapper::initializeBindings(this); + + m_delayedCallQueue.init(this); } ExecutionEngine::~ExecutionEngine() { modules.clear(); + qDeleteAll(m_extensionData); delete m_multiplyWrappedQObjects; m_multiplyWrappedQObjects = nullptr; delete identifierTable; @@ -664,6 +729,11 @@ ExecutionEngine::~ExecutionEngine() delete jsStack; gcStack->deallocate(); delete gcStack; + +#if QT_CONFIG(qml_xml_http_request) + qt_rem_qmlxmlhttprequest(this, m_xmlHttpRequestData); + m_xmlHttpRequestData = nullptr; +#endif } ExecutionContext *ExecutionEngine::currentContext() const @@ -1750,6 +1820,133 @@ QQmlRefPointer<CompiledData::CompilationUnit> ExecutionEngine::loadModule(const return newModule; } +void ExecutionEngine::initQmlGlobalObject() +{ + initializeGlobal(); + freezeObject(*globalObject); +} + +void ExecutionEngine::initializeGlobal() +{ + QV4::Scope scope(this); + QV4::GlobalExtensions::init(globalObject, QJSEngine::AllExtensions); + + QV4::ScopedObject qt(scope, memoryManager->allocate<QV4::QtObject>(qmlEngine())); + globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt); + +#if QT_CONFIG(qml_locale) + QQmlLocale::registerStringLocaleCompare(this); + QQmlDateExtension::registerExtension(this); + QQmlNumberExtension::registerExtension(this); +#endif + +#if QT_CONFIG(qml_xml_http_request) + qt_add_domexceptions(this); + m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this); +#endif + + qt_add_sqlexceptions(this); + + { + for (uint i = 0; i < globalObject->internalClass()->size; ++i) { + if (globalObject->internalClass()->nameMap.at(i).isString()) { + QV4::PropertyKey id = globalObject->internalClass()->nameMap.at(i); + m_illegalNames.insert(id.toQString()); + } + } + } +} + +const QSet<QString> &ExecutionEngine::illegalNames() const +{ + return m_illegalNames; +} + +void ExecutionEngine::setQmlEngine(QQmlEngine *engine) +{ + m_qmlEngine = engine; + initQmlGlobalObject(); +} + +static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object) +{ + if (object->as<QV4::QObjectWrapper>()) + return; + + QV4::Scope scope(v4); + + bool instanceOfObject = false; + QV4::ScopedObject p(scope, object->getPrototypeOf()); + while (p) { + if (p->d() == v4->objectPrototype()->d()) { + instanceOfObject = true; + break; + } + p = p->getPrototypeOf(); + } + if (!instanceOfObject) + return; + + QV4::Heap::InternalClass *frozen = object->internalClass()->propertiesFrozen(); + if (object->internalClass() == frozen) + return; + object->setInternalClass(frozen); + + QV4::ScopedObject o(scope); + for (uint i = 0; i < frozen->size; ++i) { + if (!frozen->nameMap.at(i).isStringOrSymbol()) + continue; + o = *object->propertyData(i); + if (o) + freeze_recursive(v4, o); + } +} + +void ExecutionEngine::freezeObject(const QV4::Value &value) +{ + QV4::Scope scope(this); + QV4::ScopedObject o(scope, value); + freeze_recursive(this, o); +} + +void ExecutionEngine::startTimer(const QString &timerName) +{ + if (!m_time.isValid()) + m_time.start(); + m_startedTimers[timerName] = m_time.elapsed(); +} + +qint64 ExecutionEngine::stopTimer(const QString &timerName, bool *wasRunning) +{ + if (!m_startedTimers.contains(timerName)) { + *wasRunning = false; + return 0; + } + *wasRunning = true; + qint64 startedAt = m_startedTimers.take(timerName); + return m_time.elapsed() - startedAt; +} + +int ExecutionEngine::consoleCountHelper(const QString &file, quint16 line, quint16 column) +{ + const QString key = file + QString::number(line) + QString::number(column); + int number = m_consoleCount.value(key, 0); + number++; + m_consoleCount.insert(key, number); + return number; +} + +void ExecutionEngine::setExtensionData(int index, Deletable *data) +{ + if (m_extensionData.count() <= index) + m_extensionData.resize(index + 1); + + if (m_extensionData.at(index)) + delete m_extensionData.at(index); + + m_extensionData[index] = data; +} + // 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. @@ -1996,4 +2193,23 @@ static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &v return wrapper->object(); } +struct QV4EngineRegistrationData +{ + QV4EngineRegistrationData() : extensionCount(0) {} + + QMutex mutex; + int extensionCount; +}; +Q_GLOBAL_STATIC(QV4EngineRegistrationData, registrationData); + +QMutex *ExecutionEngine::registrationMutex() +{ + return ®istrationData()->mutex; +} + +int ExecutionEngine::registerExtension() +{ + return registrationData()->extensionCount++; +} + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 4ce854bc52..0d113754c0 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -53,13 +53,16 @@ #include "qv4global_p.h" #include "qv4managed_p.h" #include "qv4context_p.h" +#include "qv4stackframe_p.h" #include <private/qintrusivelist_p.h> #include "qv4enginebase_p.h" #include <private/qqmlrefcount_p.h> #include <private/qqmljsengine_p.h> +#include <private/qqmldelayedcallqueue_p.h> +#include <QtCore/qelapsedtimer.h> +#include <QtCore/qmutex.h> #include "qv4function_p.h" -#include <private/qv8engine_p.h> #include <private/qv4compileddata_p.h> namespace WTF { @@ -67,9 +70,65 @@ class BumpPointerAllocator; class PageAllocation; } +#define V4_DEFINE_EXTENSION(dataclass, datafunction) \ + static inline dataclass *datafunction(QV4::ExecutionEngine *engine) \ + { \ + static int extensionId = -1; \ + if (extensionId == -1) { \ + QV4::ExecutionEngine::registrationMutex()->lock(); \ + if (extensionId == -1) \ + extensionId = QV4::ExecutionEngine::registerExtension(); \ + QV4::ExecutionEngine::registrationMutex()->unlock(); \ + } \ + dataclass *rv = (dataclass *)engine->extensionData(extensionId); \ + if (!rv) { \ + rv = new dataclass(engine); \ + engine->setExtensionData(extensionId, rv); \ + } \ + return rv; \ + } \ + + QT_BEGIN_NAMESPACE -class QV8Engine; +namespace QV4 { struct QObjectMethod; } + +// Used to allow a QObject method take and return raw V4 handles without having to expose +// 48 in the public API. +// Use like this: +// class MyClass : public QObject { +// Q_OBJECT +// ... +// Q_INVOKABLE void myMethod(QQmlV4Function*); +// }; +// The QQmlV8Function - and consequently the arguments and return value - only remains +// valid during the call. If the return value isn't set within myMethod(), the will return +// undefined. + +class QQmlV4Function +{ +public: + int length() const { return callData->argc(); } + QV4::ReturnedValue operator[](int idx) const { return (idx < callData->argc() ? callData->args[idx].asReturnedValue() : QV4::Encode::undefined()); } + void setReturnValue(QV4::ReturnedValue rv) { *retVal = rv; } + QV4::ExecutionEngine *v4engine() const { return e; } +private: + friend struct QV4::QObjectMethod; + QQmlV4Function(); + QQmlV4Function(const QQmlV4Function &); + QQmlV4Function &operator=(const QQmlV4Function &); + + QQmlV4Function(QV4::CallData *callData, QV4::Value *retVal, QV4::ExecutionEngine *e) + : callData(callData), retVal(retVal), e(e) + { + callData->thisObject = QV4::Encode::undefined(); + } + + QV4::CallData *callData; + QV4::Value *retVal; + QV4::ExecutionEngine *e; +}; + class QQmlError; class QJSEngine; class QQmlEngine; @@ -127,8 +186,7 @@ public: Function *globalCode; QJSEngine *jsEngine() const { return publicEngine; } - QQmlEngine *qmlEngine() const { return v8Engine ? v8Engine->engine() : nullptr; } - QV8Engine *v8Engine; + QQmlEngine *qmlEngine() const { return m_qmlEngine; } QJSEngine *publicEngine; enum JSObjects { @@ -599,6 +657,44 @@ public: } QV4::ReturnedValue global(); + void initQmlGlobalObject(); + void initializeGlobal(); + + void freezeObject(const QV4::Value &value); + + // Return the list of illegal id names (the names of the properties on the global object) + const QSet<QString> &illegalNames() const; + +#if QT_CONFIG(qml_xml_http_request) + void *xmlHttpRequestData() const { return m_xmlHttpRequestData; } +#endif + + void setQmlEngine(QQmlEngine *engine); + + QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; } + + // used for console.time(), console.timeEnd() + void startTimer(const QString &timerName); + qint64 stopTimer(const QString &timerName, bool *wasRunning); + + // used for console.count() + int consoleCountHelper(const QString &file, quint16 line, quint16 column); + + struct Deletable { + virtual ~Deletable() {} + }; + + static QMutex *registrationMutex(); + static int registerExtension(); + + void setExtensionData(int, Deletable *); + Deletable *extensionData(int index) const + { + if (index < m_extensionData.count()) + return m_extensionData[index]; + else + return nullptr; + } double localTZA = 0.0; // local timezone, initialized at startup @@ -616,10 +712,26 @@ private: QScopedPointer<QV4::Debugging::Debugger> m_debugger; QScopedPointer<QV4::Profiling::Profiler> m_profiler; #endif + QSet<QString> m_illegalNames; int jitCallCountThreshold; // used by generated Promise objects to handle 'then' events QScopedPointer<QV4::Promise::ReactionHandler> m_reactionHandler; + +#if QT_CONFIG(qml_xml_http_request) + void *m_xmlHttpRequestData; +#endif + + QQmlEngine *m_qmlEngine; + + QQmlDelayedCallQueue m_delayedCallQueue; + + QElapsedTimer m_time; + QHash<QString, qint64> m_startedTimers; + + QHash<QString, quint32> m_consoleCount; + + QVector<Deletable *> m_extensionData; }; #define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \ diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 3c732bc555..c0885a418c 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -72,13 +72,17 @@ QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine, m_resultObject.set(v4, resultValue(v4)); #if QT_CONFIG(qml_network) - m_network = engine->v8Engine->networkAccessManager(); + if (QQmlEngine *qmlEngine = engine->qmlEngine()) { + m_network = qmlEngine->networkAccessManager(); - QNetworkRequest request; - request.setUrl(url); + QNetworkRequest request; + request.setUrl(url); - m_reply = m_network->get(request); - QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); + m_reply = m_network->get(request); + QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); + } else { + finished(); + } #else finished(); #endif @@ -197,7 +201,7 @@ void QV4Include::finished() } /* - Documented in qv8engine.cpp + Documented in qv4engine.cpp */ QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc) { diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 64d2a064df..f9f26b6b1e 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -72,7 +72,7 @@ namespace { QT_BEGIN_NAMESPACE -class QQmlComponentExtension : public QV8Engine::Deletable +class QQmlComponentExtension : public QV4::ExecutionEngine::Deletable { public: QQmlComponentExtension(QV4::ExecutionEngine *v4); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index cb94ae379e..8bdbe0fc47 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -957,7 +957,7 @@ void QQmlEnginePrivate::init() qRegisterMetaType<QList<int> >(); qRegisterMetaType<QQmlBinding*>(); - v8engine()->setEngine(q); + q->handle()->setQmlEngine(q); rootContext = new QQmlContext(q,true); } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 6ef88404fd..668dfed91e 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -76,7 +76,6 @@ #include <private/qobject_p.h> -#include <private/qv8engine_p.h> #include <private/qjsengine_p.h> #include <private/qqmldirparser_p.h> @@ -149,7 +148,6 @@ public: QQmlDelayedError *erroredBindings; int inProgressCreations; - QV8Engine *v8engine() const { return q_func()->handle()->v8Engine; } QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); } #if QT_CONFIG(qml_worker_script) @@ -240,7 +238,6 @@ public: static void warning(QQmlEnginePrivate *, const QQmlError &); static void warning(QQmlEnginePrivate *, const QList<QQmlError> &); - inline static QV8Engine *getV8Engine(QQmlEngine *e); inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e); inline static QQmlEnginePrivate *get(QQmlEngine *e); inline static const QQmlEnginePrivate *get(const QQmlEngine *e); @@ -388,13 +385,6 @@ QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersi return QQmlMetaType::propertyCache(type, minorVersion); } -QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e) -{ - Q_ASSERT(e); - - return e->handle()->v8Engine; -} - QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) { Q_ASSERT(e); diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 53caffe040..136159993a 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -55,7 +55,6 @@ #include <QtCore/QObject> #include <private/qqmlmetaobject_p.h> #include <private/qmetaobject_p.h> -#include <private/qv8engine_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 2b17037df0..dca13ac8d4 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -662,7 +662,7 @@ LOCALE_STRING_PROPERTY(exponential) LOCALE_STRING_PROPERTY(amText) LOCALE_STRING_PROPERTY(pmText) -class QV4LocaleDataDeletable : public QV8Engine::Deletable +class QV4LocaleDataDeletable : public QV4::ExecutionEngine::Deletable { public: QV4LocaleDataDeletable(QV4::ExecutionEngine *engine); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index a6546ae330..48c4216d54 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -868,7 +868,7 @@ QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int a QString QQmlPropertyCache::signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList<QByteArray> ¶meterNameList, QString *errorString) { bool unnamedParameter = false; - const QSet<QString> &illegalNames = engine->v8Engine->illegalNames(); + const QSet<QString> &illegalNames = engine->illegalNames(); QString parameters; for (int i = 0; i < parameterNameList.count(); ++i) { diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index a953e677fa..d694909c7c 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2516,7 +2516,7 @@ bool QQmlTypeData::loadFromSource() m_document.reset(new QmlIR::Document(isDebugging())); m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp(); QQmlEngine *qmlEngine = typeLoader()->engine(); - QmlIR::IRBuilder compiler(qmlEngine->handle()->v8Engine->illegalNames()); + QmlIR::IRBuilder compiler(qmlEngine->handle()->illegalNames()); QString sourceError; const QString source = m_backupSourceCode.readAll(&sourceError); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index f08005fd20..fce753cd26 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -39,6 +39,7 @@ #include "qqmlvaluetype_p.h" +#include <QtCore/qmutex.h> #include <private/qqmlglobal_p.h> #include <QtCore/qdebug.h> #include <private/qmetaobjectbuilder_p.h> diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index c6b7f2ab3f..b435f8ef66 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -95,7 +95,7 @@ struct QQmlXMLHttpRequestData { static inline QQmlXMLHttpRequestData *xhrdata(ExecutionEngine *v4) { - return (QQmlXMLHttpRequestData *)v4->v8Engine->xmlHttpRequestData(); + return (QQmlXMLHttpRequestData *)v4->xmlHttpRequestData(); } QQmlXMLHttpRequestData::QQmlXMLHttpRequestData() @@ -591,7 +591,7 @@ ReturnedValue NodePrototype::getProto(ExecutionEngine *v4) if (d->nodePrototype.isUndefined()) { ScopedObject p(scope, v4->memoryManager->allocate<NodePrototype>()); d->nodePrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->nodePrototype.value(); } @@ -640,7 +640,7 @@ ReturnedValue Element::prototype(ExecutionEngine *engine) p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine))); p->defineAccessorProperty(QStringLiteral("tagName"), NodePrototype::method_get_nodeName, nullptr); d->elementPrototype.set(engine, p); - engine->v8Engine->freezeObject(p); + engine->freezeObject(p); } return d->elementPrototype.value(); } @@ -657,7 +657,7 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine) p->defineAccessorProperty(QStringLiteral("value"), method_value, nullptr); p->defineAccessorProperty(QStringLiteral("ownerElement"), method_ownerElement, nullptr); d->attrPrototype.set(engine, p); - engine->v8Engine->freezeObject(p); + engine->freezeObject(p); } return d->attrPrototype.value(); } @@ -713,7 +713,7 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("data"), NodePrototype::method_get_nodeValue, nullptr); p->defineAccessorProperty(QStringLiteral("length"), method_length, nullptr); d->characterDataPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->characterDataPrototype.value(); } @@ -749,7 +749,7 @@ ReturnedValue Text::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, nullptr); p->defineAccessorProperty(QStringLiteral("wholeText"), method_wholeText, nullptr); d->textPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->textPrototype.value(); } @@ -764,7 +764,7 @@ ReturnedValue CDATA::prototype(ExecutionEngine *v4) ScopedObject pp(scope); p->setPrototypeUnchecked((pp = Text::prototype(v4))); d->cdataPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->cdataPrototype.value(); } @@ -782,7 +782,7 @@ ReturnedValue Document::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("xmlStandalone"), method_xmlStandalone, nullptr); p->defineAccessorProperty(QStringLiteral("documentElement"), method_documentElement, nullptr); d->documentPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->documentPrototype.value(); } @@ -1646,7 +1646,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject Scope scope(f->engine()); const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f); - QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->v8Engine->networkAccessManager(), scope.engine); + QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->qmlEngine()->networkAccessManager(), scope.engine); Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocate<QQmlXMLHttpRequestWrapper>(r)); ScopedObject proto(scope, ctor->d()->proto); w->setPrototypeUnchecked(proto); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 3bc588b50e..532bfa8754 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -47,7 +47,6 @@ #if QT_CONFIG(qml_locale) #include <private/qqmllocale_p.h> #endif -#include <private/qv8engine_p.h> #include <private/qqmldelayedcallqueue_p.h> #include <QFileInfo> @@ -1684,10 +1683,8 @@ ReturnedValue ConsoleObject::method_time(const FunctionObject *b, const Value *, if (argc != 1) THROW_GENERIC_ERROR("console.time(): Invalid arguments"); - QV8Engine *v8engine = scope.engine->v8Engine; - QString name = argv[0].toQStringNoThrow(); - v8engine->startTimer(name); + scope.engine->startTimer(name); return QV4::Encode::undefined(); } @@ -1697,11 +1694,9 @@ ReturnedValue ConsoleObject::method_timeEnd(const FunctionObject *b, const Value if (argc != 1) THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments"); - QV8Engine *v8engine = scope.engine->v8Engine; - QString name = argv[0].toQStringNoThrow(); bool wasRunning; - qint64 elapsed = v8engine->stopTimer(name, &wasRunning); + qint64 elapsed = scope.engine->stopTimer(name, &wasRunning); if (wasRunning) { qDebug("%s: %llims", qPrintable(name), elapsed); } @@ -1717,13 +1712,12 @@ ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value * Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; - QV8Engine *v8engine = scope.engine->v8Engine; QV4::CppStackFrame *frame = v4->currentStackFrame; QString scriptName = frame->source(); - int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), 0); + int value = v4->consoleCountHelper(scriptName, frame->lineNumber(), 0); QString message = name + QLatin1String(": ") + QString::number(value); QMessageLogger(qPrintable(scriptName), frame->lineNumber(), @@ -2147,8 +2141,7 @@ function. */ ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { - QV8Engine *v8engine = b->engine()->v8Engine; - return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc); + return b->engine()->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp deleted file mode 100644 index d76344b613..0000000000 --- a/src/qml/qml/v8/qv8engine.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8engine_p.h" - -#if QT_CONFIG(qml_sequence_object) -#include "qv4sequenceobject_p.h" -#endif - -#include "private/qjsengine_p.h" - -#include <private/qqmlbuiltinfunctions_p.h> -#include <private/qqmllist_p.h> -#include <private/qqmlengine_p.h> -#if QT_CONFIG(qml_xml_http_request) -#include <private/qqmlxmlhttprequest_p.h> -#endif -#if QT_CONFIG(qml_locale) -#include <private/qqmllocale_p.h> -#endif -#include <private/qqmlglobal_p.h> -#include <private/qqmlmemoryprofiler_p.h> -#include <private/qqmlplatform_p.h> -#include <private/qjsvalue_p.h> -#include <private/qqmltypewrapper_p.h> -#include <private/qqmlvaluetypewrapper_p.h> -#include <private/qqmllistwrapper_p.h> -#include <private/qv4scopedvalue_p.h> - -#include "qv4domerrors_p.h" -#include "qv4sqlerrors_p.h" - -#include <QtCore/qjsonarray.h> -#include <QtCore/qjsonobject.h> -#include <QtCore/qjsonvalue.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qdatastream.h> -#include <private/qsimd_p.h> - -#include <private/qv4value_p.h> -#include <private/qv4dateobject_p.h> -#include <private/qv4objectiterator_p.h> -#include <private/qv4qobjectwrapper_p.h> -#include <private/qv4mm_p.h> -#include <private/qv4objectproto_p.h> -#include <private/qv4globalobject_p.h> -#include <private/qv4regexpobject_p.h> -#include <private/qv4variantobject_p.h> -#include <private/qv4script_p.h> -#include <private/qv4include_p.h> -#include <private/qv4jsonobject_p.h> -#include <private/qv4identifiertable_p.h> - -Q_DECLARE_METATYPE(QList<int>) - - -// XXX TODO: Need to check all the global functions will also work in a worker script where the -// QQmlEngine is not available -QT_BEGIN_NAMESPACE - -template <typename ReturnType> -ReturnType convertJSValueToVariantType(const QJSValue &value) -{ - return value.toVariant().value<ReturnType>(); -} - -static void saveJSValue(QDataStream &stream, const void *data) -{ - const QJSValue *jsv = reinterpret_cast<const QJSValue *>(data); - quint32 isNullOrUndefined = 0; - if (jsv->isNull()) - isNullOrUndefined |= 0x1; - if (jsv->isUndefined()) - isNullOrUndefined |= 0x2; - stream << isNullOrUndefined; - if (!isNullOrUndefined) - reinterpret_cast<const QJSValue*>(data)->toVariant().save(stream); -} - -static void restoreJSValue(QDataStream &stream, void *data) -{ - QJSValue *jsv = reinterpret_cast<QJSValue*>(data); - - quint32 isNullOrUndefined; - stream >> isNullOrUndefined; - - if (isNullOrUndefined & 0x1) { - *jsv = QJSValue(QJSValue::NullValue); - } else if (isNullOrUndefined & 0x2) { - *jsv = QJSValue(); - } else { - QVariant v; - v.load(stream); - QJSValuePrivate::setVariant(jsv, v); - } -} - -QV8Engine::QV8Engine(QV4::ExecutionEngine *v4) - : m_engine(nullptr) - , m_v4Engine(v4) -#if QT_CONFIG(qml_xml_http_request) - , m_xmlHttpRequestData(nullptr) -#endif -{ -#ifndef Q_OS_WASM // wasm does not have working simd QTBUG-63924 -#ifdef Q_PROCESSOR_X86_32 - if (!qCpuHasFeature(SSE2)) { - qFatal("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer"); - } -#endif -#endif - - QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine"); - qMetaTypeId<QJSValue>(); - qMetaTypeId<QList<int> >(); - - if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QVariantMap>()) - QMetaType::registerConverter<QJSValue, QVariantMap>(convertJSValueToVariantType<QVariantMap>); - if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QVariantList>()) - QMetaType::registerConverter<QJSValue, QVariantList>(convertJSValueToVariantType<QVariantList>); - if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QStringList>()) - QMetaType::registerConverter<QJSValue, QStringList>(convertJSValueToVariantType<QStringList>); - QMetaType::registerStreamOperators(qMetaTypeId<QJSValue>(), saveJSValue, restoreJSValue); - - m_delayedCallQueue.init(m_v4Engine); - - QV4::QObjectWrapper::initializeBindings(m_v4Engine); -} - -QV8Engine::~QV8Engine() -{ - qDeleteAll(m_extensionData); - m_extensionData.clear(); - -#if QT_CONFIG(qml_xml_http_request) - qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData); - m_xmlHttpRequestData = nullptr; -#endif -} - -#if QT_CONFIG(qml_network) -QNetworkAccessManager *QV8Engine::networkAccessManager() -{ - return QQmlEnginePrivate::get(m_engine)->getNetworkAccessManager(); -} -#endif - -const QSet<QString> &QV8Engine::illegalNames() const -{ - return m_illegalNames; -} - -void QV8Engine::initializeGlobal() -{ - QV4::Scope scope(m_v4Engine); - QV4::GlobalExtensions::init(m_v4Engine->globalObject, QJSEngine::AllExtensions); - - QV4::ScopedObject qt(scope, m_v4Engine->memoryManager->allocate<QV4::QtObject>(m_engine)); - m_v4Engine->globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt); - -#if QT_CONFIG(qml_locale) - QQmlLocale::registerStringLocaleCompare(m_v4Engine); - QQmlDateExtension::registerExtension(m_v4Engine); - QQmlNumberExtension::registerExtension(m_v4Engine); -#endif - -#if QT_CONFIG(qml_xml_http_request) - qt_add_domexceptions(m_v4Engine); - m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(m_v4Engine); -#endif - - qt_add_sqlexceptions(m_v4Engine); - - { - for (uint i = 0; i < m_v4Engine->globalObject->internalClass()->size; ++i) { - if (m_v4Engine->globalObject->internalClass()->nameMap.at(i).isString()) { - QV4::PropertyKey id = m_v4Engine->globalObject->internalClass()->nameMap.at(i); - m_illegalNames.insert(id.toQString()); - } - } - } -} - -static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object) -{ - if (object->as<QV4::QObjectWrapper>()) - return; - - QV4::Scope scope(v4); - - bool instanceOfObject = false; - QV4::ScopedObject p(scope, object->getPrototypeOf()); - while (p) { - if (p->d() == v4->objectPrototype()->d()) { - instanceOfObject = true; - break; - } - p = p->getPrototypeOf(); - } - if (!instanceOfObject) - return; - - QV4::Heap::InternalClass *frozen = object->internalClass()->propertiesFrozen(); - if (object->internalClass() == frozen) - return; - object->setInternalClass(frozen); - - QV4::ScopedObject o(scope); - for (uint i = 0; i < frozen->size; ++i) { - if (!frozen->nameMap.at(i).isStringOrSymbol()) - continue; - o = *object->propertyData(i); - if (o) - freeze_recursive(v4, o); - } -} - -void QV8Engine::freezeObject(const QV4::Value &value) -{ - QV4::Scope scope(m_v4Engine); - QV4::ScopedObject o(scope, value); - freeze_recursive(m_v4Engine, o); -} - -struct QV8EngineRegistrationData -{ - QV8EngineRegistrationData() : extensionCount(0) {} - - QMutex mutex; - int extensionCount; -}; -Q_GLOBAL_STATIC(QV8EngineRegistrationData, registrationData); - -QMutex *QV8Engine::registrationMutex() -{ - return ®istrationData()->mutex; -} - -int QV8Engine::registerExtension() -{ - return registrationData()->extensionCount++; -} - -void QV8Engine::setExtensionData(int index, Deletable *data) -{ - if (m_extensionData.count() <= index) - m_extensionData.resize(index + 1); - - if (m_extensionData.at(index)) - delete m_extensionData.at(index); - - m_extensionData[index] = data; -} - -void QV8Engine::initQmlGlobalObject() -{ - initializeGlobal(); - freezeObject(*m_v4Engine->globalObject); -} - -void QV8Engine::setEngine(QQmlEngine *engine) -{ - m_engine = engine; - initQmlGlobalObject(); -} - -void QV8Engine::startTimer(const QString &timerName) -{ - if (!m_time.isValid()) - m_time.start(); - m_startedTimers[timerName] = m_time.elapsed(); -} - -qint64 QV8Engine::stopTimer(const QString &timerName, bool *wasRunning) -{ - if (!m_startedTimers.contains(timerName)) { - *wasRunning = false; - return 0; - } - *wasRunning = true; - qint64 startedAt = m_startedTimers.take(timerName); - return m_time.elapsed() - startedAt; -} - -int QV8Engine::consoleCountHelper(const QString &file, quint16 line, quint16 column) -{ - const QString key = file + QString::number(line) + QString::number(column); - int number = m_consoleCount.value(key, 0); - number++; - m_consoleCount.insert(key, number); - return number; -} - -QT_END_NAMESPACE - diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h deleted file mode 100644 index f9b69cfacc..0000000000 --- a/src/qml/qml/v8/qv8engine_p.h +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLV8ENGINE_P_H -#define QQMLV8ENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qvariant.h> -#include <QtCore/qset.h> -#include <QtCore/qmutex.h> -#include <QtCore/qstack.h> -#include <QtCore/qstringlist.h> -#include <QtCore/QElapsedTimer> -#include <QtCore/QThreadStorage> - -#include <QtQml/qjsengine.h> -#include "private/qintrusivelist_p.h" - - -#include <private/qv4value_p.h> -#include <private/qv4identifier_p.h> -#include <private/qv4context_p.h> -#include <private/qv4stackframe_p.h> -#include <private/qqmldelayedcallqueue_p.h> - -QT_BEGIN_NAMESPACE - -namespace QV4 { - struct ArrayObject; - struct ExecutionEngine; - struct QObjectMethod; -} - -#define V4_DEFINE_EXTENSION(dataclass, datafunction) \ - static inline dataclass *datafunction(QV4::ExecutionEngine *engine) \ - { \ - static int extensionId = -1; \ - if (extensionId == -1) { \ - QV8Engine::registrationMutex()->lock(); \ - if (extensionId == -1) \ - extensionId = QV8Engine::registerExtension(); \ - QV8Engine::registrationMutex()->unlock(); \ - } \ - dataclass *rv = (dataclass *)engine->v8Engine->extensionData(extensionId); \ - if (!rv) { \ - rv = new dataclass(engine); \ - engine->v8Engine->setExtensionData(extensionId, rv); \ - } \ - return rv; \ - } \ - -// Used to allow a QObject method take and return raw V4 handles without having to expose -// 48 in the public API. -// Use like this: -// class MyClass : public QObject { -// Q_OBJECT -// ... -// Q_INVOKABLE void myMethod(QQmlV4Function*); -// }; -// The QQmlV8Function - and consequently the arguments and return value - only remains -// valid during the call. If the return value isn't set within myMethod(), the will return -// undefined. - -class QQmlV4Function -{ -public: - int length() const { return callData->argc(); } - QV4::ReturnedValue operator[](int idx) const { return (idx < callData->argc() ? callData->args[idx].asReturnedValue() : QV4::Encode::undefined()); } - void setReturnValue(QV4::ReturnedValue rv) { *retVal = rv; } - QV4::ExecutionEngine *v4engine() const { return e; } -private: - friend struct QV4::QObjectMethod; - QQmlV4Function(); - QQmlV4Function(const QQmlV4Function &); - QQmlV4Function &operator=(const QQmlV4Function &); - - QQmlV4Function(QV4::CallData *callData, QV4::Value *retVal, QV4::ExecutionEngine *e) - : callData(callData), retVal(retVal), e(e) - { - callData->thisObject = QV4::Encode::undefined(); - } - - QV4::CallData *callData; - QV4::Value *retVal; - QV4::ExecutionEngine *e; -}; - -class QObject; -class QQmlEngine; -class QNetworkAccessManager; -class QQmlContextData; - -class Q_QML_PRIVATE_EXPORT QV8Engine -{ - friend class QJSEngine; -public: -// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; } - static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; } - - QV8Engine(QV4::ExecutionEngine *v4); - virtual ~QV8Engine(); - - // This enum should be in sync with QQmlEngine::ObjectOwnership - enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; - - struct Deletable { - virtual ~Deletable() {} - }; - - void initQmlGlobalObject(); - void setEngine(QQmlEngine *engine); - QQmlEngine *engine() { return m_engine; } - QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; } - -#if QT_CONFIG(qml_xml_http_request) - void *xmlHttpRequestData() const { return m_xmlHttpRequestData; } -#endif - - void freezeObject(const QV4::Value &value); - -#if QT_CONFIG(qml_network) - // Return the network access manager for this engine. By default this returns the network - // access manager of the QQmlEngine. It is overridden in the case of a threaded v8 - // instance (like in WorkerScript). - virtual QNetworkAccessManager *networkAccessManager(); -#endif - - // Return the list of illegal id names (the names of the properties on the global object) - const QSet<QString> &illegalNames() const; - - static QMutex *registrationMutex(); - static int registerExtension(); - - inline Deletable *extensionData(int) const; - void setExtensionData(int, Deletable *); - -public: - // used for console.time(), console.timeEnd() - void startTimer(const QString &timerName); - qint64 stopTimer(const QString &timerName, bool *wasRunning); - - // used for console.count() - int consoleCountHelper(const QString &file, quint16 line, quint16 column); - -protected: - QQmlEngine *m_engine; - QQmlDelayedCallQueue m_delayedCallQueue; - - QV4::ExecutionEngine *m_v4Engine; - -#if QT_CONFIG(qml_xml_http_request) - void *m_xmlHttpRequestData; -#endif - - QVector<Deletable *> m_extensionData; - - QSet<QString> m_illegalNames; - - QElapsedTimer m_time; - QHash<QString, qint64> m_startedTimers; - - QHash<QString, quint32> m_consoleCount; - - void initializeGlobal(); - -private: - Q_DISABLE_COPY(QV8Engine) -}; - -inline QV8Engine::Deletable *QV8Engine::extensionData(int index) const -{ - if (index < m_extensionData.count()) - return m_extensionData[index]; - else - return nullptr; -} - - -QT_END_NAMESPACE - -#endif // QQMLV8ENGINE_P_H diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri index 4592022939..fbcc47de0c 100644 --- a/src/qml/qml/v8/v8.pri +++ b/src/qml/qml/v8/v8.pri @@ -1,11 +1,9 @@ HEADERS += \ - $$PWD/qv8engine_p.h \ $$PWD/qv4domerrors_p.h \ $$PWD/qv4sqlerrors_p.h \ $$PWD/qqmlbuiltinfunctions_p.h SOURCES += \ - $$PWD/qv8engine.cpp \ $$PWD/qv4domerrors.cpp \ $$PWD/qv4sqlerrors.cpp \ $$PWD/qqmlbuiltinfunctions.cpp diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h index a111f72e81..3e275c6359 100644 --- a/src/qml/qtqmlglobal.h +++ b/src/qml/qtqmlglobal.h @@ -54,6 +54,8 @@ # define QT_FEATURE_qml_debug -1 # define QT_FEATURE_qml_sequence_object 1 # define QT_FEATURE_qml_jit -1 +# define QT_FEATURE_qml_worker_script -1 +# define QT_FEATURE_qml_xml_http_request -1 #endif QT_BEGIN_NAMESPACE diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index f991ae0a69..0bc67e1aad 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE -class QQmlAdaptorModelEngineData : public QV8Engine::Deletable +class QQmlAdaptorModelEngineData : public QV4::ExecutionEngine::Deletable { public: QQmlAdaptorModelEngineData(QV4::ExecutionEngine *v4); diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 742c164508..2216e5fb50 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -123,7 +123,7 @@ DEFINE_OBJECT_VTABLE(QV4::DelegateModelGroupFunction); -class QQmlDelegateModelEngineData : public QV8Engine::Deletable +class QQmlDelegateModelEngineData : public QV4::ExecutionEngine::Deletable { public: QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4); diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h index f79c0c557a..1ef27cea3f 100644 --- a/src/qmlmodels/qqmllistmodelworkeragent_p.h +++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h @@ -57,7 +57,7 @@ #include <QMutex> #include <QWaitCondition> -#include <private/qv8engine_p.h> +#include <private/qv4engine_p.h> QT_REQUIRE_CONFIG(qml_list_model); diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index 273ec2a7a6..4da1def5f5 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -57,7 +57,6 @@ #include "qqmlnetworkaccessmanagerfactory.h" #endif -#include <private/qv8engine_p.h> #include <private/qv4serialize_p.h> #include <private/qv4value_p.h> @@ -125,6 +124,15 @@ private: QQmlError m_error; }; +struct WorkerScript : public QV4::ExecutionEngine { + WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent); + + QQuickWorkerScriptEnginePrivate *p = nullptr; + QUrl source; + QQuickWorkerScript *owner = nullptr; + int id = -1; +}; + class QQuickWorkerScriptEnginePrivate : public QObject { Q_OBJECT @@ -140,23 +148,6 @@ public: QMutex m_lock; QWaitCondition m_wait; - struct WorkerScript : public QV8Engine { - WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent); - ~WorkerScript() override; - -#if QT_CONFIG(qml_network) - QNetworkAccessManager *networkAccessManager() override; -#endif - - QQuickWorkerScriptEnginePrivate *p = nullptr; - QUrl source; - QQuickWorkerScript *owner = nullptr; -#if QT_CONFIG(qml_network) - QScopedPointer<QNetworkAccessManager> accessManager; -#endif - int id = -1; - }; - QHash<int, WorkerScript *> workers; QV4::ReturnedValue getWorker(WorkerScript *); @@ -185,7 +176,7 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4 const QV4::Value *, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - WorkerScript *script = static_cast<WorkerScript *>(scope.engine->v8Engine); + WorkerScript *script = static_cast<WorkerScript *>(scope.engine); QV4::ScopedValue v(scope, argc > 0 ? argv[0] : QV4::Value::undefinedValue()); QByteArray data = QV4::Serialize::serialize(v, scope.engine); @@ -230,21 +221,20 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d if (!script) return; - QV4::ExecutionEngine *v4 = QV8Engine::getV4(script); - QV4::Scope scope(v4); + QV4::Scope scope(script); QV4::ScopedString v(scope); - QV4::ScopedObject worker(scope, v4->globalObject->get((v = v4->newString(QStringLiteral("WorkerScript"))))); + QV4::ScopedObject worker(scope, script->globalObject->get((v = script->newString(QStringLiteral("WorkerScript"))))); QV4::ScopedFunctionObject onmessage(scope); if (worker) - onmessage = worker->get((v = v4->newString(QStringLiteral("onMessage")))); + onmessage = worker->get((v = script->newString(QStringLiteral("onMessage")))); if (!onmessage) return; - QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, v4)); + QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, script)); QV4::JSCallData jsCallData(scope, 1); - *jsCallData->thisObject = v4->global(); + *jsCallData->thisObject = script->global(); jsCallData->args[0] = value; onmessage->call(jsCallData); if (scope.hasException()) { @@ -264,35 +254,33 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url) if (!script) return; - QV4::ExecutionEngine *v4 = QV8Engine::getV4(script); - script->source = url; if (fileName.endsWith(QLatin1String(".mjs"))) { - auto moduleUnit = v4->loadModule(url); + auto moduleUnit = script->loadModule(url); if (moduleUnit) { - if (moduleUnit->instantiate(v4)) + if (moduleUnit->instantiate(script)) moduleUnit->evaluate(); } else { - v4->throwError(QStringLiteral("Could not load module file")); + script->throwError(QStringLiteral("Could not load module file")); } } else { QString error; - QV4::Scope scope(v4); + QV4::Scope scope(script); QScopedPointer<QV4::Script> program; - program.reset(QV4::Script::createFromFileOrCache(v4, /*qmlContext*/nullptr, fileName, url, &error)); + program.reset(QV4::Script::createFromFileOrCache(script, /*qmlContext*/nullptr, fileName, url, &error)); if (program.isNull()) { if (!error.isEmpty()) qWarning().nospace() << error; return; } - if (!v4->hasException) + if (!script->hasException) program->run(); } - if (v4->hasException) { - QQmlError error = v4->catchExceptionAsQmlError(); + if (script->hasException) { + QQmlError error = script->catchExceptionAsQmlError(); reportScriptException(script, error); } } @@ -389,45 +377,22 @@ QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine() d->deleteLater(); } -QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) - : QV8Engine(new QV4::ExecutionEngine) - , p(parent) +WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) + : p(parent) , id(id) { - m_v4Engine->v8Engine = this; - initQmlGlobalObject(); - QV4::Scope scope(m_v4Engine); + QV4::Scope scope(this); QV4::ScopedObject api(scope, scope.engine->newObject()); - QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage"))); - QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(m_v4Engine, name, method_sendMessage, 1)); + QV4::ScopedString name(scope, newString(QStringLiteral("sendMessage"))); + QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(this, name, QQuickWorkerScriptEnginePrivate::method_sendMessage, 1)); api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage); - m_v4Engine->globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api); -} - -QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript() -{ - delete m_v4Engine; -} - -#if QT_CONFIG(qml_network) -QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerScript::networkAccessManager() -{ - if (!accessManager) { - if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) { - accessManager.reset(p->qmlengine->networkAccessManagerFactory()->create(p)); - } else { - accessManager.reset(new QNetworkAccessManager(p)); - } - } - return accessManager.data(); + globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api); } -#endif int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) { - typedef QQuickWorkerScriptEnginePrivate::WorkerScript WorkerScript; WorkerScript *script = new WorkerScript(d->m_nextId++, d); script->owner = owner; @@ -441,8 +406,7 @@ int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) void QQuickWorkerScriptEngine::removeWorkerScript(int id) { - QQuickWorkerScriptEnginePrivate::WorkerScript* script = d->workers.value(id); - if (script) { + if (WorkerScript *script = d->workers.value(id)) { script->owner = nullptr; QCoreApplication::postEvent(d, new WorkerRemoveEvent(id)); } diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 58bc12a221..5640721c6f 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -473,7 +473,7 @@ static QFont qt_font_from_string(const QString& fontString, const QFont ¤t return newFont; } -class QQuickContext2DEngineData : public QV8Engine::Deletable +class QQuickContext2DEngineData : public QV4::ExecutionEngine::Deletable { public: QQuickContext2DEngineData(QV4::ExecutionEngine *engine); diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 8121b4559e..9ad0a77318 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -41,6 +41,7 @@ #include <QtCore/qelapsedtimer.h> #include <QtCore/qbuffer.h> +#include <QtCore/qendian.h> #include <QtQml/qqmlfile.h> #include <QtGui/private/qdistancefield_p.h> |