diff options
| author | Sergio Ahumada <sahumada@blackberry.com> | 2014-03-11 09:27:30 +0100 |
|---|---|---|
| committer | Sergio Ahumada <sahumada@blackberry.com> | 2014-03-11 09:27:30 +0100 |
| commit | 5b574892c87b564d48126540983b59e278524159 (patch) | |
| tree | ce7a90ff30c4771300f36a946b7b6e8db82e00aa | |
| parent | 735d376937feaa6e4d2140aeeca6ffb3a308a5b9 (diff) | |
| parent | ae7af3b31222be80f6f66b4c2cbee707b90fe235 (diff) | |
| download | qtwebkit-5b574892c87b564d48126540983b59e278524159.tar.gz | |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Iaf17b7c575252c72104fc8aa234b3fde81853c80
38 files changed, 781 insertions, 58 deletions
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri index 47415a774..8e126e947 100644 --- a/Source/JavaScriptCore/Target.pri +++ b/Source/JavaScriptCore/Target.pri @@ -13,10 +13,7 @@ WEBKIT += wtf QT += core QT -= gui -CONFIG += staticlib - -*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 -*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 +CONFIG += staticlib optimize_full # Rules when JIT enabled (not disabled) !contains(DEFINES, ENABLE_JIT=0) { diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h index fe63ddf7a..0ec4668fd 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocator.h +++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h @@ -104,7 +104,7 @@ class DemandExecutableAllocator; #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) #if CPU(ARM) static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024; -#elif CPU(X86_64) +#elif CPU(X86_64) && !CPU(X32) static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024; #else static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024; diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h index 9a0e0a30e..6b09781a0 100644 --- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h +++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h @@ -98,9 +98,14 @@ namespace JSC { move(tagTypeNumberRegister, regT0); done.link(this); #else +#if !CPU(X86) + // The src register is not clobbered by moveDoubleToInts with ARM, MIPS and SH4 macro assemblers, so let's use it. + moveDoubleToInts(src, regT0, regT1); +#else storeDouble(src, Address(stackPointerRegister, -(int)sizeof(double))); loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1); loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0); +#endif Jump lowNonZero = branchTestPtr(NonZero, regT1); Jump highNonZero = branchTestPtr(NonZero, regT0); move(TrustedImm32(0), regT0); diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb index 6f35b2ffd..9e783fc39 100644 --- a/Source/JavaScriptCore/offlineasm/cloop.rb +++ b/Source/JavaScriptCore/offlineasm/cloop.rb @@ -398,7 +398,7 @@ def cloopEmitUnaryOperation(operands, type, operator) end def cloopEmitCompareDoubleWithNaNCheckAndBranch(operands, condition) - $asm.putc "if (std::isnan(#{operands[0].clValue(:double)}) || isnan(#{operands[1].clValue(:double)})" + $asm.putc "if (std::isnan(#{operands[0].clValue(:double)}) || std::isnan(#{operands[1].clValue(:double)})" $asm.putc " || (#{operands[0].clValue(:double)} #{condition} #{operands[1].clValue(:double)}))" $asm.putc " goto #{operands[2].cLabel};" end diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h index 3177c6c97..e5ef96336 100644 --- a/Source/JavaScriptCore/runtime/ArrayConventions.h +++ b/Source/JavaScriptCore/runtime/ArrayConventions.h @@ -71,6 +71,8 @@ namespace JSC { // is added. #define FIRST_VECTOR_GROW 4U +#define MIN_BEYOND_LENGTH_SPARSE_INDEX 1000 + // Our policy for when to use a vector and when to use a sparse map. // For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector. // When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector @@ -82,6 +84,11 @@ inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) return length / minDensityMultiplier <= numValues; } +inline bool indexIsSufficientlyBeyondLengthForSparseMap(unsigned i, unsigned length) +{ + return i >= MIN_BEYOND_LENGTH_SPARSE_INDEX && i > length; +} + inline IndexingHeader indexingHeaderForArray(unsigned length, unsigned vectorLength) { IndexingHeader result; diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index 48fc23186..01dc96333 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -1872,7 +1872,8 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un if (i >= MAX_ARRAY_INDEX - 1 || (i >= MIN_SPARSE_ARRAY_INDEX - && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))) { + && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly))) + || indexIsSufficientlyBeyondLengthForSparseMap(i, m_butterfly->vectorLength())) { ASSERT(i <= MAX_ARRAY_INDEX); ensureArrayStorageSlow(vm); SparseArrayValueMap* map = allocateSparseIndexMap(vm); @@ -1920,7 +1921,7 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns // First, handle cases where we don't currently have a sparse map. if (LIKELY(!map)) { - // If the array is not extensible, we should have entered dictionary mode, and created the spare map. + // If the array is not extensible, we should have entered dictionary mode, and created the sparse map. ASSERT(isExtensible()); // Update m_length if necessary. @@ -1928,7 +1929,9 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns storage->setLength(i + 1); // Check that it is sensible to still be using a vector, and then try to grow the vector. - if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(vm, i + 1))) { + if (LIKELY(!indexIsSufficientlyBeyondLengthForSparseMap(i, storage->vectorLength()) + && isDenseEnoughForVector(i, storage->m_numValuesInVector) + && increaseVectorLength(vm, i + 1))) { // success! - reread m_storage since it has likely been reallocated, and store to the vector. storage = arrayStorage(); storage->m_vector[i].set(vm, this, value); @@ -1995,7 +1998,7 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue ensureArrayStorageExistsAndEnterDictionaryIndexingMode(vm)); break; } - if (i >= MIN_SPARSE_ARRAY_INDEX) { + if (indexIsSufficientlyBeyondLengthForSparseMap(i, 0) || i >= MIN_SPARSE_ARRAY_INDEX) { putByIndexBeyondVectorLengthWithArrayStorage( exec, i, value, shouldThrow, createArrayStorage(vm, 0, 0)); break; @@ -2075,7 +2078,8 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, if (LIKELY( !attributes && (isDenseEnoughForVector(i, storage->m_numValuesInVector)) - && increaseVectorLength(vm, i + 1))) { + && !indexIsSufficientlyBeyondLengthForSparseMap(i, storage->vectorLength())) + && increaseVectorLength(vm, i + 1)) { // success! - reread m_storage since it has likely been reallocated, and store to the vector. storage = arrayStorage(); storage->m_vector[i].set(vm, this, value); diff --git a/Source/ThirdParty/leveldb/Target.pri b/Source/ThirdParty/leveldb/Target.pri index 48d8550ff..ed4d8a1c8 100644 --- a/Source/ThirdParty/leveldb/Target.pri +++ b/Source/ThirdParty/leveldb/Target.pri @@ -27,10 +27,8 @@ HEADERS += \ db/version_edit.h \ db/version_set.h \ db/write_batch_internal.h \ - port/atomic_pointer.h \ - port/port_example.h \ port/port.h \ - port/port_posix.h \ + port/port_qt.h \ port/thread_annotations.h \ port/win/stdint.h \ helpers/memenv/memenv.h \ @@ -61,7 +59,7 @@ HEADERS += \ util/histogram.h \ util/logging.h \ util/mutexlock.h \ - util/posix_logger.h \ + util/qt_logger.h \ util/random.h SOURCES += \ @@ -80,7 +78,6 @@ SOURCES += \ db/version_set.cc \ db/write_batch.cc \ helpers/memenv/memenv.cc \ - port/port_posix.cc \ table/block_builder.cc \ table/block.cc \ table/filter_block.cc \ @@ -97,7 +94,7 @@ SOURCES += \ util/comparator.cc \ util/crc32c.cc \ util/env.cc \ - util/env_posix.cc \ + util/env_qt.cc \ util/filter_policy.cc \ util/hash.cc \ util/histogram.cc \ @@ -105,11 +102,10 @@ SOURCES += \ util/options.cc \ util/status.cc -posix: DEFINES += LEVELDB_PLATFORM_POSIX +DEFINES += LEVELDB_PLATFORM_QT win: DEFINES += OS_WIN mac: DEFINES += OS_MACOSX linux: DEFINES += OS_LINUX freebsd*: DEFINES += OS_FREEBSD -# We do not need anything from Qt -QT = +QT += core diff --git a/Source/ThirdParty/leveldb/db/c.cc b/Source/ThirdParty/leveldb/db/c.cc index 08ff0ad90..745817f2b 100644 --- a/Source/ThirdParty/leveldb/db/c.cc +++ b/Source/ThirdParty/leveldb/db/c.cc @@ -5,7 +5,6 @@ #include "leveldb/c.h" #include <stdlib.h> -#include <unistd.h> #include "leveldb/cache.h" #include "leveldb/comparator.h" #include "leveldb/db.h" diff --git a/Source/ThirdParty/leveldb/port/port.h b/Source/ThirdParty/leveldb/port/port.h index e667db40d..f6279fc7a 100644 --- a/Source/ThirdParty/leveldb/port/port.h +++ b/Source/ThirdParty/leveldb/port/port.h @@ -14,6 +14,8 @@ # include "port/port_posix.h" #elif defined(LEVELDB_PLATFORM_CHROMIUM) # include "port/port_chromium.h" +#elif defined(LEVELDB_PLATFORM_QT) +# include "port/port_qt.h" #endif #endif // STORAGE_LEVELDB_PORT_PORT_H_ diff --git a/Source/ThirdParty/leveldb/port/port_qt.h b/Source/ThirdParty/leveldb/port/port_qt.h new file mode 100644 index 000000000..cc8db5fe8 --- /dev/null +++ b/Source/ThirdParty/leveldb/port/port_qt.h @@ -0,0 +1,123 @@ +/* + Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef STORAGE_LEVELDB_PORT_PORT_QT_H_ +#define STORAGE_LEVELDB_PORT_PORT_QT_H_ + +#include <QAtomicInteger> +#include <QAtomicPointer> +#include <QMutex> +#include <QWaitCondition> + +#include <string> + +#ifdef SNAPPY +#include <snappy.h> +#endif + +#ifdef Q_CC_MSVC +#include "win/stdint.h" +#define snprintf _snprintf +#endif + +namespace leveldb { +namespace port { + +static const bool kLittleEndian = (Q_BYTE_ORDER == Q_LITTLE_ENDIAN); + +class Mutex : public QMutex { +public: + Mutex() { } + + void Lock() { lock(); } + void Unlock() { unlock(); } + void AssertHeld() { Q_ASSERT(!tryLock()); } +}; + +class CondVar : public QWaitCondition { +public: + explicit CondVar(Mutex* mu) : m_mutex(mu) { } + + void Wait() { wait(m_mutex); } + void Signal() { wakeOne(); } + void SignalAll() { wakeAll(); } +private: + Mutex* m_mutex; +}; + +typedef QAtomicInteger<int> OnceType; +#define LEVELDB_ONCE_INIT 0 +inline void InitOnce(port::OnceType* once, void (*initializer)()) +{ + if (once->testAndSetAcquire(0, 1)) + initializer(); +} + +class AtomicPointer : public QAtomicPointer<void> { +public: + AtomicPointer() { } + AtomicPointer(void *p) : QAtomicPointer<void>(p) { } + void* Acquire_Load() const { return loadAcquire(); } + void Release_Store(void* p) { storeRelease(p); } + void* NoBarrier_Load() const { return load(); } + void NoBarrier_Store(void* p) { store(p); } +}; + +// SNAPPY, non Qt specific: + +inline bool Snappy_Compress(const char* input, size_t length, + ::std::string* output) { +#ifdef SNAPPY + output->resize(snappy::MaxCompressedLength(length)); + size_t outlen; + snappy::RawCompress(input, length, &(*output)[0], &outlen); + output->resize(outlen); + return true; +#endif + + return false; +} + +inline bool Snappy_GetUncompressedLength(const char* input, size_t length, + size_t* result) { +#ifdef SNAPPY + return snappy::GetUncompressedLength(input, length, result); +#else + return false; +#endif +} + +inline bool Snappy_Uncompress(const char* input, size_t length, + char* output) { +#ifdef SNAPPY + return snappy::RawUncompress(input, length, output); +#else + return false; +#endif +} + + +inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { + return false; +} + +} // namespace port +} // namespace leveldb + +#endif // STORAGE_LEVELDB_PORT_PORT_QT_H_ diff --git a/Source/ThirdParty/leveldb/util/env_qt.cc b/Source/ThirdParty/leveldb/util/env_qt.cc new file mode 100644 index 000000000..a90a8afdf --- /dev/null +++ b/Source/ThirdParty/leveldb/util/env_qt.cc @@ -0,0 +1,443 @@ +/* + Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "leveldb/env.h" +#include "leveldb/slice.h" +#include "port/port.h" +#include "util/logging.h" +#include "util/qt_logger.h" + +#include <string.h> + +#include <QDateTime> +#include <QDir> +#include <QFile> +#include <QLockFile> +#include <QObject> +#include <QStandardPaths> +#include <QString> +#include <QThread> + +//#define QTENV_DEBUG + +#ifdef QTENV_DEBUG +#include <QDebug> +#endif + +typedef void (*UserFunctionPointer)(void*); + +Q_DECLARE_METATYPE(UserFunctionPointer) + +namespace leveldb { + +namespace { + + +static Status IOError(const QString& fname, const QString& errorMessage) +{ +#ifdef QTENV_DEBUG + qDebug() << Q_FUNC_INFO << fname << errorMessage; +#endif + return Status::IOError(fname.toStdString(), errorMessage.toStdString()); +} + +class QtSequentialFile: public SequentialFile { +public: + QFile m_file; + + QtSequentialFile(const std::string& fname) : m_file(QString::fromStdString(fname)) + { } + virtual ~QtSequentialFile() { m_file.close(); } + + virtual Status Read(size_t n, Slice* result, char* scratch) { + Status s; + size_t r = m_file.read(scratch, n); + *result = Slice(scratch, r); + if (r < n) { + if (m_file.atEnd()) { + // We leave status as ok if we hit the end of the file + } else { + // A partial read with an error: return a non-ok status + s = IOError(m_file.fileName(), m_file.errorString()); + } + } + return s; + } + + virtual Status Skip(uint64_t n) { + if (!m_file.seek(n + m_file.pos())) { + return IOError(m_file.fileName(), m_file.errorString()); + } + return Status::OK(); + } +}; + +class QtRandomAccessFile: public RandomAccessFile { +public: + mutable QFile m_file; + + QtRandomAccessFile(const std::string& fname) : m_file(QString::fromStdString(fname)) + { } + virtual ~QtRandomAccessFile() { m_file.close(); } + + virtual Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const + { + if (!m_file.seek(offset)) + return IOError(m_file.fileName(), m_file.errorString()); + + qint64 r = m_file.peek(scratch, n); + *result = Slice(scratch, (r < 0) ? 0 : r); + if (r < 0) { + // An error: return a non-ok status + return IOError(m_file.fileName(), m_file.errorString()); + } + return Status::OK(); + } +}; + +class QtWritableFile: public WritableFile { +public: + QFile m_file; + + QtWritableFile(const std::string& fname) : m_file(QString::fromStdString(fname)) + { } + virtual ~QtWritableFile() { m_file.close(); } + + virtual Status Append(const Slice& data) + { + m_file.unsetError(); + qint64 r = m_file.write(data.data(), data.size()); + if (r < 0) { + return IOError(m_file.fileName(), m_file.errorString()); + } + return Status::OK(); + } + virtual Status Close() + { + m_file.unsetError(); + if (!m_file.isOpen()) + return IOError(m_file.fileName(), QObject::tr("File not open")); + m_file.close(); + return Status::OK(); + } + virtual Status Flush() + { + m_file.unsetError(); + if (!m_file.flush()) + return IOError(m_file.fileName(), m_file.errorString()); + return Status::OK(); + } + + virtual Status Sync() + { + return Flush(); + } +}; + +class QtFileLock : public FileLock { +public: + QLockFile m_file; + QString m_fileName; + + QtFileLock(const std::string& fname) + : m_file(QString::fromStdString(fname)) + , m_fileName(QString::fromStdString(fname)) + { } +}; + +class BGProcessor : public QObject { + Q_OBJECT +public: + BGProcessor() + { + } + +public slots: + void slot_run(UserFunctionPointer user_function, void* arg) + { + user_function(arg); + } +}; + +class BGThread : public QThread { + Q_OBJECT +public: + BGThread() : m_processor(0), m_started(0) + { + } + + virtual void run() { + m_mutex.lock(); + m_processor = new BGProcessor(); + QObject::connect(this, SIGNAL(schedule(UserFunctionPointer,void*)), m_processor, SLOT(slot_run(UserFunctionPointer,void*)), Qt::QueuedConnection); + m_started.store(1); + m_startCond.wakeAll(); + m_mutex.unlock(); + exec(); + delete m_processor; + } + + void waitUntilStarted() { + if (m_started) + return; + m_mutex.lock(); + if (!m_started) + m_startCond.wait(&m_mutex); + m_mutex.unlock(); + } +signals: + void schedule(UserFunctionPointer user_function, void* arg); + +private: + BGProcessor* m_processor; + QMutex m_mutex; + QWaitCondition m_startCond; + QAtomicInt m_started; +}; + +class QtEnv : public Env { +public: + QtEnv() { + bgthread.start(); + } + + virtual ~QtEnv() { + qFatal("Destroying Env::Default()\n"); + } + + virtual Status NewSequentialFile(const std::string& fname, SequentialFile** result) + { + QtSequentialFile* file = new QtSequentialFile(fname); + if (!file->m_file.open(QIODevice::ReadOnly)) { + *result = 0; + Status status = IOError(file->m_file.fileName(), file->m_file.errorString()); + delete file; + return status; + } + *result = file; + return Status::OK(); + } + + virtual Status NewRandomAccessFile(const std::string& fname, RandomAccessFile** result) + { + QtRandomAccessFile* file = new QtRandomAccessFile(fname); + if (!file->m_file.open(QIODevice::ReadOnly)) { + *result = 0; + Status status = IOError(file->m_file.fileName(), file->m_file.errorString()); + delete file; + return status; + } + *result = file; + return Status::OK(); + } + + virtual Status NewWritableFile(const std::string& fname, WritableFile** result) + { + QtWritableFile* file = new QtWritableFile(fname); + if (!file->m_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + *result = 0; + Status status = IOError(file->m_file.fileName(), file->m_file.errorString()); + delete file; + return status; + } + *result = file; + return Status::OK(); + } + + virtual bool FileExists(const std::string& fname) + { + return QFile::exists(QString::fromStdString(fname)); + } + + virtual Status GetChildren(const std::string& dir, std::vector<std::string>* result) + { + result->clear(); + QDir qdir(QString::fromStdString(dir)); + foreach (const QString& filename, qdir.entryList()) { + result->push_back(filename.toStdString()); + } + return Status::OK(); + } + + virtual Status DeleteFile(const std::string& fname) + { + QFile file(QString::fromStdString(fname)); + if (!file.remove()) + return IOError(file.fileName(), file.errorString()); + return Status::OK(); + } + + virtual Status CreateDir(const std::string& name) + { + QDir dir; + if (!dir.mkdir(QString::fromStdString(name))) + return IOError(QString::fromStdString(name), QObject::tr("Could not create path")); + return Status::OK(); + } + + virtual Status DeleteDir(const std::string& name) + { + QDir dir; + if (!dir.rmdir(QString::fromStdString(name))) + return IOError(QString::fromStdString(name), QObject::tr("Could not delete path")); + return Status::OK(); + } + + virtual Status GetFileSize(const std::string& fname, uint64_t* size) + { + QFile file(QString::fromStdString(fname)); + qint64 sz = file.size(); + if (!sz) + return IOError(file.fileName(), file.errorString()); + + *size = sz; + return Status::OK(); + } + + virtual Status RenameFile(const std::string& src, const std::string& target) + { + QFile file(QString::fromStdString(src)); + // POSIX rename overwrites destination, QFile::rename does not. + if (file.exists() && QFile::exists(QString::fromStdString(target))) + QFile::remove(QString::fromStdString(target)); + if (!file.rename(QString::fromStdString(target))) + return IOError(file.fileName(), file.errorString()); + return Status::OK(); + } + + virtual Status LockFile(const std::string& fname, FileLock** lock) + { + *lock = 0; + QtFileLock* my_lock = new QtFileLock(fname); + if (!my_lock->m_file.tryLock(500)) { + if (my_lock->m_file.staleLockTime() > 30000) { + // Handle stale lock files not locked by Qt. + my_lock->m_file.setStaleLockTime(30000); + return LockFile(fname, lock); + } + QString errorString; + switch (my_lock->m_file.error()) { + case QLockFile::NoError: + errorString = QObject::tr("No error"); + break; + case QLockFile::LockFailedError: + errorString = QObject::tr("Lock failed error"); + break; + case QLockFile::PermissionError: + errorString = QObject::tr("Permission error"); + break; + case QLockFile::UnknownError: + errorString = QObject::tr("Unknown error"); + break; + } + delete my_lock; + return IOError(QString::fromStdString(fname), errorString); + } + *lock = my_lock; + return Status::OK(); + } + + virtual Status UnlockFile(FileLock* lock) + { + QtFileLock* my_lock = reinterpret_cast<QtFileLock*>(lock); + my_lock->m_file.unlock(); + delete my_lock; + return Status::OK(); + } + + virtual void Schedule(void (*function)(void*), void* arg) + { + bgthread.waitUntilStarted(); + emit bgthread.schedule(function, arg); + } + + virtual void StartThread(void (*function)(void* arg), void* arg); + + virtual Status GetTestDirectory(std::string* result) { + QByteArray env = qgetenv("TEST_TMPDIR"); + if (!env.isEmpty() && env[0] != '\0') { + *result = QString::fromLocal8Bit(env).toStdString(); + } else { + QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation); + *result = path.toStdString(); + } + // Directory may already exist + CreateDir(*result); + return Status::OK(); + } + + virtual Status NewLogger(const std::string& fname, Logger** result) + { + *result = new QtLogger(QString::fromStdString(fname)); + return Status::OK(); + } + + virtual uint64_t NowMicros() + { + return QDateTime::currentMSecsSinceEpoch() * 1000; + } + + virtual void SleepForMicroseconds(int micros) + { + QThread::usleep(micros); + } +private: + BGThread bgthread; +}; + +class StartThreadState : public QThread { +public: + StartThreadState(UserFunctionPointer user_function, void* arg) + : user_function(user_function) + , arg(arg) + { } + virtual void run() + { + user_function(arg); + } +private: + UserFunctionPointer user_function; + void* arg; +}; + +void QtEnv::StartThread(void (*function)(void*), void* arg) +{ + QThread* thread = new StartThreadState(function, arg); + QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); +} + +} // namespace + +static port::OnceType once = LEVELDB_ONCE_INIT; +static Env* default_env; +static void InitDefaultEnv() +{ + qRegisterMetaType<UserFunctionPointer>(); + default_env = new QtEnv; +} + +Env* Env::Default() { + port::InitOnce (&once, InitDefaultEnv); + return default_env; +} + +} // namespace leveldb + +#include "env_qt.moc" diff --git a/Source/ThirdParty/leveldb/util/qt_logger.h b/Source/ThirdParty/leveldb/util/qt_logger.h new file mode 100644 index 000000000..e673fd5de --- /dev/null +++ b/Source/ThirdParty/leveldb/util/qt_logger.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef STORAGE_LEVELDB_UTIL_QT_LOGGER_H_ +#define STORAGE_LEVELDB_UTIL_QT_LOGGER_H_ + +#include "leveldb/env.h" + +#include <QDateTime> +#include <QFile> +#include <QString> +#include <QTextStream> +#include <QThread> + +namespace leveldb { + +class QtLogger : public Logger { +private: + QFile file; + QTextStream log; + +public: + QtLogger(QString fname) : file(fname), log(&file) + { + file.open(QIODevice::WriteOnly | QIODevice::Append); + } + virtual ~QtLogger() { + log.flush(); + file.close(); + } + + virtual void Logv(const char* format, va_list ap) { + const uint64_t thread_id = (qintptr)QThread::currentThreadId(); + QString formated; + formated = formated.vsprintf(format, ap); + + log << QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate) << " " << thread_id << " " << formated << '\n'; + } +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_QT_LOGGER_H_ diff --git a/Source/WTF/WTF.pri b/Source/WTF/WTF.pri index a9a950012..a2f6aaa1b 100644 --- a/Source/WTF/WTF.pri +++ b/Source/WTF/WTF.pri @@ -11,7 +11,7 @@ INCLUDEPATH += $$PWD mac { # Mac OS does ship libicu but not the associated header files. # Therefore WebKit provides adequate header files. - INCLUDEPATH += $${ROOT_WEBKIT_DIR}/Source/WTF/icu + INCLUDEPATH = $${ROOT_WEBKIT_DIR}/Source/WTF/icu $$INCLUDEPATH LIBS += -licucore } else { contains(QT_CONFIG,icu) { diff --git a/Source/WTF/WTF.pro b/Source/WTF/WTF.pro index f3a77dd06..ef622920d 100644 --- a/Source/WTF/WTF.pro +++ b/Source/WTF/WTF.pro @@ -8,7 +8,7 @@ TARGET = WTF include(WTF.pri) -CONFIG += staticlib +CONFIG += staticlib optimize_full VPATH += $$PWD/wtf @@ -267,9 +267,6 @@ win32 { QT += core QT -= gui -*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 -*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 - *sh4* { QMAKE_CXXFLAGS += -mieee -w QMAKE_CFLAGS += -mieee -w diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h index cf80b762c..4594ec854 100644 --- a/Source/WTF/wtf/Platform.h +++ b/Source/WTF/wtf/Platform.h @@ -172,6 +172,11 @@ #if defined(__x86_64__) \ || defined(_M_X64) #define WTF_CPU_X86_64 1 + +#if defined(__ILP32__) +#define WTF_CPU_X32 1 +#endif + #endif /* CPU(ARM) - ARM, any version*/ @@ -735,7 +740,7 @@ #endif #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) -#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \ +#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS)) && !CPU(X32)) \ || (CPU(IA64) && !CPU(IA64_32)) \ || CPU(ALPHA) \ || CPU(SPARC64) \ @@ -754,6 +759,11 @@ #define ENABLE_JIT 0 #endif +/* Disable JIT on x32 */ +#if CPU(X32) +#define ENABLE_JIT 0 +#endif + #if !defined(ENABLE_JIT) && CPU(SH4) && PLATFORM(QT) #define ENABLE_JIT 1 #endif diff --git a/Source/WTF/wtf/StackBounds.cpp b/Source/WTF/wtf/StackBounds.cpp index 62e2665a4..0dc82d2f8 100644 --- a/Source/WTF/wtf/StackBounds.cpp +++ b/Source/WTF/wtf/StackBounds.cpp @@ -185,6 +185,11 @@ void StackBounds::initialize() MEMORY_BASIC_INFORMATION uncommittedMemory; VirtualQuery(stackOrigin.AllocationBase, &uncommittedMemory, sizeof(uncommittedMemory)); + SIZE_T extraGuardPageRegionSize = 0; + if (uncommittedMemory.Protect & PAGE_GUARD) { + extraGuardPageRegionSize = uncommittedMemory.RegionSize; + VirtualQuery(static_cast<char*>(uncommittedMemory.BaseAddress) + uncommittedMemory.RegionSize, &uncommittedMemory, sizeof(uncommittedMemory)); + } ASSERT(uncommittedMemory.State == MEM_RESERVE); MEMORY_BASIC_INFORMATION guardPage; @@ -198,12 +203,12 @@ void StackBounds::initialize() VirtualQuery(static_cast<char*>(guardPage.BaseAddress) + guardPage.RegionSize, &committedMemory, sizeof(committedMemory)); ASSERT(committedMemory.State == MEM_COMMIT); - void* computedEnd = static_cast<char*>(m_origin) - (uncommittedMemory.RegionSize + guardPage.RegionSize + committedMemory.RegionSize); + void* computedEnd = static_cast<char*>(m_origin) - (uncommittedMemory.RegionSize + extraGuardPageRegionSize + guardPage.RegionSize + committedMemory.RegionSize); ASSERT(stackOrigin.AllocationBase == uncommittedMemory.AllocationBase); ASSERT(stackOrigin.AllocationBase == guardPage.AllocationBase); ASSERT(stackOrigin.AllocationBase == committedMemory.AllocationBase); - ASSERT(stackOrigin.AllocationBase == uncommittedMemory.BaseAddress); + ASSERT(stackOrigin.AllocationBase == static_cast<char*>(uncommittedMemory.BaseAddress) - extraGuardPageRegionSize); ASSERT(endOfStack == computedEnd); #endif // NDEBUG m_bound = static_cast<char*>(endOfStack) + guardPage.RegionSize; diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index ba1ff1958..a085e71be 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -789,7 +789,8 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef case Node::TEXT_NODE: case Node::CDATA_SECTION_NODE: case Node::COMMENT_NODE: - ASSERT(endOffset <= static_cast<CharacterData*>(container)->length()); + endOffset = std::min(endOffset, static_cast<CharacterData*>(container)->length()); + startOffset = std::min(startOffset, endOffset); if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true)); deleteCharacterData(c, startOffset, endOffset, ec); @@ -803,7 +804,8 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef static_cast<CharacterData*>(container)->deleteData(startOffset, endOffset - startOffset, ec); break; case Node::PROCESSING_INSTRUCTION_NODE: - ASSERT(endOffset <= static_cast<ProcessingInstruction*>(container)->data().length()); + endOffset = std::min(endOffset, static_cast<ProcessingInstruction*>(container)->data().length()); + startOffset = std::min(startOffset, endOffset); if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true)); c->setData(c->data().substring(startOffset, endOffset - startOffset), ec); diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp index 9755d1ae7..b8c44116f 100644 --- a/Source/WebCore/loader/DocumentLoader.cpp +++ b/Source/WebCore/loader/DocumentLoader.cpp @@ -364,8 +364,13 @@ void DocumentLoader::finishedLoading(double finishTime) RefPtr<DocumentLoader> protect(this); if (m_identifierForLoadWithoutResourceLoader) { - frameLoader()->notifier()->dispatchDidFinishLoading(this, m_identifierForLoadWithoutResourceLoader, finishTime); + // A didFinishLoading delegate might try to cancel the load (despite it + // being finished). Clear m_identifierForLoadWithoutResourceLoader + // before calling dispatchDidFinishLoading so that we don't later try to + // cancel the already-finished substitute load. + unsigned long identifier = m_identifierForLoadWithoutResourceLoader; m_identifierForLoadWithoutResourceLoader = 0; + frameLoader()->notifier()->dispatchDidFinishLoading(this, identifier, finishTime); } #if USE(CONTENT_FILTERING) diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp index 2a00ac324..014d3d738 100644 --- a/Source/WebCore/platform/KURL.cpp +++ b/Source/WebCore/platform/KURL.cpp @@ -1752,7 +1752,11 @@ bool KURL::isLocalFile() const // and including feed would allow feeds to potentially let someone's blog // read the contents of the clipboard on a drag, even without a drop. // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function. +#if PLATFORM(QT) + return protocolIs("file") || protocolIs("qrc"); +#else return protocolIs("file"); +#endif } bool protocolIsJavaScript(const String& url) diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp index 07610d2d8..2e2f334c3 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.cpp +++ b/Source/WebCore/platform/graphics/BitmapImage.cpp @@ -82,7 +82,11 @@ void BitmapImage::destroyDecodedData(bool destroyAll) { unsigned frameBytesCleared = 0; const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFrame; - for (size_t i = 0; i < clearBeforeFrame; ++i) { + + // Because we can advance frames without always needing to decode the actual + // bitmap data, |m_currentFrame| may be larger than m_frames.size(); + // make sure not to walk off the end of the container in this case. + for (size_t i = 0; i < std::min(clearBeforeFrame, m_frames.size()); ++i) { // The underlying frame isn't actually changing (we're just trying to // save the memory for the framebuffer data), so we don't need to clear // the metadata. diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp index f4b9a7e98..999d52f31 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp @@ -124,7 +124,7 @@ static const char* vertexTemplate = attribute vec4 a_vertex; uniform mat4 u_modelViewMatrix; uniform mat4 u_projectionMatrix; - uniform mat4 u_textureSpaceMatrix; + uniform highp mat4 u_textureSpaceMatrix; varying vec2 v_texCoord; varying vec2 v_transformedTexCoord; @@ -220,7 +220,7 @@ static const char* fragmentTemplate = uniform vec2 u_shadowOffset; uniform vec4 u_color; uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH]; - uniform mat4 u_textureSpaceMatrix; + uniform highp mat4 u_textureSpaceMatrix; void noop(inout vec4 dummyParameter) { } void noop(inout vec4 dummyParameter, vec2 texCoord) { } diff --git a/Source/WebCore/platform/network/ResourceHandle.cpp b/Source/WebCore/platform/network/ResourceHandle.cpp index cd768f290..0ea9d1c34 100644 --- a/Source/WebCore/platform/network/ResourceHandle.cpp +++ b/Source/WebCore/platform/network/ResourceHandle.cpp @@ -212,7 +212,7 @@ bool ResourceHandle::shouldContentSniffURL(const KURL& url) return true; #endif // We shouldn't content sniff file URLs as their MIME type should be established via their extension. - return !url.protocolIs("file"); + return !url.isLocalFile(); } void ResourceHandle::forceContentSniffing() diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index a6e0840bf..5990a4075 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -216,6 +216,12 @@ void QNetworkReplyHandlerCallQueue::push(EnqueuedCall method) flush(); } +void QNetworkReplyHandlerCallQueue::requeue(EnqueuedCall method) +{ + m_enqueuedCalls.prepend(method); + flush(); +} + void QNetworkReplyHandlerCallQueue::lock() { ++m_locks; @@ -666,17 +672,25 @@ void QNetworkReplyHandler::forwardData() { ASSERT(m_replyWrapper && m_replyWrapper->reply() && !wasAborted() && !m_replyWrapper->wasRedirected()); - QByteArray data = m_replyWrapper->reply()->read(m_replyWrapper->reply()->bytesAvailable()); - ResourceHandleClient* client = m_resourceHandle->client(); if (!client) return; - // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793 - // -1 means we do not provide any data about transfer size to inspector so it would use - // Content-Length headers or content size to show transfer size. - if (!data.isEmpty()) - client->didReceiveData(m_resourceHandle, data.constData(), data.length(), -1); + qint64 bytesAvailable = m_replyWrapper->reply()->bytesAvailable(); + char* buffer = new char[8128]; // smaller than 8192 to fit within 8k including overhead. + while (bytesAvailable > 0 && !m_queue.deferSignals()) { + qint64 readSize = m_replyWrapper->reply()->read(buffer, 8128); + if (readSize <= 0) + break; + bytesAvailable -= readSize; + // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793 + // -1 means we do not provide any data about transfer size to inspector so it would use + // Content-Length headers or content size to show transfer size. + client->didReceiveData(m_resourceHandle, buffer, readSize, -1); + } + delete[] buffer; + if (bytesAvailable > 0) + m_queue.requeue(&QNetworkReplyHandler::forwardData); } void QNetworkReplyHandler::uploadProgress(qint64 bytesSent, qint64 bytesTotal) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h index 6bc35cc12..bf838fdc2 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -52,6 +52,7 @@ public: typedef void (QNetworkReplyHandler::*EnqueuedCall)(); void push(EnqueuedCall method); + void requeue(EnqueuedCall method); void clear() { m_enqueuedCalls.clear(); } void lock(); diff --git a/Source/WebCore/platform/qt/KURLQt.cpp b/Source/WebCore/platform/qt/KURLQt.cpp index 3dca4eee0..46d771f22 100644 --- a/Source/WebCore/platform/qt/KURLQt.cpp +++ b/Source/WebCore/platform/qt/KURLQt.cpp @@ -42,7 +42,7 @@ String KURL::fileSystemPath() const if (!isValid()) return String(); - if (isLocalFile()) + if (protocolIs("file")) return static_cast<QUrl>(*this).toLocalFile(); // A valid qrc resource path begins with a colon. diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp index 915c2af74..417c59d23 100644 --- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp @@ -699,6 +699,7 @@ int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) case Qt::Key_BraceRight: return VK_OEM_6; // case ']': case '}': return 0xDD; // VK_OEM_7 (DE) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key + case Qt::Key_Apostrophe: case Qt::Key_QuoteDbl: return VK_OEM_7; // case '\'': case '"': return 0xDE; // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard. diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp index f85a75bd4..14b989894 100644 --- a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp @@ -436,7 +436,7 @@ bool RenderThemeQStyle::paintSliderTrack(RenderObject* o, const PaintInfo& pi, c p.styleOption.state |= QStyleFacade::State_Sunken; // some styles need this to show a highlight on one side of the groove - HTMLInputElement* slider = o->node()->toInputElement(); + HTMLInputElement* slider = o->node() ? o->node()->toInputElement() : 0; if (slider && slider->isSteppable()) { p.styleOption.slider.upsideDown = (p.appearance == SliderHorizontalPart) && !o->style()->isLeftToRightDirection(); // Use the width as a multiplier in case the slider values are <= 1 diff --git a/Source/WebKit/qt/Api/qwebelement.cpp b/Source/WebKit/qt/Api/qwebelement.cpp index ec53effcb..17811cdc1 100644 --- a/Source/WebKit/qt/Api/qwebelement.cpp +++ b/Source/WebKit/qt/Api/qwebelement.cpp @@ -225,7 +225,9 @@ bool QWebElement::isNull() const \a selectorQuery. If there are no matching elements, an empty list is returned. - \l{Standard CSS2 selector} syntax is used for the query. + \l{Standard CSS selector} syntax is used for the query. + + This method is equivalent to Element::querySelectorAll in the \l{DOM Selectors API}. \note This search is performed recursively. @@ -240,7 +242,9 @@ QWebElementCollection QWebElement::findAll(const QString &selectorQuery) const Returns the first child element that matches the given CSS selector \a selectorQuery. - \l{Standard CSS2 selector} syntax is used for the query. + \l{Standard CSS selector} syntax is used for the query. + + This method is equivalent to Element::querySelector in the \l{DOM Selectors API}. \note This search is performed recursively. diff --git a/Source/WebKit/qt/WidgetApi/qwebframe.cpp b/Source/WebKit/qt/WidgetApi/qwebframe.cpp index 27cc73989..eb7821d53 100644 --- a/Source/WebKit/qt/WidgetApi/qwebframe.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebframe.cpp @@ -768,9 +768,11 @@ QWebElement QWebFrame::documentElement() const Returns a new list of elements matching the given CSS selector \a selectorQuery. If there are no matching elements, an empty list is returned. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is + \l{Standard CSS selector} syntax is used for the query. + This method is equivalent to Document::querySelectorAll in the \l{DOM Selectors API}. + \sa QWebElement::findAll() */ QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) const @@ -784,8 +786,9 @@ QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) c given CSS selector \a selectorQuery. If there is no matching element, a null element is returned. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is - used for the query. + \l{Standard CSS selector} syntax is used for the query. + + This method is equivalent to Document::querySelector in the \l{DOM Selectors API}. \sa QWebElement::findFirst() */ diff --git a/Source/WebKit/qt/WidgetApi/qwebview.cpp b/Source/WebKit/qt/WidgetApi/qwebview.cpp index bcbf3dcc2..f5c4050c9 100644 --- a/Source/WebKit/qt/WidgetApi/qwebview.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebview.cpp @@ -82,7 +82,7 @@ void QWebViewPrivate::_q_pageDestroyed() It can be used in various applications to display web content live from the Internet. - The image below shows QWebView previewed in \QD with a Nokia website. + The image below shows QWebView previewed in Qt Creator with the \l{Qt Homepage}. \image qwebview-url.png diff --git a/Source/WebKit/qt/WidgetSupport/QtFallbackWebPopup.cpp b/Source/WebKit/qt/WidgetSupport/QtFallbackWebPopup.cpp index 5bf90d800..61ddacaa8 100644 --- a/Source/WebKit/qt/WidgetSupport/QtFallbackWebPopup.cpp +++ b/Source/WebKit/qt/WidgetSupport/QtFallbackWebPopup.cpp @@ -128,7 +128,7 @@ void QtFallbackWebPopup::deleteComboBox() { if (!m_combo) return; - m_combo->deleteLater(); + m_combo->deleteComboBox(); m_combo = 0; } diff --git a/Source/WebKit/qt/WidgetSupport/QtWebComboBox.cpp b/Source/WebKit/qt/WidgetSupport/QtWebComboBox.cpp index 2c22cd476..4cfa366dc 100644 --- a/Source/WebKit/qt/WidgetSupport/QtWebComboBox.cpp +++ b/Source/WebKit/qt/WidgetSupport/QtWebComboBox.cpp @@ -31,7 +31,7 @@ namespace WebCore { QtWebComboBox::QtWebComboBox() - : QComboBox() + : QComboBox(), m_hiding(false), m_deleteAfterHiding(false) { // Install an event filter on the view inside the combo box popup to make sure we know // when the popup got closed. E.g. QComboBox::hidePopup() won't be called when the popup @@ -53,6 +53,25 @@ bool QtWebComboBox::eventFilter(QObject* watched, QEvent* event) return false; } +void QtWebComboBox::hidePopup() +{ + m_hiding = true; + // QComboBox::hidePopup() runs an eventloop, we need to make sure we do not delete ourselves in that loop. + QComboBox::hidePopup(); + m_hiding = false; + if (m_deleteAfterHiding) + deleteLater(); +} + + +void QtWebComboBox::deleteComboBox() +{ + if (!m_hiding) + deleteLater(); + else + m_deleteAfterHiding = true; } +} // namespace + #endif // QT_NO_COMBOBOX diff --git a/Source/WebKit/qt/WidgetSupport/QtWebComboBox.h b/Source/WebKit/qt/WidgetSupport/QtWebComboBox.h index e32427edf..90b617b3d 100644 --- a/Source/WebKit/qt/WidgetSupport/QtWebComboBox.h +++ b/Source/WebKit/qt/WidgetSupport/QtWebComboBox.h @@ -36,8 +36,15 @@ public: void showPopupAtCursorPosition(); virtual bool eventFilter(QObject* watched, QEvent*); + virtual void hidePopup() OVERRIDE; + void deleteComboBox(); + Q_SIGNALS: void didHide(); + +private: + bool m_hiding; + bool m_deleteAfterHiding; }; } diff --git a/Source/WebKit/qt/docs/qtwebkit.qdoc b/Source/WebKit/qt/docs/qtwebkit.qdoc index 5276f0170..f7dcfcb12 100644 --- a/Source/WebKit/qt/docs/qtwebkit.qdoc +++ b/Source/WebKit/qt/docs/qtwebkit.qdoc @@ -223,3 +223,13 @@ Boston, MA 02110-1301, USA. \endlegalese */ + +/*! + \externalpage http://www.w3.org/TR/selectors/ + \title Standard CSS selector +*/ + +/*! + \externalpage http://www.w3.org/TR/selectors-api/ + \title DOM Selectors API +*/ diff --git a/Source/WebKit/qt/docs/qwebview-url.png b/Source/WebKit/qt/docs/qwebview-url.png Binary files differnew file mode 100644 index 000000000..14b81948b --- /dev/null +++ b/Source/WebKit/qt/docs/qwebview-url.png diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp index 2f242c609..e053aa426 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp @@ -156,8 +156,7 @@ void QtPageClient::handleProxyAuthenticationRequiredRequest(const String& hostna void QtPageClient::setCursor(const WebCore::Cursor& cursor) { - // FIXME: This is a temporary fix until we get cursor support in QML items. - QGuiApplication::setOverrideCursor(*cursor.platformCursor()); + m_webView->setCursor(*cursor.platformCursor()); } void QtPageClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj index 2d1688b9b..c484361c0 100644 --- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj +++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 290F4275172A221C00939FF0 /* custom-protocol-sync-xhr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */; }; 290F4278172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 290F4276172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm */; }; 290F427B172A23A500939FF0 /* TestProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = 290F4279172A23A500939FF0 /* TestProtocol.mm */; }; + 291861FF17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm in Sources */ = {isa = PBXBuildFile; fileRef = 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */; }; 2943BE86161DFEB800999E3D /* UserContentTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2943BE84161DFEB800999E3D /* UserContentTest.mm */; }; 297234B4173AD04800983601 /* CustomProtocolsInvalidScheme.mm in Sources */ = {isa = PBXBuildFile; fileRef = 297234B2173AD04800983601 /* CustomProtocolsInvalidScheme.mm */; }; 297234B7173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 297234B5173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp */; }; @@ -342,6 +343,7 @@ 290F4276172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CustomProtocolsSyncXHRTest.mm; sourceTree = "<group>"; }; 290F4279172A23A500939FF0 /* TestProtocol.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestProtocol.mm; sourceTree = "<group>"; }; 290F427A172A23A500939FF0 /* TestProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestProtocol.h; sourceTree = "<group>"; }; + 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StopLoadingFromDidFinishLoading.mm; sourceTree = "<group>"; }; 2943BE84161DFEB800999E3D /* UserContentTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UserContentTest.mm; path = WebKit2ObjC/UserContentTest.mm; sourceTree = "<group>"; }; 297234B2173AD04800983601 /* CustomProtocolsInvalidScheme.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CustomProtocolsInvalidScheme.mm; path = WebKit2ObjC/CustomProtocolsInvalidScheme.mm; sourceTree = "<group>"; }; 297234B5173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomProtocolsInvalidScheme_Bundle.cpp; path = WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp; sourceTree = "<group>"; }; @@ -909,6 +911,8 @@ 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */, 52B8CF9515868CF000281053 /* SetDocumentURI.mm */, C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */, + 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */, + E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */, 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */, 37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */, E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */, @@ -917,7 +921,6 @@ 37E38C33169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm */, 1A7BFC0A171A0BDB00BC5F64 /* WillSendSubmitEvent.mm */, A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */, - E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */, ); path = mac; sourceTree = "<group>"; @@ -1080,6 +1083,7 @@ BC246D8E132F115A00B56D7C /* AboutBlankLoad.cpp in Sources */, 297234B4173AD04800983601 /* CustomProtocolsInvalidScheme.mm in Sources */, 379028B614FABD92007E6B43 /* AcceptsFirstMouse.mm in Sources */, + 291861FF17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm in Sources */, 26F1B44415CA434F00D1E4BF /* AtomicString.cpp in Sources */, B55F11A01516834F00915916 /* AttributedString.mm in Sources */, 00CD9F6315BE312C002DA2CE /* BackForwardList.mm in Sources */, diff --git a/Tools/qmake/mkspecs/features/features.prf b/Tools/qmake/mkspecs/features/features.prf index d45ea40cd..866e1c41b 100644 --- a/Tools/qmake/mkspecs/features/features.prf +++ b/Tools/qmake/mkspecs/features/features.prf @@ -135,8 +135,7 @@ defineTest(detectFeatures) { # Slider Touch is sensible to use when compiling WebKit2 enable?(touch_events): WEBKIT_CONFIG += touch_slider - # IndexedDB requires leveldb and leveldb currently requires posix - !posix:WEBKIT_CONFIG -= indexed_database + # IndexedDB requires leveldb enable?(indexed_database): WEBKIT_CONFIG += use_leveldb export(WEBKIT_CONFIG) |
