aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/views/doc/src/views.qdoc16
-rw-r--r--src/imports/testlib/TestCase.qml2
-rw-r--r--src/particles/qquickimageparticle.cpp18
-rw-r--r--src/particles/qquickimageparticle_p.h1
-rw-r--r--src/qml/jit/qv4assemblercommon.cpp19
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h6
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp62
-rw-r--r--src/qml/jit/qv4baselineassembler_p.h13
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp127
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/qml/qqmlbinding.cpp5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp1
-rw-r--r--src/qml/qml/qqmlimport.cpp34
-rw-r--r--src/qml/qml/qqmlimport_p.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp121
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h15
-rw-r--r--src/qml/qml/qqmlprivate.h2
-rw-r--r--src/quick/items/qquicktextedit.cpp9
-rw-r--r--src/quick/items/qquicktextinput.cpp4
-rw-r--r--src/quick/items/qquickwindow.cpp45
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/Imports/Derived.qml6
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/Imports/imports.pro2
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/Imports/plugins.qmltypes10
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/Imports/qmldir1
-rw-r--r--tests/auto/qml/qqmlbinding/data/nanPropertyToInt.qml14
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp11
-rw-r--r--tests/auto/qml/qqmlimport/tst_qqmlimport.cpp21
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp6
-rw-r--r--tests/auto/quick/qquicktextinput/data/qtbug77841.qml22
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp13
-rw-r--r--tools/qmlplugindump/main.cpp68
31 files changed, 470 insertions, 210 deletions
diff --git a/examples/quick/views/doc/src/views.qdoc b/examples/quick/views/doc/src/views.qdoc
index 16237a68e0..3e23f7657a 100644
--- a/examples/quick/views/doc/src/views.qdoc
+++ b/examples/quick/views/doc/src/views.qdoc
@@ -39,13 +39,13 @@
\include examples-run.qdocinc
- \section1 GridView and PathView
+ \section1 Using GridView and PathView
\e GridView and \e PathView demonstrate usage of these types to display
views.
\snippet views/gridview/gridview-example.qml 0
- \section1 Dynamic List
+ \section1 Using Dynamic List
\e{Dynamic List} demonstrates animation of runtime additions and removals to
a \l ListView.
@@ -66,12 +66,12 @@
\snippet views/listview/expandingdelegates.qml 2
\snippet views/listview/expandingdelegates.qml 3
- \section1 Highlight
+ \section1 Using Highlight
\e Highlight demonstrates adding a custom highlight to a ListView.
\snippet views/listview/highlight.qml 0
- \section1 Highlight Ranges
+ \section1 Using Highlight Ranges
\e{Highlight Ranges} shows the three different highlight range modes of
ListView.
@@ -79,13 +79,13 @@
\snippet views/listview/highlightranges.qml 1
\snippet views/listview/highlightranges.qml 2
- \section1 Sections
+ \section1 Using Sections
\e Sections demonstrates the various section headers and footers available
to \l ListView.
\snippet views/listview/sections.qml 0
- \section1 Packages
+ \section1 Using Packages
\e Packages use the \l [QML]{Package} type to transition delegates between
two views.
@@ -100,13 +100,13 @@
\snippet views/package/view.qml 0
- \section1 ObjectModel
+ \section1 Using ObjectModel
\e ObjectModel uses an ObjectModel for the model instead of a \l ListModel.
\snippet views/objectmodel/objectmodel.qml 0
- \section1 Display Margins
+ \section1 Using Display Margins
\e{Display Margins} uses delegates to display items and implements a simple
header and footer components.
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index e7669fd03d..6e075d8792 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -1631,7 +1631,7 @@ Item {
TestCase {
name: "ItemTests"
- when: area.pressed
+ when: windowShown
id: test1
function test_touch() {
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index bd3865f42f..4ce8186c7c 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1104,6 +1104,7 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
: QQuickParticlePainter(parent)
, m_color_variation(0.0)
+ , m_outgoingNode(nullptr)
, m_material(nullptr)
, m_alphaVariation(0.0)
, m_alpha(1.0)
@@ -1149,6 +1150,8 @@ void QQuickImageParticle::sceneGraphInvalidated()
{
m_nodes.clear();
m_material = nullptr;
+ delete m_outgoingNode;
+ m_outgoingNode = nullptr;
}
void QQuickImageParticle::setImage(const QUrl &image)
@@ -1931,8 +1934,11 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData
}
if (m_pleaseReset){
- if (node)
- delete node;
+ // Cannot just destroy the node and then return null (in case image
+ // loading is still in progress). Rather, keep track of the old node
+ // until we have a new one.
+ delete m_outgoingNode;
+ m_outgoingNode = node;
node = nullptr;
m_lastLevel = perfLevel;
@@ -1946,6 +1952,9 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData
m_pleaseReset = false;
m_startedImageLoading = 0;//Cancel a part-way build (may still have a pending load)
+ } else if (!m_material) {
+ delete node;
+ node = nullptr;
}
if (m_system && m_system->isRunning() && !m_system->isPaused()){
@@ -1959,6 +1968,11 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData
}
}
+ if (!node) {
+ node = m_outgoingNode;
+ m_outgoingNode = nullptr;
+ }
+
return node;
}
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 83fc75e9c9..fdb404861c 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -390,6 +390,7 @@ private:
QColor m_color;
qreal m_color_variation;
+ QSGNode *m_outgoingNode;
QHash<int, QSGGeometryNode *> m_nodes;
QHash<int, int> m_idxStarts;//TODO: Proper resizing will lead to needing a spriteEngine per particle - do this after sprite engine gains transparent sharing?
QList<QPair<int, int> > m_startsIdx;//Same data, optimized for alternate retrieval
diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
index 800ee22cd7..e75f35a665 100644
--- a/src/qml/jit/qv4assemblercommon.cpp
+++ b/src/qml/jit/qv4assemblercommon.cpp
@@ -96,8 +96,9 @@ private:
static void printDisassembledOutputWithCalls(QByteArray processedOutput,
const QHash<const void*, const char*>& functions)
{
- for (QHash<const void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
- it != end; ++it) {
+ const auto symbols = Runtime::symbolTable();
+ const QByteArray padding(" ; ");
+ for (auto it = functions.begin(), end = functions.end(); it != end; ++it) {
const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
int idx = 0;
while (idx >= 0) {
@@ -107,7 +108,9 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput,
idx = processedOutput.indexOf('\n', idx);
if (idx < 0)
break;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value());
+ const char *functionName = it.value();
+ processedOutput = processedOutput.insert(
+ idx, padding + QByteArray(functionName ? functionName : symbols[it.key()]));
}
}
@@ -302,27 +305,29 @@ void JIT::PlatformAssemblerCommon::passPointerAsArg(void *ptr, int arg)
storePtr(TrustedImmPtr(ptr), argStackAddress(arg));
}
-void PlatformAssemblerCommon::callRuntime(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::callRuntime(const void *funcPtr, const char *functionName)
{
#ifndef QT_NO_DEBUG
Q_ASSERT(remainingArgcForCall == 0);
remainingArgcForCall = NoCall;
#endif
- callRuntimeUnchecked(functionName, funcPtr);
+ callRuntimeUnchecked(funcPtr, functionName);
if (argcOnStackForCall > 0) {
addPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
argcOnStackForCall = 0;
}
}
-void PlatformAssemblerCommon::callRuntimeUnchecked(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::callRuntimeUnchecked(const void *funcPtr, const char *functionName)
{
+ Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr));
functions.insert(funcPtr, functionName);
callAbsolute(funcPtr);
}
-void PlatformAssemblerCommon::tailCallRuntime(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::tailCallRuntime(const void *funcPtr, const char *functionName)
{
+ Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr));
functions.insert(funcPtr, functionName);
setTailCallArg(EngineRegister, 1);
setTailCallArg(CppStackFrameRegister, 0);
diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h
index b18d082be6..ead1e757de 100644
--- a/src/qml/jit/qv4assemblercommon_p.h
+++ b/src/qml/jit/qv4assemblercommon_p.h
@@ -706,9 +706,9 @@ public:
void passCppFrameAsArg(int arg);
void passInt32AsArg(int value, int arg);
void passPointerAsArg(void *ptr, int arg);
- void callRuntime(const char *functionName, const void *funcPtr);
- void callRuntimeUnchecked(const char *functionName, const void *funcPtr);
- void tailCallRuntime(const char *functionName, const void *funcPtr);
+ void callRuntime(const void *funcPtr, const char *functionName = nullptr);
+ void callRuntimeUnchecked(const void *funcPtr, const char *functionName = nullptr);
+ void tailCallRuntime(const void *funcPtr, const char *functionName = nullptr);
void setTailCallArg(RegisterID src, int arg);
Address jsAlloca(int slotCount);
void storeInt32AsValue(int srcInt, Address destAddr);
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 59de86a85d..25652e0a63 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -61,7 +61,8 @@ namespace JIT {
#define ASM_GENERATE_RUNTIME_CALL(function, destination) \
pasm()->GENERATE_RUNTIME_CALL(function, destination)
-#define callHelper(x) PlatformAssemblerCommon::callRuntimeUnchecked(#x, reinterpret_cast<void *>(&x))
+#define callHelper(x) \
+ PlatformAssemblerCommon::callRuntimeUnchecked(reinterpret_cast<void *>(&x), #x)
const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
@@ -83,10 +84,9 @@ public:
: PlatformAssemblerCommon(constantTable)
{}
- void callRuntime(const char *functionName, const void *funcPtr,
- CallResultDestination dest)
+ void callRuntime(const void *funcPtr, CallResultDestination dest)
{
- PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -240,7 +240,7 @@ public:
auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
move(AccumulatorRegister, registerForArg(0));
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
isInt.link(this);
@@ -383,10 +383,9 @@ public:
: PlatformAssemblerCommon(constantTable)
{}
- void callRuntime(const char *functionName, const void *funcPtr,
- CallResultDestination dest)
+ void callRuntime(const void *funcPtr, CallResultDestination dest)
{
- PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -491,7 +490,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper));
+ callHelper(toNumberHelper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -548,7 +547,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -570,7 +569,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -1267,7 +1266,7 @@ void BaselineAssembler::cmpeqInt(int lhs)
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
pasm()->pushAccumulatorAsArg(0);
- pasm()->callRuntimeUnchecked("Equal", (void*)Runtime::Equal::call);
+ pasm()->callRuntimeUnchecked((void*)Runtime::Equal::call);
pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
@@ -1291,7 +1290,7 @@ void BaselineAssembler::cmpneInt(int lhs)
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
pasm()->pushAccumulatorAsArg(0);
- pasm()->callRuntimeUnchecked("NotEqual", (void*)Runtime::NotEqual::call);
+ pasm()->callRuntimeUnchecked((void*)Runtime::NotEqual::call);
pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
@@ -1305,7 +1304,7 @@ void BaselineAssembler::cmpneInt(int lhs)
done.link(pasm());
}
-void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
+void BaselineAssembler::cmp(int cond, CmpFunc function, int lhs)
{
auto c = static_cast<PlatformAssembler::RelationalCondition>(cond);
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){
@@ -1321,7 +1320,7 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName
pasm()->passAccumulatorAsArg(1);
pasm()->passJSSlotAsArg(lhs, 0);
- callRuntime(functionName, reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
+ callRuntime(reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
checkException();
// done.
@@ -1331,50 +1330,42 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName
void BaselineAssembler::cmpeq(int lhs)
{
- cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call,
- "CompareEqual", lhs);
+ cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call, lhs);
}
void BaselineAssembler::cmpne(int lhs)
{
- cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call,
- "CompareNotEqual", lhs);
+ cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call, lhs);
}
void BaselineAssembler::cmpgt(int lhs)
{
- cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call,
- "CompareGreaterThan", lhs);
+ cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call, lhs);
}
void BaselineAssembler::cmpge(int lhs)
{
- cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call,
- "CompareGreaterEqual", lhs);
+ cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call, lhs);
}
void BaselineAssembler::cmplt(int lhs)
{
- cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call,
- "CompareLessThan", lhs);
+ cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call, lhs);
}
void BaselineAssembler::cmple(int lhs)
{
- cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call,
- "CompareLessEqual", lhs);
+ cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call, lhs);
}
void BaselineAssembler::cmpStrictEqual(int lhs)
{
- cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call,
- "RuntimeHelpers::strictEqual", lhs);
+ cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call, lhs);
}
void BaselineAssembler::cmpStrictNotEqual(int lhs)
{
- cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call,
- "RuntimeHelpers::strictNotEqual", lhs);
+ cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call, lhs);
}
int BaselineAssembler::jump(int offset)
@@ -1463,9 +1454,9 @@ void BaselineAssembler::passPointerAsArg(void *ptr, int arg)
pasm()->passPointerAsArg(ptr, arg);
}
-void BaselineAssembler::callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest)
+void BaselineAssembler::callRuntime(const void *funcPtr, CallResultDestination dest)
{
- pasm()->callRuntime(functionName, funcPtr, dest);
+ pasm()->callRuntime(funcPtr, dest);
}
void BaselineAssembler::saveAccumulatorInFrame()
@@ -1498,8 +1489,9 @@ void BaselineAssembler::jsTailCall(int func, int thisObject, int argc, int argv)
pasm()->storeInt32AsValue(argv, Address(tos.base, argvOffset));
pasm()->moveReg(regAddr(thisObject), Address(tos.base, thisOffset));
pasm()->moveReg(regAddr(func), Address(tos.base, funcOffset));
- pasm()->tailCallRuntime("TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing",
- reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing));
+ pasm()->tailCallRuntime(
+ reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing),
+ "TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing");
}
void BaselineAssembler::checkException()
diff --git a/src/qml/jit/qv4baselineassembler_p.h b/src/qml/jit/qv4baselineassembler_p.h
index 33fd288ac3..c2c735282b 100644
--- a/src/qml/jit/qv4baselineassembler_p.h
+++ b/src/qml/jit/qv4baselineassembler_p.h
@@ -62,16 +62,11 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {
-#define JIT_STRINGIFYx(s) #s
-#define JIT_STRINGIFY(s) JIT_STRINGIFYx(s)
-
#define GENERATE_RUNTIME_CALL(function, destination) \
- callRuntime(JIT_STRINGIFY(function), \
- reinterpret_cast<void *>(&Runtime::function::call), \
+ callRuntime(reinterpret_cast<void *>(&Runtime::function::call), \
destination)
#define GENERATE_TAIL_CALL(function) \
- tailCallRuntime(JIT_STRINGIFY(function), \
- reinterpret_cast<void *>(&function))
+ tailCallRuntime(reinterpret_cast<void *>(&function))
class BaselineAssembler {
public:
@@ -153,7 +148,7 @@ public:
void passCppFrameAsArg(int arg);
void passInt32AsArg(int value, int arg);
void passPointerAsArg(void *ptr, int arg);
- void callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest);
+ void callRuntime(const void *funcPtr, CallResultDestination dest);
void saveAccumulatorInFrame();
void loadAccumulatorFromFrame();
void jsTailCall(int func, int thisObject, int argc, int argv);
@@ -179,7 +174,7 @@ protected:
private:
typedef unsigned(*CmpFunc)(const Value&,const Value&);
- void cmp(int cond, CmpFunc function, const char *functionName, int lhs);
+ void cmp(int cond, CmpFunc function, int lhs);
};
} // namespace JIT
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index aaa198c62a..21a0017728 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -2316,6 +2316,133 @@ Bool Runtime::CompareStrictNotEqual::call(const Value &left, const Value &right)
return ! RuntimeHelpers::strictEqual(left, right);
}
+template<typename Operation>
+static inline const void *symbol()
+{
+ return reinterpret_cast<void *>(&Operation::call);
+}
+
+QHash<const void *, const char *> Runtime::symbolTable()
+{
+ static const QHash<const void *, const char *> symbols({
+#ifndef V4_BOOTSTRAP
+ {symbol<CallGlobalLookup>(), "CallGlobalLookup" },
+ {symbol<CallQmlContextPropertyLookup>(), "CallQmlContextPropertyLookup" },
+ {symbol<CallName>(), "CallName" },
+ {symbol<CallProperty>(), "CallProperty" },
+ {symbol<CallPropertyLookup>(), "CallPropertyLookup" },
+ {symbol<CallElement>(), "CallElement" },
+ {symbol<CallValue>(), "CallValue" },
+ {symbol<CallWithReceiver>(), "CallWithReceiver" },
+ {symbol<CallPossiblyDirectEval>(), "CallPossiblyDirectEval" },
+ {symbol<CallWithSpread>(), "CallWithSpread" },
+ {symbol<TailCall>(), "TailCall" },
+
+ {symbol<Construct>(), "Construct" },
+ {symbol<ConstructWithSpread>(), "ConstructWithSpread" },
+
+ {symbol<StoreNameStrict>(), "StoreNameStrict" },
+ {symbol<StoreNameSloppy>(), "StoreNameSloppy" },
+ {symbol<StoreProperty>(), "StoreProperty" },
+ {symbol<StoreElement>(), "StoreElement" },
+ {symbol<LoadProperty>(), "LoadProperty" },
+ {symbol<LoadName>(), "LoadName" },
+ {symbol<LoadElement>(), "LoadElement" },
+ {symbol<LoadSuperProperty>(), "LoadSuperProperty" },
+ {symbol<StoreSuperProperty>(), "StoreSuperProperty" },
+ {symbol<LoadSuperConstructor>(), "LoadSuperConstructor" },
+ {symbol<LoadGlobalLookup>(), "LoadGlobalLookup" },
+ {symbol<LoadQmlContextPropertyLookup>(), "LoadQmlContextPropertyLookup" },
+ {symbol<GetLookup>(), "GetLookup" },
+ {symbol<SetLookupStrict>(), "SetLookupStrict" },
+ {symbol<SetLookupSloppy>(), "SetLookupSloppy" },
+
+ {symbol<TypeofValue>(), "TypeofValue" },
+ {symbol<TypeofName>(), "TypeofName" },
+
+ {symbol<DeleteProperty_NoThrow>(), "DeleteProperty_NoThrow" },
+ {symbol<DeleteProperty>(), "DeleteProperty" },
+ {symbol<DeleteName_NoThrow>(), "DeleteName_NoThrow" },
+ {symbol<DeleteName>(), "DeleteName" },
+
+ {symbol<ThrowException>(), "ThrowException" },
+ {symbol<PushCallContext>(), "PushCallContext" },
+ {symbol<PushWithContext>(), "PushWithContext" },
+ {symbol<PushCatchContext>(), "PushCatchContext" },
+ {symbol<PushBlockContext>(), "PushBlockContext" },
+ {symbol<CloneBlockContext>(), "CloneBlockContext" },
+ {symbol<PushScriptContext>(), "PushScriptContext" },
+ {symbol<PopScriptContext>(), "PopScriptContext" },
+ {symbol<ThrowReferenceError>(), "ThrowReferenceError" },
+ {symbol<ThrowOnNullOrUndefined>(), "ThrowOnNullOrUndefined" },
+
+ {symbol<Closure>(), "Closure" },
+
+ {symbol<ConvertThisToObject>(), "ConvertThisToObject" },
+ {symbol<DeclareVar>(), "DeclareVar" },
+ {symbol<CreateMappedArgumentsObject>(), "CreateMappedArgumentsObject" },
+ {symbol<CreateUnmappedArgumentsObject>(), "CreateUnmappedArgumentsObject" },
+ {symbol<CreateRestParameter>(), "CreateRestParameter" },
+
+ {symbol<ArrayLiteral>(), "ArrayLiteral" },
+ {symbol<ObjectLiteral>(), "ObjectLiteral" },
+ {symbol<CreateClass>(), "CreateClass" },
+
+ {symbol<GetIterator>(), "GetIterator" },
+ {symbol<IteratorNext>(), "IteratorNext" },
+ {symbol<IteratorNextForYieldStar>(), "IteratorNextForYieldStar" },
+ {symbol<IteratorClose>(), "IteratorClose" },
+ {symbol<DestructureRestElement>(), "DestructureRestElement" },
+
+ {symbol<ToObject>(), "ToObject" },
+ {symbol<ToBoolean>(), "ToBoolean" },
+ {symbol<ToNumber>(), "ToNumber" },
+
+ {symbol<UMinus>(), "UMinus" },
+
+ {symbol<Instanceof>(), "Instanceof" },
+ {symbol<In>(), "In" },
+ {symbol<Add>(), "Add" },
+ {symbol<Sub>(), "Sub" },
+ {symbol<Mul>(), "Mul" },
+ {symbol<Div>(), "Div" },
+ {symbol<Mod>(), "Mod" },
+ {symbol<Exp>(), "Exp" },
+ {symbol<BitAnd>(), "BitAnd" },
+ {symbol<BitOr>(), "BitOr" },
+ {symbol<BitXor>(), "BitXor" },
+ {symbol<Shl>(), "Shl" },
+ {symbol<Shr>(), "Shr" },
+ {symbol<UShr>(), "UShr" },
+ {symbol<GreaterThan>(), "GreaterThan" },
+ {symbol<LessThan>(), "LessThan" },
+ {symbol<GreaterEqual>(), "GreaterEqual" },
+ {symbol<LessEqual>(), "LessEqual" },
+ {symbol<Equal>(), "Equal" },
+ {symbol<NotEqual>(), "NotEqual" },
+ {symbol<StrictEqual>(), "StrictEqual" },
+ {symbol<StrictNotEqual>(), "StrictNotEqual" },
+
+ {symbol<CompareGreaterThan>(), "CompareGreaterThan" },
+ {symbol<CompareLessThan>(), "CompareLessThan" },
+ {symbol<CompareGreaterEqual>(), "CompareGreaterEqual" },
+ {symbol<CompareLessEqual>(), "CompareLessEqual" },
+ {symbol<CompareEqual>(), "CompareEqual" },
+ {symbol<CompareNotEqual>(), "CompareNotEqual" },
+ {symbol<CompareStrictEqual>(), "CompareStrictEqual" },
+ {symbol<CompareStrictNotEqual>(), "CompareStrictNotEqual" },
+
+ {symbol<CompareInstanceof>(), "CompareInstanceOf" },
+ {symbol<CompareIn>(), "CompareIn" },
+
+ {symbol<RegexpLiteral>(), "RegexpLiteral" },
+ {symbol<GetTemplateObject>(), "GetTemplateObject" }
+#endif
+ });
+
+ return symbols;
+}
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 05ffb84d58..d155187e48 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -501,6 +501,8 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
static const int tailCall_argv = -3;
static const int tailCall_argc = -4;
};
+
+ static QHash<const void *, const char *> symbolTable();
};
static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof");
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 2f6aabf61e..112e5b558a 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -298,8 +298,9 @@ protected:
case QMetaType::Int:
if (result.isInteger())
return doStore<int>(result.integerValue(), pd, flags);
- else if (result.isNumber())
- return doStore<int>(result.doubleValue(), pd, flags);
+ else if (result.isNumber()) {
+ return doStore<int>(QV4::StaticValue::toInteger(result.doubleValue()), pd, flags);
+ }
break;
case QMetaType::Double:
if (result.isNumber())
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index f03f90e7f3..1d5f974d5c 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -969,6 +969,7 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
if (!state->creator->populateDeferredProperties(object, deferredData))
state->errors << state->creator->errors;
+ deferredData->bindings.clear();
deferredState->constructionStates += state;
}
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 79e3585202..af6d067fbb 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -2141,6 +2141,40 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
return true;
}
+bool QQmlImportDatabase::removeDynamicPlugin(const QString &filePath)
+{
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+
+ auto it = plugins->find(QFileInfo(filePath).absoluteFilePath());
+ if (it == plugins->end())
+ return false;
+
+ QPluginLoader *loader = it->loader;
+ if (!loader)
+ return false;
+
+ if (!loader->unload()) {
+ qWarning("Unloading %s failed: %s", qPrintable(it->uri),
+ qPrintable(loader->errorString()));
+ }
+
+ delete loader;
+ plugins->erase(it);
+ return true;
+}
+
+QStringList QQmlImportDatabase::dynamicPlugins() const
+{
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+ QStringList results;
+ for (auto it = plugins->constBegin(), end = plugins->constEnd(); it != end; ++it) {
+ if (it->loader != nullptr)
+ results.append(it.key());
+ }
+ return results;
+}
#endif // QT_CONFIG(library)
void QQmlImportDatabase::clearDirCache()
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 7f781d2eb7..30d7c56a3e 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -203,7 +203,7 @@ private:
QQmlImportsPrivate *d;
};
-class QQmlImportDatabase
+class Q_QML_PRIVATE_EXPORT QQmlImportDatabase
{
Q_DECLARE_TR_FUNCTIONS(QQmlImportDatabase)
public:
@@ -214,6 +214,8 @@ public:
#if QT_CONFIG(library)
bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors);
+ bool removeDynamicPlugin(const QString &filePath);
+ QStringList dynamicPlugins() const;
#endif
QStringList importPathList(PathType type = LocalOrRemote) const;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index cf1795aafa..44006c3f6a 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -234,73 +234,23 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
return instance;
}
-// ### unify or keep in sync with populateDeferredBinding()
-bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData)
+void QQmlObjectCreator::beginPopulateDeferred(QQmlContextData *newContext)
{
- QQmlData *declarativeData = QQmlData::get(instance);
- context = deferredData->context;
- sharedState->rootContext = context;
-
- QObject *bindingTarget = instance;
-
- QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache;
- QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(instance);
-
- QObject *scopeObject = instance;
- qSwap(_scopeObject, scopeObject);
-
- QV4::Scope valueScope(v4);
+ context = newContext;
+ sharedState->rootContext = newContext;
Q_ASSERT(topLevelCreator);
Q_ASSERT(!sharedState->allJavaScriptObjects);
- sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
-
- QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc());
- qSwap(_qmlContext, qmlContext);
-
- qSwap(_propertyCache, cache);
- qSwap(_qobject, instance);
-
- int objectIndex = deferredData->deferredIdx;
- qSwap(_compiledObjectIndex, objectIndex);
-
- const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
- qSwap(_compiledObject, obj);
-
- qSwap(_ddata, declarativeData);
- qSwap(_bindingTarget, bindingTarget);
- qSwap(_vmeMetaObject, vmeMetaObject);
-
- setupBindings(/*applyDeferredBindings=*/true);
-
- qSwap(_vmeMetaObject, vmeMetaObject);
- qSwap(_bindingTarget, bindingTarget);
- qSwap(_ddata, declarativeData);
- qSwap(_compiledObject, obj);
- qSwap(_compiledObjectIndex, objectIndex);
- qSwap(_qobject, instance);
- qSwap(_propertyCache, cache);
-
- qSwap(_qmlContext, qmlContext);
- qSwap(_scopeObject, scopeObject);
-
- deferredData->bindings.clear();
- phase = ObjectsCreated;
-
- return errors.isEmpty();
+ QV4::Scope valueScope(v4);
+ sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
}
-// ### unify or keep in sync with populateDeferredProperties()
-bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding)
+void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex,
+ const QQmlPropertyPrivate *qmlProperty,
+ const QV4::CompiledData::Binding *binding)
{
- Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding);
-
- QObject *instance = qmlProperty.object();
QQmlData *declarativeData = QQmlData::get(instance);
- context = deferredData->context;
- sharedState->rootContext = context;
-
QObject *bindingTarget = instance;
QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache;
@@ -312,9 +262,6 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
QV4::Scope valueScope(v4);
Q_ASSERT(topLevelCreator);
- if (!sharedState->allJavaScriptObjects)
- sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
-
QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc());
qSwap(_qmlContext, qmlContext);
@@ -322,7 +269,7 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
- int objectIndex = deferredData->deferredIdx;
+ int objectIndex = deferredIndex;
qSwap(_compiledObjectIndex, objectIndex);
const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
@@ -332,21 +279,28 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_bindingTarget, bindingTarget);
qSwap(_vmeMetaObject, vmeMetaObject);
- QQmlListProperty<void> savedList;
- qSwap(_currentList, savedList);
+ if (binding) {
+ Q_ASSERT(qmlProperty);
+ Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding);
- const QQmlPropertyData &property = QQmlPropertyPrivate::get(qmlProperty)->core;
+ QQmlListProperty<void> savedList;
+ qSwap(_currentList, savedList);
- if (property.isQList()) {
- void *argv[1] = { (void*)&_currentList };
- QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
- } else if (_currentList.object) {
- _currentList = QQmlListProperty<void>();
- }
+ const QQmlPropertyData &property = qmlProperty->core;
+
+ if (property.isQList()) {
+ void *argv[1] = { (void*)&_currentList };
+ QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
+ } else if (_currentList.object) {
+ _currentList = QQmlListProperty<void>();
+ }
- setPropertyBinding(&property, binding);
+ setPropertyBinding(&property, binding);
- qSwap(_currentList, savedList);
+ qSwap(_currentList, savedList);
+ } else {
+ setupBindings(/*applyDeferredBindings=*/true);
+ }
qSwap(_vmeMetaObject, vmeMetaObject);
qSwap(_bindingTarget, bindingTarget);
@@ -358,12 +312,29 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
+}
- phase = ObjectsCreated;
-
+bool QQmlObjectCreator::populateDeferredProperties(QObject *instance,
+ const QQmlData::DeferredData *deferredData)
+{
+ beginPopulateDeferred(deferredData->context);
+ populateDeferred(instance, deferredData->deferredIdx);
+ finalizePopulateDeferred();
return errors.isEmpty();
}
+void QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
+ const QV4::CompiledData::Binding *binding)
+{
+ populateDeferred(qmlProperty.object(), deferredIndex, QQmlPropertyPrivate::get(qmlProperty),
+ binding);
+}
+
+void QQmlObjectCreator::finalizePopulateDeferred()
+{
+ phase = ObjectsCreated;
+}
+
void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
{
QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 59e236c855..8b6cb67341 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -112,8 +112,14 @@ public:
~QQmlObjectCreator();
QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr);
- bool populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData);
- bool populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding);
+
+ bool populateDeferredProperties(QObject *instance, const QQmlData::DeferredData *deferredData);
+
+ void beginPopulateDeferred(QQmlContextData *context);
+ void populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
+ const QV4::CompiledData::Binding *binding);
+ void finalizePopulateDeferred();
+
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
void clear();
@@ -139,6 +145,11 @@ private:
bool populateInstance(int index, QObject *instance,
QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty);
+ // If qmlProperty and binding are null, populate all properties, otherwise only the given one.
+ void populateDeferred(QObject *instance, int deferredIndex,
+ const QQmlPropertyPrivate *qmlProperty = nullptr,
+ const QV4::CompiledData::Binding *binding = nullptr);
+
void setupBindings(bool applyDeferredBindings = false);
bool setPropertyBinding(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
void setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 27dac71571..9504fc37dc 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -62,7 +62,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
-#include <QPointer>
+#include <QtCore/qpointer.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qdebug.h>
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index c4e9c0d316..7d34cc3f56 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -2060,20 +2060,19 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
firstDirtyPos = nodeIterator->startPos();
// ### this could be optimized if the first and last dirty nodes are not connected
// as the intermediate text nodes would usually only need to be transformed differently.
- int lastDirtyPos = firstDirtyPos;
+ QQuickTextNode *firstCleanNode = nullptr;
auto it = d->textNodeMap.constEnd();
while (it != nodeIterator) {
--it;
- if (it->dirty()) {
- lastDirtyPos = it->startPos();
+ if (it->dirty())
break;
- }
+ firstCleanNode = it->textNode();
}
do {
rootNode->removeChildNode(nodeIterator->textNode());
delete nodeIterator->textNode();
nodeIterator = d->textNodeMap.erase(nodeIterator);
- } while (nodeIterator != d->textNodeMap.constEnd() && nodeIterator->startPos() <= lastDirtyPos);
+ } while (nodeIterator != d->textNodeMap.constEnd() && nodeIterator->textNode() != firstCleanNode);
}
// FIXME: the text decorations could probably be handled separately (only updated for affected textFrames)
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 34105d8c81..a83b9beaa5 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -2259,8 +2259,8 @@ void QQuickTextInput::remove(int start, int end)
d->m_cursor -= qMin(d->m_cursor, end) - start;
if (d->m_selstart > start)
d->m_selstart -= qMin(d->m_selstart, end) - start;
- if (d->m_selend > end)
- d->m_selend -= qMin(d->m_selend, end) - start;
+ if (d->m_selend >= end)
+ d->m_selend -= end - start;
}
d->addCommand(QQuickTextInputPrivate::Command(
QQuickTextInputPrivate::SetSelection, d->m_cursor, 0, d->m_selstart, d->m_selend));
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 04837317be..cb4656874d 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -4220,16 +4220,18 @@ QQmlIncubationController *QQuickWindow::incubationController() const
The OpenGL context used for rendering the scene graph will be bound
at this point.
- When using the RHI and a graphics API other than OpenGL, the signal is
- emitted after the preparations for the frame have been done, meaning there
- is a command buffer in recording mode, where applicable. If desired, the
- slot function connected to this signal can query native resources like the
- command before via QSGRendererInterface. Note however that the recording of
- the main render pass is not yet started at this point and it is not
- possible to add commands within that pass. Instead, use
- beforeRenderPassRecording() for that. However, connecting to this signal is
- still important if the recording of copy type of commands is desired since
- those cannot be enqueued within a render pass.
+ When using the RHI, the signal is emitted after the preparations for the
+ frame have been done, meaning there is a command buffer in recording mode,
+ where applicable. If desired, the slot function connected to this signal
+ can query native resources like the command before via
+ QSGRendererInterface. Note however that the recording of the main render
+ pass is not yet started at this point and it is not possible to add
+ commands within that pass. Starting a pass means clearing the color, depth,
+ and stencil buffers so it is not possible to achieve an underlay type of
+ rendering by just connecting to this signal. Rather, connect to
+ beforeRenderPassRecording(). However, connecting to this signal is still
+ important if the recording of copy type of commands is desired since those
+ cannot be enqueued within a render pass.
\warning This signal is emitted from the scene graph rendering thread. If your
slot function needs to finish before execution continues, you must make sure that
@@ -4252,18 +4254,17 @@ QQmlIncubationController *QQuickWindow::incubationController() const
The OpenGL context used for rendering the scene graph will be bound at this point.
- When using the RHI and a graphics API other than OpenGL, the signal is
- emitted after scene graph has added its commands to the command buffer,
- which is not yet submitted to the graphics queue. If desired, the slot
- function connected to this signal can query native resources, like the
- command buffer, before via QSGRendererInterface. Note however that the
- render pass (or passes) are already recorded at this point and it is not
- possible to add more commands within the scenegraph's pass. Instead, use
- afterRenderPassRecording() for that. This signal has therefore limited use
- and is rarely needed in an RHI-based setup. Rather, it is the combination
- of beforeRendering() + beforeRenderPassRecording() or beforeRendering() +
- afterRenderPassRecording() that is typically used to achieve under- or
- overlaying of the custom rendering.
+ When using the RHI, the signal is emitted after scene graph has added its
+ commands to the command buffer, which is not yet submitted to the graphics
+ queue. If desired, the slot function connected to this signal can query
+ native resources, like the command buffer, before via QSGRendererInterface.
+ Note however that the render pass (or passes) are already recorded at this
+ point and it is not possible to add more commands within the scenegraph's
+ pass. Instead, use afterRenderPassRecording() for that. This signal has
+ therefore limited use and is rarely needed in an RHI-based setup. Rather,
+ it is the combination of beforeRendering() + beforeRenderPassRecording() or
+ beforeRendering() + afterRenderPassRecording() that is typically used to
+ achieve under- or overlaying of the custom rendering.
\warning This signal is emitted from the scene graph rendering thread. If your
slot function needs to finish before execution continues, you must make sure that
diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Imports/Derived.qml b/tests/auto/qml/qmlplugindump/data/dumper/Imports/Derived.qml
new file mode 100644
index 0000000000..2f0ac401d7
--- /dev/null
+++ b/tests/auto/qml/qmlplugindump/data/dumper/Imports/Derived.qml
@@ -0,0 +1,6 @@
+pragma Singleton
+import dumper.Imports 1.0
+
+Imports {
+ property int something: 2
+}
diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Imports/imports.pro b/tests/auto/qml/qmlplugindump/data/dumper/Imports/imports.pro
index d20ea967ea..b4bd9baf5b 100644
--- a/tests/auto/qml/qmlplugindump/data/dumper/Imports/imports.pro
+++ b/tests/auto/qml/qmlplugindump/data/dumper/Imports/imports.pro
@@ -17,7 +17,7 @@ HEADERS += \
imports.h
!equals(_PRO_FILE_PWD_, $$OUT_PWD) {
- cp.files = qmldir plugins.qmltypes CompositeImports.qml
+ cp.files = qmldir plugins.qmltypes CompositeImports.qml Derived.qml
cp.path = $$OUT_PWD
COPIES += cp
}
diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Imports/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/Imports/plugins.qmltypes
index 937dd60a9e..fb13928ba0 100644
--- a/tests/auto/qml/qmlplugindump/data/dumper/Imports/plugins.qmltypes
+++ b/tests/auto/qml/qmlplugindump/data/dumper/Imports/plugins.qmltypes
@@ -14,4 +14,14 @@ Module {
exports: ["dumper.Imports/Imports 1.0"]
exportMetaObjectRevisions: [0]
}
+ Component {
+ prototype: "Imports"
+ name: "dumper.Imports/Derived 1.0"
+ exports: ["dumper.Imports/Derived 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ isCreatable: false
+ isSingleton: true
+ Property { name: "something"; type: "int" }
+ }
}
diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Imports/qmldir b/tests/auto/qml/qmlplugindump/data/dumper/Imports/qmldir
index c9058a7f95..f84fca1d75 100644
--- a/tests/auto/qml/qmlplugindump/data/dumper/Imports/qmldir
+++ b/tests/auto/qml/qmlplugindump/data/dumper/Imports/qmldir
@@ -1,3 +1,4 @@
module dumper.Imports
plugin Imports
CompositeImports 1.0 CompositeImports.qml
+singleton Derived 1.0 Derived.qml
diff --git a/tests/auto/qml/qqmlbinding/data/nanPropertyToInt.qml b/tests/auto/qml/qqmlbinding/data/nanPropertyToInt.qml
new file mode 100644
index 0000000000..366dbf0464
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/nanPropertyToInt.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.11
+
+Item {
+ visible: true
+ width: 320
+ height: 200
+ property int val: other.val
+
+ Rectangle {
+ id: other
+ anchors.fill: parent;
+ property int val: undefined / 2
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 2c2d311ff7..2610402455 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -56,6 +56,7 @@ private slots:
void bindingOverwriting();
void bindToQmlComponent();
void bindingDoesNoWeirdConversion();
+ void bindNaNToInt();
private:
QQmlEngine engine;
@@ -398,6 +399,16 @@ void tst_qqmlbinding::bindingDoesNoWeirdConversion()
QVERIFY(colorLabel);
}
+//QTBUG-72442
+void tst_qqmlbinding::bindNaNToInt()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("nanPropertyToInt.qml"));
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create()));
+
+ QVERIFY(item != nullptr);
+ QCOMPARE(item->property("val").toInt(), 0);
+}
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index ca1e52ad2c..9c865b3f73 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -32,6 +32,7 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
#include <private/qqmlimport_p.h>
+#include <private/qqmlengine_p.h>
#include "../../shared/util.h"
class tst_QQmlImport : public QQmlDataTest
@@ -46,6 +47,7 @@ private slots:
void completeQmldirPaths();
void interceptQmldir();
void singletonVersionResolution();
+ void removeDynamicPlugin();
void cleanup();
};
@@ -260,6 +262,25 @@ void tst_QQmlImport::singletonVersionResolution()
}
}
+void tst_QQmlImport::removeDynamicPlugin()
+{
+ qmlClearTypeRegistrations();
+ QQmlEngine engine;
+ {
+ // Load something that adds a dynamic plugin
+ QQmlComponent component(&engine);
+ component.setData(QByteArray("import QtTest 1.0; TestResult{}"), QUrl());
+ QVERIFY(component.isReady());
+ }
+ QQmlImportDatabase *imports = &QQmlEnginePrivate::get(&engine)->importDatabase;
+ const QStringList &plugins = imports->dynamicPlugins();
+ QVERIFY(!plugins.isEmpty());
+ for (const QString &plugin : plugins)
+ QVERIFY(imports->removeDynamicPlugin(plugin));
+ QVERIFY(imports->dynamicPlugins().isEmpty());
+ qmlClearTypeRegistrations();
+}
+
QTEST_MAIN(tst_QQmlImport)
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index e2032c3b86..17dfa3d8a1 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -4728,11 +4728,13 @@ static void beginDeferredOnce(QQmlEnginePrivate *enginePriv,
typedef QMultiHash<int, const QV4::CompiledData::Binding *> QV4PropertyBindingHash;
auto it = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.second);
auto last = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.first);
+ state->creator->beginPopulateDeferred(deferData->context);
while (it != last) {
- if (!state->creator->populateDeferredBinding(property, deferData, *it))
- state->errors << state->creator->errors;
+ state->creator->populateDeferredBinding(property, deferData->deferredIdx, *it);
++it;
}
+ state->creator->finalizePopulateDeferred();
+ state->errors << state->creator->errors;
deferredState->constructionStates += state;
diff --git a/tests/auto/quick/qquicktextinput/data/qtbug77841.qml b/tests/auto/quick/qquicktextinput/data/qtbug77841.qml
new file mode 100644
index 0000000000..ebb43a8f82
--- /dev/null
+++ b/tests/auto/quick/qquicktextinput/data/qtbug77841.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.12
+
+Item {
+ id: root
+ width: 600
+ height: 300
+
+ TextInput {
+ id: qwe
+ objectName: "qwe"
+ width: 500
+ height: 100
+ font.pixelSize: 50
+ text: "123456"
+ focus: true
+ }
+
+ Component.onCompleted: {
+ qwe.insert(0, "***")
+ qwe.remove(0, 3)
+ }
+}
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index ed2d535fda..cab4e1145f 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -230,6 +230,7 @@ private slots:
void padding();
void QTBUG_51115_readOnlyResetsSelection();
+ void QTBUG_77814_InsertRemoveNoSelection();
private:
void simulateKey(QWindow *, int key);
@@ -7003,6 +7004,18 @@ void tst_qquicktextinput::QTBUG_51115_readOnlyResetsSelection()
QCOMPARE(obj->selectedText(), QString());
}
+void tst_qquicktextinput::QTBUG_77814_InsertRemoveNoSelection()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("qtbug77841.qml"));
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QQuickTextInput *textInput = view.rootObject()->findChild<QQuickTextInput*>("qwe");
+ QVERIFY(textInput);
+
+ QCOMPARE(textInput->selectedText(), QString());
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 5e999c557a..1556718471 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -380,23 +380,21 @@ public:
relocatableModuleUri = uri;
}
- const QString getExportString(QString qmlTyName, int majorVersion, int minorVersion)
+ QString getExportString(const QQmlType &type, const QmlVersionInfo &versionInfo)
{
- if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) {
- qmlTyName.remove(0, relocatableModuleUri.size() + 1);
- }
- if (qmlTyName.startsWith("./")) {
- qmlTyName.remove(0, 2);
- }
- if (qmlTyName.startsWith(QLatin1Char('/'))) {
- qmlTyName.remove(0, 1);
- }
- const QString exportString = enquote(
- QString("%1 %2.%3").arg(
- qmlTyName,
- QString::number(majorVersion),
- QString::number(minorVersion)));
- return exportString;
+ const QString module = type.module().isEmpty() ? versionInfo.pluginImportUri
+ : type.module();
+ const int majorVersion = type.majorVersion() >= 0 ? type.majorVersion()
+ : versionInfo.majorVersion;
+ const int minorVersion = type.minorVersion() >= 0 ? type.minorVersion()
+ : versionInfo.minorVersion;
+
+ const QString versionedElement = type.elementName()
+ + QString::fromLatin1(" %1.%2").arg(majorVersion).arg(minorVersion);
+
+ return enquote((module == relocatableModuleUri)
+ ? versionedElement
+ : module + QLatin1Char('/') + versionedElement);
}
void writeMetaContent(const QMetaObject *meta, KnownAttributes *knownAttributes = nullptr)
@@ -441,8 +439,9 @@ public:
}
}
- QString getPrototypeNameForCompositeType(const QMetaObject *metaObject, QSet<QByteArray> &defaultReachableNames,
- QList<const QMetaObject *> *objectsToMerge, const QmlVersionInfo &versionInfo)
+ QString getPrototypeNameForCompositeType(
+ const QMetaObject *metaObject, QList<const QMetaObject *> *objectsToMerge,
+ const QmlVersionInfo &versionInfo)
{
auto ty = QQmlMetaType::qmlType(metaObject);
QString prototypeName;
@@ -454,24 +453,28 @@ public:
&& !objectsToMerge->contains(metaObject))
objectsToMerge->append(metaObject);
const QMetaObject *superMetaObject = metaObject->superClass();
- if (!superMetaObject)
+ if (!superMetaObject) {
prototypeName = "QObject";
- else
+ } else {
+ QQmlType superType = QQmlMetaType::qmlType(superMetaObject);
+ if (superType.isValid() && !superType.isComposite())
+ return convertToId(superMetaObject->className());
prototypeName = getPrototypeNameForCompositeType(
- superMetaObject, defaultReachableNames, objectsToMerge, versionInfo);
+ superMetaObject, objectsToMerge, versionInfo);
+ }
} else {
prototypeName = convertToId(metaObject->className());
}
return prototypeName;
}
- void dumpComposite(QQmlEngine *engine, const QList<QQmlType> &compositeType, QSet<QByteArray> &defaultReachableNames, const QmlVersionInfo &versionInfo)
+ void dumpComposite(QQmlEngine *engine, const QList<QQmlType> &compositeType, const QmlVersionInfo &versionInfo)
{
for (const QQmlType &type : compositeType)
- dumpCompositeItem(engine, type, defaultReachableNames, versionInfo);
+ dumpCompositeItem(engine, type, versionInfo);
}
- void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet<QByteArray> &defaultReachableNames, const QmlVersionInfo &versionInfo)
+ void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, const QmlVersionInfo &versionInfo)
{
QQmlComponent e(engine, compositeType.sourceUrl());
if (!e.isReady()) {
@@ -492,13 +495,17 @@ public:
QList<const QMetaObject *> objectsToMerge;
KnownAttributes knownAttributes;
// Get C++ base class name for the composite type
- QString prototypeName = getPrototypeNameForCompositeType(mainMeta, defaultReachableNames,
- &objectsToMerge, versionInfo);
+ QString prototypeName = getPrototypeNameForCompositeType(mainMeta, &objectsToMerge,
+ versionInfo);
qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
QString qmlTyName = compositeType.qmlTypeName();
- const QString exportString = getExportString(qmlTyName, compositeType.majorVersion(), compositeType.minorVersion());
+ const QString exportString = getExportString(compositeType, versionInfo);
+
+ // TODO: why don't we simply output the compositeType.elementName() here?
+ // That would make more sense, but it would change the format quite a bit.
qml->writeScriptBinding(QLatin1String("name"), exportString);
+
qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString);
qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion()));
qml->writeBooleanBinding(QLatin1String("isComposite"), true);
@@ -565,7 +572,7 @@ public:
if (attachedType != meta)
attachedTypeId = convertToId(attachedType);
}
- const QString exportString = getExportString(type.qmlTypeName(), type.majorVersion(), type.minorVersion());
+ const QString exportString = getExportString(type, { QString(), -1, -1, false });
int metaObjectRevision = type.metaObjectRevision();
if (extendedObject) {
// emulate custom metaobjectrevision out of import
@@ -1239,9 +1246,6 @@ int main(int argc, char *argv[])
QSet<const QMetaObject *> uncreatableMetas;
QSet<const QMetaObject *> singletonMetas;
- // QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
- QSet<QByteArray> defaultReachableNames;
-
// this will hold the meta objects we want to dump information of
QSet<const QMetaObject *> metas;
@@ -1370,7 +1374,7 @@ int main(int argc, char *argv[])
QMap<QString, QList<QQmlType>>::const_iterator iter = compositeTypes.constBegin();
for (; iter != compositeTypes.constEnd(); ++iter)
- dumper.dumpComposite(&engine, iter.value(), defaultReachableNames, info);
+ dumper.dumpComposite(&engine, iter.value(), info);
// define QEasingCurve as an extension of QQmlEasingValueType, this way
// properties using the QEasingCurve type get useful type information.