aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-05-19 13:04:54 +0200
committerLiang Qi <liang.qi@qt.io>2016-05-19 20:41:34 +0200
commit63ec33e79cf86c4312c58bea12a2aab400890c70 (patch)
tree5c9b5cd51276ea0a3ca42567666a09e70efa11cc /src
parentb9e4a4df577959579b2322fb6077bde82d9ffce3 (diff)
parentafc84775efdc6e13e2e210bb94e115b378d90134 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp src/qml/jsruntime/qv4engine.cpp src/qml/jsruntime/qv4engine_p.h Change-Id: I89ffccd699bee675732758d039e22224b275d60d
Diffstat (limited to 'src')
-rw-r--r--src/imports/builtins/builtins.pro19
-rw-r--r--src/imports/builtins/builtins.qmltypes (renamed from src/imports/builtins.qmltypes)0
-rw-r--r--src/imports/imports.pro33
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp1
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp2
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp5
-rw-r--r--src/qml/debugger/qqmldebugpluginmanager_p.h9
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp109
-rw-r--r--src/qml/jsruntime/qv4engine_p.h35
-rw-r--r--src/qml/jsruntime/qv4value_p.h6
-rw-r--r--src/qml/qml/qqmlcomponent.cpp23
-rw-r--r--src/qml/qml/qqmlcomponent_p.h2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp13
-rw-r--r--src/qml/qml/qqmltypeloader.cpp2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp7
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp5
-rw-r--r--src/quick/accessible/qaccessiblequickitem_p.h2
-rw-r--r--src/quick/doc/qtquick.qdocconf2
-rw-r--r--src/quick/items/qquickflickable.cpp8
-rw-r--r--src/quick/items/qquickloader.cpp4
-rw-r--r--src/quick/items/qquickloader_p_p.h1
-rw-r--r--src/quickwidgets/qquickwidget.cpp10
24 files changed, 117 insertions, 185 deletions
diff --git a/src/imports/builtins/builtins.pro b/src/imports/builtins/builtins.pro
new file mode 100644
index 0000000000..112555b6de
--- /dev/null
+++ b/src/imports/builtins/builtins.pro
@@ -0,0 +1,19 @@
+TEMPLATE = aux
+
+QMLTYPEFILE = builtins.qmltypes
+
+# install rule
+builtins.files = $$QMLTYPEFILE
+builtins.path = $$[QT_INSTALL_QML]
+INSTALLS += builtins
+
+# copy to build directory
+!prefix_build: COPIES += builtins
+
+# qmltypes target
+!cross_compile:if(build_pass|!debug_and_release) {
+ qtPrepareTool(QMLPLUGINDUMP, qmlplugindump)
+
+ qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE
+ QMAKE_EXTRA_TARGETS += qmltypes
+}
diff --git a/src/imports/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes
index cca1c20d54..cca1c20d54 100644
--- a/src/imports/builtins.qmltypes
+++ b/src/imports/builtins/builtins.qmltypes
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index ff7b6e75af..5332fb0ef2 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,6 +1,7 @@
TEMPLATE = subdirs
SUBDIRS += \
+ builtins \
qtqml \
folderlistmodel \
localstorage \
@@ -18,35 +19,3 @@ qtHaveModule(quick) {
}
qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
-
-
-QMLTYPEFILE = builtins.qmltypes
-
-# install rule
-builtins.files = $$QMLTYPEFILE
-builtins.path = $$[QT_INSTALL_QML]
-INSTALLS += builtins
-
-# copy to build directory
-!force_independent:if(!debug_and_release|!build_all|CONFIG(release, debug|release)) {
- defineReplace(qmlModStripSrcDir) {
- return($$relative_path($$1, $$_PRO_FILE_PWD_))
- }
-
- qmltypes2build.input = QMLTYPEFILE
- qmltypes2build.output = $$[QT_INSTALL_QML]/${QMAKE_FUNC_FILE_IN_qmlModStripSrcDir}
- !contains(TEMPLATE, vc.*): qmltypes2build.variable_out = PRE_TARGETDEPS
- qmltypes2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
- qmltypes2build.name = COPY ${QMAKE_FILE_IN}
- qmltypes2build.CONFIG = no_link no_clean
-
- QMAKE_EXTRA_COMPILERS += qmltypes2build
-}
-
-# qmltypes target
-!cross_compile:if(build_pass|!debug_and_release) {
- qtPrepareTool(QMLPLUGINDUMP, qmlplugindump)
-
- qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE
- QMAKE_EXTRA_TARGETS += qmltypes
-}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index 9e1c8af3e6..a639cfb71e 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -54,7 +54,6 @@
QT_BEGIN_NAMESPACE
Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQuickProfilerAdapterFactory)
QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) :
QQmlConfigurableDebugService<QQmlProfilerService>(1, parent),
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index a6d93e85ae..cbde86e389 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -81,8 +81,6 @@ QT_BEGIN_NAMESPACE
*/
Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection)
-Q_QML_IMPORT_DEBUG_PLUGIN(QTcpServerConnectionFactory)
-Q_QML_IMPORT_DEBUG_PLUGIN(QLocalClientConnectionFactory)
const int protocolVersion = 1;
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index e6d1a218ad..23440e7529 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -54,14 +54,9 @@ QT_BEGIN_NAMESPACE
// Connectors. We could add more plugins here, and distinguish by arguments to instance()
Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugConnector)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebugServerFactory)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQmlNativeDebugConnectorFactory)
// Services
Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugService)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory)
-Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory)
int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7;
diff --git a/src/qml/debugger/qqmldebugpluginmanager_p.h b/src/qml/debugger/qqmldebugpluginmanager_p.h
index 2bcaf78972..8f52b65b17 100644
--- a/src/qml/debugger/qqmldebugpluginmanager_p.h
+++ b/src/qml/debugger/qqmldebugpluginmanager_p.h
@@ -74,15 +74,6 @@ QT_BEGIN_NAMESPACE
#else // QT_NO_QML_DEBUGGER
-#ifdef QT_STATIC
-#define Q_QML_IMPORT_DEBUG_PLUGIN(className)\
- QT_END_NAMESPACE\
- Q_IMPORT_PLUGIN(className)\
- QT_BEGIN_NAMESPACE
-#else
-#define Q_QML_IMPORT_DEBUG_PLUGIN(className)
-#endif // QT_STATIC
-
#define Q_QML_DEBUG_PLUGIN_LOADER(interfaceName)\
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, interfaceName##Loader,\
(interfaceName##Factory_iid, QLatin1String("/qmltooling")))\
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 500754ead4..74b61fd6e1 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -4,7 +4,7 @@ project = QtQml
description = Qt QML Reference Documentation
version = $QT_VERSION
-examplesinstallpath = qtdeclarative/qml
+examplesinstallpath = qml
qhp.projects = QtQml
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index f51f677636..2e6773a927 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -247,7 +247,7 @@ struct WithContext : public ExecutionContext
V4_MANAGED(WithContext, ExecutionContext)
};
-struct QmlContext : public ExecutionContext
+struct Q_QML_EXPORT QmlContext : public ExecutionContext
{
V4_MANAGED(QmlContext, ExecutionContext)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index bc64bbfe06..b42dc37b0f 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -111,84 +111,6 @@ static ReturnedValue throwTypeError(CallContext *ctx)
return ctx->engine()->throwTypeError();
}
-const int MinimumStackSize = 256; // in kbytes
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_MSVC(4172) // MSVC 2015: warning C4172: returning address of local variable or temporary: dummy
-
-quintptr getStackLimit()
-{
- quintptr stackLimit;
-#if USE(PTHREADS) && !OS(QNX)
-# if OS(DARWIN)
- pthread_t thread_self = pthread_self();
- void *stackTop = pthread_get_stackaddr_np(thread_self);
- stackLimit = reinterpret_cast<quintptr>(stackTop);
- quintptr size = 0;
- if (pthread_main_np()) {
- rlimit limit;
- getrlimit(RLIMIT_STACK, &limit);
- size = limit.rlim_cur;
- } else
- size = pthread_get_stacksize_np(thread_self);
- stackLimit -= size;
-# elif defined(__hppa)
- // On some architectures the stack grows upwards. All of these are rather exotic, so simply assume
- // everything is fine there.
- // Known examples:
- // -HP PA-RISC
- stackLimit = 0;
-
-# else
- pthread_attr_t attr;
-#if HAVE(PTHREAD_NP_H) && OS(FREEBSD)
- // on FreeBSD pthread_attr_init() must be called otherwise getting the attrs crashes
- if (pthread_attr_init(&attr) == 0 && pthread_attr_get_np(pthread_self(), &attr) == 0) {
-#else
- if (pthread_getattr_np(pthread_self(), &attr) == 0) {
-#endif
- void *stackBottom = Q_NULLPTR;
- size_t stackSize = 0;
-
- pthread_attr_getstack(&attr, &stackBottom, &stackSize);
- pthread_attr_destroy(&attr);
-
-# if defined(Q_OS_ANDROID)
- // Bionic pretends that the main thread has a tiny stack; work around it
- if (gettid() == getpid()) {
- rlimit limit;
- getrlimit(RLIMIT_STACK, &limit);
- stackBottom = reinterpret_cast<void*>(reinterpret_cast<quintptr>(stackBottom) + stackSize - limit.rlim_cur);
- }
-# endif
-
- stackLimit = reinterpret_cast<quintptr>(stackBottom);
- } else {
- int dummy;
- // this is inexact, as part of the stack is used when being called here,
- // but let's simply default to 1MB from where the stack is right now
- stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024;
- }
-
-# endif
-// This is wrong. StackLimit is the currently committed stack size, not the real end.
-// only way to get that limit is apparently by using VirtualQuery (Yuck)
-//#elif OS(WINDOWS)
-// PNT_TIB tib = (PNT_TIB)NtCurrentTeb();
-// stackLimit = static_cast<quintptr>(tib->StackLimit);
-#else
- int dummy;
- // this is inexact, as part of the stack is used when being called here,
- // but let's simply default to 1MB from where the stack is right now
- // (Note: triggers warning C4172 as of MSVC 2015, returning address of local variable)
- stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024;
-#endif
-
- // 256k slack
- return stackLimit + MinimumStackSize*1024;
-}
-
-QT_WARNING_POP
QJSEngine *ExecutionEngine::jsEngine() const
{
@@ -200,9 +122,12 @@ QQmlEngine *ExecutionEngine::qmlEngine() const
return v8Engine->engine();
}
+qint32 ExecutionEngine::maxCallDepth = -1;
+
ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
: current(0)
, hasException(false)
+ , callDepth(0)
, memoryManager(new QV4::MemoryManager(this))
, executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
@@ -219,6 +144,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, regExpCache(0)
, m_multiplyWrappedQObjects(0)
{
+ if (maxCallDepth == -1) {
+ bool ok = false;
+ maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
+ if (!ok || maxCallDepth <= 0) {
+ maxCallDepth = 1234;
+ }
+ }
+ Q_ASSERT(maxCallDepth > 0);
+
MemoryManager::GCBlocker gcBlocker(memoryManager);
if (!factory) {
@@ -267,9 +201,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
// set up stack limits
jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value);
- cStackLimit = getStackLimit();
- if (!recheckCStackLimits())
- qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize);
identifierTable = new IdentifierTable(this);
@@ -1103,22 +1034,6 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError()
return error;
}
-bool ExecutionEngine::recheckCStackLimits()
-{
- int dummy;
-#ifdef Q_OS_WIN
- // ### this is only required on windows, where we currently use heuristics to get the stack limit
- if (cStackLimit - reinterpret_cast<quintptr>(&dummy) > 128*1024)
- // we're more then 128k away from our stack limit, assume the thread has changed, and
- // call getStackLimit
-#endif
- // this can happen after a thread change
- cStackLimit = getStackLimit();
-
- return (reinterpret_cast<quintptr>(&dummy) >= cStackLimit);
-}
-
-
// Variant conversion code
typedef QSet<QV4::Heap::Object *> V4ObjectSet;
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 7da4a1c3c1..73d506c4d2 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -81,15 +81,11 @@ namespace CompiledData {
struct CompilationUnit;
}
-#define CHECK_STACK_LIMITS(v4) \
- if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast<quintptr>(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \
- else \
- return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded."))
-
-
struct Q_QML_EXPORT ExecutionEngine
{
private:
+ static qint32 maxCallDepth;
+
friend struct ExecutionContextSaver;
friend struct ExecutionContext;
friend struct Heap::ExecutionContext;
@@ -98,6 +94,7 @@ public:
Value *jsStackTop;
quint32 hasException;
+ qint32 callDepth;
MemoryManager *memoryManager;
ExecutableAllocator *executableAllocator;
@@ -107,7 +104,6 @@ public:
ExecutionContext *currentContext;
Value *jsStackLimit;
- quintptr cStackLimit;
WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine.
@@ -437,8 +433,6 @@ public:
InternalClass *newClass(const InternalClass &other);
- bool recheckCStackLimits();
-
// Exception handling
Value *exceptionValue;
StackTrace exceptionStackTrace;
@@ -471,6 +465,8 @@ public:
QV4::ReturnedValue metaTypeToJS(int type, const void *data);
void assertObjectBelongsToEngine(const Heap::Base &baseObject);
+
+ bool checkStackLimits(ReturnedValue &exception);
};
inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context)
@@ -516,7 +512,7 @@ inline Heap::QmlContext *ExecutionEngine::qmlContext() const
if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
ctx = parentContext(currentContext)->d();
- if (!ctx->outer)
+ if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer)
return 0;
while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
@@ -552,7 +548,26 @@ inline void Value::mark(ExecutionEngine *e)
o->mark(e);
}
+#define CHECK_STACK_LIMITS(v4) { ReturnedValue e; if ((v4)->checkStackLimits(e)) return e; } \
+ ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4);
+
+struct ExecutionEngineCallDepthRecorder
+{
+ ExecutionEngine *ee;
+ ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; }
+ ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; }
+};
+
+inline bool ExecutionEngine::checkStackLimits(ReturnedValue &exception)
+{
+ if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) {
+ exception = throwRangeError(QStringLiteral("Maximum call stack size exceeded."));
+ return true;
+ }
+
+ return false;
+}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 514bdafb48..a8d9b0fa71 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -56,11 +56,7 @@
#include "qv4global_p.h"
#include <private/qv4heap_p.h>
-/* We cannot rely on QT_POINTER_SIZE to be set correctly on host builds. In qmldevtools the Value objects
- are only used to store primitives, never object pointers. So we can use the 64-bit encoding. */
-#ifdef V4_BOOTSTRAP
-#define QV4_USE_64_BIT_VALUE_ENCODING
-#elif QT_POINTER_SIZE == 8
+#if QT_POINTER_SIZE == 8
#define QV4_USE_64_BIT_VALUE_ENCODING
#endif
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index fbd2d13e40..2f4d9ec909 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1077,6 +1077,7 @@ struct QmlIncubatorObject : Object {
QPointer<QObject> parent;
QV4::Value valuemap;
QV4::Value statusChanged;
+ Pointer<Heap::QmlContext> qmlContext;
};
}
@@ -1191,7 +1192,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
*/
-static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value &o, const QV4::Value &v)
+static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v)
{
QV4::Scope scope(engine);
QV4::ScopedObject object(scope);
@@ -1202,6 +1203,9 @@ static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value
if (engine->hasException)
return;
+ QV4::ExecutionContextSaver saver(scope);
+ engine->pushContext(qmlContext);
+
while (1) {
name = it.nextPropertyNameAsString(val);
if (!name)
@@ -1275,8 +1279,10 @@ void QQmlComponent::createObject(QQmlV4Function *args)
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4, rv));
Q_ASSERT(object->isObject());
- if (!valuemap->isUndefined())
- setInitialProperties(v4, object, valuemap);
+ if (!valuemap->isUndefined()) {
+ QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext());
+ setInitialProperties(v4, qmlContext, object, valuemap);
+ }
d->completeCreate();
@@ -1393,6 +1399,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
if (!valuemap->isUndefined())
r->d()->valuemap = valuemap;
+ r->d()->qmlContext = v4->qmlContext();
r->d()->parent = parent;
QQmlIncubator *incubator = r->d()->incubator.data();
@@ -1406,7 +1413,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
}
// XXX used by QSGLoader
-void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate)
+void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate)
{
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QV4::ExecutionEngine *v4engine = QV8Engine::getV4(ep->v8engine());
@@ -1416,7 +1423,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
Q_ASSERT(object->as<QV4::Object>());
if (!valuemap.isUndefined())
- setInitialProperties(v4engine, object, valuemap);
+ setInitialProperties(v4engine, qmlContext, object, valuemap);
}
QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
@@ -1493,6 +1500,7 @@ QQmlComponentExtension::~QQmlComponentExtension()
QV4::Heap::QmlIncubatorObject::QmlIncubatorObject(QQmlIncubator::IncubationMode m)
: valuemap(QV4::Primitive::undefinedValue())
, statusChanged(QV4::Primitive::undefinedValue())
+ , qmlContext(0)
{
incubator.reset(new QQmlComponentIncubator(this, m));
}
@@ -1505,7 +1513,8 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o)
QV4::ExecutionEngine *v4 = engine();
QV4::Scope scope(v4);
QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o));
- setInitialProperties(v4, obj, d()->valuemap);
+ QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, d()->qmlContext);
+ setInitialProperties(v4, qmlCtxt, obj, d()->valuemap);
}
}
@@ -1514,6 +1523,8 @@ void QV4::QmlIncubatorObject::markObjects(QV4::Heap::Base *that, QV4::ExecutionE
QmlIncubatorObject::Data *o = static_cast<QmlIncubatorObject::Data *>(that);
o->valuemap.mark(e);
o->statusChanged.mark(e);
+ if (o->qmlContext)
+ o->qmlContext->mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index ba2982d76d..039b267433 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -86,7 +86,7 @@ public:
QObject *beginCreate(QQmlContextData *);
void completeCreate();
- void initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate);
+ void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate);
QQmlTypeData *typeData;
virtual void typeDataReady(QQmlTypeData *);
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 8613c78f6d..02d7f1f6e3 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -105,14 +105,23 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
+ // In V8 the JS global object would come _before_ the QML global object,
+ // so simulate that here.
+ bool hasProp;
+ QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp));
+ if (hasProp) {
+ if (hasProperty)
+ *hasProperty = hasProp;
+ return result->asReturnedValue();
+ }
+
if (resource->d()->isNullWrapper)
return Object::get(m, name, hasProperty);
if (v4->callingQmlContext() != resource->d()->context)
return Object::get(m, name, hasProperty);
- bool hasProp;
- QV4::ScopedValue result(scope, Object::get(m, name, &hasProp));
+ result = Object::get(m, name, &hasProp);
if (hasProp) {
if (hasProperty)
*hasProperty = hasProp;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 3f58e4a7e1..29fdf78797 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -964,7 +964,7 @@ struct CachedLoader {
}
void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
{
- loader->m_thread->loadWithCachedUnit(blob, unit);
+ loader->m_thread->loadWithCachedUnitAsync(blob, unit);
}
};
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index c81f665ad3..f3d1c4121f 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -671,9 +671,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
} else {
QV4::MemberData *md = propertiesAsMemberData();
if (md) {
- QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
- if (v)
- QQml_valueTypeProvider()->readValueType(v->d()->data, a[0], t);
+ QVariant propertyAsVariant;
+ if (QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
+ propertyAsVariant = v->d()->data;
+ QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], t);
}
}
break;
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 932f7663c3..a56d098717 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -54,6 +54,11 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
{
}
+QWindow *QAccessibleQuickItem::window() const
+{
+ return item()->window();
+}
+
int QAccessibleQuickItem::childCount() const
{
return childItems().count();
diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h
index d6792b0850..8541734d39 100644
--- a/src/quick/accessible/qaccessiblequickitem_p.h
+++ b/src/quick/accessible/qaccessiblequickitem_p.h
@@ -66,6 +66,8 @@ class QAccessibleQuickItem : public QAccessibleObject, public QAccessibleActionI
public:
QAccessibleQuickItem(QQuickItem *item);
+ QWindow *window() const Q_DECL_OVERRIDE;
+
QRect rect() const;
QRect viewRect() const;
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 131cd758a5..fae2eeae2e 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -4,7 +4,7 @@ project = QtQuick
description = Qt Quick Reference Documentation
version = $QT_VERSION
-examplesinstallpath = qtdeclarative/quick
+examplesinstallpath = quick
qhp.projects = QtQuick
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index ae138d7ceb..1853a1d948 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1402,15 +1402,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
break;
case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse
case Qt::ScrollUpdate:
- if (d->scrollingPhase) {
+ if (d->scrollingPhase)
d->pressed = true;
- d->movementEndingTimer.start(MovementEndingTimerInterval, this);
- }
+#ifdef Q_OS_OSX
+ d->movementEndingTimer.start(MovementEndingTimerInterval, this);
+#endif
break;
case Qt::ScrollEnd:
d->pressed = false;
d->scrollingPhase = false;
- d->movementEndingTimer.start(MovementEndingTimerInterval, this);
d->draggingEnding();
event->accept();
returnToBounds();
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index c1126d9b12..63c9558d7a 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -583,6 +583,7 @@ void QQuickLoader::setSource(QQmlV4Function *args)
d->disposeInitialPropertyValues();
d->initialPropertyValues.set(args->v4engine(), ipv);
}
+ d->qmlCallingContext.set(scope.engine, scope.engine->qmlContext());
setSource(sourceUrl, false); // already cleared and set ipv above.
}
@@ -651,7 +652,8 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj)
Q_ASSERT(v4);
QV4::Scope scope(v4);
QV4::ScopedValue ipv(scope, initialPropertyValues.value());
- d->initializeObjectWithInitialProperties(ipv, obj);
+ QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
+ d->initializeObjectWithInitialProperties(qmlContext, ipv, obj);
}
void QQuickLoaderIncubator::statusChanged(Status status)
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index ad05bb00ec..9ef89a74d6 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -108,6 +108,7 @@ public:
QQmlContext *itemContext;
QQuickLoaderIncubator *incubator;
QV4::PersistentValue initialPropertyValues;
+ QV4::PersistentValue qmlCallingContext;
bool updatingSize: 1;
bool active : 1;
bool loadingFromSource : 1;
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index f720513b85..2f43582529 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -1103,12 +1103,16 @@ void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e)
void QQuickWidget::showEvent(QShowEvent *)
{
Q_D(QQuickWidget);
- d->updatePending = false;
d->createContext();
- if (d->offscreenWindow->openglContext())
+ if (d->offscreenWindow->openglContext()) {
d->render(true);
- else
+ if (d->updatePending) {
+ d->updatePending = false;
+ update();
+ }
+ } else {
triggerUpdate();
+ }
QWindowPrivate *offscreenPrivate = QWindowPrivate::get(d->offscreenWindow);
if (!offscreenPrivate->visible) {
offscreenPrivate->visible = true;