aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp8
-rw-r--r--src/qml/compiler/qv4compileddata.cpp5
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp5
-rw-r--r--src/qml/compiler/qv4ssa.cpp2
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h59
-rw-r--r--src/qml/doc/src/examples.qdoc36
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc8
-rw-r--r--src/qml/jit/qv4assembler.cpp182
-rw-r--r--src/qml/jit/qv4assembler_p.h4
-rw-r--r--src/qml/jit/qv4binop.cpp86
-rw-r--r--src/qml/jit/qv4binop_p.h98
-rw-r--r--src/qml/jit/qv4isel_masm.cpp171
-rw-r--r--src/qml/jit/qv4regalloc.cpp4
-rw-r--r--src/qml/jsapi/qjsvalue.cpp3
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4global_p.h8
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h5
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp3
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp1
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
-rw-r--r--src/qml/jsruntime/qv4string.cpp12
-rw-r--r--src/qml/jsruntime/qv4string_p.h6
-rw-r--r--src/qml/memory/qv4mm.cpp25
-rw-r--r--src/qml/memory/qv4mm_p.h24
-rw-r--r--src/qml/qml.pro2
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp2
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp15
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp9
-rw-r--r--src/qml/qml/qqmlcomponent.cpp15
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp2
-rw-r--r--src/qml/qml/qqmlengine.cpp31
-rw-r--r--src/qml/qml/qqmlerror.cpp72
-rw-r--r--src/qml/qml/qqmlerror.h3
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp10
-rw-r--r--src/qml/qml/qqmlinfo.cpp127
-rw-r--r--src/qml/qml/qqmlinfo.h16
-rw-r--r--src/qml/qml/qqmllist.cpp5
-rw-r--r--src/qml/qml/qqmlloggingcategory.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp13
-rw-r--r--src/qml/qml/qqmlplatform.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp2
-rw-r--r--src/qml/types/qqmlbind.cpp4
-rw-r--r--src/qml/types/qqmlconnections.cpp6
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp68
-rw-r--r--src/qml/types/qqmllistmodel.cpp50
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp6
48 files changed, 706 insertions, 522 deletions
diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp
index 457b702ac3..37cac846a0 100644
--- a/src/qml/compiler/qv4compilationunitmapper_win.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp
@@ -75,7 +75,6 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
CloseHandle(handle);
});
-#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900
CompiledData::Unit header;
DWORD bytesRead;
if (!ReadFile(handle, reinterpret_cast<char *>(&header), sizeof(header), &bytesRead, nullptr)) {
@@ -115,19 +114,12 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
}
return reinterpret_cast<CompiledData::Unit*>(dataPtr);
-#else
- Q_UNUSED(sourcePath);
- *errorString = QStringLiteral("Compilation unit mapping not supported on WinRT 8.1");
- return nullptr;
-#endif
}
void CompilationUnitMapper::close()
{
-#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900
if (dataPtr != nullptr)
UnmapViewOfFile(dataPtr);
-#endif
dataPtr = nullptr;
}
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 8586c84c3d..6aac111897 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -407,6 +407,11 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
+ if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
+ *errorString = QStringLiteral("QML source file has moved to a different location.");
+ return false;
+ }
+
{
const QString foundArchitecture = stringAt(data->architectureIndex);
const QString expectedArchitecture = QSysInfo::buildAbi();
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 1f5c22eb97..9dbebd1128 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -242,6 +242,11 @@ void InstructionSelection::run(int functionIndex)
addInstruction(set);
}
exceptionHandler = _block->catchBlock;
+ } else if (_block->catchBlock == nullptr && _block->index() != 0 && _block->in.isEmpty()) {
+ exceptionHandler = nullptr;
+ Instruction::SetExceptionHandler set;
+ set.offset = 0;
+ addInstruction(set);
}
for (IR::Stmt *s : _block->statements()) {
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 943700de44..1d512711b8 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2758,7 +2758,7 @@ public:
visit(s);
}
- foreach (const Conversion &conversion, _conversions) {
+ for (const Conversion &conversion : qAsConst(_conversions)) {
IR::Move *move = conversion.stmt->asMove();
// Note: isel only supports move into member when source is a temp, so convert
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 242f26ee0d..3a507bef74 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -149,40 +149,38 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef
Q_OBJECT
public:
- class BindingRefCount : public QQmlRefCount {
+ class FunctionRefCount : public QQmlRefCount {
public:
- BindingRefCount(QQmlBinding *binding):
- m_binding(binding)
+ FunctionRefCount(QV4::Function *function):
+ m_function(function)
{
- m_binding->ref.ref();
+ m_function->compilationUnit->addref();
}
- BindingRefCount(const BindingRefCount &other) :
- QQmlRefCount(other), m_binding(other.m_binding)
+ FunctionRefCount(const FunctionRefCount &other) :
+ QQmlRefCount(other), m_function(other.m_function)
{
- m_binding->ref.ref();
+ m_function->compilationUnit->addref();
}
- BindingRefCount &operator=(const BindingRefCount &other)
+ FunctionRefCount &operator=(const FunctionRefCount &other)
{
if (this != &other) {
QQmlRefCount::operator=(other);
- other.m_binding->ref.ref();
- if (!m_binding->ref.deref())
- delete m_binding;
- m_binding = other.m_binding;
+ other.m_function->compilationUnit->addref();
+ m_function->compilationUnit->release();
+ m_function = other.m_function;
}
return *this;
}
- ~BindingRefCount()
+ ~FunctionRefCount()
{
- if (!m_binding->ref.deref())
- delete m_binding;
+ m_function->compilationUnit->release();
}
private:
- QQmlBinding *m_binding;
+ QV4::Function *m_function;
};
struct Location {
@@ -199,14 +197,10 @@ public:
RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false)
{}
- RefLocation(QQmlBinding *binding, QV4::FunctionObject *function) :
+ RefLocation(QV4::Function *function) :
Location(function->sourceLocation()), locationType(Binding),
- ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
- {}
-
- RefLocation(QQmlBinding *binding, QV4::Function *function) :
- Location(function->sourceLocation()), locationType(Binding),
- ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
+ ref(new FunctionRefCount(function),
+ QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
{}
RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj,
@@ -236,16 +230,21 @@ public:
typedef QHash<quintptr, Location> LocationHash;
- void startBinding(QQmlBinding *binding, QV4::Function *function)
+ void startBinding(QV4::Function *function)
{
- quintptr locationId(id(binding));
+ // Use the QV4::Function as ID, as that is common among different instances of the same
+ // component. QQmlBinding is per instance.
+ // Add 1 to the ID, to make it different from the IDs the V4 profiler produces. The +1 makes
+ // the pointer point into the middle of the QV4::Function. Thus it still points to valid
+ // memory but we cannot accidentally create a duplicate key from another object.
+ quintptr locationId(id(function) + 1);
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), Binding,
locationId));
RefLocation &location = m_locations[locationId];
if (!location.isValid())
- location = RefLocation(binding, function);
+ location = RefLocation(function);
}
// Have toByteArrays() construct another RangeData event from the same QString later.
@@ -281,7 +280,8 @@ public:
Creating, id(obj)));
}
- void updateCreating(const QV4::CompiledData::Object *obj, QV4::CompiledData::CompilationUnit *ref,
+ void updateCreating(const QV4::CompiledData::Object *obj,
+ QV4::CompiledData::CompilationUnit *ref,
const QUrl &url, const QString &type)
{
quintptr locationId(id(obj));
@@ -330,12 +330,11 @@ struct QQmlProfilerHelper : public QQmlProfilerDefinitions {
};
struct QQmlBindingProfiler : public QQmlProfilerHelper {
- QQmlBindingProfiler(QQmlProfiler *profiler, QQmlBinding *binding,
- QV4::Function *function) :
+ QQmlBindingProfiler(QQmlProfiler *profiler, QV4::Function *function) :
QQmlProfilerHelper(profiler)
{
Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
- startBinding(binding, function));
+ startBinding(function));
}
~QQmlBindingProfiler()
diff --git a/src/qml/doc/src/examples.qdoc b/src/qml/doc/src/examples.qdoc
index f3550ae199..4f12d42f48 100644
--- a/src/qml/doc/src/examples.qdoc
+++ b/src/qml/doc/src/examples.qdoc
@@ -32,4 +32,40 @@
The list of examples demonstrating how to extend C++ to QML or the other way
around.
+
+\noautolist
+
+\table
+ \row
+ \li \l {Extending QML - Adding Types Example}
+ \li Exporting C++ Classes
+ \row
+ \li \l {Extending QML - Object and List Property Types Example}
+ \li Exporting C++ Properties
+ \row
+ \li \l {Extending QML - Extension Objects Example}
+ \li Extension Objects
+ \row
+ \li \l {Extending QML - Inheritance and Coercion Example}
+ \li C++ Inheritance and Coercion
+ \row
+ \li \l {Extending QML - Methods Example}
+ \li Methods Support
+ \row
+ \li \l {Extending QML - Attached Properties Example}
+ \li Attached Properties
+ \row
+ \li \l {Extending QML - Signal Support Example}
+ \li Signal Support
+ \row
+ \li \l {Extending QML - Property Value Source Example}
+ \li Property Value Source
+ \row
+ \li \l {Extending QML - Default Property Example}
+ \li Default Property
+ \row
+ \li \l {Extending QML - Grouped Properties Example}
+ \li Grouped Properties
+\endtable
+
*/
diff --git a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
index 7fa271c2d9..5cfd80f8a0 100644
--- a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
@@ -48,12 +48,8 @@ Image {
}
\endqml
-Network transparency is supported throughout QML, for example:
-
-\list
-\li Fonts - the \c source property of FontLoader is a URL
-\li WebViews - the \c url property of WebView (obviously!)
-\endlist
+Network transparency is supported throughout QML, for example, both the FontLoader
+and Image elements support loading resources from a remote server.
Even QML types themselves can be on the network - if the \l {Prototyping with qmlscene} is used to load
\tt http://example.com/mystuff/Hello.qml and that content refers to a type "World", the engine
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index e1acc33f82..018396318e 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -52,6 +52,8 @@
#include <WTFStubs.h>
#include <iostream>
+#include <QBuffer>
+#include <QCoreApplication>
#if ENABLE(ASSEMBLER)
@@ -146,11 +148,11 @@ bool CompilationUnit::memoryMapCode(QString *errorString)
const Assembler::VoidType Assembler::Void;
-Assembler::Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator)
+Assembler::Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator)
: _function(function)
, _nextBlock(0)
, _executableAllocator(executableAllocator)
- , _isel(isel)
+ , _jsGenerator(jsGenerator)
{
_addrs.resize(_function->basicBlockCount());
_patches.resize(_function->basicBlockCount());
@@ -301,7 +303,7 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), Assembler::ScratchRegister);
loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, compilationUnit)), Assembler::ScratchRegister);
loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
- const int id = _isel->registerString(string);
+ const int id = _jsGenerator->registerString(string);
return Pointer(reg, id * sizeof(QV4::String*));
}
@@ -314,13 +316,13 @@ Assembler::Address Assembler::loadConstant(const Primitive &v, RegisterID baseRe
{
loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg);
loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg);
- const int index = _isel->jsUnitGenerator()->registerConstant(v.asReturnedValue());
+ const int index = _jsGenerator->registerConstant(v.asReturnedValue());
return Address(baseReg, index * sizeof(QV4::Value));
}
void Assembler::loadStringRef(RegisterID reg, const QString &string)
{
- const int id = _isel->registerString(string);
+ const int id = _jsGenerator->registerString(string);
move(TrustedImm32(id), reg);
}
@@ -496,4 +498,174 @@ void Assembler::setStackLayout(int maxArgCountForBuiltins, int regularRegistersT
_stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave));
}
+
+namespace {
+class QIODevicePrintStream: public FilePrintStream
+{
+ Q_DISABLE_COPY(QIODevicePrintStream)
+
+public:
+ explicit QIODevicePrintStream(QIODevice *dest)
+ : FilePrintStream(0)
+ , dest(dest)
+ , buf(4096, '0')
+ {
+ Q_ASSERT(dest);
+ }
+
+ ~QIODevicePrintStream()
+ {}
+
+ void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
+ {
+ const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
+ if (written > 0)
+ dest->write(buf.constData(), written);
+ memset(buf.data(), 0, qMin(written, buf.size()));
+ }
+
+ void flush()
+ {}
+
+private:
+ QIODevice *dest;
+ QByteArray buf;
+};
+} // anonymous namespace
+
+static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<void*, const char*>& functions)
+{
+ for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
+ it != end; ++it) {
+ const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
+ int idx = processedOutput.indexOf(ptrString);
+ if (idx < 0)
+ continue;
+ idx = processedOutput.lastIndexOf('\n', idx);
+ if (idx < 0)
+ continue;
+ processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; call ") + it.value());
+ }
+
+ qDebug("%s", processedOutput.constData());
+}
+
+#if defined(Q_OS_LINUX)
+static FILE *pmap;
+
+static void qt_closePmap()
+{
+ if (pmap) {
+ fclose(pmap);
+ pmap = 0;
+ }
+}
+
+#endif
+
+JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
+{
+ Label endOfCode = label();
+
+ {
+ for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
+ Q_ASSERT(target.isSet());
+ for (Jump jump : qAsConst(_patches.at(i)))
+ jump.linkTo(target, this);
+ }
+ }
+
+ JSC::JSGlobalData dummy(_executableAllocator);
+ JSC::LinkBuffer linkBuffer(dummy, this, 0);
+
+ for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
+ linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
+
+ // link exception handlers
+ for (Jump jump : qAsConst(exceptionPropagationJumps))
+ linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
+
+ {
+ for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
+ Q_ASSERT(target.isSet());
+ for (DataLabelPtr label : _labelPatches.at(i))
+ linkBuffer.patch(label, linkBuffer.locationOf(target));
+ }
+ }
+
+ *codeSize = linkBuffer.offsetOf(endOfCode);
+
+ QByteArray name;
+
+ JSC::MacroAssemblerCodeRef codeRef;
+
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
+ if (showCode) {
+ QHash<void*, const char*> functions;
+#ifndef QT_NO_DEBUG
+ for (CallInfo call : qAsConst(_callInfos))
+ functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
+#endif
+
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ WTF::setDataFile(new QIODevicePrintStream(&buf));
+
+ name = _function->name->toUtf8();
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
+ codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
+
+ WTF::setDataFile(stderr);
+ printDisassembledOutputWithCalls(buf.data(), functions);
+ } else {
+ codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+ }
+
+#if defined(Q_OS_LINUX)
+ // This implements writing of JIT'd addresses so that perf can find the
+ // symbol names.
+ //
+ // Perf expects the mapping to be in a certain place and have certain
+ // content, for more information, see:
+ // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
+ static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
+ static bool profileInitialized = false;
+ if (doProfile && !profileInitialized) {
+ profileInitialized = true;
+
+ char pname[PATH_MAX];
+ snprintf(pname, PATH_MAX - 1, "/tmp/perf-%lu.map",
+ (unsigned long)QCoreApplication::applicationPid());
+
+ pmap = fopen(pname, "w");
+ if (!pmap)
+ qWarning("QV4: Can't write %s, call stacks will not contain JavaScript function names", pname);
+
+ // make sure we clean up nicely
+ std::atexit(qt_closePmap);
+ }
+
+ if (pmap) {
+ // this may have been pre-populated, if QV4_SHOW_ASM was on
+ if (name.isEmpty()) {
+ name = _function->name->toUtf8();
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
+ }
+
+ fprintf(pmap, "%llx %x %.*s\n",
+ (long long unsigned int)codeRef.code().executableAddress(),
+ *codeSize,
+ name.length(),
+ name.constData());
+ fflush(pmap);
+ }
+#endif
+
+ return codeRef;
+}
+
#endif
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 94478cd9cd..de9c246ed6 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -111,7 +111,7 @@ class Assembler : public JSC::MacroAssembler, public TargetPlatform
Q_DISABLE_COPY(Assembler)
public:
- Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator);
+ Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator);
// Explicit type to allow distinguishing between
// pushing an address itself or the value it points
@@ -1092,7 +1092,7 @@ private:
IR::BasicBlock *_nextBlock;
QV4::ExecutableAllocator *_executableAllocator;
- InstructionSelection *_isel;
+ QV4::Compiler::JSUnitGenerator *_jsGenerator;
};
template <typename Result, typename Source>
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
index 9c535bb0bb..d2758c4a47 100644
--- a/src/qml/jit/qv4binop.cpp
+++ b/src/qml/jit/qv4binop.cpp
@@ -112,7 +112,7 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
return;
}
- Assembler::Jump done;
+ Jump done;
if (lhs->type != IR::StringType && rhs->type != IR::StringType)
done = genInlineBinop(lhs, rhs, target);
@@ -129,13 +129,13 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
RuntimeCall context(info.contextImplementation);
if (fallBack.isValid()) {
as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, fallBack,
- Assembler::PointerToValue(lhs),
- Assembler::PointerToValue(rhs));
+ PointerToValue(lhs),
+ PointerToValue(rhs));
} else if (context.isValid()) {
as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, context,
Assembler::EngineRegister,
- Assembler::PointerToValue(lhs),
- Assembler::PointerToValue(rhs));
+ PointerToValue(lhs),
+ PointerToValue(rhs));
} else {
Q_ASSERT(!"unreachable");
}
@@ -148,9 +148,9 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
{
IR::Temp *targetTemp = target->asTemp();
- Assembler::FPRegisterID targetReg;
+ FPRegisterID targetReg;
if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- targetReg = (Assembler::FPRegisterID) targetTemp->index;
+ targetReg = (FPRegisterID) targetTemp->index;
else
targetReg = Assembler::FPGpr0;
@@ -162,7 +162,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X + constant -> Y = X; Y += [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->addDouble(addr, targetReg);
break;
}
@@ -184,7 +184,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X * constant -> Y = X; Y *= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->mulDouble(addr, targetReg);
break;
}
@@ -203,7 +203,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X - constant -> Y = X; Y -= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->subDouble(addr, targetReg);
break;
}
@@ -231,7 +231,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X / constant -> Y = X; Y /= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->divDouble(addr, targetReg);
break;
}
@@ -258,9 +258,9 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
default: {
Q_ASSERT(target->type == IR::BoolType);
- Assembler::Jump trueCase = as->branchDouble(false, op, lhs, rhs);
+ Jump trueCase = as->branchDouble(false, op, lhs, rhs);
as->storeBool(false, target);
- Assembler::Jump done = as->jump();
+ Jump done = as->jump();
trueCase.link(as);
as->storeBool(true, target);
done.link(as);
@@ -305,13 +305,13 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
bool inplaceOpWithAddress = false;
IR::Temp *targetTemp = target->asTemp();
- Assembler::RegisterID targetReg = Assembler::ReturnValueRegister;
+ RegisterID targetReg = Assembler::ReturnValueRegister;
if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
IR::Temp *rhs = rightSource->asTemp();
if (!rhs || rhs->kind != IR::Temp::PhysicalRegister || rhs->index != targetTemp->index) {
// We try to load leftSource into the target's register, but we can't do that if
// the target register is the same as rightSource.
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
} else if (rhs && rhs->kind == IR::Temp::PhysicalRegister && targetTemp->index == rhs->index) {
// However, if the target register is the same as the rightSource register, we can flip
// the operands for certain operations.
@@ -323,7 +323,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpMul:
// X = Y op X -> X = X op Y (or rephrased: X op= Y (so an in-place operation))
std::swap(leftSource, rightSource);
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
break;
case IR::OpLShift:
@@ -368,7 +368,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
&& targetTemp->kind == IR::Temp::PhysicalRegister
&& targetTemp->index == rightSource->asTemp()->index) {
// X = Y - X -> Tmp = X; X = Y; X -= Tmp
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
as->move(targetReg, Assembler::ScratchRegister);
as->move(as->toInt32Register(leftSource, targetReg), targetReg);
as->sub32(Assembler::ScratchRegister, targetReg);
@@ -384,7 +384,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpURShift:
if (IR::Const *c = rightSource->asConst()) {
if ((QV4::Primitive::toUInt32(c->value) & 0x1f) == 0) {
- Assembler::RegisterID r = as->toInt32Register(leftSource, targetReg);
+ RegisterID r = as->toInt32Register(leftSource, targetReg);
as->storeInt32(r, target);
return true;
}
@@ -395,10 +395,10 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
break;
}
- Assembler::RegisterID l = as->toInt32Register(leftSource, targetReg);
+ RegisterID l = as->toInt32Register(leftSource, targetReg);
if (IR::Const *c = rightSource->asConst()) { // All cases of Y = X op Const
- Assembler::TrustedImm32 r(int(c->value));
- Assembler::TrustedImm32 ur(QV4::Primitive::toUInt32(c->value) & 0x1f);
+ TrustedImm32 r(int(c->value));
+ TrustedImm32 ur(QV4::Primitive::toUInt32(c->value) & 0x1f);
switch (op) {
case IR::OpBitAnd: as->and32(r, l, targetReg); break;
@@ -419,7 +419,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
return false;
}
} else if (inplaceOpWithAddress) { // All cases of X = X op [address-of-Y]
- Assembler::Pointer rhsAddr = as->loadAddress(Assembler::ScratchRegister, rightSource);
+ Pointer rhsAddr = as->loadAddress(Assembler::ScratchRegister, rightSource);
switch (op) {
case IR::OpBitAnd: as->and32(rhsAddr, targetReg); break;
case IR::OpBitOr: as->or32 (rhsAddr, targetReg); break;
@@ -433,7 +433,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
return false;
}
} else { // All cases of Z = X op Y
- Assembler::RegisterID r = as->toInt32Register(rightSource, Assembler::ScratchRegister);
+ RegisterID r = as->toInt32Register(rightSource, Assembler::ScratchRegister);
switch (op) {
case IR::OpBitAnd: as->and32(l, r, targetReg); break;
case IR::OpBitOr: as->or32 (l, r, targetReg); break;
@@ -452,10 +452,10 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
// Not all CPUs accept shifts over more than 31 bits, and some CPUs (like ARM) will do
// surprising stuff when shifting over 0 bits.
#define CHECK_RHS(op) { \
- as->and32(Assembler::TrustedImm32(0x1f), r, Assembler::ScratchRegister); \
- Assembler::Jump notZero = as->branch32(Assembler::NotEqual, Assembler::ScratchRegister, Assembler::TrustedImm32(0)); \
+ as->and32(TrustedImm32(0x1f), r, Assembler::ScratchRegister); \
+ Jump notZero = as->branch32(RelationalCondition::NotEqual, Assembler::ScratchRegister, TrustedImm32(0)); \
as->move(l, targetReg); \
- Assembler::Jump done = as->jump(); \
+ Jump done = as->jump(); \
notZero.link(as); \
op; \
done.link(as); \
@@ -493,7 +493,7 @@ static inline Assembler::FPRegisterID getFreeFPReg(IR::Expr *shouldNotOverlap, u
Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
{
- Assembler::Jump done;
+ Jump done;
// Try preventing a call for a few common binary operations. This is used in two cases:
// - no register allocation was performed (not available for the platform, or the IR was
@@ -505,10 +505,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
// register.
switch (op) {
case IR::OpAdd: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->addDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -520,10 +520,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpMul: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->mulDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -535,10 +535,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpSub: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->subDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -550,10 +550,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpDiv: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->divDouble(rReg, lReg);
as->storeDouble(lReg, target);
diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h
index 37601f54ba..3742e99e5a 100644
--- a/src/qml/jit/qv4binop_p.h
+++ b/src/qml/jit/qv4binop_p.h
@@ -67,13 +67,23 @@ struct Binop {
, op(operation)
{}
+ using Jump = Assembler::Jump;
+ using Address = Assembler::Address;
+ using RegisterID = Assembler::RegisterID;
+ using FPRegisterID = Assembler::FPRegisterID;
+ using TrustedImm32 = Assembler::TrustedImm32;
+ using ResultCondition = Assembler::ResultCondition;
+ using RelationalCondition = Assembler::RelationalCondition;
+ using Pointer = Assembler::Pointer;
+ using PointerToValue = Assembler::PointerToValue;
+
void generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
void doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
bool int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
- Assembler::Jump genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
+ Jump genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
- typedef Assembler::Jump (Binop::*MemRegOp)(Assembler::Address, Assembler::RegisterID);
- typedef Assembler::Jump (Binop::*ImmRegOp)(Assembler::TrustedImm32, Assembler::RegisterID);
+ typedef Jump (Binop::*MemRegOp)(Address, RegisterID);
+ typedef Jump (Binop::*ImmRegOp)(TrustedImm32, RegisterID);
struct OpInfo {
const char *name;
@@ -88,97 +98,97 @@ struct Binop {
static const OpInfo &operation(IR::AluOp operation)
{ return operations[operation]; }
- Assembler::Jump inline_add32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_add32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchAdd32(Assembler::Overflow, addr, reg);
+ return as->branchAdd32(ResultCondition::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchAdd32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchAdd32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_add32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_add32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchAdd32(Assembler::Overflow, imm, reg);
+ return as->branchAdd32(ResultCondition::Overflow, imm, reg);
}
- Assembler::Jump inline_sub32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_sub32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchSub32(Assembler::Overflow, addr, reg);
+ return as->branchSub32(ResultCondition::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchSub32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchSub32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_sub32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_sub32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchSub32(Assembler::Overflow, imm, reg);
+ return as->branchSub32(ResultCondition::Overflow, imm, reg);
}
- Assembler::Jump inline_mul32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_mul32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
return as->branchMul32(Assembler::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchMul32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchMul32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_mul32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_mul32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchMul32(Assembler::Overflow, imm, reg, reg);
+ return as->branchMul32(ResultCondition::Overflow, imm, reg, reg);
}
- Assembler::Jump inline_shl32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_shl32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->lshift32(Assembler::ScratchRegister, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shl32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_shl32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->lshift32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shr32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_shr32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->rshift32(Assembler::ScratchRegister, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shr32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_shr32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->rshift32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_ushr32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_ushr32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->urshift32(Assembler::ScratchRegister, reg);
- return as->branchTest32(Assembler::Signed, reg, reg);
+ return as->branchTest32(ResultCondition::Signed, reg, reg);
}
- Assembler::Jump inline_ushr32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_ushr32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->urshift32(imm, reg);
- return as->branchTest32(Assembler::Signed, reg, reg);
+ return as->branchTest32(ResultCondition::Signed, reg, reg);
}
- Assembler::Jump inline_and32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_and32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->and32(addr, reg);
@@ -186,16 +196,16 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->and32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_and32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_and32(TrustedImm32 imm, RegisterID reg)
{
as->and32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_or32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_or32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->or32(addr, reg);
@@ -203,16 +213,16 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->or32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_or32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_or32(TrustedImm32 imm, RegisterID reg)
{
as->or32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_xor32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_xor32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->xor32(addr, reg);
@@ -220,13 +230,13 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->xor32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_xor32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_xor32(TrustedImm32 imm, RegisterID reg)
{
as->xor32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index c5d612ae65..20752b5c34 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -68,175 +68,6 @@ using namespace QV4;
using namespace QV4::JIT;
-namespace {
-class QIODevicePrintStream: public FilePrintStream
-{
- Q_DISABLE_COPY(QIODevicePrintStream)
-
-public:
- explicit QIODevicePrintStream(QIODevice *dest)
- : FilePrintStream(0)
- , dest(dest)
- , buf(4096, '0')
- {
- Q_ASSERT(dest);
- }
-
- ~QIODevicePrintStream()
- {}
-
- void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
- {
- const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
- if (written > 0)
- dest->write(buf.constData(), written);
- memset(buf.data(), 0, qMin(written, buf.size()));
- }
-
- void flush()
- {}
-
-private:
- QIODevice *dest;
- QByteArray buf;
-};
-} // anonymous namespace
-
-static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<void*, const char*>& functions)
-{
- for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
- it != end; ++it) {
- const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
- int idx = processedOutput.indexOf(ptrString);
- if (idx < 0)
- continue;
- idx = processedOutput.lastIndexOf('\n', idx);
- if (idx < 0)
- continue;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; call ") + it.value());
- }
-
- qDebug("%s", processedOutput.constData());
-}
-
-#if defined(Q_OS_LINUX)
-static FILE *pmap;
-
-static void qt_closePmap()
-{
- if (pmap) {
- fclose(pmap);
- pmap = 0;
- }
-}
-
-#endif
-
-JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
-{
- Label endOfCode = label();
-
- {
- for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (Jump jump : qAsConst(_patches.at(i)))
- jump.linkTo(target, this);
- }
- }
-
- JSC::JSGlobalData dummy(_executableAllocator);
- JSC::LinkBuffer linkBuffer(dummy, this, 0);
-
- for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
- linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
-
- // link exception handlers
- for (Jump jump : qAsConst(exceptionPropagationJumps))
- linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
-
- {
- for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (DataLabelPtr label : _labelPatches.at(i))
- linkBuffer.patch(label, linkBuffer.locationOf(target));
- }
- }
-
- *codeSize = linkBuffer.offsetOf(endOfCode);
-
- QByteArray name;
-
- JSC::MacroAssemblerCodeRef codeRef;
-
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
- if (showCode) {
- QHash<void*, const char*> functions;
-#ifndef QT_NO_DEBUG
- for (CallInfo call : qAsConst(_callInfos))
- functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
-#endif
-
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- WTF::setDataFile(new QIODevicePrintStream(&buf));
-
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
-
- WTF::setDataFile(stderr);
- printDisassembledOutputWithCalls(buf.data(), functions);
- } else {
- codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
- }
-
-#if defined(Q_OS_LINUX)
- // This implements writing of JIT'd addresses so that perf can find the
- // symbol names.
- //
- // Perf expects the mapping to be in a certain place and have certain
- // content, for more information, see:
- // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
- static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
- static bool profileInitialized = false;
- if (doProfile && !profileInitialized) {
- profileInitialized = true;
-
- char pname[PATH_MAX];
- snprintf(pname, PATH_MAX - 1, "/tmp/perf-%lu.map",
- (unsigned long)QCoreApplication::applicationPid());
-
- pmap = fopen(pname, "w");
- if (!pmap)
- qWarning("QV4: Can't write %s, call stacks will not contain JavaScript function names", pname);
-
- // make sure we clean up nicely
- std::atexit(qt_closePmap);
- }
-
- if (pmap) {
- // this may have been pre-populated, if QV4_SHOW_ASM was on
- if (name.isEmpty()) {
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- }
-
- fprintf(pmap, "%llx %x %.*s\n",
- (long long unsigned int)codeRef.code().executableAddress(),
- *codeSize,
- name.length(),
- name.constData());
- fflush(pmap);
- }
-#endif
-
- return codeRef;
-}
-
InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
: EvalInstructionSelection(execAllocator, module, jsGenerator, iselFactory)
, _block(0)
@@ -278,7 +109,7 @@ void InstructionSelection::run(int functionIndex)
qSwap(_removableJumps, removableJumps);
Assembler* oldAssembler = _as;
- _as = new Assembler(this, _function, executableAllocator);
+ _as = new Assembler(jsGenerator, _function, executableAllocator);
_as->setStackLayout(6, // 6 == max argc for calls to built-ins with an argument array
regularRegistersToSave.size(),
fpRegistersToSave.size());
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 63d542b5c8..3fb0815299 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -1087,12 +1087,12 @@ private:
if (_info->def(it->temp()) != successorStart && !it->isSplitFromInterval()) {
const int successorEnd = successor->terminator()->id();
const int idx = successor->in.indexOf(predecessor);
- foreach (const Use &use, _info->uses(it->temp())) {
+ for (const Use &use : _info->uses(it->temp)) {
if (use.pos == static_cast<unsigned>(successorStart)) {
// only check the current edge, not all other possible ones. This is
// important for phi nodes: they have uses that are only valid when
// coming in over a specific edge.
- foreach (Stmt *s, successor->statements()) {
+ for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
Q_ASSERT(it->temp().index != phi->targetTemp->index);
Q_ASSERT(phi->d->incoming[idx]->asTemp() == 0
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index b473e96286..bab2e633a7 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -73,7 +73,8 @@
For the object-based types (including Date and RegExp), use the
newT() functions in QJSEngine (e.g. QJSEngine::newObject())
to create a QJSValue of the desired type. For the primitive types,
- use one of the QJSValue constructor overloads.
+ use one of the QJSValue constructor overloads. For other types, e.g.
+ registered gadget types such as QPoint, you can use QJSEngine::toScriptValue.
The methods named isT() (e.g. isBool(), isUndefined()) can be
used to test if a value is of a certain type. The methods named
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8f2c5174da..a11f7f0875 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -158,8 +158,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
}
Q_ASSERT(maxCallDepth > 0);
- MemoryManager::GCBlocker gcBlocker(memoryManager);
-
if (!factory) {
#if QT_CONFIG(qml_interpreter)
bool jitDisabled = true;
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index c37ad1668d..1dbc538be2 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -97,19 +97,19 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
//
// NOTE: This should match the logic in qv4targetplatform_p.h!
-#if defined(Q_PROCESSOR_X86) && !defined(__ILP32__) \
+#if defined(Q_PROCESSOR_X86) && (QT_POINTER_SIZE == 4) \
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_X86_64) && !defined(__ILP32__) \
+#elif defined(Q_PROCESSOR_X86_64) && (QT_POINTER_SIZE == 8) \
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_ARM_32)
+#elif defined(Q_PROCESSOR_ARM_32) && (QT_POINTER_SIZE == 4)
# if defined(thumb2) || defined(__thumb2__) || ((defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4)
# define V4_ENABLE_JIT
# elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2 // clang 3.5 and later will set this if the core supports the Thumb-2 ISA.
# define V4_ENABLE_JIT
# endif
-#elif defined(Q_PROCESSOR_ARM_64)
+#elif defined(Q_PROCESSOR_ARM_64) && (QT_POINTER_SIZE == 8)
# if defined(Q_OS_LINUX)
# define V4_ENABLE_JIT
# endif
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index d27e853343..f75ac4d33a 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -158,12 +158,11 @@ public:
FunctionCall &operator=(const FunctionCall &other) {
if (&other != this) {
- if (m_function)
- m_function->compilationUnit->release();
+ other.m_function->compilationUnit->addref();
+ m_function->compilationUnit->release();
m_function = other.m_function;
m_start = other.m_start;
m_end = other.m_end;
- m_function->compilationUnit->addref();
}
return *this;
}
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 218695624b..41d8010fef 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -307,7 +307,8 @@ void RegExpCtor::markObjects(Heap::Base *that, ExecutionEngine *e)
{
RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
This->lastMatch.mark(e);
- This->lastInput->mark(e);
+ if (This->lastInput)
+ This->lastInput->mark(e);
FunctionObject::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index d6c55926b1..023a739e33 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -499,6 +499,7 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val
{
Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
+ Q_ASSERT(!prim->isManaged() || prim->isString());
return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index b54177bee9..62145f36cc 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -88,8 +88,6 @@ void Script::parse()
ExecutionEngine *v4 = scope->engine();
Scope valueScope(v4);
- MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
-
IR::Module module(v4->debugger() != 0);
QQmlJS::Engine ee, *engine = &ee;
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 1efd8cb714..cde2131aab 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -102,6 +102,7 @@ void Heap::String::init(MemoryManager *mm, String *l, String *r)
stringHash = UINT_MAX;
largestSubLength = qMax(l->largestSubLength, r->largestSubLength);
len = l->len + r->len;
+ Q_ASSERT(largestSubLength <= len);
if (!l->largestSubLength && l->len > largestSubLength)
largestSubLength = l->len;
@@ -113,6 +114,15 @@ void Heap::String::init(MemoryManager *mm, String *l, String *r)
simplifyString();
}
+void Heap::String::destroy() {
+ if (!largestSubLength) {
+ mm->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
+ if (!text->ref.deref())
+ QStringData::deallocate(text);
+ }
+ Base::destroy();
+}
+
uint String::toUInt(bool *ok) const
{
*ok = true;
@@ -151,7 +161,7 @@ void Heap::String::simplifyString() const
text->ref.ref();
identifier = 0;
largestSubLength = 0;
- mm->growUnmanagedHeapSizeUsage(size_t(text->size) * sizeof(QChar));
+ mm->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
}
void Heap::String::append(const String *data, QChar *ch)
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 4890a85724..5b0fd292d6 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -73,11 +73,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
#ifndef V4_BOOTSTRAP
void init(MemoryManager *mm, const QString &text);
void init(MemoryManager *mm, String *l, String *n);
- void destroy() {
- if (!largestSubLength && !text->ref.deref())
- QStringData::deallocate(text);
- Base::destroy();
- }
+ void destroy();
void simplifyString() const;
int length() const {
Q_ASSERT((largestSubLength &&
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 606d3ec162..51eb82059a 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -194,10 +194,8 @@ struct MemoryManager::Data
namespace {
-bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine, std::size_t *unmanagedHeapSize)
+bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine)
{
- Q_ASSERT(unmanagedHeapSize);
-
bool isEmpty = true;
Heap::Base *tail = &header->freeItems;
// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4);
@@ -222,13 +220,6 @@ bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, Exec
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
- if (std::size_t(header->itemSize) == MemoryManager::align(sizeof(Heap::String)) && m->vtable()->isString) {
- std::size_t heapBytes = static_cast<Heap::String *>(m)->retainedTextSize();
- Q_ASSERT(*unmanagedHeapSize >= heapBytes);
-// qDebug() << "-- it's a string holding on to" << heapBytes << "bytes";
- *unmanagedHeapSize -= heapBytes;
- }
-
if (m->vtable()->destroy) {
m->vtable()->destroy(m);
m->_checkIsDestroyed();
@@ -502,7 +493,7 @@ void MemoryManager::sweep(bool lastSweep)
for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base());
- chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine, &m_d->unmanagedHeapSize);
+ chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine);
}
std::vector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin();
@@ -565,16 +556,6 @@ void MemoryManager::sweep(bool lastSweep)
}
}
-bool MemoryManager::isGCBlocked() const
-{
- return m_d->gcBlocked;
-}
-
-void MemoryManager::setGCBlocked(bool blockGC)
-{
- m_d->gcBlocked = blockGC;
-}
-
void MemoryManager::runGC()
{
if (m_d->gcBlocked) {
@@ -652,7 +633,7 @@ size_t MemoryManager::getLargeItemsMem() const
return total;
}
-void MemoryManager::growUnmanagedHeapSizeUsage(size_t delta)
+void MemoryManager::changeUnmanagedHeapSizeUsage(qptrdiff delta)
{
m_d->unmanagedHeapSize += delta;
}
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index dfa0d85dff..e6417cb2e0 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -76,26 +76,6 @@ class Q_QML_EXPORT MemoryManager
public:
struct Data;
- class GCBlocker
- {
- public:
- GCBlocker(MemoryManager *mm)
- : mm(mm)
- , wasBlocked(mm->isGCBlocked())
- {
- mm->setGCBlocked(true);
- }
-
- ~GCBlocker()
- {
- mm->setGCBlocked(wasBlocked);
- }
-
- private:
- MemoryManager *mm;
- bool wasBlocked;
- };
-
public:
MemoryManager(ExecutionEngine *engine);
~MemoryManager();
@@ -309,8 +289,6 @@ public:
return t->d();
}
- bool isGCBlocked() const;
- void setGCBlocked(bool blockGC);
void runGC();
void dumpStats() const;
@@ -319,7 +297,7 @@ public:
size_t getAllocatedMem() const;
size_t getLargeItemsMem() const;
- void growUnmanagedHeapSizeUsage(size_t delta); // called when a JS object grows itself. Specifically: Heap::String::append
+ void changeUnmanagedHeapSizeUsage(qptrdiff delta); // called when a JS object grows itself. Specifically: Heap::String::append
protected:
/// expects size to be aligned
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 826a074701..8f9e4b7f83 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -14,6 +14,8 @@ solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
# Ensure this gcc optimization is switched off for mips platforms to avoid trouble with JIT.
gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
+DEFINES += QT_NO_FOREACH
+
exists("qqml_enable_gcov") {
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
LIBS_PRIVATE += -lgcov
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index 39d609454f..b1c320afd4 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -191,7 +191,7 @@ void QQmlAbstractBinding::removeFromObject()
void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop)
{
- qmlInfo(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
+ qmlWarning(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
}
QString QQmlAbstractBinding::expression() const
diff --git a/src/qml/qml/qqmlabstracturlinterceptor.h b/src/qml/qml/qqmlabstracturlinterceptor.h
index dfb8a46027..665b37fb3a 100644
--- a/src/qml/qml/qqmlabstracturlinterceptor.h
+++ b/src/qml/qml/qqmlabstracturlinterceptor.h
@@ -47,7 +47,6 @@ QT_BEGIN_NAMESPACE
class Q_QML_EXPORT QQmlAbstractUrlInterceptor
{
- Q_FLAGS(InterceptionPoint)
public:
enum DataType { //Matches QQmlDataBlob::Type
QmlFile = 0,
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 8a97b7eba7..2a96d96302 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -190,9 +190,14 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
/*!
\fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url)
- This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object.
- Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the
- QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath).
+ This signal is emitted when an object finishes loading. If loading was
+ successful, \a object contains a pointer to the loaded object, otherwise
+ the pointer is NULL.
+
+ The \a url to the component the \a object came from is also provided.
+
+ \note If the path to the component was provided as a QString containing a
+ relative path, the \a url will contain a fully resolved path to the file.
*/
/*!
@@ -226,7 +231,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent)
This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards.
*/
QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent)
- : QQmlApplicationEngine(QUrl::fromLocalFile(filePath), parent)
+ : QQmlApplicationEngine(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile), parent)
{
}
@@ -265,7 +270,7 @@ void QQmlApplicationEngine::load(const QUrl &url)
void QQmlApplicationEngine::load(const QString &filePath)
{
Q_D(QQmlApplicationEngine);
- d->startLoad(QUrl::fromLocalFile(filePath));
+ d->startLoad(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile));
}
/*!
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 284ae1f36f..62288a5845 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -163,7 +163,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
- QQmlBindingProfiler prof(ep->profiler, this, function());
+ QQmlBindingProfiler prof(ep->profiler, function());
doUpdate(watcher, flags, scope);
if (!watcher.wasDeleted())
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 254d5e1907..4fbd828307 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -91,7 +91,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
function += QQmlPropertyCache::signalParameterStringForJS(v4, signal.parameterNames(), &error);
if (!error.isEmpty()) {
- qmlInfo(scopeObject()) << error;
+ qmlWarning(scopeObject()) << error;
return;
}
} else
@@ -129,7 +129,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
QString error;
QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, &error);
if (!error.isEmpty()) {
- qmlInfo(scopeObject()) << error;
+ qmlWarning(scopeObject()) << error;
return;
}
runtimeFunction->updateInternalClass(engine, signalParameters);
@@ -199,7 +199,10 @@ void QQmlBoundSignalExpression::evaluate(void **a)
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == qMetaTypeId<QJSValue>()) {
- callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
+ if (QV4::Value *v4Value = QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1])))
+ callData->args[ii] = *v4Value;
+ else
+ callData->args[ii] = QV4::Encode::undefined();
} else if (type == QMetaType::QVariant) {
callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 6ebcd142fb..50ed58e63d 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -47,8 +47,6 @@
#include "qqml.h"
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
-#include <private/qqmldebugconnector_p.h>
-#include <private/qqmldebugserviceinterfaces_p.h>
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
#include <private/qqmljavascriptexpression_p.h>
@@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
depthIncreased = false;
}
- if (rv) {
- if (QQmlEngineDebugService *service =
- QQmlDebugConnector::service<QQmlEngineDebugService>()) {
- if (!context->isInternal)
- context->asQQmlContextPrivate()->instances.append(rv);
- service->objectCreated(engine, rv);
- }
- }
-
return rv;
}
@@ -1244,7 +1233,7 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
- qmlInfo(this) << tr("createObject: value is not an object");
+ qmlWarning(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -1361,7 +1350,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[1]);
if (v->isNull()) {
} else if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
- qmlInfo(this) << tr("createObject: value is not an object");
+ qmlWarning(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
} else {
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 85c91a592a..0b0bbef795 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE
by \a data, which is a block of data previously returned by a call
to compile().
- Errors should be reported using qmlInfo(object).
+ Errors should be reported using qmlWarning(object).
The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
*/
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index c2915c840b..e1fa97b52f 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -436,7 +436,6 @@ The following functions are also on the Qt object.
\list
\li \c "android" - Android
- \li \c "blackberry" - BlackBerry OS
\li \c "ios" - iOS
\li \c "tvos" - tvOS
\li \c "linux" - Linux
@@ -444,7 +443,6 @@ The following functions are also on the Qt object.
\li \c "unix" - Other Unix-based OS
\li \c "windows" - Windows
\li \c "winrt" - WinRT / UWP
- \li \c "winphone" - Windows Phone
\endlist
\endtable
*/
@@ -1914,9 +1912,29 @@ void QQmlEnginePrivate::sendExit(int retCode)
static void dumpwarning(const QQmlError &error)
{
- QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).warning().nospace()
- << qPrintable(error.toString());
+ switch (error.messageType()) {
+ case QtDebugMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).debug().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtInfoMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).info().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtWarningMsg:
+ case QtFatalMsg: // fatal does not support streaming, and furthermore, is actually fatal. Probably not desirable for QML.
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).warning().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtCriticalMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).critical().nospace()
+ << qPrintable(error.toString());
+ break;
+ }
}
static void dumpwarning(const QList<QQmlError> &errors)
@@ -2129,8 +2147,7 @@ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList
Returns the directory where SQL and other offline
storage is placed.
- QQuickWebView and the SQL databases created with openDatabase()
- are stored here.
+ The SQL databases created with openDatabase() are stored here.
The default is QML/OfflineStorage in the platform-standard
user application data directory.
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 0a6c7b4960..7a1e02eec6 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -85,11 +85,12 @@ public:
QString description;
quint16 line;
quint16 column;
+ QtMsgType messageType;
QObject *object;
};
QQmlErrorPrivate::QQmlErrorPrivate()
-: line(0), column(0), object()
+: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object()
{
}
@@ -119,12 +120,14 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
delete d;
d = 0;
} else {
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->url = other.d->url;
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
d->object = other.d->object;
+ d->messageType = other.d->messageType;
}
return *this;
}
@@ -150,8 +153,9 @@ bool QQmlError::isValid() const
*/
QUrl QQmlError::url() const
{
- if (d) return d->url;
- else return QUrl();
+ if (d)
+ return d->url;
+ return QUrl();
}
/*!
@@ -159,7 +163,8 @@ QUrl QQmlError::url() const
*/
void QQmlError::setUrl(const QUrl &url)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->url = url;
}
@@ -168,8 +173,9 @@ void QQmlError::setUrl(const QUrl &url)
*/
QString QQmlError::description() const
{
- if (d) return d->description;
- else return QString();
+ if (d)
+ return d->description;
+ return QString();
}
/*!
@@ -177,7 +183,8 @@ QString QQmlError::description() const
*/
void QQmlError::setDescription(const QString &description)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->description = description;
}
@@ -186,8 +193,9 @@ void QQmlError::setDescription(const QString &description)
*/
int QQmlError::line() const
{
- if (d) return qmlSourceCoordinate(d->line);
- else return -1;
+ if (d)
+ return qmlSourceCoordinate(d->line);
+ return -1;
}
/*!
@@ -195,7 +203,8 @@ int QQmlError::line() const
*/
void QQmlError::setLine(int line)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->line = qmlSourceCoordinate(line);
}
@@ -204,8 +213,9 @@ void QQmlError::setLine(int line)
*/
int QQmlError::column() const
{
- if (d) return qmlSourceCoordinate(d->column);
- else return -1;
+ if (d)
+ return qmlSourceCoordinate(d->column);
+ return -1;
}
/*!
@@ -213,7 +223,8 @@ int QQmlError::column() const
*/
void QQmlError::setColumn(int column)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->column = qmlSourceCoordinate(column);
}
@@ -225,8 +236,9 @@ void QQmlError::setColumn(int column)
*/
QObject *QQmlError::object() const
{
- if (d) return d->object;
- else return 0;
+ if (d)
+ return d->object;
+ return 0;
}
/*!
@@ -234,11 +246,37 @@ QObject *QQmlError::object() const
*/
void QQmlError::setObject(QObject *object)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->object = object;
}
/*!
+ \since 5.9
+
+ Returns the message type.
+ */
+QtMsgType QQmlError::messageType() const
+{
+ if (d)
+ return d->messageType;
+ return QtMsgType::QtWarningMsg;
+}
+
+/*!
+ \since 5.9
+
+ Sets the \a messageType for this message. The message type determines which
+ QDebug handlers are responsible for recieving the message.
+ */
+void QQmlError::setMessageType(QtMsgType messageType)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->messageType = messageType;
+}
+
+/*!
Returns the error as a human readable string.
*/
QString QQmlError::toString() const
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index e4c42223cf..ef529e3828 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -47,6 +47,7 @@
QT_BEGIN_NAMESPACE
+// ### Qt 6: should this be called QQmlMessage, since it can have a message type?
class QDebug;
class QQmlErrorPrivate;
class Q_QML_EXPORT QQmlError
@@ -69,6 +70,8 @@ public:
void setColumn(int);
QObject *object() const;
void setObject(QObject *);
+ QtMsgType messageType() const;
+ void setMessageType(QtMsgType messageType);
QString toString() const;
private:
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index ca19691e93..097fa71200 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -117,4 +117,14 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
Q_UNUSED(uri);
}
+/*!
+ \class QQmlExtensionInterface
+ \internal
+ \inmodule QtQml
+
+ \class QQmlTypesExtensionInterface
+ \internal
+ \inmodule QtQml
+*/
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 5b6e02d5b1..dae15e2eca 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -50,13 +50,45 @@
QT_BEGIN_NAMESPACE
/*!
+ \fn QQmlInfo QtQml::qmlDebug(const QObject *object)
+ \relates QQmlEngine
+ \since 5.9
+
+ Prints debug messages that include the file and line number for the
+ specified QML \a object.
+
+ When QML types produce logging messages, it improves traceability
+ if they include the QML file and line number on which the
+ particular instance was instantiated.
+
+ To include the file and line number, an object must be passed. If
+ the file and line number is not available for that instance
+ (either it was not instantiated by the QML engine or location
+ information is disabled), "unknown location" will be used instead.
+
+ For example,
+
+ \code
+ qmlDebug(object) << "Internal state: 42";
+ \endcode
+
+ prints
+
+ \code
+ QML MyCustomType (unknown location): Internal state: 42
+ \endcode
+
+ \sa QtQml::qmlInfo, QtQml::qmlWarning
+*/
+
+/*!
\fn QQmlInfo QtQml::qmlInfo(const QObject *object)
\relates QQmlEngine
- Prints warning messages that include the file and line number for the
+ Prints informational messages that include the file and line number for the
specified QML \a object.
- When QML types display warning messages, it improves traceability
+ When QML types produce logging messages, it improves traceability
if they include the QML file and line number on which the
particular instance was instantiated.
@@ -76,14 +108,58 @@ QT_BEGIN_NAMESPACE
\code
QML MyCustomType (unknown location): component property is a write-once property
\endcode
+
+ \note In versions prior to Qt 5.9, qmlInfo reported messages using a warning
+ QtMsgType. For Qt 5.9 and above, qmlInfo uses an info QtMsgType. To send
+ warnings, use qmlWarning.
+
+ \sa QtQml::qmlDebug, QtQml::qmlWarning
+*/
+
+
+/*!
+ \fn QQmlInfo QtQml::qmlWarning(const QObject *object)
+ \relates QQmlEngine
+ \since 5.9
+
+ Prints warning messages that include the file and line number for the
+ specified QML \a object.
+
+ When QML types produce logging messages, it improves traceability
+ if they include the QML file and line number on which the
+ particular instance was instantiated.
+
+ To include the file and line number, an object must be passed. If
+ the file and line number is not available for that instance
+ (either it was not instantiated by the QML engine or location
+ information is disabled), "unknown location" will be used instead.
+
+ For example,
+
+ \code
+ qmlInfo(object) << tr("property cannot be set to 0");
+ \endcode
+
+ prints
+
+ \code
+ QML MyCustomType (unknown location): property cannot be set to 0
+ \endcode
+
+ \sa QtQml::qmlDebug, QtQml::qmlInfo
*/
class QQmlInfoPrivate
{
public:
- QQmlInfoPrivate() : ref (1), object(0) {}
+ QQmlInfoPrivate(QtMsgType type)
+ : ref (1)
+ , msgType(type)
+ , object(nullptr)
+ {}
int ref;
+ QtMsgType msgType;
const QObject *object;
QString buffer;
QList<QQmlError> errors;
@@ -110,6 +186,7 @@ QQmlInfo::~QQmlInfo()
if (!d->buffer.isEmpty()) {
QQmlError error;
+ error.setMessageType(d->msgType);
QObject *object = const_cast<QObject *>(d->object);
@@ -139,28 +216,32 @@ QQmlInfo::~QQmlInfo()
namespace QtQml {
-QQmlInfo qmlInfo(const QObject *me)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- return QQmlInfo(d);
-}
+#define MESSAGE_FUNCS(FuncName, MessageLevel) \
+ QQmlInfo FuncName(const QObject *me) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ return QQmlInfo(d); \
+ } \
+ QQmlInfo FuncName(const QObject *me, const QQmlError &error) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ d->errors << error; \
+ return QQmlInfo(d); \
+ } \
+ QQmlInfo FuncName(const QObject *me, const QList<QQmlError> &errors) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ d->errors = errors; \
+ return QQmlInfo(d); \
+ }
-QQmlInfo qmlInfo(const QObject *me, const QQmlError &error)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- d->errors << error;
- return QQmlInfo(d);
-}
+MESSAGE_FUNCS(qmlDebug, QtMsgType::QtDebugMsg)
+MESSAGE_FUNCS(qmlInfo, QtMsgType::QtInfoMsg)
+MESSAGE_FUNCS(qmlWarning, QtMsgType::QtWarningMsg)
-QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- d->errors = errors;
- return QQmlInfo(d);
-}
} // namespace QtQml
diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h
index ab0281a688..673125632e 100644
--- a/src/qml/qml/qqmlinfo.h
+++ b/src/qml/qml/qqmlinfo.h
@@ -48,11 +48,19 @@ QT_BEGIN_NAMESPACE
class QQmlInfo;
+// declared in namespace to avoid symbol conflicts with QtDeclarative
namespace QtQml {
- // declared in namespace to avoid symbol conflicts with QtDeclarative
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me);
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QQmlError &error);
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QList<QQmlError> &errors);
+
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me);
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error);
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me);
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QQmlError &error);
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QList<QQmlError> &errors);
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wheader-hygiene")
@@ -93,9 +101,15 @@ public:
#endif
private:
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QQmlError &error);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QList<QQmlError> &errors);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QQmlError &error);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QQmlError &error);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QList<QQmlError> &errors);
QQmlInfo(QQmlInfoPrivate *);
QQmlInfoPrivate *d;
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index a719956483..edd93ef03d 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -335,7 +335,7 @@ int QQmlListReference::count() const
\since 5.0
\inmodule QtQml
\brief The QQmlListProperty class allows applications to expose list-like
-properties to QML.
+properties of QObject-derived classes to QML.
QML has many list properties, where more than one object value can be assigned.
The use of a list property from QML looks like this:
@@ -369,7 +369,8 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th
The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
-\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
+\sa {Extending QML - Object and List Property Types Example}
+
*/
/*!
diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp
index 70e59db07b..764b874131 100644
--- a/src/qml/qml/qqmlloggingcategory.cpp
+++ b/src/qml/qml/qqmlloggingcategory.cpp
@@ -112,13 +112,13 @@ void QQmlLoggingCategory::componentComplete()
{
m_initialized = true;
if (m_name.isNull())
- qmlInfo(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !");
+ qmlWarning(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !");
}
void QQmlLoggingCategory::setName(const QString &name)
{
if (m_initialized) {
- qmlInfo(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created");
+ qmlWarning(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created");
return;
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 2e2a3fb303..09936f6e7a 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -53,6 +53,8 @@
#include <private/qqmlscriptstring_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
#include <private/qqmlvaluetypeproxybinding_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
QT_USE_NAMESPACE
@@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
phase = ObjectsCreated;
+ if (instance) {
+ if (QQmlEngineDebugService *service
+ = QQmlDebugConnector::service<QQmlEngineDebugService>()) {
+ if (!parentContext->isInternal)
+ parentContext->asQQmlContextPrivate()->instances.append(instance);
+ service->objectCreated(engine, instance);
+ } else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) {
+ parentContext->asQQmlContextPrivate()->instances.append(instance);
+ }
+ }
+
return instance;
}
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index a47a0ab4a4..64ca208f1b 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -59,16 +59,12 @@ QString QQmlPlatform::os()
{
#if defined(Q_OS_ANDROID)
return QStringLiteral("android");
-#elif defined(Q_OS_BLACKBERRY)
- return QStringLiteral("blackberry");
#elif defined(Q_OS_IOS)
return QStringLiteral("ios");
#elif defined(Q_OS_TVOS)
return QStringLiteral("tvos");
#elif defined(Q_OS_MAC)
return QStringLiteral("osx");
-#elif defined(Q_OS_WINPHONE)
- return QStringLiteral("winphone");
#elif defined(Q_OS_WINRT)
return QStringLiteral("winrt");
#elif defined(Q_OS_WIN)
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 76ac15e2f1..ac993a1037 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2428,7 +2428,7 @@ void QQmlTypeData::continueLoadFromIR()
QList<QQmlError> errors;
- foreach (const QV4::CompiledData::Import *import, m_document->imports) {
+ for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) {
if (!addImport(import, &errors)) {
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index a545fe57ca..2ded9c13c8 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -82,12 +82,12 @@ void QQmlBindPrivate::validate(QObject *binding) const
return;
if (!prop.isValid()) {
- qmlInfo(binding) << "Property '" << propName << "' does not exist on " << QQmlMetaType::prettyTypeName(obj) << ".";
+ qmlWarning(binding) << "Property '" << propName << "' does not exist on " << QQmlMetaType::prettyTypeName(obj) << ".";
return;
}
if (!prop.isWritable()) {
- qmlInfo(binding) << "Property '" << propName << "' on " << QQmlMetaType::prettyTypeName(obj) << " is read-only.";
+ qmlWarning(binding) << "Property '" << propName << "' on " << QQmlMetaType::prettyTypeName(obj) << " is read-only.";
return;
}
}
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 2aed4d9972..870aeaa6e2 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -168,7 +168,7 @@ void QQmlConnections::setTarget(QObject *obj)
if (d->targetSet && d->target == obj)
return;
d->targetSet = true; // even if setting to 0, it is *set*
- foreach (QQmlBoundSignal *s, d->boundsignals) {
+ for (QQmlBoundSignal *s : qAsConst(d->boundsignals)) {
// It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater().
if (s->isNotifying())
@@ -278,7 +278,7 @@ void QQmlConnections::connectSignals()
QQmlContextData *ctxtdata = ddata ? ddata->outerContext : 0;
const QV4::CompiledData::Unit *qmlUnit = d->compilationUnit->data;
- foreach (const QV4::CompiledData::Binding *binding, d->bindings) {
+ for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
QString propName = qmlUnit->stringAt(binding->propertyNameIndex);
@@ -295,7 +295,7 @@ void QQmlConnections::connectSignals()
d->boundsignals += signal;
} else {
if (!d->ignoreUnknownSignals)
- qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName);
+ qmlWarning(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName);
}
}
}
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index be10b270ae..c0d75cae33 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -264,7 +264,7 @@ QQmlDelegateModel::~QQmlDelegateModel()
{
Q_D(QQmlDelegateModel);
- foreach (QQmlDelegateModelItem *cacheItem, d->m_cache) {
+ for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) {
if (cacheItem->object) {
delete cacheItem->object;
@@ -310,7 +310,7 @@ void QQmlDelegateModel::componentComplete()
--d->m_groupCount;
--i;
} else if (name.at(0).isUpper()) {
- qmlInfo(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
+ qmlWarning(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
--d->m_groupCount;
--i;
@@ -404,7 +404,7 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
{
Q_D(QQmlDelegateModel);
if (d->m_transaction) {
- qmlInfo(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
+ qmlWarning(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
return;
}
bool wasValid = d->m_delegate != 0;
@@ -610,7 +610,7 @@ void QQmlDelegateModelPrivate::group_append(
if (d->m_complete)
return;
if (d->m_groupCount == Compositor::MaximumGroupCount) {
- qmlInfo(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
+ qmlWarning(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
return;
}
d->m_groups[d->m_groupCount] = group;
@@ -719,7 +719,7 @@ void QQmlDelegateModel::setFilterGroup(const QString &group)
Q_D(QQmlDelegateModel);
if (d->m_transaction) {
- qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
return;
}
@@ -764,7 +764,8 @@ void QQmlDelegateModelPrivate::updateFilterGroup()
emit q->countChanged();
if (m_parts) {
- foreach (QQmlPartsModel *model, m_parts->models)
+ auto partsCopy = m_parts->models; // deliberate; this may alter m_parts
+ for (QQmlPartsModel *model : qAsConst(partsCopy))
model->updateFilterGroup(m_compositorGroup, changeSet);
}
}
@@ -889,7 +890,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
emitCreatedItem(incubationTask, cacheItem->object);
cacheItem->releaseObject();
} else if (status == QQmlIncubator::Error) {
- qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
+ qmlWarning(q, m_delegate->errors()) << "Error creating delegate";
}
if (!cacheItem->isObjectReferenced()) {
@@ -1472,7 +1473,8 @@ void QQmlDelegateModelPrivate::emitChanges()
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
- foreach (QQmlDelegateModelItem *cacheItem, m_cache) {
+ auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
+ for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
if (cacheItem->attached)
cacheItem->attached->emitChanges();
}
@@ -2459,7 +2461,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
if (!model->m_context || !model->m_context->isValid()) {
return QQmlV4Handle(QV4::Encode::undefined());
} else if (index < 0 || index >= model->m_compositor.count(d->group)) {
- qmlInfo(this) << tr("get: index out of range");
+ qmlWarning(this) << tr("get: index out of range");
return QQmlV4Handle(QV4::Encode::undefined());
}
@@ -2552,7 +2554,7 @@ void QQmlDelegateModelGroup::insert(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[i]);
if (d->parseIndex(v, &index, &group)) {
if (index < 0 || index > model->m_compositor.count(group)) {
- qmlInfo(this) << tr("insert: index out of range");
+ qmlWarning(this) << tr("insert: index out of range");
return;
}
if (++i == args->length())
@@ -2637,7 +2639,7 @@ void QQmlDelegateModelGroup::create(QQmlV4Function *args)
}
}
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("create: index out of range");
+ qmlWarning(this) << tr("create: index out of range");
return;
}
@@ -2690,22 +2692,22 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[0]);
if (d->parseIndex(v, &from, &fromGroup)) {
if (from < 0 || from >= model->m_compositor.count(fromGroup)) {
- qmlInfo(this) << tr("resolve: from index out of range");
+ qmlWarning(this) << tr("resolve: from index out of range");
return;
}
} else {
- qmlInfo(this) << tr("resolve: from index invalid");
+ qmlWarning(this) << tr("resolve: from index invalid");
return;
}
v = (*args)[1];
if (d->parseIndex(v, &to, &toGroup)) {
if (to < 0 || to >= model->m_compositor.count(toGroup)) {
- qmlInfo(this) << tr("resolve: to index out of range");
+ qmlWarning(this) << tr("resolve: to index out of range");
return;
}
} else {
- qmlInfo(this) << tr("resolve: to index invalid");
+ qmlWarning(this) << tr("resolve: to index invalid");
return;
}
@@ -2713,11 +2715,11 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
Compositor::iterator toIt = model->m_compositor.find(toGroup, to);
if (!fromIt->isUnresolved()) {
- qmlInfo(this) << tr("resolve: from is not an unresolved item");
+ qmlWarning(this) << tr("resolve: from is not an unresolved item");
return;
}
if (!toIt->list) {
- qmlInfo(this) << tr("resolve: to is not a model item");
+ qmlWarning(this) << tr("resolve: to is not a model item");
return;
}
@@ -2787,7 +2789,7 @@ void QQmlDelegateModelGroup::remove(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
if (!d->parseIndex(v, &index, &group)) {
- qmlInfo(this) << tr("remove: invalid index");
+ qmlWarning(this) << tr("remove: invalid index");
return;
}
@@ -2799,11 +2801,11 @@ void QQmlDelegateModelGroup::remove(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("remove: index out of range");
+ qmlWarning(this) << tr("remove: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("remove: invalid count");
+ qmlWarning(this) << tr("remove: invalid count");
} else {
model->removeGroups(it, count, d->group, 1 << d->group);
}
@@ -2858,11 +2860,11 @@ void QQmlDelegateModelGroup::addGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("addGroups: index out of range");
+ qmlWarning(this) << tr("addGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("addGroups: invalid count");
+ qmlWarning(this) << tr("addGroups: invalid count");
} else {
model->addGroups(it, count, d->group, groups);
}
@@ -2888,11 +2890,11 @@ void QQmlDelegateModelGroup::removeGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("removeGroups: index out of range");
+ qmlWarning(this) << tr("removeGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("removeGroups: invalid count");
+ qmlWarning(this) << tr("removeGroups: invalid count");
} else {
model->removeGroups(it, count, d->group, groups);
}
@@ -2918,11 +2920,11 @@ void QQmlDelegateModelGroup::setGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("setGroups: index out of range");
+ qmlWarning(this) << tr("setGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("setGroups: invalid count");
+ qmlWarning(this) << tr("setGroups: invalid count");
} else {
model->setGroups(it, count, d->group, groups);
}
@@ -2957,13 +2959,13 @@ void QQmlDelegateModelGroup::move(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
if (!d->parseIndex(v, &from, &fromGroup)) {
- qmlInfo(this) << tr("move: invalid from index");
+ qmlWarning(this) << tr("move: invalid from index");
return;
}
v = (*args)[1];
if (!d->parseIndex(v, &to, &toGroup)) {
- qmlInfo(this) << tr("move: invalid to index");
+ qmlWarning(this) << tr("move: invalid to index");
return;
}
@@ -2976,11 +2978,11 @@ void QQmlDelegateModelGroup::move(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (count < 0) {
- qmlInfo(this) << tr("move: invalid count");
+ qmlWarning(this) << tr("move: invalid count");
} else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) {
- qmlInfo(this) << tr("move: from index out of range");
+ qmlWarning(this) << tr("move: from index out of range");
} else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count, d->group)) {
- qmlInfo(this) << tr("move: to index out of range");
+ qmlWarning(this) << tr("move: to index out of range");
} else if (count > 0) {
QVector<Compositor::Remove> removes;
QVector<Compositor::Insert> inserts;
@@ -3038,7 +3040,7 @@ QString QQmlPartsModel::filterGroup() const
void QQmlPartsModel::setFilterGroup(const QString &group)
{
if (QQmlDelegateModelPrivate::get(m_model)->m_transaction) {
- qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
return;
}
@@ -3151,7 +3153,7 @@ QObject *QQmlPartsModel::object(int index, bool asynchronous)
model->release(object);
if (!model->m_delegateValidated) {
if (object)
- qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+ qmlWarning(model->m_delegate) << tr("Delegate component must be Package type.");
model->m_delegateValidated = true;
}
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 1a2e4c7f6f..cc4ccbaeb1 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -99,7 +99,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::Da
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -112,7 +112,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -226,7 +226,7 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
}
if (type == Role::Invalid) {
- qmlInfo(0) << "Can't create role for unsupported data type";
+ qmlWarning(0) << "Can't create role for unsupported data type";
return 0;
}
@@ -1201,7 +1201,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
}
roleIndex = setListProperty(role, subModel);
} else {
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
}
} else if (d.isBoolean()) {
roleIndex = setBoolProperty(role, d.booleanValue());
@@ -1267,10 +1267,12 @@ void ModelNodeMetaObject::updateValues()
{
const int roleCount = m_model->m_listModel->roleCount();
if (!m_initialized) {
- int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
- for (int i = 0; i < roleCount; ++i)
- changedRoles[i] = i;
- emitDirectNotifies(changedRoles, roleCount);
+ if (roleCount) {
+ int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
+ for (int i = 0; i < roleCount; ++i)
+ changedRoles[i] = i;
+ emitDirectNotifies(changedRoles, roleCount);
+ }
return;
}
for (int i=0 ; i < roleCount ; ++i) {
@@ -1984,18 +1986,18 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
if (m_mainThread && m_agent == 0) {
if (enableDynamicRoles) {
if (m_layout->roleCount())
- qmlInfo(this) << tr("unable to enable dynamic roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty!");
else
m_dynamicRoles = true;
} else {
if (m_roles.count()) {
- qmlInfo(this) << tr("unable to enable static roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable static roles as this model is not empty!");
} else {
m_dynamicRoles = false;
}
}
} else {
- qmlInfo(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created");
+ qmlWarning(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created");
}
}
@@ -2048,7 +2050,7 @@ void QQmlListModel::remove(QQmlV4Function *args)
int removeCount = (argLength == 2 ? QV4::ScopedValue(scope, (*args)[1])->toInt32() : 1);
if (index < 0 || index+removeCount > count() || removeCount <= 0) {
- qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count());
+ qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count());
return;
}
@@ -2064,7 +2066,7 @@ void QQmlListModel::remove(QQmlV4Function *args)
emitItemsRemoved(index, removeCount);
} else {
- qmlInfo(this) << tr("remove: incorrect number of arguments");
+ qmlWarning(this) << tr("remove: incorrect number of arguments");
}
}
@@ -2092,7 +2094,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
int index = arg0->toInt32();
if (index < 0 || index > count()) {
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
return;
}
@@ -2124,10 +2126,10 @@ void QQmlListModel::insert(QQmlV4Function *args)
emitItemsInserted(index, 1);
} else {
- qmlInfo(this) << tr("insert: value is not an object");
+ qmlWarning(this) << tr("insert: value is not an object");
}
} else {
- qmlInfo(this) << tr("insert: value is not an object");
+ qmlWarning(this) << tr("insert: value is not an object");
}
}
@@ -2150,7 +2152,7 @@ void QQmlListModel::move(int from, int to, int n)
if (n==0 || from==to)
return;
if (!canMove(from, to, n)) {
- qmlInfo(this) << tr("move: out of range");
+ qmlWarning(this) << tr("move: out of range");
return;
}
@@ -2239,10 +2241,10 @@ void QQmlListModel::append(QQmlV4Function *args)
emitItemsInserted(index, 1);
} else {
- qmlInfo(this) << tr("append: value is not an object");
+ qmlWarning(this) << tr("append: value is not an object");
}
} else {
- qmlInfo(this) << tr("append: value is not an object");
+ qmlWarning(this) << tr("append: value is not an object");
}
}
@@ -2321,11 +2323,11 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
QV4::ScopedObject object(scope, handle);
if (!object) {
- qmlInfo(this) << tr("set: value is not an object");
+ qmlWarning(this) << tr("set: value is not an object");
return;
}
if (index > count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("set: index %1 out of range").arg(index);
return;
}
@@ -2371,7 +2373,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
void QQmlListModel::setProperty(int index, const QString& property, const QVariant& value)
{
if (count() == 0 || index >= count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("set: index %1 out of range").arg(index);
return;
}
@@ -2401,7 +2403,7 @@ void QQmlListModel::sync()
// This is just a dummy method to make it look like sync() exists in
// ListModel (and not just QQmlListModelWorkerAgent) and to let
// us document sync().
- qmlInfo(this) << "List sync() can only be called from a WorkerScript";
+ qmlWarning(this) << "List sync() can only be called from a WorkerScript";
}
bool QQmlListModelParser::verifyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding)
@@ -2543,7 +2545,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, QV4::CompiledData::Compila
}
if (setRoles == false)
- qmlInfo(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
+ qmlWarning(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
}
bool QQmlListModelParser::definesEmptyList(const QString &s)
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index 695043b592..21205f4490 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -373,7 +373,7 @@ void QQmlObjectModel::insert(int index, QObject *object)
{
Q_D(QQmlObjectModel);
if (index < 0 || index > count()) {
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
return;
}
d->insert(index, object);
@@ -400,7 +400,7 @@ void QQmlObjectModel::move(int from, int to, int n)
if (n <= 0 || from == to)
return;
if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
- qmlInfo(this) << tr("move: out of range");
+ qmlWarning(this) << tr("move: out of range");
return;
}
d->move(from, to, n);
@@ -418,7 +418,7 @@ void QQmlObjectModel::remove(int index, int n)
{
Q_D(QQmlObjectModel);
if (index < 0 || n <= 0 || index + n > count()) {
- qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
+ qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
return;
}
d->remove(index, n);