aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-01 01:00:10 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-01 01:00:10 +0200
commitbbc52bcbb6391c4925df26672eb1f26040c6f67c (patch)
tree14b8580e21aecc5b08a35f69ac55e7fbc3aef3ba
parent5ff4facd8efc41b30b5ffa5abb6a12406685ca0b (diff)
parentcc0829cbf300e56360e3d61efe4dfd20efcabb1c (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.h18
-rw-r--r--src/3rdparty/masm/stubs/WTFStubs.cpp6
-rw-r--r--src/3rdparty/masm/yarr/YarrJIT.cpp8
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro2
-rw-r--r--src/imports/localstorage/localstorage.pro2
-rw-r--r--src/imports/qtqml/qtqml.pro4
-rw-r--r--src/imports/qtquick2/qtquick2.pro2
-rw-r--r--src/imports/shapes/shapes.pro2
-rw-r--r--src/qml/compiler/qv4bytecodehandler.cpp3
-rw-r--r--src/qml/compiler/qv4codegen.cpp56
-rw-r--r--src/qml/compiler/qv4codegen_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp4
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/jit/qv4assemblercommon.cpp4
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h2
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp2
-rw-r--r--src/qml/jit/qv4baselinejit.cpp13
-rw-r--r--src/qml/jit/qv4baselinejit_p.h1
-rw-r--r--src/qml/jsruntime/qv4function_p.h1
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h28
-rw-r--r--src/qml/jsruntime/qv4generatorobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4generatorobject_p.h10
-rw-r--r--src/qml/jsruntime/qv4global_p.h1
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp1
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp52
-rw-r--r--src/qml/jsruntime/qv4object.cpp105
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp102
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp11
-rw-r--r--src/qml/parser/qqmljs.g4
-rw-r--r--src/qml/parser/qqmljsast.cpp2
-rw-r--r--src/qml/parser/qqmljsast_p.h1
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp6
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h5
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp4
-rw-r--r--src/quick/handlers/qquickmultipointhandler_p.h2
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp27
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h14
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp14
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h4
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp11
-rw-r--r--src/quick/handlers/qquicksinglepointhandler_p.h3
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp6
-rw-r--r--src/quick/handlers/qquicktaphandler_p.h2
-rw-r--r--src/quick/items/qquickevents_p_p.h4
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp3
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations22
-rw-r--r--tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp58
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp26
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp4
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/data/mouse.qml9
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp53
-rw-r--r--tests/manual/pointer/singlePointHandlerProperties.qml49
-rw-r--r--tools/qmlplugindump/main.cpp4
55 files changed, 469 insertions, 332 deletions
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index 9b0016e96a..c79b0663c8 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -211,7 +211,7 @@ public:
// displaying disassembly.
inline CodeRef finalizeCodeWithoutDisassembly();
- inline CodeRef finalizeCodeWithDisassembly(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
+ inline CodeRef finalizeCodeWithDisassembly(const char *jitKind, const char* format, ...) WTF_ATTRIBUTE_PRINTF(3, 4);
CodePtr trampolineAt(Label label)
{
@@ -265,9 +265,9 @@ protected:
#endif
};
-#define FINALIZE_CODE_IF(condition, linkBufferReference, dataLogFArgumentsForHeading) \
+#define FINALIZE_CODE_IF(condition, linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
(UNLIKELY((condition)) \
- ? ((linkBufferReference).finalizeCodeWithDisassembly (dataLogFArgumentsForHeading)) \
+ ? ((linkBufferReference).finalizeCodeWithDisassembly (jitKind, dataLogFArgumentsForHeading)) \
: (linkBufferReference).finalizeCodeWithoutDisassembly())
// Use this to finalize code, like so:
@@ -286,11 +286,11 @@ protected:
// Note that the dataLogFArgumentsForHeading are only evaluated when showDisassembly
// is true, so you can hide expensive disassembly-only computations inside there.
-#define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading) \
- FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
+#define FINALIZE_CODE(linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
+ FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, jitKind, dataLogFArgumentsForHeading)
-#define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading) \
- FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)
+#define FINALIZE_DFG_CODE(linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
+ FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, jitKind, dataLogFArgumentsForHeading)
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
@@ -302,13 +302,13 @@ inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::Code
}
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
-inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char* format, ...)
+inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char *jitKind, const char* format, ...)
{
ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());
CodeRef result = finalizeCodeWithoutDisassembly();
- dataLogF("Generated JIT code for ");
+ dataLogF("Generated %s code for ", jitKind);
va_list argList;
va_start(argList, format);
WTF::dataLogFV(format, argList);
diff --git a/src/3rdparty/masm/stubs/WTFStubs.cpp b/src/3rdparty/masm/stubs/WTFStubs.cpp
index ea7e2d78e0..b26d10b3ab 100644
--- a/src/3rdparty/masm/stubs/WTFStubs.cpp
+++ b/src/3rdparty/masm/stubs/WTFStubs.cpp
@@ -91,7 +91,7 @@ void dataLogFV(const char* format, va_list args)
{
char buffer[1024];
qvsnprintf(buffer, sizeof(buffer), format, args);
- qDebug("%s", buffer);
+ qDebug().nospace().noquote() << buffer;
}
void dataLogF(const char* format, ...)
@@ -101,12 +101,12 @@ void dataLogF(const char* format, ...)
va_start(args, format);
qvsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
- qDebug("%s", buffer);
+ qDebug().nospace().noquote() << buffer;
}
void dataLogFString(const char* str)
{
- qDebug("%s", str);
+ qDebug().nospace().noquote() << str;
}
}
diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp
index 056de2dbde..ce7c7163ed 100644
--- a/src/3rdparty/masm/yarr/YarrJIT.cpp
+++ b/src/3rdparty/masm/yarr/YarrJIT.cpp
@@ -3521,14 +3521,14 @@ public:
if (compileMode == MatchOnly) {
if (m_charSize == Char8)
- codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "Match-only 8-bit regular expression"));
+ codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 8-bit regular expression"));
else
- codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "Match-only 16-bit regular expression"));
+ codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 16-bit regular expression"));
} else {
if (m_charSize == Char8)
- codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "8-bit regular expression"));
+ codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression"));
else
- codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "16-bit regular expression"));
+ codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression"));
}
if (m_failureReason)
codeBlock.setFallBackWithFailureReason(*m_failureReason);
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
index 99c54113e4..54ef107e45 100644
--- a/src/imports/folderlistmodel/folderlistmodel.pro
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlfolderlistmodelplugin
TARGETPATH = Qt/labs/folderlistmodel
-IMPORT_VERSION = 2.1
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
QT = core-private qml-private
diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro
index 2fc976d37d..5c8177e238 100644
--- a/src/imports/localstorage/localstorage.pro
+++ b/src/imports/localstorage/localstorage.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmllocalstorageplugin
TARGETPATH = QtQuick/LocalStorage
-IMPORT_VERSION = 2.$${QT_MINOR_VERSION}
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
QT = sql qml-private core-private
diff --git a/src/imports/qtqml/qtqml.pro b/src/imports/qtqml/qtqml.pro
index 8804c944e7..283ba8f131 100644
--- a/src/imports/qtqml/qtqml.pro
+++ b/src/imports/qtqml/qtqml.pro
@@ -7,8 +7,6 @@ load(qml_module)
!cross_compile:if(build_pass|!debug_and_release) {
qtPrepareTool(QMLPLUGINDUMP, qmlplugindump)
- # Use QtQml version defined in qmlplugindump source
- # TODO: retrieve the correct version from QtQml
- qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable QtQml 2.2 > $$PWD/plugins.qmltypes
+ qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable QtQml 2.$$QT_MINOR_VERSION > $$PWD/plugins.qmltypes
QMAKE_EXTRA_TARGETS += qmltypes
}
diff --git a/src/imports/qtquick2/qtquick2.pro b/src/imports/qtquick2/qtquick2.pro
index b3c44b412b..744dce4195 100644
--- a/src/imports/qtquick2/qtquick2.pro
+++ b/src/imports/qtquick2/qtquick2.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qtquick2plugin
TARGETPATH = QtQuick.2
-IMPORT_VERSION = 2.12
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/imports/shapes/shapes.pro b/src/imports/shapes/shapes.pro
index 71bb456866..857fcd7564 100644
--- a/src/imports/shapes/shapes.pro
+++ b/src/imports/shapes/shapes.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlshapesplugin
TARGETPATH = QtQuick/Shapes
-IMPORT_VERSION = 1.11
+IMPORT_VERSION = 1.$$QT_MINOR_VERSION
QT = core gui-private qml quick-private quickshapes-private
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp
index 181594010d..3a3f4a6adb 100644
--- a/src/qml/compiler/qv4bytecodehandler.cpp
+++ b/src/qml/compiler/qv4bytecodehandler.cpp
@@ -246,6 +246,9 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(CallValue)
COLLECTOR_END_INSTR(CallValue)
+ COLLECTOR_BEGIN_INSTR(CallWithReceiver)
+ COLLECTOR_END_INSTR(CallWithReceiver)
+
COLLECTOR_BEGIN_INSTR(CallProperty)
COLLECTOR_END_INSTR(CallProperty)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 412d787d11..62dbcdaa7d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1826,6 +1826,8 @@ bool Codegen::visit(CallExpression *ast)
case Reference::Super:
handleConstruct(base, ast->arguments);
return false;
+ case Reference::SuperProperty:
+ break;
default:
base = base.storeOnStack();
break;
@@ -1861,11 +1863,11 @@ bool Codegen::visit(CallExpression *ast)
}
- handleCall(base, calldata);
+ handleCall(base, calldata, functionObject, thisObject);
return false;
}
-void Codegen::handleCall(Reference &base, Arguments calldata)
+void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject)
{
//### Do we really need all these call instructions? can's we load the callee in a temp?
if (base.type == Reference::QmlScopeObject) {
@@ -1924,6 +1926,22 @@ void Codegen::handleCall(Reference &base, Arguments calldata)
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
}
+ } else if (base.type == Reference::SuperProperty) {
+ Reference receiver = base.baseObject();
+ if (!base.isStackSlot()) {
+ base.storeOnStack(slotForFunction);
+ base = Reference::fromStackSlot(this, slotForFunction);
+ }
+ if (!receiver.isStackSlot()) {
+ receiver.storeOnStack(slotForThisObject);
+ receiver = Reference::fromStackSlot(this, slotForThisObject);
+ }
+ Instruction::CallWithReceiver call;
+ call.name = base.stackSlot();
+ call.thisObject = receiver.stackSlot();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
} else {
Q_ASSERT(base.isStackSlot());
Instruction::CallValue call;
@@ -2157,6 +2175,8 @@ bool Codegen::visit(TaggedTemplate *ast)
RegisterScope scope(this);
+ int functionObject = -1, thisObject = -1;
+
Reference base = expression(ast->base);
if (hasError)
return false;
@@ -2167,6 +2187,10 @@ bool Codegen::visit(TaggedTemplate *ast)
break;
case Reference::Name:
break;
+ case Reference::SuperProperty:
+ thisObject = bytecodeGenerator->newRegister();
+ functionObject = bytecodeGenerator->newRegister();
+ break;
default:
base = base.storeOnStack();
break;
@@ -2181,7 +2205,7 @@ bool Codegen::visit(TaggedTemplate *ast)
Q_ASSERT(calldata.argv == arrayTemp + 1);
--calldata.argv;
- handleCall(base, calldata);
+ handleCall(base, calldata, functionObject, thisObject);
return false;
}
@@ -2450,7 +2474,7 @@ bool Codegen::visit(ObjectPattern *ast)
for (; it; it = it->next) {
PatternProperty *p = it->property;
AST::ComputedPropertyName *cname = AST::cast<AST::ComputedPropertyName *>(p->name);
- if (cname || p->type == PatternProperty::Getter || p->type == PatternProperty::Setter)
+ if (cname || p->type != PatternProperty::Literal)
break;
QString name = p->name->asString();
uint arrayIndex = QV4::String::toArrayIndex(name);
@@ -2477,7 +2501,9 @@ bool Codegen::visit(ObjectPattern *ast)
PatternProperty *p = it->property;
AST::ComputedPropertyName *cname = AST::cast<AST::ComputedPropertyName *>(p->name);
ObjectLiteralArgument argType = ObjectLiteralArgument::Value;
- if (p->type == PatternProperty::Getter)
+ if (p->type == PatternProperty::Method)
+ argType = ObjectLiteralArgument::Method;
+ else if (p->type == PatternProperty::Getter)
argType = ObjectLiteralArgument::Getter;
else if (p->type == PatternProperty::Setter)
argType = ObjectLiteralArgument::Setter;
@@ -2508,10 +2534,20 @@ bool Codegen::visit(ObjectPattern *ast)
push(Reference::fromAccumulator(this));
{
RegisterScope innerScope(this);
- Reference value = expression(p->initializer);
- if (hasError)
- return false;
- value.loadInAccumulator();
+ if (p->type != PatternProperty::Literal) {
+ // need to get the closure id for the method
+ FunctionExpression *f = p->initializer->asFunctionDefinition();
+ Q_ASSERT(f);
+ int function = defineFunction(f->name.toString(), f, f->formals, f->body);
+ if (hasError)
+ return false;
+ Reference::fromConst(this, Encode(function)).loadInAccumulator();
+ } else {
+ Reference value = expression(p->initializer);
+ if (hasError)
+ return false;
+ value.loadInAccumulator();
+ }
}
push(Reference::fromAccumulator(this));
}
@@ -3966,6 +4002,8 @@ Codegen::Reference Codegen::Reference::baseObject() const
Q_UNREACHABLE();
} else if (type == Reference::Subscript) {
return Reference::fromStackSlot(codegen, elementBase.stackSlot());
+ } else if (type == Reference::SuperProperty) {
+ return Reference::fromStackSlot(codegen, CallData::This);
} else {
return Reference::fromConst(codegen, Encode::undefined());
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index adea8b3009..ae3e074e07 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -683,7 +683,7 @@ public:
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
struct Arguments { int argc; int argv; bool hasSpread; };
Arguments pushArgs(AST::ArgumentList *args);
- void handleCall(Reference &base, Arguments calldata);
+ void handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject);
Arguments pushTemplateArgs(AST::TemplateLiteral *args);
int createTemplateArray(AST::TemplateLiteral *t);
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 4653b7217d..e70b246181 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -357,6 +357,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(name, nFormals) << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallValue)
+ MOTH_BEGIN_INSTR(CallWithReceiver)
+ d << dumpRegister(name, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallWithReceiver)
+
MOTH_BEGIN_INSTR(CallProperty)
d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallProperty)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 7c2cbf717e..2690151a23 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -104,6 +104,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1, base)
#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2, base, index)
#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3, name, argc, argv)
+#define INSTR_CallWithReceiver(op) INSTRUCTION(op, CallWithReceiver, 4, name, thisObject, argc, argv)
#define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4, name, base, argc, argv)
#define INSTR_CallPropertyLookup(op) INSTRUCTION(op, CallPropertyLookup, 4, lookupIndex, base, argc, argv)
#define INSTR_CallElement(op) INSTRUCTION(op, CallElement, 4, base, index, argc, argv)
@@ -283,6 +284,7 @@ QT_BEGIN_NAMESPACE
F(Mod) \
F(Sub) \
F(CallValue) \
+ F(CallWithReceiver) \
F(CallProperty) \
F(CallPropertyLookup) \
F(CallElement) \
diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
index 79a8237878..0ae4da17fa 100644
--- a/src/qml/jit/qv4assemblercommon.cpp
+++ b/src/qml/jit/qv4assemblercommon.cpp
@@ -126,7 +126,7 @@ static QByteArray functionName(Function *function)
JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon()
{}
-void PlatformAssemblerCommon::link(Function *function)
+void PlatformAssemblerCommon::link(Function *function, const char *jitKind)
{
for (const auto &jumpTarget : jumpsToLink)
jumpTarget.jump.linkTo(labelForOffset[jumpTarget.offset], this);
@@ -148,7 +148,7 @@ void PlatformAssemblerCommon::link(Function *function)
WTF::setDataFile(new QIODevicePrintStream(&buf));
QByteArray name = functionName(function);
- codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.constData());
+ codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, "%s", name.constData());
WTF::setDataFile(stderr);
printDisassembledOutputWithCalls(buf.data(), functions);
diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h
index a48d6fae44..d64b9d0e5d 100644
--- a/src/qml/jit/qv4assemblercommon_p.h
+++ b/src/qml/jit/qv4assemblercommon_p.h
@@ -645,7 +645,7 @@ public:
ehTargets.push_back({ label, offset });
}
- void link(Function *function);
+ void link(Function *function, const char *jitKind);
Value constant(int idx) const
{ return constantTable[idx]; }
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 5950901499..c822a0f371 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -827,7 +827,7 @@ void BaselineAssembler::generateEpilogue()
void BaselineAssembler::link(Function *function)
{
- pasm()->link(function);
+ pasm()->link(function, "BaselineJIT");
}
void BaselineAssembler::addLabel(int offset)
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index 36375461f9..9e9c586982 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -418,6 +418,19 @@ void BaselineJIT::generate_CallValue(int name, int argc, int argv)
as->checkException();
}
+void BaselineJIT::generate_CallWithReceiver(int name, int thisObject, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passJSSlotAsArg(argv, 3);
+ as->passJSSlotAsArg(thisObject, 2);
+ as->passJSSlotAsArg(name, 1);
+ as->passEngineAsArg(0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callWithReceiver, CallResultDestination::InAccumulator);
+ as->checkException();
+}
+
void BaselineJIT::generate_CallProperty(int name, int base, int argc, int argv)
{
STORE_IP();
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index a3cb850fc1..972e9d07b7 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -120,6 +120,7 @@ public:
void generate_Resume(int) override;
void generate_CallValue(int name, int argc, int argv) override;
+ void generate_CallWithReceiver(int name, int thisObject, int argc, int argv) override;
void generate_CallProperty(int name, int base, int argc, int argv) override;
void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) override;
void generate_CallElement(int base, int index, int argc, int argv) override;
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index d542ce752f..029dd7786b 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -81,6 +81,7 @@ struct Q_QML_EXPORT Function {
uint nFormals;
int interpreterCallCount = 0;
bool hasQmlDependencies;
+ bool isEval = false;
Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function);
~Function();
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index f7bea9a5f0..fe1ebbd556 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -175,7 +175,7 @@ Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *sco
return scope->engine()->memoryManager->allocate<ScriptFunction>(scope, function);
}
-Heap::FunctionObject *FunctionObject::createConstructorFunction(ExecutionContext *scope, Function *function, bool isDerivedConstructor)
+Heap::FunctionObject *FunctionObject::createConstructorFunction(ExecutionContext *scope, Function *function, Object *homeObject, bool isDerivedConstructor)
{
if (!function) {
Heap::DefaultClassConstructorFunction *c = scope->engine()->memoryManager->allocate<DefaultClassConstructorFunction>(scope);
@@ -183,13 +183,16 @@ Heap::FunctionObject *FunctionObject::createConstructorFunction(ExecutionContext
return c;
}
Heap::ConstructorFunction *c = scope->engine()->memoryManager->allocate<ConstructorFunction>(scope, function);
+ c->homeObject.set(scope->engine(), homeObject->d());
c->isDerivedConstructor = isDerivedConstructor;
return c;
}
-Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *scope, Function *function, QV4::String *name)
+Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *scope, Function *function, Object *homeObject, QV4::String *name)
{
- return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function, name);
+ Heap::MemberFunction *m = scope->engine()->memoryManager->allocate<MemberFunction>(scope, function, name);
+ m->homeObject.set(scope->engine(), homeObject->d());
+ return m;
}
Heap::FunctionObject *FunctionObject::createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 54964b9bbd..766960d2ac 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -122,13 +122,16 @@ DECLARE_HEAP_OBJECT(ScriptFunction, FunctionObject) {
void init(QV4::ExecutionContext *scope, Function *function, QV4::String *name = nullptr);
};
-struct ConstructorFunction : ScriptFunction
-{
- bool isDerivedConstructor;
+#define MemberFunctionMembers(class, Member) \
+ Member(class, Pointer, Object *, homeObject)
+
+DECLARE_HEAP_OBJECT(MemberFunction, ScriptFunction) {
+ DECLARE_MARKOBJECTS(MemberFunction)
};
-struct MemberFunction : ScriptFunction
+struct ConstructorFunction : MemberFunction
{
+ bool isDerivedConstructor;
};
struct DefaultClassConstructorFunction : FunctionObject
@@ -187,8 +190,8 @@ struct Q_QML_EXPORT FunctionObject: Object {
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function);
- static Heap::FunctionObject *createConstructorFunction(ExecutionContext *scope, Function *function, bool isDerivedConstructor);
- static Heap::FunctionObject *createMemberFunction(ExecutionContext *scope, Function *function, String *name);
+ static Heap::FunctionObject *createConstructorFunction(ExecutionContext *scope, Function *function, Object *homeObject, bool isDerivedConstructor);
+ static Heap::FunctionObject *createMemberFunction(ExecutionContext *scope, Function *function, Object *homeObject, String *name);
static Heap::FunctionObject *createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount);
bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
@@ -261,18 +264,17 @@ struct ScriptFunction : FunctionObject {
Heap::InternalClass *classForConstructor() const;
};
-struct ConstructorFunction : ScriptFunction {
- V4_OBJECT2(ConstructorFunction, ScriptFunction)
- V4_INTERNALCLASS(ConstructorFunction)
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *);
- static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
-};
-
struct MemberFunction : ScriptFunction {
V4_OBJECT2(MemberFunction, ScriptFunction)
V4_INTERNALCLASS(MemberFunction)
};
+struct ConstructorFunction : MemberFunction {
+ V4_OBJECT2(ConstructorFunction, MemberFunction)
+ V4_INTERNALCLASS(ConstructorFunction)
+ static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *);
+ static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
+};
struct DefaultClassConstructorFunction : FunctionObject {
V4_OBJECT2(DefaultClassConstructorFunction, FunctionObject)
diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp
index bab0cfbfb1..82d8d88882 100644
--- a/src/qml/jsruntime/qv4generatorobject.cpp
+++ b/src/qml/jsruntime/qv4generatorobject.cpp
@@ -230,13 +230,19 @@ ReturnedValue GeneratorObject::resume(ExecutionEngine *engine, const Value &arg)
DEFINE_OBJECT_VTABLE(MemberGeneratorFunction);
-Heap::FunctionObject *MemberGeneratorFunction::create(ExecutionContext *context, Function *function, String *name)
+Heap::FunctionObject *MemberGeneratorFunction::create(ExecutionContext *context, Function *function, Object *homeObject, String *name)
{
Scope scope(context);
- Scoped<GeneratorFunction> g(scope, context->engine()->memoryManager->allocate<MemberGeneratorFunction>(context, function, name));
+ Scoped<MemberGeneratorFunction> g(scope, context->engine()->memoryManager->allocate<MemberGeneratorFunction>(context, function, name));
+ g->d()->homeObject.set(scope.engine, homeObject->d());
ScopedObject proto(scope, scope.engine->newObject());
proto->setPrototypeOf(scope.engine->generatorPrototype());
g->defineDefaultProperty(scope.engine->id_prototype(), proto, Attr_NotConfigurable|Attr_NotEnumerable);
g->setPrototypeOf(ScopedObject(scope, scope.engine->generatorFunctionCtor()->get(scope.engine->id_prototype())));
return g->d();
}
+
+ReturnedValue MemberGeneratorFunction::virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ return GeneratorFunction::virtualCall(f, thisObject, argv, argc);
+}
diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h
index f00f730344..55e6091ad5 100644
--- a/src/qml/jsruntime/qv4generatorobject_p.h
+++ b/src/qml/jsruntime/qv4generatorobject_p.h
@@ -75,7 +75,7 @@ struct GeneratorFunctionCtor : FunctionObject {
struct GeneratorFunction : ScriptFunction {
};
-struct MemberGeneratorFunction : ScriptFunction {
+struct MemberGeneratorFunction : MemberFunction {
};
struct GeneratorPrototype : FunctionObject {
@@ -113,12 +113,14 @@ struct GeneratorFunction : ScriptFunction
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
-struct MemberGeneratorFunction : GeneratorFunction
+struct MemberGeneratorFunction : MemberFunction
{
- V4_OBJECT2(MemberGeneratorFunction, GeneratorFunction)
+ V4_OBJECT2(MemberGeneratorFunction, MemberFunction)
V4_INTERNALCLASS(MemberGeneratorFunction)
- static Heap::FunctionObject *create(ExecutionContext *scope, Function *function, String *name);
+ static Heap::FunctionObject *create(ExecutionContext *scope, Function *function, Object *homeObject, String *name);
+ static constexpr VTable::CallAsConstructor virtualCallAsConstructor = nullptr;
+ static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct GeneratorPrototype : Object
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index f89a4b9909..c53465d24e 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -383,6 +383,7 @@ typedef QVector<StackFrame> StackTrace;
enum class ObjectLiteralArgument {
Value,
+ Method,
Getter,
Setter
};
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 43895011f3..1f747b62d7 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -371,6 +371,7 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc,
Function *function = script.function();
if (!function)
return Encode::undefined();
+ function->isEval = true;
if (function->isStrict() || isStrict) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 0412695404..14a580462f 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -253,51 +253,29 @@ void IdentifierTable::markObjects(MarkStack *markStack)
}
template <typename Key>
-int sweepTable(Heap::StringOrSymbol **table, int alloc, std::function<Key(Heap::StringOrSymbol *)> f) {
+int sweepTable(Heap::StringOrSymbol **&table, int alloc, std::function<Key(Heap::StringOrSymbol *)> f) {
int freed = 0;
- uint lastKey = 0;
-
- int lastEntry = -1;
- int start = 0;
- // start at an empty entry so we compress properly
- for (; start < alloc; ++start) {
- if (!table[start])
- break;
- }
+ Heap::StringOrSymbol **newTable = (Heap::StringOrSymbol **)malloc(alloc*sizeof(Heap::String *));
+ memset(newTable, 0, alloc*sizeof(Heap::StringOrSymbol *));
for (int i = 0; i < alloc; ++i) {
- int idx = (i + start) % alloc;
- Heap::StringOrSymbol *entry = table[idx];
- if (!entry) {
- lastEntry = -1;
+ Heap::StringOrSymbol *e = table[i];
+ if (!e)
continue;
- }
- if (entry->isMarked()) {
- if (lastEntry >= 0 && lastKey == (f(entry) % alloc)) {
- Q_ASSERT(table[lastEntry] == nullptr);
- table[lastEntry] = entry;
- table[idx] = nullptr;
-
- // find next free slot just like in addEntry()
- do {
- lastEntry = (lastEntry + 1) % alloc;
- } while (table[lastEntry] != nullptr);
- }
+ if (!e->isMarked()) {
+ ++freed;
continue;
}
- if (lastEntry == -1) {
- lastEntry = idx;
- lastKey = f(entry) % alloc;
+ uint idx = f(e) % alloc;
+ while (newTable[idx]) {
+ ++idx;
+ idx %= alloc;
}
- table[idx] = nullptr;
- ++freed;
- }
- for (int i = 0; i < alloc; ++i) {
- Heap::StringOrSymbol *entry = table[i];
- if (!entry)
- continue;
- Q_ASSERT(entry->isMarked());
+ newTable[idx] = e;
}
+ free(table);
+ table = newTable;
+
return freed;
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index eb4e392c0f..17cc058c39 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -462,95 +462,50 @@ ReturnedValue Object::internalGetIndexed(uint index, const Value *receiver, bool
// Section 8.12.5
bool Object::internalPut(PropertyKey id, const Value &value, Value *receiver)
{
- ExecutionEngine *engine = this->engine();
- if (engine->hasException)
+ Scope scope(this);
+ if (scope.engine->hasException)
return false;
- uint index = id.asArrayIndex();
- Scope scope(engine);
-
+ ScopedProperty p(scope);
PropertyAttributes attrs;
- PropertyIndex propertyIndex{nullptr, nullptr};
-
- if (index != UINT_MAX) {
- if (arrayData())
- propertyIndex = arrayData()->getValueOrSetter(index, &attrs);
-
- if (propertyIndex.isNull() && isStringObject()) {
- if (index < static_cast<StringObject *>(this)->length())
- // not writable
- return false;
- }
- } else {
- uint member = internalClass()->find(id);
- if (member < UINT_MAX) {
- attrs = internalClass()->propertyData[member];
- propertyIndex = d()->writablePropertyData(attrs.isAccessor() ? member + SetterOffset : member);
- }
+ attrs = getOwnProperty(id, p);
+ if (attrs == Attr_Invalid) {
+ ScopedObject p(scope, getPrototypeOf());
+ if (p)
+ return p->put(id, value, receiver);
+ attrs = Attr_Data;
}
- // clause 1
- if (!propertyIndex.isNull()) {
- if (attrs.isAccessor()) {
- if (propertyIndex->as<FunctionObject>())
- goto cont;
- return false;
- } else if (!attrs.isWritable())
- return false;
- else if (isArrayObject() && id == engine->id_length()->propertyKey()) {
- bool ok;
- uint l = value.asArrayLength(&ok);
- if (!ok) {
- engine->throwRangeError(value);
- return false;
- }
- ok = setArrayLength(l);
- if (!ok)
- return false;
- } else {
- propertyIndex.set(engine, value);
- }
- return true;
- } else if (!getPrototypeOf()) {
- if (!isExtensible())
- return false;
- } else {
- // clause 4
- propertyIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(id, &attrs);
- if (!propertyIndex.isNull()) {
- if (attrs.isAccessor()) {
- if (!propertyIndex->as<FunctionObject>())
- return false;
- } else if (!isExtensible() || !attrs.isWritable()) {
- return false;
- }
- } else if (!isExtensible()) {
+ if (attrs.isAccessor()) {
+ ScopedFunctionObject setter(scope, p->setter());
+ if (!setter)
return false;
- }
- }
-
- cont:
-
- // Clause 5
- if (!propertyIndex.isNull() && attrs.isAccessor()) {
- Q_ASSERT(propertyIndex->as<FunctionObject>());
-
- Scope scope(engine);
- ScopedFunctionObject setter(scope, *propertyIndex);
JSCallData jsCallData(scope, 1);
jsCallData->args[0] = value;
*jsCallData->thisObject = *receiver;
setter->call(jsCallData);
- return !engine->hasException;
+ return !scope.engine->hasException;
}
- if (index != UINT_MAX) {
- arraySet(index, value);
+ // Data property
+ if (!attrs.isWritable())
+ return false;
+ Object *r = receiver->objectValue();
+ if (!r)
+ return false;
+ attrs = r->getOwnProperty(id, p);
+
+ if (attrs != Attr_Invalid) {
+ if (attrs.isAccessor() || !attrs.isWritable())
+ return false;
} else {
- Scoped<StringOrSymbol> name(scope, id.asStringOrSymbol());
- insertMember(name, value);
+ if (!r->isExtensible())
+ return false;
+ attrs = Attr_Data;
}
- return true;
+
+ p->value = value;
+ return r->defineOwnProperty(id, p, attrs);
}
// Section 8.12.7
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 3317003ea4..3a1dabeae3 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -875,38 +875,65 @@ ReturnedValue Runtime::method_loadName(ExecutionEngine *engine, int nameIndex)
return static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).getProperty(name);
}
+static Object *getSuperBase(Scope &scope)
+{
+ if (scope.engine->currentStackFrame->jsFrame->thisObject.isEmpty()) {
+ scope.engine->throwReferenceError(QStringLiteral("Missing call to super()."), QString(), 0, 0);
+ return nullptr;
+ }
+
+ ScopedFunctionObject f(scope, scope.engine->currentStackFrame->jsFrame->function);
+ MemberFunction *m = f->as<MemberFunction>();
+ if (!m) {
+ ScopedContext ctx(scope, static_cast<ExecutionContext *>(&scope.engine->currentStackFrame->jsFrame->context));
+ Q_ASSERT(ctx);
+ while (ctx) {
+ if (CallContext *c = ctx->asCallContext()) {
+ f = c->d()->function;
+ QV4::Function *fn = f->function();
+ if (fn && !fn->isArrowFunction() && !fn->isEval)
+ break;
+ }
+ ctx = ctx->d()->outer;
+ }
+ m = f->as<MemberFunction>();
+ }
+ if (!m) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ ScopedObject homeObject(scope, m->d()->homeObject);
+ Q_ASSERT(homeObject);
+ ScopedObject proto(scope, homeObject->getPrototypeOf());
+ if (!proto) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ return proto;
+}
+
ReturnedValue Runtime::method_loadSuperProperty(ExecutionEngine *engine, const Value &property)
{
Scope scope(engine);
- ScopedObject base(scope, engine->currentStackFrame->thisObject());
+ Object *base = getSuperBase(scope);
if (!base)
- return engine->throwTypeError();
- ScopedObject proto(scope, base->getPrototypeOf());
- if (!proto)
- return engine->throwTypeError();
+ return Encode::undefined();
ScopedPropertyKey key(scope, property.toPropertyKey(engine));
if (engine->hasException)
return Encode::undefined();
- return proto->get(key, base);
+ return base->get(key, &engine->currentStackFrame->jsFrame->thisObject);
}
void Runtime::method_storeSuperProperty(ExecutionEngine *engine, const Value &property, const Value &value)
{
Scope scope(engine);
- ScopedObject base(scope, engine->currentStackFrame->thisObject());
- if (!base) {
- engine->throwTypeError();
- return;
- }
- ScopedObject proto(scope, base->getPrototypeOf());
- if (!proto) {
- engine->throwTypeError();
+ Object *base = getSuperBase(scope);
+ if (!base)
return;
- }
ScopedPropertyKey key(scope, property.toPropertyKey(engine));
if (engine->hasException)
return;
- bool result = proto->put(key, value, base);
+ bool result = base->put(key, value, &engine->currentStackFrame->jsFrame->thisObject);
if (!result && engine->currentStackFrame->v4Function->isStrict())
engine->throwTypeError();
}
@@ -1288,6 +1315,13 @@ ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &fu
return static_cast<const FunctionObject &>(func).call(&undef, argv, argc);
}
+ReturnedValue Runtime::method_callWithReceiver(ExecutionEngine *engine, const Value &func, const Value *thisObject, Value *argv, int argc)
+{
+ if (!func.isFunctionObject())
+ return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
+ return static_cast<const FunctionObject &>(func).call(thisObject, argv, argc);
+}
+
ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, Value *base,
int propertyIndex, Value *argv, int argc)
{
@@ -1529,30 +1563,48 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, int classId
ScopedProperty pd(scope);
ScopedFunctionObject fn(scope);
ScopedString fnName(scope);
+ ScopedValue value(scope);
for (int i = 0; i < additionalArgs; ++i) {
Q_ASSERT(args->isInteger());
ObjectLiteralArgument arg = ObjectLiteralArgument(args->integerValue());
name = args[1].toPropertyKey(engine);
+ value = args[2];
if (engine->hasException)
return Encode::undefined();
- if (args[2].isFunctionObject()) {
- fn = static_cast<const FunctionObject &>(args[2]);
+ if (arg != ObjectLiteralArgument::Value) {
+ Q_ASSERT(args[2].isInteger());
+ int functionId = args[2].integerValue();
+ QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeFunctions[functionId];
+ Q_ASSERT(clos);
+
PropertyKey::FunctionNamePrefix prefix = PropertyKey::None;
if (arg == ObjectLiteralArgument::Getter)
prefix = PropertyKey::Getter;
else if (arg == ObjectLiteralArgument::Setter)
prefix = PropertyKey::Setter;
-
+ else
+ arg = ObjectLiteralArgument::Value;
fnName = name->asFunctionName(engine, prefix);
+
+ ExecutionContext *current = static_cast<ExecutionContext *>(&engine->currentStackFrame->jsFrame->context);
+ if (clos->isGenerator())
+ value = MemberGeneratorFunction::create(current, clos, o, fnName)->asReturnedValue();
+ else
+ value = FunctionObject::createMemberFunction(current, clos, o, fnName)->asReturnedValue();
+ } else if (args[2].isFunctionObject()) {
+ fn = static_cast<const FunctionObject &>(args[2]);
+
+ fnName = name->asFunctionName(engine, PropertyKey::None);
fn->setName(fnName);
}
- Q_ASSERT(arg == ObjectLiteralArgument::Value || args[2].isFunctionObject());
+ Q_ASSERT(arg != ObjectLiteralArgument::Method);
+ Q_ASSERT(arg == ObjectLiteralArgument::Value || value->isFunctionObject());
if (arg == ObjectLiteralArgument::Value || arg == ObjectLiteralArgument::Getter) {
- pd->value = args[2];
+ pd->value = value;
pd->set = Primitive::emptyValue();
} else {
pd->value = Primitive::emptyValue();
- pd->set = args[2];
+ pd->set = value;
}
bool ok = o->defineOwnProperty(name, pd, (arg == ObjectLiteralArgument::Value ? Attr_Data : Attr_Accessor));
if (!ok)
@@ -1594,7 +1646,7 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde
ScopedFunctionObject constructor(scope);
QV4::Function *f = cls->constructorFunction != UINT_MAX ? unit->runtimeFunctions[cls->constructorFunction] : nullptr;
- constructor = FunctionObject::createConstructorFunction(current, f, !superClass.isEmpty())->asReturnedValue();
+ constructor = FunctionObject::createConstructorFunction(current, f, proto, !superClass.isEmpty())->asReturnedValue();
constructor->setPrototypeUnchecked(constructorParent);
Value argCount = Primitive::fromInt32(f ? f->nFormals : 0);
constructor->defineReadonlyConfigurableProperty(scope.engine->id_length(), argCount);
@@ -1637,9 +1689,9 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde
name = propertyName->asFunctionName(engine, prefix);
if (f->isGenerator())
- function = MemberGeneratorFunction::create(current, f, name);
+ function = MemberGeneratorFunction::create(current, f, receiver, name);
else
- function = FunctionObject::createMemberFunction(current, f, name);
+ function = FunctionObject::createMemberFunction(current, f, receiver, name);
Q_ASSERT(function);
PropertyAttributes attributes;
switch (methods[i].type) {
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 5dafeee6ce..62ba85efde 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -98,6 +98,7 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, Value *base, uint index, Value *argv, int argc)) \
F(ReturnedValue, callElement, (ExecutionEngine *engine, Value *base, const Value &index, Value *argv, int argc)) \
F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
+ F(ReturnedValue, callWithReceiver, (ExecutionEngine *engine, const Value &func, const Value *thisObject, Value *argv, int argc)) \
F(ReturnedValue, callPossiblyDirectEval, (ExecutionEngine *engine, Value *argv, int argc)) \
F(ReturnedValue, callWithSpread, (ExecutionEngine *engine, const Value &func, const Value &thisObject, Value *argv, int argc)) \
\
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index fd2328beaa..2d1f4c3e91 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -689,6 +689,17 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
CHECK_EXCEPTION;
MOTH_END_INSTR(CallValue)
+ MOTH_BEGIN_INSTR(CallWithReceiver)
+ STORE_IP();
+ Value func = STACK_VALUE(name);
+ if (Q_UNLIKELY(!func.isFunctionObject())) {
+ acc = engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
+ goto handleUnwind;
+ }
+ acc = static_cast<const FunctionObject &>(func).call(stack + thisObject, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallWithReceiver)
+
MOTH_BEGIN_INSTR(CallProperty)
STORE_IP();
acc = Runtime::method_callProperty(engine, stack + base, name, stack + argv, argc);
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index b5e63fe7fe..a844e3cb3e 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -3669,7 +3669,7 @@ MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN Function
f->rparenToken = loc(4);
f->lbraceToken = loc(5);
f->rbraceToken = loc(7);
- AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, f);
+ AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, f, AST::PatternProperty::Method);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
@@ -3685,7 +3685,7 @@ MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_R
f->lbraceToken = loc(6);
f->rbraceToken = loc(8);
f->isGenerator = true;
- AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f);
+ AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Method);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 9484b53a39..4ebb2d3b5c 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -465,6 +465,8 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
*errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression.");
return false;
}
+ if (type == Method)
+ type = Literal;
Q_ASSERT(type == Literal);
return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage);
}
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index b69fb6272b..72c47cbe32 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -670,6 +670,7 @@ public:
enum Type {
// object literal types
Literal,
+ Method,
Getter,
Setter,
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index ffdaa909dd..b8f08639ef 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -109,10 +109,10 @@ QPointF QQuickDragHandler::targetCentroidPosition()
return pos;
}
-void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
{
- QQuickMultiPointHandler::onGrabChanged(grabber, stateChange, point);
- if (grabber == this && stateChange == QQuickEventPoint::GrabExclusive) {
+ QQuickMultiPointHandler::onGrabChanged(grabber, transition, point);
+ if (grabber == this && transition == QQuickEventPoint::GrabExclusive) {
// In case the grab got handed over from another grabber, we might not get the Press.
if (!m_pressedInsideTarget) {
if (target())
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index 25101a98c4..387a81eb43 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -74,15 +74,14 @@ public:
QVector2D translation() const { return m_translation; }
void setTranslation(const QVector2D &trans);
- Q_INVOKABLE void enforceConstraints();
+ void enforceConstraints();
Q_SIGNALS:
-// void gestureStarted(QQuickGestureEvent *gesture);
void translationChanged();
protected:
void onActiveChanged() override;
- void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override;
private:
void ungrab();
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index cb3becaa2d..859a9135b7 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -143,13 +143,13 @@ void QQuickMultiPointHandler::onActiveChanged()
}
}
-void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *)
+void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *)
{
// If another handler or item takes over this set of points, assume it has
// decided that it's the better fit for them. Don't immediately re-grab
// at the next opportunity. This should help to avoid grab cycles
// (e.g. between DragHandler and PinchHandler).
- if (stateChange == QQuickEventPoint::UngrabExclusive || stateChange == QQuickEventPoint::CancelGrabExclusive)
+ if (transition == QQuickEventPoint::UngrabExclusive || transition == QQuickEventPoint::CancelGrabExclusive)
m_currentPoints.clear();
}
diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h
index 199ea7cd10..94142013cc 100644
--- a/src/quick/handlers/qquickmultipointhandler_p.h
+++ b/src/quick/handlers/qquickmultipointhandler_p.h
@@ -93,7 +93,7 @@ protected:
bool wantsPointerEvent(QQuickPointerEvent *event) override;
void handlePointerEventImpl(QQuickPointerEvent *event) override;
void onActiveChanged() override;
- void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override;
bool hasCurrentPoints(QQuickPointerEvent *event);
QVector<QQuickEventPoint *> eligiblePoints(QQuickPointerEvent *event);
qreal averageTouchPointDistance(const QPointF &ref);
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 24f9885534..00376944c7 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -152,29 +152,6 @@ void QQuickPinchHandler::setMaximumRotation(qreal maximumRotation)
}
/*!
- \qmlproperty real QtQuick::PinchHandler::pinchOrigin
-
- The point to be held in place, around which the \l target is scaled and
- rotated.
-
- \value FirstPoint
- the first touch point, wherever the first finger is pressed
- \value PinchCenter
- the centroid between all the touch points at the time when the
- PinchHandler becomes \l active
- \value TargetCenter
- the center of the \l target
-*/
-void QQuickPinchHandler::setPinchOrigin(QQuickPinchHandler::PinchOrigin pinchOrigin)
-{
- if (m_pinchOrigin == pinchOrigin)
- return;
-
- m_pinchOrigin = pinchOrigin;
- emit pinchOriginChanged();
-}
-
-/*!
\qmlproperty real QtQuick::PinchHandler::minimumX
The minimum acceptable x coordinate of the centroid
@@ -445,7 +422,6 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
if (!active())
return;
}
- // TODO check m_pinchOrigin: right now it acts like it's set to PinchCenter
// avoid mapping the minima and maxima, as they might have unmappable values
// such as -inf/+inf. Because of this we perform the bounding to min/max in local coords.
@@ -523,8 +499,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
\qmlproperty QQuickHandlerPoint QtQuick::PinchHandler::centroid
A point exactly in the middle of the currently-pressed touch points.
- If \l pinchOrigin is set to \c PinchCenter, the \l target will be rotated
- around this point.
+ The \l target will be rotated around this point.
*/
/*!
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
index 6ec119ba72..8f24d18166 100644
--- a/src/quick/handlers/qquickpinchhandler_p.h
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -66,7 +66,6 @@ class Q_AUTOTEST_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
- Q_PROPERTY(PinchOrigin pinchOrigin READ pinchOrigin WRITE setPinchOrigin NOTIFY pinchOriginChanged)
Q_PROPERTY(qreal scale READ scale NOTIFY updated)
Q_PROPERTY(qreal activeScale READ activeScale NOTIFY updated)
Q_PROPERTY(qreal rotation READ rotation NOTIFY updated)
@@ -79,11 +78,6 @@ class Q_AUTOTEST_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
public:
- enum PinchOrigin {
- FirstPoint, PinchCenter, TargetCenter
- };
- Q_ENUM(PinchOrigin)
-
explicit QQuickPinchHandler(QQuickItem *parent = nullptr);
qreal minimumScale() const { return m_minimumScale; }
@@ -98,9 +92,6 @@ public:
qreal maximumRotation() const { return m_maximumRotation; }
void setMaximumRotation(qreal maximumRotation);
- PinchOrigin pinchOrigin() const { return m_pinchOrigin; }
- void setPinchOrigin(PinchOrigin pinchOrigin);
-
QVector2D translation() const { return m_activeTranslation; }
qreal scale() const { return m_accumulatedScale; }
qreal activeScale() const { return m_activeScale; }
@@ -126,7 +117,6 @@ signals:
void maximumXChanged();
void minimumYChanged();
void maximumYChanged();
- void pinchOriginChanged();
void updated();
protected:
@@ -154,8 +144,6 @@ private:
QQuickDragAxis m_xAxis;
QQuickDragAxis m_yAxis;
- PinchOrigin m_pinchOrigin = PinchOrigin::PinchCenter;
-
// internal
qreal m_startScale = 1;
qreal m_startRotation = 0;
@@ -166,8 +154,6 @@ private:
QVector<PointData> m_startAngles;
QMatrix4x4 m_startMatrix;
QQuickMatrix4x4 m_transform;
-
-
};
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index db58046e81..9b8281b519 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -116,7 +116,7 @@ void QQuickPointerHandler::setMargin(qreal pointDistanceThreshold)
Notification that the grab has changed in some way which is relevant to this handler.
The \a grabber (subject) will be the Input Handler whose state is changing,
or null if the state change regards an Item.
- The \a stateChange (verb) tells what happened.
+ The \a transition (verb) tells what happened.
The \a point (object) is the point that was grabbed or ungrabbed.
EventPoint has the sole responsibility to call this function.
The Input Handler must react in whatever way is appropriate, and must
@@ -125,13 +125,13 @@ void QQuickPointerHandler::setMargin(qreal pointDistanceThreshold)
call its parent class's implementation in addition to (usually after)
whatever custom behavior it implements.
*/
-void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
{
- qCDebug(lcPointerHandlerGrab) << point << stateChange << grabber;
+ qCDebug(lcPointerHandlerGrab) << point << transition << grabber;
Q_ASSERT(point);
if (grabber == this) {
bool wasCanceled = false;
- switch (stateChange) {
+ switch (transition) {
case QQuickEventPoint::GrabPassive:
case QQuickEventPoint::GrabExclusive:
break;
@@ -156,7 +156,7 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEv
}
if (wasCanceled)
emit canceled(point);
- emit grabChanged(stateChange, point);
+ emit grabChanged(transition, point);
}
}
@@ -500,12 +500,12 @@ void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event)
*/
/*!
- \qmlsignal QtQuick::PointerHandler::grabChanged(GrabState stateChange, EventPoint point)
+ \qmlsignal QtQuick::PointerHandler::grabChanged(GrabTransition transition, EventPoint point)
This signal is emitted when the grab has changed in some way which is
relevant to this handler.
- The \a stateChange (verb) tells what happened.
+ The \a transition (verb) tells what happened.
The \a point (object) is the point that was grabbed or ungrabbed.
*/
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index 69a38706b3..c600e42491 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -115,7 +115,7 @@ Q_SIGNALS:
void activeChanged();
void targetChanged();
void marginChanged();
- void grabChanged(QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point);
+ void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point);
void grabPermissionChanged();
void canceled(QQuickEventPoint *point);
@@ -132,7 +132,7 @@ protected:
void setActive(bool active);
virtual void onTargetChanged(QQuickItem *oldTarget) { Q_UNUSED(oldTarget); }
virtual void onActiveChanged() { }
- virtual void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point);
+ virtual void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point);
virtual bool canGrab(QQuickEventPoint *point);
virtual bool approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber);
void setPassiveGrab(QQuickEventPoint *point, bool grab = true);
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index 177ad21079..82e5b1b05d 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -138,19 +138,19 @@ void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
emit pointChanged();
}
-void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
{
if (grabber != this)
return;
- switch (stateChange) {
+ switch (transition) {
case QQuickEventPoint::GrabExclusive:
m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition();
setActive(true);
- QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ QQuickPointerHandler::onGrabChanged(grabber, transition, point);
break;
case QQuickEventPoint::GrabPassive:
m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition();
- QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ QQuickPointerHandler::onGrabChanged(grabber, transition, point);
break;
case QQuickEventPoint::OverrideGrabPassive:
return; // don't emit
@@ -159,11 +159,10 @@ void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQui
case QQuickEventPoint::CancelGrabPassive:
case QQuickEventPoint::CancelGrabExclusive:
// the grab is lost or relinquished, so the point is no longer relevant
- QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ QQuickPointerHandler::onGrabChanged(grabber, transition, point);
reset();
break;
}
- emit singlePointGrabChanged();
}
void QQuickSinglePointHandler::setIgnoreAdditionalPoints(bool v)
diff --git a/src/quick/handlers/qquicksinglepointhandler_p.h b/src/quick/handlers/qquicksinglepointhandler_p.h
index 6caf4294b8..b9e5b12224 100644
--- a/src/quick/handlers/qquicksinglepointhandler_p.h
+++ b/src/quick/handlers/qquicksinglepointhandler_p.h
@@ -67,7 +67,6 @@ public:
Q_SIGNALS:
void pointChanged();
- void singlePointGrabChanged(); // QQuickPointerHandler::grabChanged signal can't be a property notifier here
protected:
bool wantsPointerEvent(QQuickPointerEvent *event) override;
@@ -75,7 +74,7 @@ protected:
virtual void handleEventPoint(QQuickEventPoint *point) = 0;
QQuickEventPoint *currentPoint(QQuickPointerEvent *ev) { return ev->pointById(m_pointInfo.m_id); }
- void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override;
void setIgnoreAdditionalPoints(bool v = true);
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index 45240a62ab..e97722d6b7 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -313,10 +313,10 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi
}
}
-void QQuickTapHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+void QQuickTapHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
{
- QQuickSinglePointHandler::onGrabChanged(grabber, stateChange, point);
- bool isCanceled = stateChange == QQuickEventPoint::CancelGrabExclusive || stateChange == QQuickEventPoint::CancelGrabPassive;
+ QQuickSinglePointHandler::onGrabChanged(grabber, transition, point);
+ bool isCanceled = transition == QQuickEventPoint::CancelGrabExclusive || transition == QQuickEventPoint::CancelGrabPassive;
if (grabber == this && (isCanceled || point->state() == QQuickEventPoint::Released))
setPressed(false, isCanceled, point);
}
diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h
index 954175f161..6ec5d55227 100644
--- a/src/quick/handlers/qquicktaphandler_p.h
+++ b/src/quick/handlers/qquicktaphandler_p.h
@@ -100,7 +100,7 @@ Q_SIGNALS:
void longPressed();
protected:
- void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override;
void timerEvent(QTimerEvent *event) override;
bool wantsEventPoint(QQuickEventPoint *point) override;
void handleEventPoint(QQuickEventPoint *point) override;
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 4dec23d3ae..3623dcdf3a 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -281,7 +281,7 @@ public:
Q_DECLARE_FLAGS(States, State)
Q_FLAG(States)
- enum GrabState {
+ enum GrabTransition {
GrabPassive = 0x01,
UngrabPassive = 0x02,
CancelGrabPassive = 0x03,
@@ -290,7 +290,7 @@ public:
UngrabExclusive = 0x20,
CancelGrabExclusive = 0x30,
};
- Q_ENUM(GrabState)
+ Q_ENUM(GrabTransition)
QQuickEventPoint(QQuickPointerEvent *parent);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index b1438d7541..3eca535a67 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -610,6 +610,9 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
else { // QEvent::MouseButtonPress
addTouchPoint(me);
started = true;
+ _mouseQpaTouchPoint.setStartPos(me->localPos());
+ _mouseQpaTouchPoint.setStartScenePos(me->windowPos());
+ _mouseQpaTouchPoint.setStartScreenPos(me->screenPos());
_mouseQpaTouchPoint.setState(Qt::TouchPointPressed);
}
touchPoints << _mouseQpaTouchPoint;
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index f9a405db6d..bcb6729ab6 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -431,14 +431,7 @@ built-ins/Proxy/proxy-no-prototype.js fails
built-ins/Proxy/revocable/revocation-function-name.js fails
built-ins/Proxy/revocable/revocation-function-nonconstructor.js fails
built-ins/Proxy/set/trap-is-not-callable-realm.js fails
-built-ins/Proxy/set/trap-is-undefined-receiver.js fails
built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js fails
-built-ins/Reflect/set/creates-a-data-descriptor.js fails
-built-ins/Reflect/set/different-property-descriptors.js fails
-built-ins/Reflect/set/receiver-is-not-object.js fails
-built-ins/Reflect/set/return-false-if-target-is-not-writable.js fails
-built-ins/Reflect/set/set-value-on-data-descriptor.js fails
-built-ins/Reflect/set/symbol-property.js fails
built-ins/RegExp/S15.10.2.12_A2_T1.js fails
built-ins/RegExp/proto-from-ctor-realm.js fails
built-ins/RegExp/prototype/Symbol.match/builtin-success-u-return-val-groups.js fails
@@ -941,21 +934,9 @@ language/expressions/prefix-increment/S11.4.4_A5_T3.js sloppyFails
language/expressions/prefix-increment/S11.4.4_A5_T4.js sloppyFails
language/expressions/prefix-increment/S11.4.4_A5_T5.js fails
language/expressions/prefix-increment/S11.4.4_A6_T3.js fails
-language/expressions/super/prop-dot-cls-ref-strict.js fails
-language/expressions/super/prop-dot-cls-ref-this.js fails
-language/expressions/super/prop-dot-cls-this-uninit.js fails
language/expressions/super/prop-dot-cls-val-from-arrow.js fails
-language/expressions/super/prop-dot-obj-ref-non-strict.js sloppyFails
-language/expressions/super/prop-dot-obj-ref-strict.js strictFails
-language/expressions/super/prop-dot-obj-ref-this.js fails
language/expressions/super/prop-dot-obj-val-from-arrow.js fails
-language/expressions/super/prop-expr-cls-ref-strict.js fails
-language/expressions/super/prop-expr-cls-ref-this.js fails
-language/expressions/super/prop-expr-cls-this-uninit.js fails
language/expressions/super/prop-expr-cls-val-from-arrow.js fails
-language/expressions/super/prop-expr-obj-ref-non-strict.js sloppyFails
-language/expressions/super/prop-expr-obj-ref-strict.js strictFails
-language/expressions/super/prop-expr-obj-ref-this.js fails
language/expressions/super/prop-expr-obj-val-from-arrow.js fails
language/expressions/super/realm.js fails
language/expressions/tagged-template/cache-different-functions-same-site.js fails
@@ -1109,7 +1090,6 @@ language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.
language/statements/class/subclass/builtins.js fails
language/statements/class/subclass/class-definition-null-proto-this.js fails
language/statements/class/subclass/default-constructor-spread-override.js fails
-language/statements/class/super/in-methods.js fails
language/statements/do-while/tco-body.js strictFails
language/statements/for-in/head-lhs-let.js sloppyFails
language/statements/for-in/head-var-bound-names-let.js sloppyFails
@@ -1214,4 +1194,4 @@ language/statements/while/tco-body.js strictFails
language/statements/with/unscopables-inc-dec.js sloppyFails
language/types/reference/get-value-prop-base-primitive-realm.js fails
language/types/reference/put-value-prop-base-primitive-realm.js fails
-language/types/reference/put-value-prop-base-primitive.js fails
+language/types/reference/put-value-prop-base-primitive.js strictFails
diff --git a/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp b/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
index b2908ac5bb..095943cdc7 100644
--- a/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
+++ b/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
@@ -41,6 +41,7 @@ private slots:
void sweepFirstEntryInSameBucketWithDifferingHash();
void dontSweepAcrossBucketBoundaries();
void sweepAcrossBucketBoundariesIfFirstBucketFull();
+ void sweepBucketGap();
};
void tst_qv4identifiertable::sweepFirstEntryInBucket()
@@ -300,6 +301,63 @@ void tst_qv4identifiertable::sweepAcrossBucketBoundariesIfFirstBucketFull()
QCOMPARE(table.entriesByHash[3], nullptr);
}
+void tst_qv4identifiertable::sweepBucketGap()
+{
+ QV4::ExecutionEngine engine;
+ QV4::IdentifierTable table(&engine, /*numBits*/3);
+
+ auto entry1 = engine.newString(QStringLiteral("one"));
+ auto entry2 = engine.newString(QStringLiteral("two"));
+ auto entry3 = engine.newString(QStringLiteral("three"));
+ auto entry4 = engine.newString(QStringLiteral("four"));
+
+ entry1->createHashValue();
+ entry2->createHashValue();
+ entry3->createHashValue();
+ entry4->createHashValue();
+
+ // We have two buckets where the second entry in the first bucket
+ // flows into the second bucket. So insertion into the second bucket
+ // will shift by one and create
+ // [entry1][entry2 (would map to first but overflows into second), entry3, entry4]
+ // Garbage collecting the first entry should not only move the second entry
+ // into its own first bucket (where there is space now), it is also critical to
+ // not leave a gap but move the third and fourth entries to the beginning of
+ // their bucket:
+ // [entry2][entry3, entry4]
+ entry1->stringHash = 0; // % 11 -> 0
+ entry2->stringHash = 11; // % 11 -> 0, but ends up at idx 1 because 0 taken
+ entry3->stringHash = 12; // % 11 -> 1, but ends up at idx 2 because 1 taken
+ entry4->stringHash = 12; // % 11 -> 1, but ends up at idx 3 because 1+2 taken
+
+ // trigger insertion
+ table.asPropertyKey(entry1);
+ table.asPropertyKey(entry2);
+ table.asPropertyKey(entry3);
+ table.asPropertyKey(entry4);
+
+ QCOMPARE(table.size, 4);
+ QCOMPARE(table.alloc, 11);
+
+ QCOMPARE(table.entriesByHash[0], entry1);
+ QCOMPARE(table.entriesByHash[1], entry2);
+ QCOMPARE(table.entriesByHash[2], entry3);
+ QCOMPARE(table.entriesByHash[3], entry4);
+ QCOMPARE(table.entriesByHash[4], nullptr);
+
+ // first entry not marked
+ entry2->setMarkBit();
+ entry3->setMarkBit();
+ entry4->setMarkBit();
+
+ table.sweep();
+
+ QCOMPARE(table.entriesByHash[0], entry2);
+ QCOMPARE(table.entriesByHash[1], entry3);
+ QCOMPARE(table.entriesByHash[2], entry4);
+ QCOMPARE(table.entriesByHash[3], nullptr);
+}
+
QTEST_MAIN(tst_qv4identifiertable)
#include "tst_qv4identifiertable.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
index 2a9ec272fa..e8b076052a 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
@@ -51,14 +51,14 @@ public:
};
Q_ENUM(Destination)
- Event(Destination d, QEvent::Type t, Qt::TouchPointState s, int grabState, QPointF item, QPointF scene)
- : destination(d), type(t), state(s), grabState(grabState), posWrtItem(item), posWrtScene(scene)
+ Event(Destination d, QEvent::Type t, Qt::TouchPointState s, int grabTransition, QPointF item, QPointF scene)
+ : destination(d), type(t), state(s), grabTransition(grabTransition), posWrtItem(item), posWrtScene(scene)
{}
Destination destination;
QEvent::Type type; // if this represents a QEvent that was received
Qt::TouchPointState state; // if this represents an event (pointer, touch or mouse)
- int grabState; // if this represents an onGrabChanged() notification (QQuickEventPoint::GrabState)
+ int grabTransition; // if this represents an onGrabChanged() notification (QQuickEventPoint::GrabTransition)
QPointF posWrtItem;
QPointF posWrtScene;
};
@@ -73,9 +73,9 @@ QDebug operator<<(QDebug dbg, const class Event &event) {
QtDebugUtils::formatQEnum(dbg, event.type);
dbg << ' ';
QtDebugUtils::formatQEnum(dbg, event.state);
- if (event.grabState) {
+ if (event.grabTransition) {
dbg << ' ';
- QtDebugUtils::formatQEnum(dbg, QQuickEventPoint::GrabState(event.grabState));
+ QtDebugUtils::formatQEnum(dbg, QQuickEventPoint::GrabTransition(event.grabTransition));
}
dbg << " @ ";
QtDebugUtils::formatQPoint(dbg, event.posWrtItem);
@@ -98,7 +98,7 @@ public:
: QQuickItem(parent), acceptPointer(false), grabPointer(false), acceptMouse(false), acceptTouch(false), filterTouch(false)
{}
- inline int grabState(bool accept, Qt::TouchPointState state) {
+ inline int grabTransition(bool accept, Qt::TouchPointState state) {
return (accept && (state != Qt::TouchPointReleased)) ? (int)QQuickEventPoint::GrabExclusive : (int)NoGrab;
}
@@ -106,31 +106,31 @@ public:
{
qCDebug(lcPointerTests) << event << "will accept?" << acceptTouch;
for (const QTouchEvent::TouchPoint &tp : event->touchPoints())
- eventList.append(Event(Event::TouchDestination, event->type(), tp.state(), grabState(acceptTouch, tp.state()), tp.pos(), tp.scenePos()));
+ eventList.append(Event(Event::TouchDestination, event->type(), tp.state(), grabTransition(acceptTouch, tp.state()), tp.pos(), tp.scenePos()));
event->setAccepted(acceptTouch);
}
void mousePressEvent(QMouseEvent *event)
{
qCDebug(lcPointerTests) << event;
- eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabState(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabTransition(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
event->setAccepted(acceptMouse);
}
void mouseMoveEvent(QMouseEvent *event)
{
qCDebug(lcPointerTests) << event;
- eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointMoved, grabState(acceptMouse, Qt::TouchPointMoved), event->pos(), event->windowPos()));
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointMoved, grabTransition(acceptMouse, Qt::TouchPointMoved), event->pos(), event->windowPos()));
event->setAccepted(acceptMouse);
}
void mouseReleaseEvent(QMouseEvent *event)
{
qCDebug(lcPointerTests) << event;
- eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointReleased, grabState(acceptMouse, Qt::TouchPointReleased), event->pos(), event->windowPos()));
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointReleased, grabTransition(acceptMouse, Qt::TouchPointReleased), event->pos(), event->windowPos()));
event->setAccepted(acceptMouse);
}
void mouseDoubleClickEvent(QMouseEvent *event)
{
qCDebug(lcPointerTests) << event;
- eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabState(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabTransition(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
event->setAccepted(acceptMouse);
}
@@ -177,7 +177,7 @@ public:
QCOMPARE(event.destination, d);\
QCOMPARE(event.type, t);\
QCOMPARE(event.state, s);\
- QCOMPARE(event.grabState, g);\
+ QCOMPARE(event.grabTransition, g);\
}\
class EventHandler : public QQuickPointerHandler
@@ -204,7 +204,7 @@ class EventHandler : public QQuickPointerHandler
}
}
- void onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override
+ void onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabTransition stateChange, QQuickEventPoint *point) override
{
EventItem *item = static_cast<EventItem *>(target());
item->eventList.append(Event(Event::HandlerDestination, QEvent::None,
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
index f9970df9f0..467c964001 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -600,8 +600,8 @@ void tst_TapHandler::componentUserBehavioralOverride()
QQuickTapHandler *userTapHandler = button->findChild<QQuickTapHandler*>("override");
QVERIFY(userTapHandler);
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
- QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabState, QQuickEventPoint *)));
- QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabState, QQuickEventPoint *)));
+ QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabTransition, QQuickEventPoint *)));
+ QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabTransition, QQuickEventPoint *)));
QSignalSpy innerPressedChangedSpy(innerTapHandler, SIGNAL(pressedChanged()));
QSignalSpy userPressedChangedSpy(userTapHandler, SIGNAL(pressedChanged()));
diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/mouse.qml b/tests/auto/quick/qquickmultipointtoucharea/data/mouse.qml
index 0abcc76f7c..b0410dac4a 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/data/mouse.qml
+++ b/tests/auto/quick/qquickmultipointtoucharea/data/mouse.qml
@@ -6,6 +6,9 @@ MultiPointTouchArea {
property int touchCount: 0
property int cancelCount: 0
+ property int gestureStartedX: 0
+ property int gestureStartedY: 0
+ property bool grabGesture: false
minimumTouchPoints: 1
maximumTouchPoints: 4
@@ -17,6 +20,12 @@ MultiPointTouchArea {
onPressed: { touchCount = touchPoints.length }
onTouchUpdated: { touchCount = touchPoints.length }
onCanceled: { cancelCount = touchPoints.length }
+ onGestureStarted: {
+ gestureStartedX = gesture.touchPoints[0].startX
+ gestureStartedY = gesture.touchPoints[0].startY
+ if (grabGesture)
+ gesture.grab()
+ }
Rectangle {
color: "red"
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 73f3cab318..d4ad282701 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -69,6 +69,8 @@ private slots:
void transformedTouchArea();
void mouseInteraction();
void mouseInteraction_data();
+ void mouseGestureStarted_data();
+ void mouseGestureStarted();
void cancel();
private:
@@ -1196,6 +1198,57 @@ void tst_QQuickMultiPointTouchArea::mouseInteraction()
QCOMPARE(area->property("touchCount").toInt(), 0);
}
+void tst_QQuickMultiPointTouchArea::mouseGestureStarted_data()
+{
+ QTest::addColumn<bool>("grabGesture");
+ QTest::addColumn<int>("distanceFromOrigin");
+
+ QTest::newRow("near origin, don't grab") << false << 4;
+ QTest::newRow("near origin, grab") << true << 4;
+ QTest::newRow("away from origin, don't grab") << false << 100;
+ QTest::newRow("away from origin, grab") << true << 100;
+}
+
+void tst_QQuickMultiPointTouchArea::mouseGestureStarted() // QTBUG-70258
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QFETCH(bool, grabGesture);
+ QFETCH(int, distanceFromOrigin);
+
+ QScopedPointer<QQuickView> view(createAndShowView("mouse.qml"));
+ QVERIFY(view->rootObject() != nullptr);
+
+ QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(view->rootObject());
+ QVERIFY(area);
+ area->setProperty("grabGesture", grabGesture);
+ QQuickTouchPoint *point1 = view->rootObject()->findChild<QQuickTouchPoint*>("point1");
+ QCOMPARE(point1->pressed(), false);
+ QSignalSpy gestureStartedSpy(area, SIGNAL(gestureStarted(QQuickGrabGestureEvent *)));
+
+ QPoint p1 = QPoint(distanceFromOrigin, distanceFromOrigin);
+ QTest::mousePress(view.data(), Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(gestureStartedSpy.count(), 0);
+
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mouseMove(view.data(), p1);
+ QCOMPARE(gestureStartedSpy.count(), 0);
+
+ p1 += QPoint(1, 1);
+ QTest::mouseMove(view.data(), p1);
+ QTRY_COMPARE(gestureStartedSpy.count(), 1);
+ QTRY_COMPARE(area->property("gestureStartedX").toInt(), distanceFromOrigin);
+ QCOMPARE(area->property("gestureStartedY").toInt(), distanceFromOrigin);
+
+ p1 += QPoint(10, 10);
+ QTest::mouseMove(view.data(), p1);
+ // if nobody called gesteure->grab(), gestureStarted will keep happening
+ QTRY_COMPARE(gestureStartedSpy.count(), grabGesture ? 1 : 2);
+ QCOMPARE(area->property("gestureStartedX").toInt(), distanceFromOrigin);
+ QCOMPARE(area->property("gestureStartedY").toInt(), distanceFromOrigin);
+
+ QTest::mouseRelease(view.data(), Qt::LeftButton);
+}
+
void tst_QQuickMultiPointTouchArea::cancel()
{
QScopedPointer<QQuickView> window(createAndShowView("cancel.qml"));
diff --git a/tests/manual/pointer/singlePointHandlerProperties.qml b/tests/manual/pointer/singlePointHandlerProperties.qml
index 6ee88f9f9d..71bff2d829 100644
--- a/tests/manual/pointer/singlePointHandlerProperties.qml
+++ b/tests/manual/pointer/singlePointHandlerProperties.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -36,11 +36,11 @@ Rectangle {
Item {
id: crosshairs
- x: dragHandler.centroid.position.x - width / 2
- y: dragHandler.centroid.position.y - height / 2
+ x: pointHandler.point.position.x - width / 2
+ y: pointHandler.point.position.y - height / 2
width: parent.width / 2; height: parent.height / 2
- visible: dragHandler.active
- rotation: dragHandler.centroid.rotation
+ visible: pointHandler.active
+ rotation: pointHandler.point.rotation
Rectangle {
color: "goldenrod"
@@ -56,7 +56,7 @@ Rectangle {
}
Rectangle {
color: "goldenrod"
- width: Math.max(2, 50 * dragHandler.centroid.pressure)
+ width: Math.max(2, 50 * pointHandler.point.pressure)
height: width
radius: width / 2
anchors.centerIn: parent
@@ -69,9 +69,9 @@ Rectangle {
implicitHeight: label.implicitHeight
Text {
id: label
- text: 'id: ' + dragHandler.centroid.id.toString(16) + " uid: " + dragHandler.centroid.uniqueId.numericId +
- '\npos: (' + dragHandler.centroid.position.x.toFixed(2) + ', ' + dragHandler.centroid.position.y.toFixed(2) + ')' +
- '\nmodifiers: ' + dragHandler.centroid.modifiers.toString(16)
+ text: 'id: ' + pointHandler.point.id.toString(16) + " uid: " + pointHandler.point.uniqueId.numericId +
+ '\npos: (' + pointHandler.point.position.x.toFixed(2) + ', ' + pointHandler.point.position.y.toFixed(2) + ')' +
+ '\nmodifiers: ' + pointHandler.point.modifiers.toString(16)
}
}
}
@@ -79,8 +79,8 @@ Rectangle {
color: "transparent"
border.color: "white"
antialiasing: true
- width: dragHandler.centroid.ellipseDiameters.width
- height: dragHandler.centroid.ellipseDiameters.height
+ width: pointHandler.point.ellipseDiameters.width
+ height: pointHandler.point.ellipseDiameters.height
radius: Math.min(width / 2, height / 2)
anchors.centerIn: parent
}
@@ -88,11 +88,11 @@ Rectangle {
Rectangle {
id: velocityVector
visible: width > 0
- width: dragHandler.centroid.velocity.length() * 100
+ width: pointHandler.point.velocity.length() * 100
height: 2
- x: dragHandler.centroid.position.x
- y: dragHandler.centroid.position.y
- rotation: Math.atan2(dragHandler.centroid.velocity.y, dragHandler.centroid.velocity.x) * 180 / Math.PI
+ x: pointHandler.point.position.x
+ y: pointHandler.point.position.y
+ rotation: Math.atan2(pointHandler.point.velocity.y, pointHandler.point.velocity.x) * 180 / Math.PI
transformOrigin: Item.BottomLeft
antialiasing: true
@@ -135,17 +135,18 @@ Rectangle {
}
}
- DragHandler {
- id: dragHandler
+ PointHandler {
+ id: pointHandler
target: null
-// acceptedButtons: Qt.AllButtons // TODO: only SinglePointHandler has this so far
- onGrabChanged: if (active) {
- console.log("grabbed " + centroid.pointId + " @ " + centroid.sceneGrabPos)
- grabbingLocationIndicator.createObject(root, {"x": centroid.sceneGrabPosition.x, "y": centroid.sceneGrabPosition.y - 16})
+ acceptedButtons: Qt.AllButtons
+ onGrabChanged: if (active) { // 'point' is an implicit parameter referencing to a QQuickEventPoint instance
+ console.log("grabbed " + point.pointId + " @ " + point.sceneGrabPos)
+ grabbingLocationIndicator.createObject(root, {"x": point.sceneGrabPosition.x, "y": point.sceneGrabPosition.y - 16})
}
- onCentroidChanged: {
- if (centroid.pressedButtons)
- mouseButtonIndicator.createObject(root, {"x": centroid.pressPosition.x - 44, "y": centroid.pressPosition.y - 64, "buttons": centroid.pressedButtons})
+ onPointChanged: {
+ // Here, 'point' is referring to the property of the PointHandler
+ if (point.pressedButtons)
+ mouseButtonIndicator.createObject(root, {"x": point.pressPosition.x - 44, "y": point.pressPosition.y - 64, "buttons": point.pressedButtons})
}
}
}
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 5c5a6a8eb1..56bb633b9b 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -79,9 +79,9 @@
namespace {
const uint qtQmlMajorVersion = 2;
-const uint qtQmlMinorVersion = 2;
+const uint qtQmlMinorVersion = QT_VERSION_MINOR;
const uint qtQuickMajorVersion = 2;
-const uint qtQuickMinorVersion = 8;
+const uint qtQuickMinorVersion = QT_VERSION_MINOR;
const QString qtQuickQualifiedName = QString::fromLatin1("QtQuick %1.%2")
.arg(qtQuickMajorVersion)