6#include <private/qqmlobjectorgadget_p.h>
7#include <private/qqmlengine_p.h>
8#include <private/qqmlvmemetaobject_p.h>
9#include <private/qqmlbinding_p.h>
10#include <private/qjsvalue_p.h>
11#include <private/qqmlexpression_p.h>
12#include <private/qqmlglobal_p.h>
13#include <private/qqmltypewrapper_p.h>
14#include <private/qqmlvaluetypewrapper_p.h>
15#include <private/qqmllistwrapper_p.h>
16#include <private/qqmlbuiltinfunctions_p.h>
17#if QT_CONFIG(qml_locale)
18#include <private/qqmllocale_p.h>
21#include <private/qv4arraybuffer_p.h>
22#include <private/qv4functionobject_p.h>
23#include <private/qv4runtime_p.h>
24#include <private/qv4variantobject_p.h>
25#include <private/qv4identifiertable_p.h>
26#include <private/qv4lookup_p.h>
27#include <private/qv4qmlcontext_p.h>
28#include <private/qv4sequenceobject_p.h>
29#include <private/qv4objectproto_p.h>
30#include <private/qv4jsonobject_p.h>
31#include <private/qv4regexpobject_p.h>
32#include <private/qv4dateobject_p.h>
33#include <private/qv4scopedvalue_p.h>
34#include <private/qv4jscall_p.h>
35#include <private/qv4mm_p.h>
36#include <private/qqmlscriptstring_p.h>
37#include <private/qv4compileddata_p.h>
38#include <private/qqmlpropertybinding_p.h>
39#include <private/qqmlpropertycachemethodarguments_p.h>
40#include <private/qqmlsignalnames_p.h>
42#include <QtQml/qjsvalue.h>
43#include <QtCore/qjsonarray.h>
44#include <QtCore/qjsonobject.h>
45#include <QtCore/qjsonvalue.h>
46#include <QtCore/qvarlengtharray.h>
47#include <QtCore/qtimer.h>
48#include <QtCore/qatomic.h>
49#include <QtCore/qmetaobject.h>
50#if QT_CONFIG(qml_itemmodel)
51#include <QtCore/qabstractitemmodel.h>
53#include <QtCore/qloggingcategory.h>
54#include <QtCore/qqueue.h>
55#include <QtCore/qtypes.h>
70using namespace
Qt::StringLiterals;
74QPair<QObject *, int> QObjectMethod::extractQtMethod(
const FunctionObject *function)
89 if (
value.isObject()) {
94 return QObjectMethod::extractQtMethod(function);
96 Scoped<QmlSignalHandler> handler(scope,
value);
98 return qMakePair(handler->object(), handler->signalIndex());
108 Heap::ReferenceObject::Flags
flags = Heap::ReferenceObject::NoFlag;
110 if (stackFrame->v4Function->executableCompilationUnit()->valueTypesAreCopied())
111 flags |= Heap::ReferenceObject::EnforcesLocation;
115 flags |= Heap::ReferenceObject::CanWriteBack;
127 const QMetaType propMetaType =
property.propType();
130 property.readProperty(
object, &rv);
132 return QObjectWrapper::wrapConst(v4, rv);
134 return QObjectWrapper::wrap(v4, rv);
138 return QmlListWrapper::create(v4,
object,
property.coreIndex(), propMetaType);
140 const auto encodeSimple = [&](
auto v) {
141 property.readProperty(
object, &
v);
145 const auto encodeInt = [&](
auto v) {
146 property.readProperty(
object, &
v);
150 const auto encodeDouble = [&](
auto v) {
151 property.readProperty(
object, &
v);
155 const auto encodeDate = [&](
auto v) {
156 property.readProperty(
object, &
v);
161 const auto encodeString = [&](
auto v) {
162 property.readProperty(
object, &
v);
166 const auto encodeSequence = [&](
QMetaSequence metaSequence) {
169 v4, propMetaType, metaSequence,
nullptr,
174 switch (
property.isEnum() ? propMetaType.underlyingType().id() : propMetaType.id()) {
176 case QMetaType::Void:
177 return Encode::undefined();
178 case QMetaType::Nullptr:
179 case QMetaType::VoidStar:
180 return Encode::null();
182 return encodeSimple(
int());
183 case QMetaType::Bool:
184 return encodeSimple(
bool());
185 case QMetaType::QString:
186 return encodeString(
QString());
187 case QMetaType::QByteArray: {
189 property.readProperty(
object, &
v);
192 case QMetaType::QChar:
193 return encodeString(
QChar());
194 case QMetaType::Char16:
195 return encodeString(
char16_t());
196 case QMetaType::UInt:
197 return encodeSimple(
uint());
198 case QMetaType::Float:
199 return encodeSimple(
float());
200 case QMetaType::Double:
201 return encodeSimple(
double());
202 case QMetaType::Short:
203 return encodeInt(
short());
204 case QMetaType::UShort:
205 return encodeInt(
ushort());
206 case QMetaType::Char:
207 return encodeInt(
char());
208 case QMetaType::UChar:
209 return encodeInt(
uchar());
210 case QMetaType::SChar:
211 return encodeInt(
qint8());
212 case QMetaType::Long:
213 return encodeDouble(
long());
214 case QMetaType::ULong:
215 return encodeDouble(
ulong());
216 case QMetaType::LongLong:
218 case QMetaType::ULongLong:
220 case QMetaType::QDateTime:
222 case QMetaType::QDate:
223 return encodeDate(
QDate());
224 case QMetaType::QTime:
225 return encodeDate(
QTime());
226#if QT_CONFIG(regularexpression)
227 case QMetaType::QRegularExpression: {
229 property.readProperty(
object, &
v);
233 case QMetaType::QVariantMap: {
235 property.readProperty(
object, &
v);
239 case QMetaType::QJsonValue: {
241 property.readProperty(
object, &
v);
244 case QMetaType::QJsonObject: {
246 property.readProperty(
object, &
v);
249 case QMetaType::QJsonArray: {
251 property.readProperty(
object, &
v);
254 case QMetaType::QStringList:
255 return encodeSequence(QMetaSequence::fromContainer<QStringList>());
256 case QMetaType::QVariantList:
257 return encodeSequence(QMetaSequence::fromContainer<QVariantList>());
258 case QMetaType::QUrl: {
261 property.readProperty(
object, &
v);
264 case QMetaType::QPixmap:
265 case QMetaType::QImage: {
268 property.readProperty(
object,
v.data());
275 if (propMetaType == QMetaType::fromType<QJSValue>()) {
277 property.readProperty(
object, &
v);
285 property.readProperty(
object, &
v);
291 if (!propMetaType.isValid()) {
293 qWarning(
"QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
294 "'%s::%s'",
p.typeName(),
object->metaObject()->className(),
p.name());
295 return Encode::undefined();
306 return QQmlValueTypeWrapper::create(
307 v4,
nullptr, valueTypeMetaObject, propMetaType,
wrapper,
318 property.readProperty(
object,
v.data());
326 engine->functionPrototype()->defineDefaultProperty(
QStringLiteral(
"disconnect"), method_disconnect);
344 if (ddata && ddata->propertyCache)
361 return vmemo->vmeMethod(
property->coreIndex());
362 }
else if (
property->isV4Function()) {
363 return QObjectMethod::create(
365 }
else if (
property->isSignalHandler()) {
366 QmlSignalHandler::initProto(
engine);
368 object,
property->coreIndex())->asReturnedValue();
370 return QObjectMethod::create(
384 return vmemo->vmeProperty(
property->coreIndex());
395 index = QObjectMethod::DestroyMethod;
397 index = QObjectMethod::ToStringMethod;
408 QObject *qobj,
bool *hasProperty =
nullptr)
422 if (
r.scriptIndex != -1) {
424 }
else if (
r.type.isValid()) {
426 QQmlTypeWrapper::create(v4, qobj,
r.type, Heap::QQmlTypeWrapper::ExcludeEnums));
427 }
else if (
r.importNamespace) {
429 v4, qobj,
qmlContext->imports(),
r.importNamespace,
430 Heap::QQmlTypeWrapper::ExcludeEnums));
438ReturnedValue QObjectWrapper::getQmlProperty(
440 QObjectWrapper::Flags
flags,
bool *hasProperty)
const
446 *hasProperty =
false;
447 return Encode::undefined();
450 ExecutionEngine *v4 =
engine();
460 if ((
flags & IncludeImports) &&
name->startsWithUpper()) {
463 return *importProperty;
465 return Object::virtualGet(
this,
name->propertyKey(),
this, hasProperty);
470 if ((
flags & CheckRevision) &&
result->hasRevision()) {
471 if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(
result)) {
473 *hasProperty =
false;
474 return Encode::undefined();
491 *hasProperty =
false;
492 return Encode::null();
503 if ((
flags & QObjectWrapper::CheckRevision) &&
result->hasRevision()) {
504 if (ddata && ddata->propertyCache
505 && !ddata->propertyCache->isAllowedInRevision(
result)) {
507 *hasProperty =
false;
508 return Encode::undefined();
521 if (!ddata || (ddata->jsWrapper.isUndefined() &&
522 (ddata->jsEngineId == 0 ||
523 !ddata->hasTaintedV4Object))) {
528 Object *proto = QObjectWrapper::defaultPrototype(
engine);
529 return proto->get(
name, hasProperty);
538 Scoped<QObjectWrapper> rewrapped(scope,
wrap(
engine,
object));
541 *hasProperty =
false;
542 return Encode::null();
548bool QObjectWrapper::setQmlProperty(
560 if ((
flags & QObjectWrapper::CheckRevision) &&
result->hasRevision()) {
562 if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(
result))
592void QObjectWrapper::setProperty(
605 if (!
f->isBinding()) {
606 const bool isAliasToAllowed = [&]() {
615 = targetCache->property(targetIndex.coreIndex());
616 object = targetObject;
617 property = targetProperty;
618 return targetProperty->
isVarProperty() || targetProperty->
propType() == QMetaType::fromType<QJSValue>();
623 if (!isAliasToAllowed && !
property->isVarProperty()
624 &&
property->propType() != QMetaType::fromType<QJSValue>()) {
637 Scoped<QQmlBindingFunction> bindingFunction(scope, (
const Value &)
f);
638 Scoped<JavaScriptFunctionObject>
f(scope, bindingFunction->bindingFunction());
646 if (
f->isBoundFunction()) {
647 auto boundFunction =
static_cast<BoundFunction *
>(
f.getPointer());
649 ctx, targetObject, targetIndex);
652 ctx, targetObject, targetIndex);
655 void *argv = {&bindable};
667 if (
f->isBoundFunction())
676 if (
Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) {
678 const auto stackFrame =
engine->currentStackFrame;
679 switch (binding->kind()) {
681 const auto qmlBinding =
static_cast<const QQmlBinding*
>(binding);
683 "Overwriting binding on %s::%s at %s:%d that was initially bound at %s",
685 qPrintable(stackFrame->source()), stackFrame->lineNumber(),
686 qPrintable(qmlBinding->expressionIdentifier()));
692 "Overwriting binding on %s::%s at %s:%d",
694 qPrintable(stackFrame->source()), stackFrame->lineNumber());
710#define PROPERTY_STORE(cpptype, value) \
714 void *argv[] = { &o, 0, &status, &flags }; \
715 QMetaObject::metacall(object, QMetaObject::WriteProperty, property->coreIndex(), argv);
717 const QMetaType propType =
property->propType();
723 }
else if (
value.isUndefined() &&
property->isResettable()) {
724 void *
a[] = {
nullptr };
726 }
else if (
value.isUndefined() && propType == QMetaType::fromType<QVariant>()) {
728 }
else if (
value.isUndefined() && propType == QMetaType::fromType<QJsonValue>()) {
730 }
else if (propType == QMetaType::fromType<QJSValue>()) {
732 }
else if (
value.isUndefined() && propType != QMetaType::fromType<QQmlScriptString>()) {
734 if (!propType.
name())
740 }
else if (propType == QMetaType::fromType<int>() &&
value.isNumber()) {
742 }
else if (propType == QMetaType::fromType<qreal>() &&
value.isNumber()) {
744 }
else if (propType == QMetaType::fromType<float>() &&
value.isNumber()) {
746 }
else if (propType == QMetaType::fromType<double>() &&
value.isNumber()) {
748 }
else if (propType == QMetaType::fromType<QString>() &&
value.isString()) {
750 }
else if (
property->isVarProperty()) {
754 }
else if (propType == QMetaType::fromType<QQmlScriptString>()
755 && (
value.isUndefined() ||
value.isPrimitive())) {
757 if (
value.isNumber()) {
758 ss.d->numberValue =
value.toNumber();
759 ss.d->isNumberLiteral =
true;
760 }
else if (
value.isString()) {
761 ss.d->script = CompiledData::Binding::escapedString(ss.d->script);
762 ss.d->isStringLiteral =
true;
770 v = ExecutionEngine::toVariant(
value, propType);
778 const char *targetTypeName = propType.
name();
780 targetTypeName =
"an unregistered type";
798 return Encode::undefined();
802 if (ddata->jsWrapper.isUndefined() &&
803 (ddata->jsEngineId ==
engine->m_engineId ||
804 ddata->jsEngineId == 0 ||
805 !ddata->hasTaintedV4Object)) {
808 ddata->jsWrapper.set(scope.engine, rv);
809 ddata->jsEngineId =
engine->m_engineId;
810 return rv->asReturnedValue();
815 ScopedObject alternateWrapper(scope, (
Object *)
nullptr);
816 if (
engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
817 alternateWrapper =
engine->m_multiplyWrappedQObjects->value(
object);
821 if (ddata->jsWrapper.isUndefined() && !alternateWrapper) {
823 ddata->jsWrapper.set(scope.engine,
result);
824 ddata->jsEngineId =
engine->m_engineId;
825 return result->asReturnedValue();
828 if (!alternateWrapper) {
830 if (!
engine->m_multiplyWrappedQObjects)
831 engine->m_multiplyWrappedQObjects =
new MultiplyWrappedQObjectMap;
832 engine->m_multiplyWrappedQObjects->insert(
object, alternateWrapper->d());
833 ddata->hasTaintedV4Object =
true;
836 return alternateWrapper.asReturnedValue();
848 if (
engine->m_multiplyWrappedQObjects && ddata->hasConstWrapper)
849 constWrapper =
engine->m_multiplyWrappedQObjects->value(constObject);
853 constWrapper->setInternalClass(constWrapper->internalClass()->cryopreserved());
854 if (!
engine->m_multiplyWrappedQObjects)
855 engine->m_multiplyWrappedQObjects =
new MultiplyWrappedQObjectMap;
856 engine->m_multiplyWrappedQObjects->insert(constObject, constWrapper->d());
857 ddata->hasConstWrapper =
true;
860 return constWrapper.asReturnedValue();
873 if (ddata->jsEngineId ==
engine->m_engineId)
874 ddata->jsWrapper.markOnce(markStack);
875 else if (
engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
876 engine->m_multiplyWrappedQObjects->mark(
object, markStack);
877 if (ddata->hasConstWrapper) {
879 engine->m_multiplyWrappedQObjects->mark(
static_cast<const QObject *
>(
object), markStack);
900 const QQmlPropertyData *
property = ddata->propertyCache->property(propertyIndex);
910 return qmlTypeWrapper->
object() == aobjectWrapper->object();
914 return bobjectWrapper && aobjectWrapper->
object() == bobjectWrapper->object();
922 if (
cache->callJSFactoryMethod(
object,
args))
931 return Object::virtualGet(
m,
id, receiver, hasProperty);
936 QQmlRefPointer<QQmlContextData>
qmlContext = that->
engine()->callingQmlContext();
937 return that->getQmlProperty(
qmlContext,
n, IncludeImports | AttachMethods, hasProperty);
943 return Object::virtualPut(
m,
id,
value, receiver);
949 if (that->internalClass()->isFrozen()) {
964 if (ddata && ddata->context) {
970 return Object::virtualPut(
m,
id,
value, receiver);
981 const QObject *thatObject = that->d()->object();
987 if (that->findProperty(
qmlContext,
n, NoFlag, &local)
992 p->value = that->getQmlProperty(
993 qmlContext,
n, IncludeImports | AttachMethods, &hasProperty);
1000 return Object::virtualGetOwnProperty(
m,
id,
p);
1005 int propertyIndex = 0;
1010 QSet<QByteArray> m_alreadySeen;
1016 static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal(
"destroyed(QObject*)");
1017 static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal(
"destroyed()");
1018 static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot(
"deleteLater()");
1022 QObject *thatObject = that->d()->object();
1026 const bool preventDestruction =
mo->superClass() ||
mo == &QObject::staticMetaObject;
1027 const int propertyCount =
mo->propertyCount();
1028 if (propertyIndex < propertyCount) {
1030 Scope scope(thatEngine);
1039 pd->
value = that->getProperty(
1040 thatEngine, that->d(), thatObject, &local,
1041 QObjectWrapper::AttachMethods);
1043 return propName->toPropertyKey();
1045 const int methodCount =
mo->methodCount();
1046 while (propertyIndex < propertyCount + methodCount) {
1047 Q_ASSERT(propertyIndex >= propertyCount);
1048 int index = propertyIndex - propertyCount;
1054 if (m_alreadySeen.contains(
method.name()))
1057 m_alreadySeen.insert(
method.name());
1059 Scope scope(thatEngine);
1066 pd->
value = that->getProperty(
1067 thatEngine, that->d(), thatObject, &local,
1068 QObjectWrapper::AttachMethods);
1074 return ObjectOwnPropertyKeyIterator::next(
o, pd,
attrs);
1086 PropertyKey id =
engine->identifierTable->asPropertyKey(
engine->currentStackFrame->v4Function->compilationUnit->
1089 return Object::virtualResolveLookupGetter(
object,
engine, lookup);
1099 return Encode::undefined();
1103 Scoped<QObjectMethod>
method(scope, *methodValue);
1106 lookup->
getter = Lookup::getterQObjectMethod;
1107 return method.asReturnedValue();
1110 if (!ddata || !ddata->propertyCache) {
1116 lookup->
forCall ? NoFlag : AttachMethods)
1117 : Encode::undefined();
1123 if (
name->startsWithUpper()) {
1125 return *importProperty;
1127 return Object::virtualResolveLookupGetter(
object,
engine, lookup);
1134 QV4::Heap::QObjectMethod *
method =
nullptr;
1136 lookup->
getter = Lookup::getterQObjectMethod;
1141 lookup->
getter = Lookup::getterQObject;
1148 return Lookup::getterGeneric(l,
engine,
object);
1154 return Object::virtualResolveLookupSetter(
object,
engine, lookup,
value);
1177 const int id =
metaObject->indexOfMethod(
"toString()");
1183 if (
result.metaType() == QMetaType::fromType<QString>())
1184 return result.toString();
1187 return value->toQString();
1193 QString objectName =
object->objectName();
1210 static void impl(
int which, QSlotObjectBase *this_,
QObject *receiver,
void **metaArgs,
bool *
ret)
1232 int argCount =
storage.size();
1239 for (
int ii = 0; ii < argCount; ++ii) {
1241 if (
type == QMetaType::fromType<QVariant>()) {
1248 f->call(jsCallData);
1251 if (
error.description().isEmpty()) {
1253 error.setDescription(
QStringLiteral(
"Unknown exception occurred during evaluation of connected function: %1").
arg(
name->toQString()));
1260 <<
error.toString();
1284 QObject *receiverToDisconnect =
reinterpret_cast<QObject*
>(metaArgs[3]);
1285 int slotIndexToDisconnect = *
reinterpret_cast<int*
>(metaArgs[4]);
1287 if (slotIndexToDisconnect != -1) {
1290 (
connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*
connection->thisObject.valueRef(), thisObject))) {
1293 QPair<QObject *, int> connectedFunctionData = QObjectMethod::extractQtMethod(
f);
1294 if (connectedFunctionData.first == receiverToDisconnect &&
1295 connectedFunctionData.second == slotIndexToDisconnect) {
1302 if (RuntimeHelpers::strictEqual(*
connection->function.valueRef(), function) &&
1304 (
connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*
connection->thisObject.valueRef(), thisObject))) {
1327 QObject *signalObject = signalInfo.first;
1336 auto signalMetaMethod = signalObject->metaObject()->method(
signalIndex);
1345 }
else if (argc >= 2) {
1357 slot->
signal = signalMetaMethod;
1368 QPair<QObject *, int> functionData = QObjectMethod::extractQtMethod(
f);
1371 if (functionData.first)
1372 receiver = functionData.first;
1374 receiver = qobjectWrapper->object();
1376 receiver = typeWrapper->object();
1382 "Could not find receiver of the connection, using sender as receiver. Disconnect "
1383 "explicitly (or delete the sender) to make sure the connection is removed.");
1398 QObject *signalObject = signalInfo.first;
1405 THROW_GENERIC_ERROR(
"Function.prototype.disconnect: cannot disconnect from deleted QObject");
1411 ScopedValue functionThisValue(scope, Encode::undefined());
1414 functionValue = argv[0];
1415 }
else if (argc >= 2) {
1416 functionThisValue = argv[0];
1417 functionValue = argv[1];
1423 if (!functionThisValue->isUndefined() && !functionThisValue->isObject())
1426 QPair<QObject *, int> functionData = QObjectMethod::extractQtMethod(functionValue);
1431 functionThisValue.ptr,
1433 &functionData.second
1438 if (functionData.first)
1439 receiver = functionData.first;
1441 receiver = qobjectWrapper->object();
1443 receiver = typeWrapper->object();
1447 reinterpret_cast<void **
>(&
a));
1450 reinterpret_cast<void **
>(&
a));
1458 QQueue<QObject *>
queue;
1461 while (!
queue.isEmpty()) {
1465 QObjectWrapper::markWrapper(
child, markStack);
1476 if (ddata->hasVMEMetaObject) {
1479 vme->
mark(markStack);
1483 if (ddata->hasConstWrapper) {
1484 Scope scope(that->internalClass->engine);
1487 Scoped<QV4::QObjectWrapper> constWrapper(
1494 if (This == constWrapper->d()) {
1497 ddata->jsWrapper.markOnce(markStack);
1502 constWrapper->mark(markStack);
1515 Object::markObjects(that, markStack);
1518void QObjectWrapper::destroyObject(
bool lastCall)
1526 if (!
o->parent() && !ddata->indestructible) {
1527 if (ddata && ddata->ownContext) {
1528 Q_ASSERT(ddata->ownContext.data() == ddata->context);
1529 ddata->ownContext->deepClearContextObject(
o);
1530 ddata->ownContext.reset();
1531 ddata->context =
nullptr;
1538 ddata->isQueuedForDeletion =
true;
1540 ddata->compilationUnit.reset();
1543 ddata->deferredData.clear();
1552 ddata->jsWrapper.clear();
1553 if (lastCall && ddata->propertyCache)
1554 ddata->propertyCache.reset();
1567template<
typename A,
typename B,
typename C,
typename D,
typename E,
typename F,
typename G>
1569 template<
typename Z,
typename X>
1571 char dummy[
sizeof(Z) >
sizeof(X) ?
sizeof(Z) : sizeof(X)];
1574 static const size_t Size =
sizeof(SMax<A, SMax<B, SMax<C, SMax<D, SMax<E, SMax<F, G> > > > > >);
1577struct CallArgument {
1578 Q_DISABLE_COPY_MOVE(CallArgument);
1580 CallArgument() =
default;
1581 ~CallArgument() { cleanup(); }
1583 inline void *dataPtr();
1586 inline bool fromValue(
QMetaType type, ExecutionEngine *,
const Value &);
1592 enum { QVariantWrappedType = -1 };
1594 inline void cleanup();
1596 template <
class T,
class M>
1597 bool fromContainerValue(
const Value &
object,
M CallArgument::*member);
1605 std::vector<int> *stdVectorIntPtr;
1606 std::vector<qreal> *stdVectorRealPtr;
1607 std::vector<bool> *stdVectorBoolPtr;
1608 std::vector<QString> *stdVectorQStringPtr;
1609 std::vector<QUrl> *stdVectorQUrlPtr;
1610#if QT_CONFIG(qml_itemmodel)
1611 std::vector<QModelIndex> *stdVectorQModelIndexPtr;
1614 char allocData[MaxSizeOf7<
QVariant,
1629 QList<QObject *> *qlistPtr;
1646 QVarLengthArray<CallArgument, 9>
args(argCount + 1);
1647 args[0].initAsType(returnType);
1648 for (
int ii = 0; ii < argCount; ++ii) {
1649 if (!
args[ii + 1].fromValue(argTypes[ii],
engine,
1661 const bool is_signal =
1664 qWarning() <<
"Passing incompatible arguments to signals is not supported.";
1666 return engine->throwTypeError(
1667 QLatin1String(
"Passing incompatible arguments to C++ functions from "
1668 "JavaScript is not allowed."));
1672 QVarLengthArray<void *, 9> argData(
args.
size());
1673 for (
int ii = 0; ii <
args.
size(); ++ii)
1674 argData[ii] =
args[ii].dataPtr();
1676 object.metacall(callType,
index, argData.data());
1680 }
else if (returnType != QMetaType::fromType<void>()) {
1683 arg.initAsType(returnType);
1685 void *
args[] = {
arg.dataPtr() };
1693 void *
args[] = {
nullptr };
1695 return Encode::undefined();
1700template<
typename Retrieve>
1702 if (conversionMetaType == QMetaType::fromType<QVariant>())
1706 if (
type == conversionMetaType)
1709 if (
const QMetaObject *conversionMetaObject = conversionMetaType.metaObject()) {
1728 const int conversionType = conversionMetaType.id();
1729 if (actual.isNumber()) {
1730 switch (conversionType) {
1731 case QMetaType::Double:
1733 case QMetaType::Float:
1735 case QMetaType::LongLong:
1736 case QMetaType::ULongLong:
1738 case QMetaType::Long:
1739 case QMetaType::ULong:
1741 case QMetaType::Int:
1742 case QMetaType::UInt:
1744 case QMetaType::Short:
1745 case QMetaType::UShort:
1748 case QMetaType::Char:
1749 case QMetaType::UChar:
1751 case QMetaType::QJsonValue:
1756 }
else if (actual.isString()) {
1757 switch (conversionType) {
1758 case QMetaType::QString:
1760 case QMetaType::QJsonValue:
1762 case QMetaType::QUrl:
1767 }
else if (actual.isBoolean()) {
1768 switch (conversionType) {
1769 case QMetaType::Bool:
1771 case QMetaType::QJsonValue:
1777 switch (conversionType) {
1778 case QMetaType::QDateTime:
1780 case QMetaType::QDate:
1782 case QMetaType::QTime:
1788 switch (conversionType) {
1789#if QT_CONFIG(regularexpression)
1790 case QMetaType::QRegularExpression:
1797 switch (conversionType) {
1798 case QMetaType::QByteArray:
1804 switch (conversionType) {
1805 case QMetaType::QJsonArray:
1807 case QMetaType::QStringList:
1808 case QMetaType::QVariantList:
1810 case QMetaType::QVector4D:
1811 case QMetaType::QMatrix4x4:
1813 case QMetaType::QVector3D:
1818 }
else if (actual.isNull()) {
1819 switch (conversionType) {
1820 case QMetaType::Nullptr:
1821 case QMetaType::VoidStar:
1822 case QMetaType::QObjectStar:
1823 case QMetaType::QJsonValue:
1834 return MatchVariant(conversionMetaType, [variantObject]() {
1835 return variantObject->d()->
data().metaType();
1840 switch (conversionType) {
1841 case QMetaType::QObjectStar:
1857 if (
type.isSingleton()) {
1859 if (metaType == conversionMetaType)
1864 &&
type.metaObject()->inherits(conversionMetaType.metaObject())) {
1878 if (SequencePrototype::metaTypeForSequence(sequence) == conversionMetaType)
1886 return wrapper->d()->isVariant()
1887 ?
wrapper->toVariant().metaType()
1892 if (conversionType == QMetaType::QJsonObject)
1894 if (conversionType == qMetaTypeId<QJSValue>())
1896 if (conversionType == QMetaType::QVariantMap)
1916 const int indexOfClassInfo =
metaObject->indexOfClassInfo(
"QML.StrictArguments");
1917 return indexOfClassInfo != -1
1921ReturnedValue QObjectMethod::callPrecise(
1927 QMetaType returnType =
object.methodReturnType(
data, &unknownTypeError);
1934 auto handleTooManyArguments = [&](
int expectedArguments) {
1940 const auto stackTrace =
engine->stackTrace();
1941 if (stackTrace.isEmpty()) {
1943 <<
"When matching arguments for "
1944 <<
object.className() <<
"::" <<
data.name(
object.
metaObject()) <<
"():";
1946 const StackFrame
frame = stackTrace.first();
1953 .arg(callArgs->argc() - expectedArguments);
1959 if (
data.hasArguments()) {
1964 if (
data.isConstructor())
1965 ok =
object.constructorParameterTypes(
data.coreIndex(), &
storage, &unknownTypeError);
1967 ok =
object.methodParameterTypes(
data.coreIndex(), &
storage, &unknownTypeError);
1974 if (
storage.size() > callArgs->argc()) {
1979 if (
storage.size() < definedArgumentCount) {
1980 if (!handleTooManyArguments(
storage.size()))
1981 return Encode::undefined();
1988 if (definedArgumentCount > 0 && !handleTooManyArguments(0))
1989 return Encode::undefined();
1991 return CallMethod(
object,
data.coreIndex(), returnType, 0,
nullptr,
engine, callArgs, callType);
2010 ExecutionEngine *
engine, CallData *callArgs)
2012 const int argumentCount = callArgs->argc();
2016 int bestParameterScore = INT_MAX;
2017 int bestMaxMatchScore = INT_MAX;
2018 int bestSumMatchScore = INT_MAX;
2021 ScopedValue
v(scope);
2023 for (
int i = 0;
i < methodCount; ++
i) {
2026 if (lcOverloadResolution().isDebugEnabled()) {
2029 ?
object.metaObject()->constructor(candidate.
coreIndex())
2030 :
object.metaObject()->method(candidate.
coreIndex());
2031 qCDebug(lcOverloadResolution) <<
"::: considering signature" <<
m.methodSignature();
2035 int methodParameterScore = 1;
2037 int maxMethodMatchScore = 9;
2039 int sumMethodMatchScore = bestSumMatchScore;
2041 if (!attempt->isV4Function()) {
2043 int methodArgumentCount = 0;
2044 if (attempt->hasArguments()) {
2045 if (attempt->isConstructor()) {
2046 if (!
object.constructorParameterTypes(attempt->coreIndex(), &
storage,
nullptr)) {
2047 qCDebug(lcOverloadResolution,
"rejected, could not get ctor argument types");
2051 if (!
object.methodParameterTypes(attempt->coreIndex(), &
storage,
nullptr)) {
2052 qCDebug(lcOverloadResolution,
"rejected, could not get ctor argument types");
2056 methodArgumentCount =
storage.size();
2059 if (methodArgumentCount > argumentCount) {
2060 qCDebug(lcOverloadResolution,
"rejected, insufficient arguments");
2064 methodParameterScore = (definedArgumentCount == methodArgumentCount)
2066 : (definedArgumentCount - methodArgumentCount + 1);
2067 if (methodParameterScore > bestParameterScore) {
2068 qCDebug(lcOverloadResolution) <<
"rejected, score too bad. own" << methodParameterScore <<
"vs best:" << bestParameterScore;
2072 maxMethodMatchScore = 0;
2073 sumMethodMatchScore = 0;
2074 for (
int ii = 0; ii < methodArgumentCount; ++ii) {
2075 const int score =
MatchScore((
v = Value::fromStaticValue(callArgs->args[ii])),
2077 maxMethodMatchScore =
qMax(maxMethodMatchScore, score);
2078 sumMethodMatchScore += score;
2082 if (bestParameterScore > methodParameterScore || bestMaxMatchScore > maxMethodMatchScore
2083 || (bestParameterScore == methodParameterScore
2084 && bestMaxMatchScore == maxMethodMatchScore
2085 && bestSumMatchScore > sumMethodMatchScore)) {
2087 bestParameterScore = methodParameterScore;
2088 bestMaxMatchScore = maxMethodMatchScore;
2089 bestSumMatchScore = sumMethodMatchScore;
2090 qCDebug(lcOverloadResolution) <<
"updated best" <<
"bestParameterScore" << bestParameterScore <<
"\n"
2091 <<
"bestMaxMatchScore" << bestMaxMatchScore <<
"\n"
2092 <<
"bestSumMatchScore" << bestSumMatchScore <<
"\n";
2094 qCDebug(lcOverloadResolution) <<
"did not update best\n"
2095 <<
"bestParameterScore" << bestParameterScore <<
"\t"
2096 <<
"methodParameterScore" << methodParameterScore <<
"\n"
2097 <<
"bestMaxMatchScore" << bestMaxMatchScore <<
"\t"
2098 <<
"maxMethodMatchScore" << maxMethodMatchScore <<
"\n"
2099 <<
"bestSumMatchScore" << bestSumMatchScore <<
"\t"
2100 <<
"sumMethodMatchScore" << sumMethodMatchScore <<
"\n";
2103 if (bestParameterScore == 0 && bestMaxMatchScore == 0) {
2104 qCDebug(lcOverloadResolution,
"perfect match");
2110 if (best && best->isValid()) {
2114 for (
int i = 0;
i < methodCount; ++
i) {
2117 ?
object.metaObject()->constructor(candidate.
coreIndex())
2118 :
object.metaObject()->method(candidate.
coreIndex());
2129 if (required == QMetaType::fromType<QVariant>()
2130 || required == QMetaType::fromType<QJSValue>()
2131 || required == QMetaType::fromType<QJSManagedValue>()) {
2136 if (passed == QMetaType::fromType<QVariant>())
2137 passed =
static_cast<const QVariant *
>(
data)->metaType();
2138 else if (passed == QMetaType::fromType<QJSPrimitiveValue>())
2142 if (passed == required)
2145 if (required == QMetaType::fromType<QJSPrimitiveValue>()) {
2146 switch (passed.id()) {
2148 case QMetaType::Nullptr:
2149 case QMetaType::Bool:
2150 case QMetaType::Int:
2151 case QMetaType::Double:
2152 case QMetaType::QString:
2167 for (
int i = 0;
i < methodCount; ++
i) {
2169 if (
types[0].isValid() && !ExactMatch(attempt->propType(),
types[0],
nullptr))
2173 if (
method.parameterCount() != argc)
2177 for (
int i = 0;
i < argc; ++
i) {
2178 if (!ExactMatch(
types[
i + 1],
method.parameterMetaType(
i), argv[
i + 1])) {
2191void CallArgument::cleanup()
2194 case QMetaType::QString:
2195 qstringPtr->~QString();
2197 case QMetaType::QByteArray:
2198 qbyteArrayPtr->~QByteArray();
2201 case QVariantWrappedType:
2202 qvariantPtr->~QVariant();
2204 case QMetaType::QJsonArray:
2205 jsonArrayPtr->~QJsonArray();
2207 case QMetaType::QJsonObject:
2208 jsonObjectPtr->~QJsonObject();
2210 case QMetaType::QJsonValue:
2211 jsonValuePtr->~QJsonValue();
2214 if (
type == qMetaTypeId<QJSValue>()) {
2215 qjsValuePtr->~QJSValue();
2220 qlistPtr->~QList<
QObject *>();
2230void *CallArgument::dataPtr()
2235 case QVariantWrappedType:
2236 return qvariantPtr->data();
2239 return stdVectorIntPtr;
2241 return stdVectorRealPtr;
2243 return stdVectorBoolPtr;
2245 return stdVectorQStringPtr;
2247 return stdVectorQUrlPtr;
2248#if QT_CONFIG(qml_itemmodel)
2250 return stdVectorQModelIndexPtr;
2255 return (
void *)&allocData;
2258void CallArgument::initAsType(
QMetaType metaType)
2265 case QMetaType::Void:
2269 case QMetaType::Int:
2270 case QMetaType::UInt:
2271 case QMetaType::Bool:
2272 case QMetaType::Double:
2273 case QMetaType::Float:
2275 case QMetaType::QObjectStar:
2276 qobjectPtr =
nullptr;
2278 case QMetaType::QString:
2279 qstringPtr =
new (&allocData)
QString();
2282 qvariantPtr =
new (&allocData)
QVariant();
2284 case QMetaType::QJsonArray:
2285 jsonArrayPtr =
new (&allocData)
QJsonArray();
2287 case QMetaType::QJsonObject:
2290 case QMetaType::QJsonValue:
2291 jsonValuePtr =
new (&allocData)
QJsonValue();
2294 if (metaType == QMetaType::fromType<QJSValue>()) {
2295 qjsValuePtr =
new (&allocData)
QJSValue();
2300 qlistPtr =
new (&allocData) QList<QObject *>();
2304 type = QVariantWrappedType;
2305 qvariantPtr =
new (&allocData)
QVariant(metaType, (
void *)
nullptr);
2311template <
class T,
class M>
2312bool CallArgument::fromContainerValue(
const Value &
value,
M CallArgument::*member)
2314 if (
const Sequence *sequence =
value.as<Sequence>()) {
2317 (this->*member) =
ptr;
2321 (this->*member) =
nullptr;
2333 case QMetaType::Int:
2336 case QMetaType::UInt:
2339 case QMetaType::Bool:
2342 case QMetaType::Double:
2343 doubleValue = double(
value.toNumber());
2345 case QMetaType::Float:
2346 floatValue = float(
value.toNumber());
2348 case QMetaType::QString:
2349 if (
value.isNullOrUndefined())
2350 qstringPtr =
new (&allocData)
QString();
2352 qstringPtr =
new (&allocData)
QString(
value.toQStringNoThrow());
2354 case QMetaType::QByteArray:
2355 qbyteArrayPtr =
new (&allocData)
QByteArray();
2356 ExecutionEngine::metaTypeFromJS(
value, metaType, qbyteArrayPtr);
2358 case QMetaType::QObjectStar:
2359 if (
const QObjectWrapper *qobjectWrapper =
value.as<QObjectWrapper>()) {
2360 qobjectPtr = qobjectWrapper->object();
2364 if (
const QQmlTypeWrapper *qmlTypeWrapper =
value.as<QQmlTypeWrapper>()) {
2365 if (qmlTypeWrapper->isSingleton()) {
2369 }
else if (
QObject *
obj = qmlTypeWrapper->object()) {
2381 qobjectPtr =
nullptr;
2382 return value.isNullOrUndefined();
2386 case QMetaType::QJsonArray: {
2389 jsonArrayPtr =
new (&allocData)
QJsonArray(JsonObject::toJsonArray(
o));
2392 case QMetaType::QJsonObject: {
2395 jsonObjectPtr =
new (&allocData)
QJsonObject(JsonObject::toJsonObject(
o));
2398 case QMetaType::QJsonValue:
2399 jsonValuePtr =
new (&allocData)
QJsonValue(JsonObject::toJsonValue(
value));
2401 case QMetaType::Void:
2407 if (
type == qMetaTypeId<QJSValue>()) {
2408 qjsValuePtr =
new (&allocData)
QJSValue;
2414 qlistPtr =
new (&allocData) QList<QObject *>();
2418 Scoped<QObjectWrapper> qobjectWrapper(scope);
2423 qobjectWrapper =
array->get(ii);
2424 if (!!qobjectWrapper)
2425 o = qobjectWrapper->object();
2426 qlistPtr->append(
o);
2431 if (
const QObjectWrapper *qobjectWrapper =
value.as<QObjectWrapper>()) {
2432 qlistPtr->append(qobjectWrapper->object());
2436 if (
const QmlListWrapper *listWrapper =
value.as<QmlListWrapper>()) {
2437 *qlistPtr = listWrapper->d()->property()->toList<QList<QObject *>>();
2441 qlistPtr->append(
nullptr);
2442 return value.isNullOrUndefined();
2447 if (
value.isNullOrUndefined()) {
2448 qvariantPtr =
new (&allocData)
QVariant(metaType,
nullptr);
2455 if (fromContainerValue<std::vector<int>>(
value, &CallArgument::stdVectorIntPtr))
2458 if (fromContainerValue<std::vector<qreal>>(
value, &CallArgument::stdVectorRealPtr))
2461 if (fromContainerValue<std::vector<bool>>(
value, &CallArgument::stdVectorBoolPtr))
2464 if (fromContainerValue<std::vector<QString>>(
value, &CallArgument::stdVectorQStringPtr))
2467 if (fromContainerValue<std::vector<QUrl>>(
value, &CallArgument::stdVectorQUrlPtr))
2469#if QT_CONFIG(qml_itemmodel)
2471 if (fromContainerValue<std::vector<QModelIndex>>(
2472 value, &CallArgument::stdVectorQModelIndexPtr)) {
2481 qvariantPtr =
new (&allocData)
QVariant(metaType);
2482 type = QVariantWrappedType;
2484 if (ExecutionEngine::metaTypeFromJS(
value, metaType, qvariantPtr->data()))
2494 case QMetaType::Int:
2495 return Encode(
int(intValue));
2496 case QMetaType::UInt:
2497 return Encode((
uint)intValue);
2498 case QMetaType::Bool:
2499 return Encode(boolValue);
2500 case QMetaType::Double:
2501 return Encode(doubleValue);
2502 case QMetaType::Float:
2503 return Encode(floatValue);
2504 case QMetaType::QString:
2505 return Encode(
engine->newString(*qstringPtr));
2506 case QMetaType::QByteArray:
2507 return Encode(
engine->newArrayBuffer(*qbyteArrayPtr));
2508 case QMetaType::QObjectStar:
2511 return QObjectWrapper::wrap(
engine, qobjectPtr);
2512 case QMetaType::QJsonArray:
2513 return JsonObject::fromJsonArray(
engine, *jsonArrayPtr);
2514 case QMetaType::QJsonObject:
2515 return JsonObject::fromJsonObject(
engine, *jsonObjectPtr);
2516 case QMetaType::QJsonValue:
2517 return JsonObject::fromJsonValue(
engine, *jsonValuePtr);
2519 case QVariantWrappedType: {
2521 ScopedValue rv(scope, scope.engine->fromVariant(*qvariantPtr));
2522 Scoped<QObjectWrapper> qobjectWrapper(scope, rv);
2523 if (!!qobjectWrapper) {
2524 if (
QObject *
object = qobjectWrapper->object())
2527 return rv->asReturnedValue();
2533 if (
type == qMetaTypeId<QJSValue>()) {
2542 QList<QObject *> &
list = *qlistPtr;
2546 ScopedValue
v(scope);
2547 for (
int ii = 0; ii <
list.
size(); ++ii)
2550 return array.asReturnedValue();
2553 return Encode::undefined();
2559 Scoped<QObjectMethod>
method(
2562 return method.asReturnedValue();
2569 Scoped<QObjectMethod>
method(
2572 return method.asReturnedValue();
2577 Heap::Object *
wrapper, Heap::Object *
object)
2581 Scoped<QQmlValueTypeWrapper> valueTypeWrapper(valueScope);
2582 if (cloneFrom->wrapper) {
2583 Scoped<QQmlValueTypeWrapper>
ref(valueScope, cloneFrom->wrapper);
2585 valueTypeWrapper = QQmlValueTypeWrapper::create(
engine,
ref->d(),
wrapper);
2590 return Encode::undefined();
2594 Scoped<QObjectMethod>
method(
2597 engine, valueTypeWrapper ? valueTypeWrapper->d() :
object, cloneFrom->index));
2599 method->d()->methodCount = cloneFrom->methodCount;
2602 switch (cloneFrom->methodCount) {
2604 Q_ASSERT(cloneFrom->methods ==
nullptr);
2610 *
method->d()->methods = *cloneFrom->methods;
2613 Q_ASSERT(cloneFrom->methods !=
nullptr);
2615 memcpy(
method->d()->methods, cloneFrom->methods,
2620 return method.asReturnedValue();
2625 Heap::FunctionObject::init(
engine);
2627 index = methodIndex;
2630const QMetaObject *Heap::QObjectMethod::metaObject()
const
2632 Scope scope(internalClass->engine);
2634 if (Scoped<QV4::QQmlValueTypeWrapper> valueWrapper(scope,
wrapper); valueWrapper)
2635 return valueWrapper->metaObject();
2637 return self->metaObject();
2642QObject *Heap::QObjectMethod::object()
const
2644 Scope scope(internalClass->engine);
2646 if (Scoped<QV4::QObjectWrapper> objectWrapper(scope,
wrapper); objectWrapper)
2647 return objectWrapper->object();
2648 if (Scoped<QV4::QQmlTypeWrapper> typeWrapper(scope,
wrapper); typeWrapper)
2649 return typeWrapper->object();
2653bool Heap::QObjectMethod::isDetached()
const
2659 if (Scoped<QV4::QQmlValueTypeWrapper> valueWrapper(scope,
wrapper); valueWrapper)
2660 return valueWrapper->d()->object() ==
nullptr;
2665bool Heap::QObjectMethod::isAttachedTo(
QObject *
o)
const
2668 if (Scoped<QV4::QObjectWrapper> objectWrapper(scope,
wrapper); objectWrapper)
2669 return objectWrapper->object() ==
o;
2670 if (Scoped<QV4::QQmlTypeWrapper> typeWrapper(scope,
wrapper); typeWrapper)
2671 return typeWrapper->object() ==
o;
2673 if (Scoped<QV4::QQmlValueTypeWrapper> valueWrapper(scope,
wrapper); valueWrapper) {
2676 return qobject->object() ==
o;
2678 return type->object() ==
o;
2687Heap::QObjectMethod::ThisObjectMode Heap::QObjectMethod::checkThisObject(
2698 const auto check = [&](
const QMetaObject *included) {
2699 const auto stackFrame = internalClass->engine->currentStackFrame;
2700 if (stackFrame && !stackFrame->v4Function->executableCompilationUnit()
2701 ->nativeMethodsAcceptThisObjects()) {
2703 "%s:%d: Calling C++ methods with 'this' objects different from the one "
2704 "they were retrieved from is broken, due to historical reasons. The "
2705 "original object is used as 'this' object. You can allow the given "
2706 "'this' object to be used by setting "
2707 "'pragma NativeMethodBehavior: AcceptThisObject'",
2708 qPrintable(stackFrame->source()), stackFrame->lineNumber());
2714 return thisMeta->inherits(&QObject::staticMetaObject) ? Explicit :
Invalid;
2717 int methodOffset = included->methodOffset();
2719 if (included == thisMeta)
2722 if (methodOffset <=
index)
2723 return thisMeta->inherits(included) ? Explicit :
Invalid;
2725 included = included->superClass();
2730 Q_UNREACHABLE_RETURN(
Invalid);
2741QString Heap::QObjectMethod::name()
const
2752 int methodOffset =
mo->methodOffset();
2753 while (methodOffset >
index) {
2754 mo =
mo->superClass();
2762void Heap::QObjectMethod::ensureMethodsCache(
const QMetaObject *thisMeta)
2776 int methodOffset =
mo->methodOffset();
2777 while (methodOffset >
index) {
2778 mo =
mo->superClass();
2781 QVarLengthArray<QQmlPropertyData, 9> resolvedMethods;
2786 resolvedMethods.append(dummy);
2789 for (
int ii =
index - 1; ii >= methodOffset; --ii) {
2793 resolvedMethods.append(dummy);
2796 if (resolvedMethods.size() > 1) {
2799 methodCount = resolvedMethods.size();
2802 *
methods = resolvedMethods.at(0);
2811 return engine->newString(
2812 QObjectWrapper::objectToString(
2813 engine,
o ?
o->metaObject() :
d()->metaObject(),
o))->asReturnedValue();
2820 return Encode::undefined();
2827 delay =
args[0].toUInt32();
2834 return Encode::undefined();
2844void QObjectMethod::virtualCallWithMetaTypes(
2858 Heap::QQmlValueTypeWrapper *valueWrapper =
nullptr;
2860 thisMeta =
w->metaObject();
2863 thisMeta =
w->metaObject();
2866 thisMeta =
w->metaObject();
2867 valueWrapper =
w->d();
2870 Heap::QObjectMethod::ThisObjectMode
mode = Heap::QObjectMethod::Invalid;
2871 if (
o &&
o ==
d()->
object()) {
2872 mode = Heap::QObjectMethod::Explicit;
2874 }
else if (valueWrapper && valueWrapper ==
d()->
wrapper) {
2875 mode = Heap::QObjectMethod::Explicit;
2878 mode =
d()->checkThisObject(thisMeta);
2879 if (
mode == Heap::QObjectMethod::Invalid) {
2882 return Encode::undefined();
2887 if (
mode == Heap::QObjectMethod::Included) {
2894 valueWrapper =
value->d();
2903 if (!valueWrapper->enforcesLocation())
2909 if (
object.isNull())
2910 return Encode::undefined();
2912 if (
d()->index == DestroyMethod)
2913 return method_destroy(v4,
object.qObject(), argv, argc);
2914 else if (
d()->index == ToStringMethod)
2915 return method_toString(v4,
object.qObject());
2917 d()->ensureMethodsCache(thisMeta);
2921 CallData *callData = cData.callData(scope);
2927 const auto doCall = [&](
const auto &call) {
2928 if (!
method->isConstant()) {
2929 if (valueWrapper && valueWrapper->isReference()) {
2931 valueWrapper->writeBack();
2932 return rv->asReturnedValue();
2939 if (
d()->methodCount != 1) {
2941 method = resolveOverloaded(
object,
d()->
methods,
d()->methodCount, v4, callData);
2943 return Encode::undefined();
2946 if (
method->isV4Function()) {
2947 return doCall([&]() {
2952 void *
args[] = {
nullptr, &funcptr };
2955 return rv->asReturnedValue();
2959 return doCall([&]() {
return callPrecise(
object, *
method, v4, callData); });
2969void QObjectMethod::callInternalWithMetaTypes(
2975 Heap::QQmlValueTypeWrapper *valueWrapper =
nullptr;
2978 thisMeta = thisObject->metaObject();
2981 valueWrapper =
d()->wrapper.cast<Heap::QQmlValueTypeWrapper>();
2982 thisMeta = valueWrapper->metaObject();
2993 Heap::QQmlValueTypeWrapper *valueWrapper =
wrapper->d();
2994 if (!valueWrapper->enforcesLocation())
2999 if (
object.isNull())
3002 if (
d()->index == DestroyMethod) {
3005 v4, thisObject, argv,
types, std::min(argc, 1),
3006 [
this, v4,
object](
const Value *thisObject,
const Value *argv,
int argc) {
3008 return method_destroy(v4,
object.qObject(), argv, argc);
3013 if (
d()->index == ToStringMethod) {
3016 v4, &metaMethod, argv,
types, argc,
3017 [v4, thisMeta,
object](
void **argv,
int) {
3018 *
static_cast<QString *
>(argv[0])
3019 = QObjectWrapper::objectToString(v4, thisMeta,
object.qObject());
3024 d()->ensureMethodsCache(thisMeta);
3027 if (
d()->methodCount != 1) {
3034 v4, thisObject, argv,
types, argc,
3035 [
this](
const Value *thisObject,
const Value *argv,
int argc) {
3036 return callInternal(thisObject, argv, argc);
3041 v4, &metaMethod, argv,
types, argc,
3042 [v4,
object, valueWrapper,
method](
void **argv,
int argc) {
3048 if (!
method->isConstant()) {
3049 if (valueWrapper && valueWrapper->isReference())
3050 valueWrapper->writeBack();
3055 QObject *qobjectPtr =
nullptr;
3059 qobjectPtr = *
static_cast<QObject **
>(argv[0]);
3060 }
else if (resultType == QMetaType::fromType<QVariant>()) {
3064 qobjectPtr = *
static_cast<QObject *
const *
>(
result->data());
3070 if (!ddata->explicitIndestructibleSet) {
3071 ddata->indestructible =
false;
3072 QObjectWrapper::ensureWrapper(v4, qobjectPtr);
3095 <<
QStringLiteral(
"Property '%1' of object %2 is a signal handler. You should "
3096 "not call it directly. Make it a proper function and call "
3097 "that or emit the signal.")
3101 Scoped<QObjectMethod>
method(
3102 scope, QObjectMethod::create(
3107 return method->call(thisObject, argv, argc);
3112 if (
engine->signalHandlerPrototype()->d_unchecked())
3122 engine->jsObjects[ExecutionEngine::SignalHandlerProto] =
o->d();
3135void MultiplyWrappedQObjectMap::removeDestroyedObject(
QObject *
object)
3145#include "moc_qv4qobjectwrapper_p.cpp"
static JNINativeMethod methods[]
\inmodule QtCore\reentrant
\inmodule QtCore \reentrant
bool remove(const Key &key)
Removes the item that has the key from the hash.
iterator erase(const_iterator it)
void throwError(const QString &message)
Throws a run-time error (exception) with the given message.
QJSValue newObject()
Creates a JavaScript object of class Object.
T fromVariant(const QVariant &value)
Returns the given value converted to the template type {T}.
The QJSPrimitiveValue class operates on primitive types in JavaScript semantics.
constexpr QMetaType metaType() const
static QJSValue fromReturnedValue(QV4::ReturnedValue d)
static QV4::ReturnedValue asReturnedValue(const QJSValue *jsval)
static QV4::ReturnedValue convertToReturnedValue(QV4::ExecutionEngine *e, const QJSValue &jsval)
static void setValue(QJSValue *jsval, const QV4::Value &v)
static void manageStringOnV4Heap(QV4::ExecutionEngine *e, QJSValue *jsval)
The QJSValue class acts as a container for Qt/JavaScript data types.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void void Q_DECL_COLD_FUNCTION void warning(const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(2
Logs a warning message specified with format msg.
static QObjectPrivate * get(QObject *o)
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
const QObjectList & children() const
Returns a list of child objects.
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
@ PropertyToPropertyBinding
void setTarget(const QQmlProperty &)
void setBoundFunction(QV4::BoundFunction *boundFunction)
void setSourceLocation(const QQmlSourceLocation &location)
static QQmlBinding * create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *)
QQmlEngine * engine() const
Return the context's QQmlEngine, or \nullptr if the context has no QQmlEngine or the QQmlEngine was d...
static void flushPendingBinding(QObject *object, int coreIndex)
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
static bool keepAliveDuringGarbageCollection(const QObject *object)
static bool wasDeleted(const QObject *)
static QQmlData * get(QObjectPrivate *priv, bool create)
QQmlPropertyCapture * propertyCapture
static QQmlEnginePrivate * get(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
The QQmlError class encapsulates a QML error.
virtual bool mustCaptureBindableProperty() const
static QUntypedPropertyBinding createFromBoundFunction(const QQmlPropertyData *pd, QV4::BoundFunction *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex)
static QUntypedPropertyBinding create(const QQmlPropertyData *pd, QV4::Function *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex)
const QQmlPropertyData * property(const K &key, QObject *object, const QQmlRefPointer< QQmlContextData > &context) const
QQmlJavaScriptExpression * expression
void captureProperty(QQmlNotifier *)
bool isConstructor() const
bool isVarProperty() const
void setMetaObject(const QMetaObject *metaObject)
QMetaType propType() const
void load(const QMetaProperty &)
static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags=None, QQmlPropertyData::WriteFlags writeFlags=QQmlPropertyData::DontRemoveBinding)
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *)
static void removeBinding(const QQmlProperty &that)
static bool write(QObject *, const QQmlPropertyData &, const QVariant &, const QQmlRefPointer< QQmlContextData > &, QQmlPropertyData::WriteFlags flags={})
static void flushSignal(const QObject *sender, int signal_index)
static QQmlAbstractBinding * binding(QObject *, QQmlPropertyIndex index)
The QQmlScriptString class encapsulates a script and its context.
static QString signalNameToHandlerName(QAnyStringView signal)
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
bool isSequentialContainer() const
QMetaSequence listMetaSequence() const
\inmodule QtCore \reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore \reentrant
bool singleShot
whether the timer is a single-shot timer
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
void mark(Pointer key, MarkStack *markStack)
ReturnedValue value(Pointer key) const
ExecutionEngine * engine() const
ReturnedValue value() const
void set(ExecutionEngine *engine, const Value &value)
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
void setupQObjectMethodLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
QBiPointer< QObject, const QObject > QObjectBiPointer
static int MatchScore(const Value &actual, QMetaType conversionMetaType)
static QPair< QObject *, int > extractQtSignal(const Value &value)
Scoped< FunctionObject > ScopedFunctionObject
ReturnedValue convertAndCall(ExecutionEngine *engine, const Function::AOTCompiledFunction *aotFunction, const Value *thisObject, const Value *argv, int argc, Callable call)
static ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, QMetaType returnType, int argCount, const QMetaType *argTypes, ExecutionEngine *engine, CallData *callArgs, QMetaObject::Call callType=QMetaObject::InvokeMetaMethod)
static bool requiresStrictArguments(const QQmlObjectOrGadget &object)
static bool ExactMatch(QMetaType passed, QMetaType required, const void *data)
static ReturnedValue loadProperty(ExecutionEngine *v4, Heap::Object *wrapper, QObject *object, const QQmlPropertyData &property)
static void markChildQObjectsRecursively(QObject *parent, MarkStack *markStack)
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
Scoped< Object > ScopedObject
Scoped< ArrayObject > ScopedArrayObject
Scoped< String > ScopedString
ReturnedValue coerceAndCall(ExecutionEngine *engine, const Function::JSTypedFunction *typedFunction, const CompiledData::Function *compiledFunction, const Value *argv, int argc, Callable call)
int MatchVariant(QMetaType conversionMetaType, Retrieve &&retrieve)
static OptionalReturnedValue getDestroyOrToStringMethod(ExecutionEngine *v4, String *name, Heap::Object *qobj, bool *hasProperty=nullptr)
static Heap::ReferenceObject::Flags referenceFlags(ExecutionEngine *v4, const QQmlPropertyData &property)
static OptionalReturnedValue getPropertyFromImports(ExecutionEngine *v4, String *name, const QQmlRefPointer< QQmlContextData > &qmlContext, QObject *qobj, bool *hasProperty=nullptr)
Scoped< ExecutionContext > ScopedContext
static int numDefinedArguments(CallData *callArgs)
QString boolValue(bool v)
#define QT_WARNING_DISABLE_GCC(text)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection * connection
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QString methodName(const QDBusIntrospection::Method &method)
static struct AttrInfo attrs[]
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCInfo(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei GLenum GLenum * types
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
bool qmlobject_can_cpp_cast(QObject *object, const QMetaObject *mo)
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QT_BEGIN_NAMESPACE typedef signed char qint8
#define PROPERTY_STORE(cpptype, value)
#define RETURN_UNDEFINED()
#define THROW_GENERIC_ERROR(str)
#define DEFINE_OBJECT_VTABLE(classname)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
obj metaObject() -> className()
myObject disconnect()
[26]
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)
\inmodule QtCore \reentrant
CppStackFrame * currentStackFrame
QQmlRefPointer< QQmlContextData > callingQmlContext() const
QQmlError catchExceptionAsQmlError()
Heap::DateObject * newDateObject(double dateTime)
ReturnedValue throwError(const Value &value)
QV4::ReturnedValue fromVariant(const QVariant &)
String * id_destroy() const
String * id_toString() const
Heap::String * newString(char16_t c)
QQmlEngine * qmlEngine() const
Heap::Object * newVariantObject(const QMetaType type, const void *data)
QV4::ReturnedValue fromData(QMetaType type, const void *ptr, Heap::Object *parent=nullptr, int property=-1, uint flags=0)
TypeLoader * typeLoader()
Heap::ArrayBuffer * newArrayBuffer(const QByteArray &array)
Heap::RegExpObject * newRegExpObject(const QString &pattern, int flags)
MultiplyWrappedQObjectMap * m_multiplyWrappedQObjects
ReturnedValue asReturnedValue() const
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
static ReturnedValue fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
ReturnedValue(* getter)(Lookup *l, ExecutionEngine *engine, const Value &object)
void mark(MarkStack *markStack)
ExecutionEngine * engine() const
void callInternalWithMetaTypes(QObject *thisObject, void **argv, const QMetaType *types, int argc) const
ReturnedValue callInternal(const Value *thisObject, const Value *argv, int argc) const
PersistentValue thisObject
static void impl(int which, QSlotObjectBase *this_, QObject *receiver, void **metaArgs, bool *ret)
~QObjectWrapperOwnPropertyKeyIterator() override=default
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
static bool readReference(HeapObject *ref)
bool hasException() const
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data, Heap::Object *object, int propertyIndex, Heap::ReferenceObject::Flags flags)
static void * getRawContainerPtr(const Sequence *object, QMetaType typeHint)
const Value & asValue() const
constexpr ReturnedValue asReturnedValue() const
QString toQStringNoThrow() const
static void markCustom(Engine *engine, F &&markFunction)