aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-12-12 01:00:38 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-12-12 13:08:25 +0100
commit39643ef86e8bc48b8b6cf83ac0ebae7411029030 (patch)
tree79277e468160ebc04a65a85c9668dabefbf3ce33 /src/qml
parent489d6c28dda51c187c85017e30c1e018420e26ac (diff)
parente3446c8225acbaa6a613d6c62e8e2fc58e2b70b0 (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.cpp10
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h1
-rw-r--r--src/qml/compiler/qv4codegen.cpp70
-rw-r--r--src/qml/compiler/qv4codegen_p.h6
-rw-r--r--src/qml/jsruntime/qv4alloca_p.h2
-rw-r--r--src/qml/jsruntime/qv4script.cpp1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp1
-rw-r--r--src/qml/parser/qqmljslexer.cpp2
-rw-r--r--src/qml/qml/qqmlengine.cpp3
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);