From a4fb128b733667dcc8269efbb1b0227f09e3a64c Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 2 Jan 2020 13:27:10 +0100 Subject: QSequentialIterableImpl: support append Task-number: QTBUG-80916 Change-Id: I87e74da0ce454e56b5fe94d9db3693a587d35edf Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Shawn Rutledge Reviewed-by: Ulf Hermann --- src/corelib/kernel/qmetatype.h | 88 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index d41f7ee80e..d13fdeb642 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -977,6 +977,30 @@ enum IteratorCapability RandomAccessCapability = 4 }; +enum ContainerCapability +{ + ContainerIsAppendable = 1 +}; + +template +struct ContainerCapabilitiesImpl +{ + enum {ContainerCapabilities = 0}; + using appendFunction = void(*)(const void *container, const void *newElement); + static constexpr const appendFunction appendImpl = nullptr; +}; + +template +struct ContainerCapabilitiesImpl().push_back(std::declval()))> +{ + enum {ContainerCapabilities = ContainerIsAppendable}; + + // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl + // pointed to a const object to begin with + static void appendImpl(const void *container, const void *value) + { static_cast(const_cast(container))->push_back(*static_cast(value)); } +}; + template::iterator_category> struct CapabilitiesImpl; @@ -1012,6 +1036,12 @@ template struct ContainerAPI > : CapabilitiesImpl > { static int size(const std::list *t) { return int(t->size()); } }; +/* + revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set + revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce + _revision, _containerCapabilities and _unused. The latter contains 21 bits that are + not used yet +*/ class QSequentialIterableImpl { public: @@ -1020,19 +1050,37 @@ public: int _metaType_id; uint _metaType_flags; uint _iteratorCapabilities; + // Iterator capabilities looks actually like + // uint _iteratorCapabilities:4; + // uint _revision:3; + // uint _containerCapabilities:4; + // uint _unused:21;*/ typedef int(*sizeFunc)(const void *p); typedef const void * (*atFunc)(const void *p, int); typedef void (*moveIteratorFunc)(const void *p, void **); + enum Position { ToBegin, ToEnd }; + typedef void (*moveIteratorFunc2)(const void *p, void **, Position position); typedef void (*advanceFunc)(void **p, int); typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags); typedef void (*destroyIterFunc)(void **p); typedef bool (*equalIterFunc)(void * const *p, void * const *other); typedef void (*copyIterFunc)(void **, void * const *); + typedef void(*appendFunction)(const void *container, const void *newElement); + + IteratorCapability iteratorCapabilities() {return static_cast(_iteratorCapabilities & 0xF);} + uint revision() {return _iteratorCapabilities >> 4 & 0x7;} + uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;} sizeFunc _size; atFunc _at; - moveIteratorFunc _moveToBegin; - moveIteratorFunc _moveToEnd; + union { + moveIteratorFunc _moveToBegin; + moveIteratorFunc2 _moveTo; + }; + union { + moveIteratorFunc _moveToEnd; + appendFunction _append; + }; advanceFunc _advance; getFunc _get; destroyIterFunc _destroyIter; @@ -1059,6 +1107,15 @@ public: static void moveToEndImpl(const void *container, void **iterator) { IteratorOwner::assign(iterator, static_cast(container)->end()); } + template + static void moveToImpl(const void *container, void **iterator, Position position) + { + if (position == ToBegin) + moveToBeginImpl(container, iterator); + else + moveToEndImpl(container, iterator); + } + template static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags) { return VariantData(metaTypeId, IteratorOwner::getData(iterator), flags); } @@ -1069,11 +1126,11 @@ public: , _iterator(nullptr) , _metaType_id(qMetaTypeId()) , _metaType_flags(QTypeInfo::isPointer) - , _iteratorCapabilities(ContainerAPI::IteratorCapabilities) + , _iteratorCapabilities(ContainerAPI::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl::ContainerCapabilities << (4+3))) , _size(sizeImpl) , _at(atImpl) - , _moveToBegin(moveToBeginImpl) - , _moveToEnd(moveToEndImpl) + , _moveTo(moveToImpl) + , _append(ContainerCapabilitiesImpl::appendImpl) , _advance(IteratorOwner::advance) , _get(getImpl) , _destroyIter(IteratorOwner::destroy) @@ -1087,7 +1144,7 @@ public: , _iterator(nullptr) , _metaType_id(QMetaType::UnknownType) , _metaType_flags(0) - , _iteratorCapabilities(0) + , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1 , _size(nullptr) , _at(nullptr) , _moveToBegin(nullptr) @@ -1100,8 +1157,18 @@ public: { } - inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); } - inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); } + inline void moveToBegin() { + if (revision() == 0) + _moveToBegin(_iterable, &_iterator); + else + _moveTo(_iterable, &_iterator, ToBegin); + } + inline void moveToEnd() { + if (revision() == 0) + _moveToEnd(_iterable, &_iterator); + else + _moveTo(_iterable, &_iterator, ToEnd); + } inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); } inline QSequentialIterableImpl &advance(int i) { Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability); @@ -1109,6 +1176,11 @@ public: return *this; } + inline void append(const void *newElement) { + if (containerCapabilities() & ContainerIsAppendable) + _append(_iterable, newElement); + } + inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); } VariantData at(int idx) const -- cgit v1.2.3 From e6f1fde24f77f63fb16b2df239f82a89d2bf05dd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Jan 2020 09:26:27 -0800 Subject: QLibrary/Unix: do not attempt to load a library relative to $PWD I added the code in commit 5219c37f7c98f37f078fee00fe8ca35d83ff4f5d to find libraries in a haswell/ subdir of the main path, but we only need to do that transformation if the library is contains at least one directory seprator. That is, if the user asks to load "lib/foo", then we should try "lib/haswell/foo" (often, the path prefix will be absolute). When the library name the user requested has no directory separators, we let dlopen() do the transformation for us. Testing on Linux confirms glibc does so: $ LD_DEBUG=libs /lib64/ld-linux-x86-64.so.2 --inhibit-cache ./qml -help |& grep Xcursor 1972475: find library=libXcursor.so.1 [0]; searching 1972475: trying file=/usr/lib64/haswell/avx512_1/libXcursor.so.1 1972475: trying file=/usr/lib64/haswell/libXcursor.so.1 1972475: trying file=/usr/lib64/libXcursor.so.1 1972475: calling init: /usr/lib64/libXcursor.so.1 1972475: calling fini: /usr/lib64/libXcursor.so.1 [0] Fixes: QTBUG-81272 Change-Id: I596aec77785a4e4e84d5fffd15e89689bb91ffbb Reviewed-by: Thiago Macieira --- src/corelib/plugin/qlibrary_unix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index f0de1010d7..135b82cd37 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation +** Copyright (C) 2020 Intel Corporation ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -218,6 +218,8 @@ bool QLibraryPrivate::load_sys() for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) { if (!prefixes.at(prefix).isEmpty() && name.startsWith(prefixes.at(prefix))) continue; + if (path.isEmpty() && prefixes.at(prefix).contains(QLatin1Char('/'))) + continue; if (!suffixes.at(suffix).isEmpty() && name.endsWith(suffixes.at(suffix))) continue; if (loadHints & QLibrary::LoadArchiveMemberHint) { -- cgit v1.2.3 From bab1473b7e20c91287e5ce9685725be21abb7226 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jan 2020 10:56:03 -0800 Subject: Doc: QPluginLoader: remove the claim we search the current dir Commit bf131e8d2181b3404f5293546ed390999f760404 removed it and it's a good thing. Change-Id: Idc3fae4d0f614c389d27fffd15ea245420035e66 Reviewed-by: Jani Heikkinen --- src/corelib/plugin/qpluginloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index c2443dbdda..dac8502dae 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -342,7 +342,7 @@ static QString locatePlugin(const QString& fileName) QPluginLoader will automatically look for the file with the appropriate suffix (see QLibrary::isLibrary()). - When loading the plugin, QPluginLoader searches in the current directory and + When loading the plugin, QPluginLoader searches in all plugin locations specified by QCoreApplication::libraryPaths(), unless the file name has an absolute path. After loading the plugin successfully, fileName() returns the fully-qualified file name of -- cgit v1.2.3