QML: When available, use QQmlAccessors to read properties.
When a property is read from a QObject or the QML scope object, and we can statically resolve the type to qreal/QObject/int/bool/QString, and the property has an accessor declared for it, then use that accessor to do the read. This collapses the path of e.g.: Runtime::getQmlScopeObjectProperty -> QObjectWrapper::getProperty -> QObjectWrapper::getProperty -> LoadProperty -> QQmlAccessor::read (all of which do various checks for all the stuff mentioned above) to: Runtime::accessQmlScopeObjectQRealProperty -> QQmlAccessor::read which is a simple 4-line function, and doesn't need to do any check. According to valgrind, this saves 170 instructions on x86 for the simple binding: Item { width: height } Change-Id: I0761d01e8f1a3c13ecbffe2d8e0317ce9c0a4db0 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
parent
8ca22ca7eb
commit
f6fee09942
|
@ -81,9 +81,19 @@ QT_BEGIN_NAMESPACE
|
|||
F(SetLookup, setLookup) \
|
||||
F(StoreQObjectProperty, storeQObjectProperty) \
|
||||
F(LoadQObjectProperty, loadQObjectProperty) \
|
||||
F(LoadQRealQObjectPropertyDirectly, loadQRealQObjectPropertyDirectly) \
|
||||
F(LoadQObjectQObjectPropertyDirectly, loadQObjectQObjectPropertyDirectly) \
|
||||
F(LoadIntQObjectPropertyDirectly, loadIntQObjectPropertyDirectly) \
|
||||
F(LoadBoolQObjectPropertyDirectly, loadBoolQObjectPropertyDirectly) \
|
||||
F(LoadQStringQObjectPropertyDirectly, loadQStringQObjectPropertyDirectly) \
|
||||
F(StoreScopeObjectProperty, storeScopeObjectProperty) \
|
||||
F(StoreContextObjectProperty, storeContextObjectProperty) \
|
||||
F(LoadScopeObjectProperty, loadScopeObjectProperty) \
|
||||
F(LoadScopeObjectQRealPropertyDirectly, loadScopeObjectQRealPropertyDirectly) \
|
||||
F(LoadScopeObjectQObjectPropertyDirectly, loadScopeObjectQObjectPropertyDirectly) \
|
||||
F(LoadScopeObjectIntPropertyDirectly, loadScopeObjectIntPropertyDirectly) \
|
||||
F(LoadScopeObjectBoolPropertyDirectly, loadScopeObjectBoolPropertyDirectly) \
|
||||
F(LoadScopeObjectQStringPropertyDirectly, loadScopeObjectQStringPropertyDirectly) \
|
||||
F(LoadContextObjectProperty, loadContextObjectProperty) \
|
||||
F(LoadIdObject, loadIdObject) \
|
||||
F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \
|
||||
|
@ -323,6 +333,36 @@ union Instr
|
|||
Param base;
|
||||
Param result;
|
||||
};
|
||||
struct instr_loadScopeObjectQRealPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
};
|
||||
struct instr_loadScopeObjectQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
};
|
||||
struct instr_loadScopeObjectIntPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
};
|
||||
struct instr_loadScopeObjectBoolPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
};
|
||||
struct instr_loadScopeObjectQStringPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
};
|
||||
struct instr_loadContextObjectProperty {
|
||||
MOTH_INSTR_HEADER
|
||||
int propertyIndex;
|
||||
|
@ -342,6 +382,46 @@ union Instr
|
|||
Param result;
|
||||
bool captureRequired;
|
||||
};
|
||||
struct instr_loadQRealQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
int coreIndex;
|
||||
int notifyIndex;
|
||||
};
|
||||
struct instr_loadQObjectQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
int coreIndex;
|
||||
int notifyIndex;
|
||||
};
|
||||
struct instr_loadIntQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
int coreIndex;
|
||||
int notifyIndex;
|
||||
};
|
||||
struct instr_loadBoolQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
int coreIndex;
|
||||
int notifyIndex;
|
||||
};
|
||||
struct instr_loadQStringQObjectPropertyDirectly {
|
||||
MOTH_INSTR_HEADER
|
||||
Param base;
|
||||
Param result;
|
||||
QQmlAccessors *accessors;
|
||||
int coreIndex;
|
||||
int notifyIndex;
|
||||
};
|
||||
struct instr_loadAttachedQObjectProperty {
|
||||
MOTH_INSTR_HEADER
|
||||
int propertyIndex;
|
||||
|
@ -800,9 +880,19 @@ union Instr
|
|||
instr_loadProperty loadProperty;
|
||||
instr_getLookup getLookup;
|
||||
instr_loadScopeObjectProperty loadScopeObjectProperty;
|
||||
instr_loadScopeObjectQRealPropertyDirectly loadScopeObjectQRealPropertyDirectly;
|
||||
instr_loadScopeObjectQObjectPropertyDirectly loadScopeObjectQObjectPropertyDirectly;
|
||||
instr_loadScopeObjectIntPropertyDirectly loadScopeObjectIntPropertyDirectly;
|
||||
instr_loadScopeObjectBoolPropertyDirectly loadScopeObjectBoolPropertyDirectly;
|
||||
instr_loadScopeObjectQStringPropertyDirectly loadScopeObjectQStringPropertyDirectly;
|
||||
instr_loadContextObjectProperty loadContextObjectProperty;
|
||||
instr_loadIdObject loadIdObject;
|
||||
instr_loadQObjectProperty loadQObjectProperty;
|
||||
instr_loadQRealQObjectPropertyDirectly loadQRealQObjectPropertyDirectly;
|
||||
instr_loadQObjectQObjectPropertyDirectly loadQObjectQObjectPropertyDirectly;
|
||||
instr_loadIntQObjectPropertyDirectly loadIntQObjectPropertyDirectly;
|
||||
instr_loadBoolQObjectPropertyDirectly loadBoolQObjectPropertyDirectly;
|
||||
instr_loadQStringQObjectPropertyDirectly loadQStringQObjectPropertyDirectly;
|
||||
instr_loadAttachedQObjectProperty loadAttachedQObjectProperty;
|
||||
instr_storeProperty storeProperty;
|
||||
instr_setLookup setLookup;
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include <private/qv4regexpobject_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qqmlengine_p.h>
|
||||
#include "qml/qqmlaccessors_p.h"
|
||||
#include "qml/qqmlpropertycache_p.h"
|
||||
|
||||
#undef USE_TYPE_INFO
|
||||
|
||||
|
@ -737,8 +739,51 @@ void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *target
|
|||
addInstruction(store);
|
||||
}
|
||||
|
||||
void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target)
|
||||
void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind,
|
||||
QQmlPropertyData *property, int index,
|
||||
IR::Expr *target)
|
||||
{
|
||||
if (property && property->hasAccessors() && property->isFullyResolved()) {
|
||||
if (kind == IR::Member::MemberOfQmlScopeObject) {
|
||||
if (property->propType == QMetaType::QReal) {
|
||||
Instruction::LoadScopeObjectQRealPropertyDirectly load;
|
||||
load.base = getParam(source);
|
||||
load.accessors = property->accessors;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->isQObject()) {
|
||||
Instruction::LoadScopeObjectQObjectPropertyDirectly load;
|
||||
load.base = getParam(source);
|
||||
load.accessors = property->accessors;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Int) {
|
||||
Instruction::LoadScopeObjectIntPropertyDirectly load;
|
||||
load.base = getParam(source);
|
||||
load.accessors = property->accessors;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Bool) {
|
||||
Instruction::LoadScopeObjectBoolPropertyDirectly load;
|
||||
load.base = getParam(source);
|
||||
load.accessors = property->accessors;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::QString) {
|
||||
Instruction::LoadScopeObjectQStringPropertyDirectly load;
|
||||
load.base = getParam(source);
|
||||
load.accessors = property->accessors;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kind == IR::Member::MemberOfQmlScopeObject) {
|
||||
Instruction::LoadScopeObjectProperty load;
|
||||
load.base = getParam(source);
|
||||
|
@ -762,8 +807,59 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::M
|
|||
}
|
||||
}
|
||||
|
||||
void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
|
||||
void InstructionSelection::getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
|
||||
{
|
||||
if (property && property->hasAccessors() && property->isFullyResolved()) {
|
||||
if (!attachedPropertiesId && !isSingletonProperty) {
|
||||
if (property->propType == QMetaType::QReal) {
|
||||
Instruction::LoadQRealQObjectPropertyDirectly load;
|
||||
load.base = getParam(base);
|
||||
load.accessors = property->accessors;
|
||||
load.coreIndex = property->coreIndex;
|
||||
load.notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->isQObject()) {
|
||||
Instruction::LoadQObjectQObjectPropertyDirectly load;
|
||||
load.base = getParam(base);
|
||||
load.accessors = property->accessors;
|
||||
load.coreIndex = property->coreIndex;
|
||||
load.notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Int) {
|
||||
Instruction::LoadIntQObjectPropertyDirectly load;
|
||||
load.base = getParam(base);
|
||||
load.accessors = property->accessors;
|
||||
load.coreIndex = property->coreIndex;
|
||||
load.notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Bool) {
|
||||
Instruction::LoadBoolQObjectPropertyDirectly load;
|
||||
load.base = getParam(base);
|
||||
load.accessors = property->accessors;
|
||||
load.coreIndex = property->coreIndex;
|
||||
load.notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
} else if (property->propType == QMetaType::QString) {
|
||||
Instruction::LoadQStringQObjectPropertyDirectly load;
|
||||
load.base = getParam(base);
|
||||
load.accessors = property->accessors;
|
||||
load.coreIndex = property->coreIndex;
|
||||
load.notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
load.result = getResultParam(target);
|
||||
addInstruction(load);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const int propertyIndex = property->coreIndex;
|
||||
if (attachedPropertiesId != 0) {
|
||||
Instruction::LoadAttachedQObjectProperty load;
|
||||
load.propertyIndex = propertyIndex;
|
||||
|
|
|
@ -134,8 +134,8 @@ protected:
|
|||
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
|
||||
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
|
||||
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target);
|
||||
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target);
|
||||
virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
|
||||
virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target);
|
||||
virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex);
|
||||
virtual void copyValue(IR::Expr *source, IR::Expr *target);
|
||||
|
|
|
@ -156,14 +156,15 @@ void IRDecoder::visitMove(IR::Move *s)
|
|||
}
|
||||
}
|
||||
if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) {
|
||||
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex, s->target);
|
||||
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property,
|
||||
m->property->coreIndex, s->target);
|
||||
return;
|
||||
}
|
||||
getQObjectProperty(m->base, m->property->coreIndex, captureRequired, isSingletonProperty, attachedPropertiesId, s->target);
|
||||
getQObjectProperty(m->base, m->property, captureRequired, isSingletonProperty, attachedPropertiesId, s->target);
|
||||
#endif // V4_BOOTSTRAP
|
||||
return;
|
||||
} else if (m->kind == IR::Member::MemberOfIdObjectsArray) {
|
||||
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->idIndex, s->target);
|
||||
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, nullptr, m->idIndex, s->target);
|
||||
return;
|
||||
} else if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) {
|
||||
getProperty(m->base, *m->name, s->target);
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QQmlAccessors;
|
||||
class QQmlEnginePrivate;
|
||||
|
||||
namespace QV4 {
|
||||
|
@ -165,8 +166,8 @@ public: // to implement by subclasses:
|
|||
virtual void setActivationProperty(IR::Expr *source, const QString &targetName) = 0;
|
||||
virtual void initClosure(IR::Closure *closure, IR::Expr *target) = 0;
|
||||
virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) = 0;
|
||||
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0;
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target) = 0;
|
||||
virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0;
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target) = 0;
|
||||
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) = 0;
|
||||
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) = 0;
|
||||
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) = 0;
|
||||
|
|
|
@ -927,12 +927,16 @@ void IRPrinter::visitMember(Member *e)
|
|||
e->base->accept(this);
|
||||
*out << '.' << *e->name;
|
||||
#ifndef V4_BOOTSTRAP
|
||||
if (e->property)
|
||||
if (e->property) {
|
||||
*out << " (meta-property " << e->property->coreIndex
|
||||
<< " <" << QMetaType::typeName(e->property->propType)
|
||||
<< ">)";
|
||||
else if (e->kind == Member::MemberOfIdObjectsArray)
|
||||
<< " <" << QMetaType::typeName(e->property->propType) << ">";
|
||||
if (e->property->hasAccessors() && e->property->isFullyResolved()) {
|
||||
*out << ", accessible";
|
||||
}
|
||||
*out << ")";
|
||||
} else if (e->kind == Member::MemberOfIdObjectsArray) {
|
||||
*out << "(id object " << e->idIndex << ")";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "qv4assembler_p.h"
|
||||
#include "qv4unop_p.h"
|
||||
#include "qv4binop_p.h"
|
||||
#include <private/qqmlpropertycache_p.h>
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
@ -753,8 +754,39 @@ void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::
|
|||
}
|
||||
}
|
||||
|
||||
void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, IR::Expr *target)
|
||||
void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target)
|
||||
{
|
||||
if (property && property->hasAccessors() && property->isFullyResolved()) {
|
||||
if (kind == IR::Member::MemberOfQmlScopeObject) {
|
||||
if (property->propType == QMetaType::QReal) {
|
||||
generateRuntimeCall(target, accessQmlScopeObjectQRealProperty,
|
||||
Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors));
|
||||
return;
|
||||
} else if (property->isQObject()) {
|
||||
generateRuntimeCall(target, accessQmlScopeObjectQObjectProperty,
|
||||
Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Int) {
|
||||
generateRuntimeCall(target, accessQmlScopeObjectIntProperty,
|
||||
Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Bool) {
|
||||
generateRuntimeCall(target, accessQmlScopeObjectBoolProperty,
|
||||
Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::QString) {
|
||||
generateRuntimeCall(target, accessQmlScopeObjectQStringProperty,
|
||||
Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kind == IR::Member::MemberOfQmlScopeObject)
|
||||
generateRuntimeCall(target, getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
|
||||
else if (kind == IR::Member::MemberOfQmlContextObject)
|
||||
|
@ -765,8 +797,51 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::Mem
|
|||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target)
|
||||
void InstructionSelection::getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target)
|
||||
{
|
||||
if (property && property->hasAccessors() && property->isFullyResolved()) {
|
||||
if (!attachedPropertiesId && !isSingleton) {
|
||||
const int notifyIndex = captureRequired ? property->notifyIndex : -1;
|
||||
if (property->propType == QMetaType::QReal) {
|
||||
generateRuntimeCall(target, accessQObjectQRealProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors),
|
||||
Assembler::TrustedImm32(property->coreIndex),
|
||||
Assembler::TrustedImm32(notifyIndex));
|
||||
return;
|
||||
} else if (property->isQObject()) {
|
||||
generateRuntimeCall(target, accessQObjectQObjectProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors),
|
||||
Assembler::TrustedImm32(property->coreIndex),
|
||||
Assembler::TrustedImm32(notifyIndex));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Int) {
|
||||
generateRuntimeCall(target, accessQObjectIntProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors),
|
||||
Assembler::TrustedImm32(property->coreIndex),
|
||||
Assembler::TrustedImm32(notifyIndex));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::Bool) {
|
||||
generateRuntimeCall(target, accessQObjectBoolProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors),
|
||||
Assembler::TrustedImm32(property->coreIndex),
|
||||
Assembler::TrustedImm32(notifyIndex));
|
||||
return;
|
||||
} else if (property->propType == QMetaType::QString) {
|
||||
generateRuntimeCall(target, accessQObjectQStringProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToValue(base),
|
||||
Assembler::TrustedImmPtr(property->accessors),
|
||||
Assembler::TrustedImm32(property->coreIndex),
|
||||
Assembler::TrustedImm32(notifyIndex));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int propertyIndex = property->coreIndex;
|
||||
if (attachedPropertiesId != 0)
|
||||
generateRuntimeCall(target, getQmlAttachedProperty, Assembler::EngineRegister, Assembler::TrustedImm32(attachedPropertiesId), Assembler::TrustedImm32(propertyIndex));
|
||||
else if (isSingleton)
|
||||
|
|
|
@ -124,8 +124,8 @@ protected:
|
|||
virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
|
||||
virtual void initClosure(IR::Closure *closure, IR::Expr *target);
|
||||
virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target);
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target);
|
||||
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
|
||||
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target);
|
||||
virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
|
||||
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
|
||||
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
|
||||
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
|
||||
|
|
|
@ -528,14 +528,14 @@ protected: // IRDecoder
|
|||
addCall();
|
||||
}
|
||||
|
||||
virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/, IR::Expr *target)
|
||||
virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, QQmlPropertyData * /*property*/, int /*index*/, IR::Expr *target)
|
||||
{
|
||||
addDef(target);
|
||||
addUses(base->asTemp(), Use::CouldHaveRegister);
|
||||
addCall();
|
||||
}
|
||||
|
||||
virtual void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target)
|
||||
virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData * /*property*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target)
|
||||
{
|
||||
addDef(target);
|
||||
addUses(base->asTemp(), Use::CouldHaveRegister);
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include <private/qqmldata_p.h>
|
||||
#include <private/qqmlpropertycache_p.h>
|
||||
#include <private/qintrusivelist_p.h>
|
||||
#include <private/qqmlaccessors_p.h>
|
||||
|
||||
#include <private/qv4value_p.h>
|
||||
#include <private/qv4functionobject_p.h>
|
||||
|
|
|
@ -1415,6 +1415,116 @@ ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, con
|
|||
return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->object(), propertyIndex, captureRequired);
|
||||
}
|
||||
|
||||
template <typename PropertyType>
|
||||
static inline PropertyType getQObjectProperty(QObject *object, ExecutionEngine *engine, QQmlAccessors *accessors, int coreIndex, int notifyIndex)
|
||||
{
|
||||
PropertyType t;
|
||||
accessors->read(object, &t);
|
||||
if (notifyIndex != -1) {
|
||||
QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
|
||||
if (ep && ep->propertyCapture) {
|
||||
if (accessors->notifier) {
|
||||
QQmlNotifier *n = nullptr;
|
||||
accessors->notifier(object, &n);
|
||||
if (n) {
|
||||
ep->propertyCapture->captureProperty(n);
|
||||
}
|
||||
} else {
|
||||
ep->propertyCapture->captureProperty(object, coreIndex, notifyIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQObjectQRealProperty(ExecutionEngine *engine,
|
||||
const Value &object,
|
||||
QQmlAccessors *accessors, int coreIndex,
|
||||
int notifyIndex)
|
||||
{
|
||||
auto casted = object.as<QObjectWrapper>();
|
||||
QObject *o = casted ? casted->object() : nullptr;
|
||||
if (Q_LIKELY(o)) {
|
||||
return QV4::Encode(getQObjectProperty<qreal>(o, engine, accessors, coreIndex, notifyIndex));
|
||||
}
|
||||
engine->throwTypeError(QStringLiteral("Cannot read property of null"));
|
||||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQObjectQObjectProperty(ExecutionEngine *engine,
|
||||
const Value &object,
|
||||
QQmlAccessors *accessors, int coreIndex,
|
||||
int notifyIndex)
|
||||
{
|
||||
auto casted = object.as<QObjectWrapper>();
|
||||
QObject *o = casted ? casted->object() : nullptr;
|
||||
if (Q_LIKELY(o)) {
|
||||
return QV4::QObjectWrapper::wrap(engine, getQObjectProperty<QObject *>(o, engine, accessors,
|
||||
coreIndex,
|
||||
notifyIndex));
|
||||
}
|
||||
|
||||
engine->throwTypeError(QStringLiteral("Cannot read property of null"));
|
||||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQObjectIntProperty(ExecutionEngine *engine, const Value &object,
|
||||
QQmlAccessors *accessors, int coreIndex,
|
||||
int notifyIndex)
|
||||
{
|
||||
auto casted = object.as<QObjectWrapper>();
|
||||
QObject *o = casted ? casted->object() : nullptr;
|
||||
if (Q_LIKELY(o)) {
|
||||
return QV4::Encode(getQObjectProperty<int>(o, engine, accessors, coreIndex, notifyIndex));
|
||||
}
|
||||
engine->throwTypeError(QStringLiteral("Cannot read property of null"));
|
||||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQObjectBoolProperty(ExecutionEngine *engine, const Value &object,
|
||||
QQmlAccessors *accessors, int coreIndex,
|
||||
int notifyIndex)
|
||||
{
|
||||
auto casted = object.as<QObjectWrapper>();
|
||||
QObject *o = casted ? casted->object() : nullptr;
|
||||
if (Q_LIKELY(o)) {
|
||||
return QV4::Encode(getQObjectProperty<bool>(o, engine, accessors, coreIndex, notifyIndex));
|
||||
}
|
||||
engine->throwTypeError(QStringLiteral("Cannot read property of null"));
|
||||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQObjectQStringProperty(ExecutionEngine *engine,
|
||||
const Value &object,
|
||||
QQmlAccessors *accessors, int coreIndex,
|
||||
int notifyIndex)
|
||||
{
|
||||
auto casted = object.as<QObjectWrapper>();
|
||||
QObject *o = casted ? casted->object() : nullptr;
|
||||
if (Q_LIKELY(o)) {
|
||||
return QV4::Encode(engine->newString(getQObjectProperty<QString>(o, engine, accessors,
|
||||
coreIndex, notifyIndex)));
|
||||
}
|
||||
engine->throwTypeError(QStringLiteral("Cannot read property of null"));
|
||||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::method_accessQmlScopeObjectQObjectProperty(const Value &context,
|
||||
QQmlAccessors *accessors)
|
||||
{
|
||||
#ifndef V4_BOOTSTRAP
|
||||
const QmlContext &c = static_cast<const QmlContext &>(context);
|
||||
QObject *rv = 0;
|
||||
accessors->read(c.d()->qml->scopeObject, &rv);
|
||||
return QV4::QObjectWrapper::wrap(c.engine(), rv);
|
||||
#else
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(accessors);
|
||||
return QV4::Encode::undefined();
|
||||
#endif
|
||||
}
|
||||
|
||||
QV4::ReturnedValue Runtime::method_getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)
|
||||
{
|
||||
QObject *scopeObject = engine->qmlScopeObject();
|
||||
|
|
|
@ -56,8 +56,12 @@
|
|||
#include "qv4engine_p.h"
|
||||
#include "qv4math_p.h"
|
||||
#include "qv4runtimeapi_p.h"
|
||||
#include <QtCore/qnumeric.h>
|
||||
#ifndef V4_BOOTSTRAP
|
||||
#include <private/qqmlaccessors_p.h>
|
||||
#include <private/qqmlcontextwrapper_p.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/qnumeric.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -417,6 +421,68 @@ inline Bool Runtime::method_toBoolean(const Value &value)
|
|||
return value.toBoolean();
|
||||
}
|
||||
|
||||
inline ReturnedValue Runtime::method_accessQmlScopeObjectQRealProperty(const Value &context,
|
||||
QQmlAccessors *accessors)
|
||||
{
|
||||
#ifndef V4_BOOTSTRAP
|
||||
const QmlContext &c = static_cast<const QmlContext &>(context);
|
||||
qreal rv = 0;
|
||||
accessors->read(c.d()->qml->scopeObject, &rv);
|
||||
return QV4::Encode(rv);
|
||||
#else
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(accessors);
|
||||
return QV4::Encode::undefined();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline ReturnedValue Runtime::method_accessQmlScopeObjectIntProperty(const Value &context,
|
||||
QQmlAccessors *accessors)
|
||||
{
|
||||
#ifndef V4_BOOTSTRAP
|
||||
const QmlContext &c = static_cast<const QmlContext &>(context);
|
||||
int rv = 0;
|
||||
accessors->read(c.d()->qml->scopeObject, &rv);
|
||||
return QV4::Encode(rv);
|
||||
#else
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(accessors);
|
||||
return QV4::Encode::undefined();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline ReturnedValue Runtime::method_accessQmlScopeObjectBoolProperty(const Value &context,
|
||||
QQmlAccessors *accessors)
|
||||
{
|
||||
#ifndef V4_BOOTSTRAP
|
||||
const QmlContext &c = static_cast<const QmlContext &>(context);
|
||||
bool rv = false;
|
||||
accessors->read(c.d()->qml->scopeObject, &rv);
|
||||
return QV4::Encode(rv);
|
||||
#else
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(accessors);
|
||||
return QV4::Encode::undefined();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline ReturnedValue Runtime::method_accessQmlScopeObjectQStringProperty(ExecutionEngine *engine,
|
||||
const Value &context,
|
||||
QQmlAccessors *accessors)
|
||||
{
|
||||
#ifndef V4_BOOTSTRAP
|
||||
const QmlContext &c = static_cast<const QmlContext &>(context);
|
||||
QString rv;
|
||||
accessors->read(c.d()->qml->scopeObject, &rv);
|
||||
return QV4::Encode(engine->newString(rv));
|
||||
#else
|
||||
Q_UNUSED(engine);
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(accessors);
|
||||
return QV4::Encode::undefined();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QV4
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -156,6 +156,16 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
|
|||
, INIT_RUNTIME_METHOD(setQmlScopeObjectProperty)
|
||||
, INIT_RUNTIME_METHOD(setQmlContextObjectProperty)
|
||||
, INIT_RUNTIME_METHOD(setQmlQObjectProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQObjectQRealProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQObjectQObjectProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQObjectIntProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQObjectBoolProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQObjectQStringProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQmlScopeObjectQRealProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQmlScopeObjectQObjectProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQmlScopeObjectIntProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQmlScopeObjectBoolProperty)
|
||||
, INIT_RUNTIME_METHOD(accessQmlScopeObjectQStringProperty)
|
||||
{ }
|
||||
|
||||
// call
|
||||
|
@ -292,6 +302,17 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
|
|||
RUNTIME_METHOD(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value));
|
||||
RUNTIME_METHOD(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value));
|
||||
RUNTIME_METHOD(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value));
|
||||
|
||||
RUNTIME_METHOD(ReturnedValue, accessQObjectQRealProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQObjectQObjectProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQObjectIntProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQObjectBoolProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQObjectQStringProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQRealProperty, (const Value &context, QQmlAccessors *accessors));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQObjectProperty, (const Value &context, QQmlAccessors *accessors));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectIntProperty, (const Value &context, QQmlAccessors *accessors));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectBoolProperty, (const Value &context, QQmlAccessors *accessors));
|
||||
RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQStringProperty, (ExecutionEngine *engine, const Value &context, QQmlAccessors *accessors));
|
||||
};
|
||||
|
||||
#undef RUNTIME_METHOD
|
||||
|
|
|
@ -519,6 +519,26 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
STOREVALUE(instr.result, engine->runtime.getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
|
||||
MOTH_END_INSTR(LoadQObjectProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadQRealQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQObjectQRealProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex));
|
||||
MOTH_END_INSTR(LoadQRealQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadQObjectQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQObjectQObjectProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex));
|
||||
MOTH_END_INSTR(LoadQObjectQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadIntQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQObjectIntProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex));
|
||||
MOTH_END_INSTR(LoadIntQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadBoolQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQObjectBoolProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex));
|
||||
MOTH_END_INSTR(LoadQRealQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadQStringQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQObjectQStringProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex));
|
||||
MOTH_END_INSTR(LoadQStringQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
|
||||
engine->runtime.setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
|
||||
CHECK_EXCEPTION;
|
||||
|
@ -528,6 +548,26 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
STOREVALUE(instr.result, engine->runtime.getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex));
|
||||
MOTH_END_INSTR(LoadScopeObjectProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadScopeObjectQRealPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQRealProperty(VALUE(instr.base), instr.accessors));
|
||||
MOTH_END_INSTR(LoadScopeObjectQRealPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadScopeObjectQObjectPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQObjectProperty(VALUE(instr.base), instr.accessors));
|
||||
MOTH_END_INSTR(LoadScopeObjectQObjectPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadScopeObjectIntPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectIntProperty(VALUE(instr.base), instr.accessors));
|
||||
MOTH_END_INSTR(LoadScopeObjectIntPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadScopeObjectBoolPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectBoolProperty(VALUE(instr.base), instr.accessors));
|
||||
MOTH_END_INSTR(LoadScopeObjectBoolPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadScopeObjectQStringPropertyDirectly)
|
||||
STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQStringProperty(engine, VALUE(instr.base), instr.accessors));
|
||||
MOTH_END_INSTR(LoadScopeObjectQStringPropertyDirectly)
|
||||
|
||||
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
|
||||
engine->runtime.setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
|
||||
CHECK_EXCEPTION;
|
||||
|
|
|
@ -162,6 +162,8 @@ public:
|
|||
overrideIndex >= 0; }
|
||||
bool hasRevision() const { return !(flags & HasAccessors) && revision != 0; }
|
||||
|
||||
bool isFullyResolved() const { return !(flags & NotFullyResolved); }
|
||||
|
||||
// Returns -1 if not a value type virtual property
|
||||
inline int getValueTypeCoreIndex() const;
|
||||
|
||||
|
|
|
@ -68,6 +68,12 @@ private slots:
|
|||
void itemtests_qml_data();
|
||||
void itemtests_qml();
|
||||
|
||||
void bindings_cpp();
|
||||
void bindings_cpp2();
|
||||
void bindings_qml();
|
||||
|
||||
void bindings_parent_qml();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
};
|
||||
|
@ -373,6 +379,89 @@ void tst_creation::itemtests_qml()
|
|||
QBENCHMARK { delete component.create(); }
|
||||
}
|
||||
|
||||
void tst_creation::bindings_cpp()
|
||||
{
|
||||
QQuickItem item;
|
||||
QMetaProperty widthProp = item.metaObject()->property(item.metaObject()->indexOfProperty("width"));
|
||||
QMetaProperty heightProp = item.metaObject()->property(item.metaObject()->indexOfProperty("height"));
|
||||
connect(&item, &QQuickItem::heightChanged, [&item, &widthProp, &heightProp](){
|
||||
QVariant height = heightProp.read(&item);
|
||||
widthProp.write(&item, height);
|
||||
});
|
||||
|
||||
int height = 0;
|
||||
QBENCHMARK {
|
||||
item.setHeight(++height);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_creation::bindings_cpp2()
|
||||
{
|
||||
QQuickItem item;
|
||||
int widthProp = item.metaObject()->indexOfProperty("width");
|
||||
int heightProp = item.metaObject()->indexOfProperty("height");
|
||||
connect(&item, &QQuickItem::heightChanged, [&item, widthProp, heightProp](){
|
||||
|
||||
qreal height = -1;
|
||||
void *args[] = { &height, 0 };
|
||||
QMetaObject::metacall(&item, QMetaObject::ReadProperty, heightProp, args);
|
||||
|
||||
int flags = 0;
|
||||
int status = -1;
|
||||
void *argv[] = { &height, 0, &status, &flags };
|
||||
QMetaObject::metacall(&item, QMetaObject::WriteProperty, widthProp, argv);
|
||||
});
|
||||
|
||||
int height = 0;
|
||||
QBENCHMARK {
|
||||
item.setHeight(++height);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_creation::bindings_qml()
|
||||
{
|
||||
QByteArray data = "import QtQuick 2.0\nItem { width: height }";
|
||||
|
||||
QQmlComponent component(&engine);
|
||||
component.setData(data, QUrl());
|
||||
if (!component.isReady()) {
|
||||
qWarning() << "Unable to create component: " << component.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
|
||||
QVERIFY(obj != nullptr);
|
||||
|
||||
int height = 0;
|
||||
QBENCHMARK {
|
||||
obj->setHeight(++height);
|
||||
}
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
||||
void tst_creation::bindings_parent_qml()
|
||||
{
|
||||
QByteArray data = "import QtQuick 2.0\nItem { Item { width: parent.height }}";
|
||||
|
||||
QQmlComponent component(&engine);
|
||||
component.setData(data, QUrl());
|
||||
if (!component.isReady()) {
|
||||
qWarning() << "Unable to create component: " << component.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
|
||||
QVERIFY(obj != nullptr);
|
||||
|
||||
int height = 0;
|
||||
QBENCHMARK {
|
||||
obj->setHeight(++height);
|
||||
}
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_creation)
|
||||
|
||||
#include "tst_creation.moc"
|
||||
|
|
Loading…
Reference in New Issue