diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-12-12 01:00:38 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-12-12 13:08:25 +0100 |
commit | 39643ef86e8bc48b8b6cf83ac0ebae7411029030 (patch) | |
tree | 79277e468160ebc04a65a85c9668dabefbf3ce33 /src/qml | |
parent | 489d6c28dda51c187c85017e30c1e018420e26ac (diff) | |
parent | e3446c8225acbaa6a613d6c62e8e2fc58e2b70b0 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
Change-Id: Ic1dace832ad4b29023d24808b8617b5dcc915eb5
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 70 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4alloca_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 1 | ||||
-rw-r--r-- | src/qml/parser/qqmljslexer.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 3 |
9 files changed, 86 insertions, 10 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 9ff38db911..84fd66b114 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1835,8 +1835,9 @@ JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator * , _scopeObject(nullptr) , _qmlContextSlot(-1) , _importedScriptsSlot(-1) - , m_globalNames(globalNames) { + m_globalNames = globalNames; + _module = jsModule; _fileNameIsUrl = true; } @@ -2306,15 +2307,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n return Reference::fromQmlContextObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy); } } - - Reference r = Reference::fromName(this, name); - if (m_globalNames.contains(name)) - r.global = true; - return r; #else Q_UNUSED(name) - return Reference(); #endif // V4_BOOTSTRAP + return Reference(); } #ifndef V4_BOOTSTRAP diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index d1e2b17bb7..3dde929cc4 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -640,7 +640,6 @@ private: QQmlPropertyCache *_scopeObject; int _qmlContextSlot; int _importedScriptsSlot; - QSet<QString> m_globalNames; }; struct Q_QML_PRIVATE_EXPORT IRLoader { diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 63cdb78d27..cdba21604d 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -102,6 +102,62 @@ Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict) jsUnitGenerator->codeGeneratorName = QStringLiteral("moth"); } +const char *globalNames[] = { + "isNaN", + "parseFloat", + "String", + "EvalError", + "URIError", + "Math", + "encodeURIComponent", + "RangeError", + "eval", + "isFinite", + "ReferenceError", + "Infinity", + "Function", + "RegExp", + "Number", + "parseInt", + "Object", + "decodeURI", + "TypeError", + "Boolean", + "encodeURI", + "NaN", + "Error", + "decodeURIComponent", + "Date", + "Array", + "Symbol", + "escape", + "unescape", + "SyntaxError", + "undefined", + "JSON", + "ArrayBuffer", + "SharedArrayBuffer", + "DataView", + "Int8Array", + "Uint8Array", + "Uint8ClampedArray", + "Int16Array", + "Uint16Array", + "Int32Array", + "Uint32Array", + "Float32Array", + "Float64Array", + "WeakSet", + "Set", + "WeakMap", + "Map", + "Reflect", + "Proxy", + "Atomics", + "Promise", + nullptr +}; + void Codegen::generateFromProgram(const QString &fileName, const QString &finalUrl, const QString &sourceCode, @@ -118,6 +174,18 @@ void Codegen::generateFromProgram(const QString &fileName, _module->fileName = fileName; _module->finalUrl = finalUrl; + if (contextType == ContextType::ScriptImportedByQML) { + // the global object is frozen, so we know that members of it are + // pointing to the global object. This is important so that references + // to Math etc. do not go through the expensive path in the context wrapper + // that tries to see whether we have a matching type + // + // Since this can be called from the loader thread we can't get the list + // directly from the engine, so let's hardcode the most important ones here + for (const char **g = globalNames; *g != nullptr; ++g) + m_globalNames << QString::fromLatin1(*g); + } + ScanFunctions scan(this, sourceCode, contextType); scan(node); @@ -2336,6 +2404,8 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs, co Reference r = Reference::fromName(this, name); r.global = useFastLookups && (resolved.type == Context::ResolvedName::Global); + if (!r.global && m_globalNames.contains(name)) + r.global = true; return r; } diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index 289728f505..3f96afc7c2 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -708,6 +708,11 @@ public: return *_returnLabel; } + void setGlobalNames(const QSet<QString>& globalNames) { + m_globalNames = globalNames; + } + + protected: friend class ScanFunctions; friend struct ControlFlow; @@ -730,6 +735,7 @@ protected: bool inFormalParameterList = false; bool functionEndsWithReturn = false; bool _tailCallsAreAllowed = true; + QSet<QString> m_globalNames; ControlFlow *controlFlow = nullptr; diff --git a/src/qml/jsruntime/qv4alloca_p.h b/src/qml/jsruntime/qv4alloca_p.h index 1e9f83a90e..65c3e4d65a 100644 --- a/src/qml/jsruntime/qv4alloca_p.h +++ b/src/qml/jsruntime/qv4alloca_p.h @@ -89,7 +89,7 @@ public: Qt_AllocaWrapper() { m_data = 0; } ~Qt_AllocaWrapper() { free(m_data); } void *data() { return m_data; } - void allocate(int size) { m_data = malloc(size); } + void allocate(int size) { m_data = malloc(size); memset(m_data, 0, size); } private: void *m_data; }; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index f80db86be5..7bbef3335e 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -241,6 +241,7 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo QmlIR::Document::removeScriptPragmas(sourceCode); auto result = new QV4::Script(engine, qmlContext, /*parseAsBinding*/false, sourceCode, originalUrl.toString()); + result->contextType = QV4::Compiler::ContextType::ScriptImportedByQML; result->parse(); return result; } diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 5208894934..937a535b83 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -550,6 +550,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_END_INSTR(LoadName) MOTH_BEGIN_INSTR(LoadGlobalLookup) + STORE_IP(); QV4::Lookup *l = function->compilationUnit->runtimeLookups + index; acc = l->globalGetter(l, engine); CHECK_EXCEPTION; diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp index e5b8894fb1..c53b13f64d 100644 --- a/src/qml/parser/qqmljslexer.cpp +++ b/src/qml/parser/qqmljslexer.cpp @@ -884,7 +884,7 @@ int Lexer::scanString(ScanStringMode mode) scanChar(); while (_codePtr <= _endPtr) { - if (_char == mode) { + if (_char == quote) { scanChar(); if (_engine) { diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index f288646ec7..c400e9239b 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -755,6 +755,9 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) d->context = nullptr; } + if (d->outerContext && d->outerContext->contextObject == o) + d->outerContext->contextObject = nullptr; + // Mark this object as in the process of deletion to // prevent it resolving in bindings QQmlData::markAsDeleted(o); |