Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4jscall_p.h
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4#ifndef QV4JSCALL_H
5#define QV4JSCALL_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qqmllistwrapper_p.h>
19#include <private/qqmlvaluetypewrapper_p.h>
20
21#include <private/qv4alloca_p.h>
22#include <private/qv4dateobject_p.h>
23#include <private/qv4function_p.h>
24#include <private/qv4functionobject_p.h>
25#include <private/qv4qobjectwrapper_p.h>
26#include <private/qv4regexpobject_p.h>
27#include <private/qv4scopedvalue_p.h>
28#include <private/qv4sequenceobject_p.h>
29#include <private/qv4urlobject_p.h>
30#include <private/qv4variantobject_p.h>
31
32#if QT_CONFIG(regularexpression)
33#include <QtCore/qregularexpression.h>
34#endif
35
37
38namespace QV4 {
39
40template<typename Args>
41CallData *callDatafromJS(const Scope &scope, const Args *args, const FunctionObject *f)
42{
43 int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + args->argc;
44 CallData *ptr = reinterpret_cast<CallData *>(scope.alloc(size));
45 ptr->function = Encode::undefined();
46 ptr->context = Encode::undefined();
47 ptr->accumulator = Encode::undefined();
48 ptr->thisObject = args->thisObject ? args->thisObject->asReturnedValue() : Encode::undefined();
49 ptr->newTarget = Encode::undefined();
50 ptr->setArgc(args->argc);
51 if (args->argc)
52 memcpy(ptr->args, args->args, args->argc*sizeof(Value));
53 if (f)
54 ptr->function = f->asReturnedValue();
55 return ptr;
56}
57
59{
60 JSCallArguments(const Scope &scope, int argc = 0)
61 : thisObject(scope.constructUndefined(1)), args(scope.constructUndefined (argc)), argc(argc)
62 {
63 }
64
65 CallData *callData(const Scope &scope, const FunctionObject *f = nullptr) const
66 {
67 return callDatafromJS(scope, this, f);
68 }
69
70 Value *thisObject;
71 Value *args;
72 const int argc;
73};
74
76{
77 JSCallData(const Value *thisObject, const Value *argv, int argc)
78 : thisObject(thisObject), args(argv), argc(argc)
79 {
80 }
81
86
87 CallData *callData(const Scope &scope, const FunctionObject *f = nullptr) const
88 {
89 return callDatafromJS(scope, this, f);
90 }
91
92 const Value *thisObject;
93 const Value *args;
94 const int argc;
95};
96
97inline
102
103inline
108
109void populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc,
110 void **args, const QMetaType *types);
111
112inline QObject *cppThisObject(const Value *thisObject)
113{
114 if (!thisObject)
115 return nullptr;
116 if (const QV4::QObjectWrapper *wrapper = thisObject->as<QV4::QObjectWrapper>())
117 return wrapper->object();
118 return nullptr;
119}
120
121inline void defaultConstructReturnValue(QMetaType returnType, void *returnValue)
122{
123 if (returnType.flags() & QMetaType::NeedsConstruction)
124 returnType.construct(returnValue);
125}
126
128 ExecutionEngine *engine, QMetaType returnType, void *returnValue)
129{
130 const ReturnedValue result = engine->metaTypeToJS(returnType, returnValue);
131 if (returnType.flags() & QMetaType::NeedsDestruction)
132 returnType.destruct(returnValue);
133 return result;
134}
135
136inline bool defaultConversionErrorHandler(QMetaType argumentType, void *argument, qsizetype i)
137{
138 Q_UNUSED(i);
139
140 // If we can't convert the argument, we need to default-construct it even if it
141 // doesn't formally need construction. For example:
142 // - An int doesn't need construction, but we still want it to be 0.
143 // - A QObject* should be nullptr by default, rather than some random value.
144 if (!(argumentType.flags() & QMetaType::NeedsConstruction))
145 argumentType.construct(argument);
146 return true;
147}
148
149template<typename Callable,
150 typename ConstructReturnValue = decltype(defaultConstructReturnValue),
151 typename ConvertReturnValue = decltype(defaultConvertReturnValue),
152 typename ConversionErrorHandler = decltype(defaultConversionErrorHandler)>
154 ExecutionEngine *engine, const QMetaType *types, int numTypes,
155 const Value *argv, int argc, Callable &&call,
156 ConstructReturnValue &&constructReturnValue = defaultConstructReturnValue,
157 ConvertReturnValue &&convertReturnValue = defaultConvertReturnValue,
158 ConversionErrorHandler &&errorHandler = defaultConversionErrorHandler)
159{
160 Q_ALLOCA_INIT();
161 Q_ALLOCA_VAR(void *, values, numTypes * sizeof(void *));
162
163 for (qsizetype i = 1; i < numTypes; ++i) {
164 const auto failConversion = [&]() {
165 for (qsizetype j = 1; j < i; ++j) {
166 if (types[j].flags() & QMetaType::NeedsDestruction)
167 types[j].destruct(values[j]);
168 }
169 return Encode::undefined();
170 };
171
172 const QMetaType argumentType = types[i];
173 if (const qsizetype argumentSize = argumentType.sizeOf()) {
174 Q_ALLOCA_VAR(void, argument, argumentSize);
175 const int argIndex = i - 1;
176 if (argumentType.flags() & QMetaType::NeedsConstruction)
177 argumentType.construct(argument);
178
179 if (argIndex < argc) {
180 if (argumentType == QMetaType::fromType<QVariant>()) {
181 // When the argument type is QVariant, JS objects are to be passed as
182 // QJSValue wrapped in QVariant. metaTypeFromJS unwraps them, unfortunately.
183 *static_cast<QVariant *>(argument) =
184 ExecutionEngine::toVariant(argv[argIndex], QMetaType{ });
185 } else if (!ExecutionEngine::metaTypeFromJS(argv[argIndex], argumentType, argument)
186 && !errorHandler(argumentType, argument, argIndex)) {
187 return failConversion();
188 }
189 } else {
190 return failConversion();
191 }
192
193 values[i] = argument;
194 } else {
195 values[i] = nullptr;
196 }
197 }
198
199 Q_ALLOCA_DECLARE(void, returnValue);
200 if (const qsizetype returnSize = types[0].sizeOf()) {
201 Q_ALLOCA_ASSIGN(void, returnValue, returnSize);
202 constructReturnValue(types[0], returnValue);
203 values[0] = returnValue;
204 } else {
205 values[0] = nullptr;
206 }
207
208 call(values, types, argc);
209
210 const ReturnedValue result = values[0]
211 ? convertReturnValue(engine, types[0], returnValue)
212 : Encode::undefined();
213
214 for (qsizetype i = 1, end = numTypes; i < end; ++i) {
215 if (types[i].flags() & QMetaType::NeedsDestruction)
216 types[i].destruct(values[i]);
217 }
218
219 return result;
220}
221
222template<typename Callable>
223bool convertAndCall(ExecutionEngine *engine, QObject *thisObject,
224 void **a, const QMetaType *types, int argc, Callable call)
225{
226 Scope scope(engine);
227 QV4::JSCallArguments jsCallData(scope, argc);
228
229 for (int ii = 0; ii < argc; ++ii)
230 jsCallData.args[ii] = engine->metaTypeToJS(types[ii + 1], a[ii + 1]);
231
232 ScopedObject jsThisObject(scope);
233 if (thisObject) {
234 // The result of wrap() can only be null, undefined, or an object.
235 jsThisObject = QV4::QObjectWrapper::wrap(engine, thisObject);
236 if (!jsThisObject)
237 jsThisObject = engine->globalObject;
238 } else {
239 jsThisObject = engine->globalObject;
240 }
241
242 ScopedValue jsResult(scope, call(jsThisObject, jsCallData.args, argc));
243 void *result = a[0];
244 if (!result)
245 return !jsResult->isUndefined();
246
247 const QMetaType resultType = types[0];
248 if (scope.hasException()) {
249 // Clear the return value
250 resultType.destruct(result);
251 resultType.construct(result);
252 } else if (resultType == QMetaType::fromType<QVariant>()) {
253 // When the return type is QVariant, JS objects are to be returned as
254 // QJSValue wrapped in QVariant. metaTypeFromJS unwraps them, unfortunately.
255 *static_cast<QVariant *>(result) = ExecutionEngine::toVariant(jsResult, QMetaType {});
256 } else if (!ExecutionEngine::metaTypeFromJS(jsResult, resultType, result)) {
257 // If we cannot convert, also clear the return value.
258 // The caller may have given us an uninitialized QObject*, expecting it to be overwritten.
259 resultType.destruct(result);
260 resultType.construct(result);
261 }
262 return !jsResult->isUndefined();
263}
264
265inline ReturnedValue coerce(
266 ExecutionEngine *engine, const Value &value, const QQmlType &qmlType, bool isList);
267
268inline QObject *coerceQObject(const Value &value, const QQmlType &qmlType)
269{
270 QObject *o;
271 if (const QV4::QObjectWrapper *wrapper = value.as<QV4::QObjectWrapper>())
272 o = wrapper->object();
273 else if (const QV4::QQmlTypeWrapper *wrapper = value.as<QQmlTypeWrapper>())
274 o = wrapper->object();
275 else
276 return nullptr;
277
278 return (o && qmlobject_can_qml_cast(o, qmlType)) ? o : nullptr;
279}
280
286
287Q_QML_EXPORT void warnAboutCoercionToVoid(
288 ExecutionEngine *engine, const Value &value, CoercionProblem problem);
289
291 ExecutionEngine *engine, const Value &value, const QQmlType &qmlType)
292{
293 QMetaType type = qmlType.qListTypeId();
294 const auto metaSequence = [&]() {
295 // TODO: We should really add the metasequence to the same QQmlType that holds
296 // all the other type information. Then we can get rid of the extra
297 // QQmlMetaType::qmlListType() here.
298 return qmlType.isSequentialContainer()
299 ? qmlType.listMetaSequence()
300 : QQmlMetaType::qmlListType(type).listMetaSequence();
301 };
302
303 if (const QV4::Sequence *sequence = value.as<QV4::Sequence>()) {
304 if (sequence->d()->listType() == type)
305 return value.asReturnedValue();
306 }
307
308 if (const QmlListWrapper *list = value.as<QmlListWrapper>()) {
309 if (list->d()->propertyType() == type)
310 return value.asReturnedValue();
311 }
312
313 QMetaType listValueType = qmlType.typeId();
314 if (!listValueType.isValid()) {
315 warnAboutCoercionToVoid(engine, value, InvalidListType);
316 return value.asReturnedValue();
317 }
318
319 QV4::Scope scope(engine);
320
321 const ArrayObject *array = value.as<ArrayObject>();
322 if (!array) {
323 return (listValueType.flags() & QMetaType::PointerToQObject)
324 ? QmlListWrapper::create(engine, listValueType)
325 : SequencePrototype::fromData(engine, type, metaSequence(), nullptr);
326 }
327
328 if (listValueType.flags() & QMetaType::PointerToQObject) {
329 QV4::Scoped<QmlListWrapper> newList(scope, QmlListWrapper::create(engine, type));
330 QQmlListProperty<QObject> *listProperty = newList->d()->property();
331
332 const qsizetype length = array->getLength();
333 qsizetype i = 0;
334 ScopedValue v(scope);
335 for (; i < length; ++i) {
336 v = array->get(i);
337 listProperty->append(listProperty, coerceQObject(v, qmlType));
338 }
339
340 return newList->asReturnedValue();
341 }
342
343 QV4::Scoped<Sequence> sequence(
344 scope, SequencePrototype::fromData(engine, type, metaSequence(), nullptr));
345 const qsizetype length = array->getLength();
346 ScopedValue v(scope);
347 for (qsizetype i = 0; i < length; ++i) {
348 v = array->get(i);
349 sequence->put(PropertyKey::fromArrayIndex(i), v);
350 }
351 return sequence->asReturnedValue();
352}
353
355 ExecutionEngine *engine, const Value &value, const QQmlType &qmlType, bool isList)
356{
357 // These are all the named non-list, non-QObject builtins. Only those need special handling.
358 // Some of them may be wrapped in VariantObject because that is how they are stored in VME
359 // properties.
360 if (isList)
361 return coerceListType(engine, value, qmlType);
362
363 const QMetaType metaType = qmlType.typeId();
364 if (!metaType.isValid()) {
365 if (!value.isUndefined())
366 warnAboutCoercionToVoid(engine, value, InsufficientAnnotation);
367 return value.asReturnedValue();
368 }
369
370 switch (metaType.id()) {
371 case QMetaType::Void:
372 return Encode::undefined();
373 case QMetaType::QVariant:
374 return value.asReturnedValue();
375 case QMetaType::Int:
376 return Encode(value.toInt32());
377 case QMetaType::Double:
378 return value.convertedToNumber();
379 case QMetaType::QString:
380 return value.toString(engine)->asReturnedValue();
381 case QMetaType::Bool:
382 return Encode(value.toBoolean());
383 case QMetaType::QDateTime:
384 if (value.as<DateObject>())
385 return value.asReturnedValue();
386 if (const VariantObject *varObject = value.as<VariantObject>()) {
387 const QVariant &var = varObject->d()->data();
388 switch (var.metaType().id()) {
389 case QMetaType::QDateTime:
390 return engine->newDateObject(var.value<QDateTime>())->asReturnedValue();
391 case QMetaType::QTime:
392 return engine->newDateObject(var.value<QTime>(), nullptr, -1, 0)->asReturnedValue();
393 case QMetaType::QDate:
394 return engine->newDateObject(var.value<QDate>(), nullptr, -1, 0)->asReturnedValue();
395 default:
396 break;
397 }
398 }
399 return engine->newDateObject(QDateTime())->asReturnedValue();
400 case QMetaType::QUrl:
401 if (value.as<UrlObject>())
402 return value.asReturnedValue();
403 if (const VariantObject *varObject = value.as<VariantObject>()) {
404 const QVariant &var = varObject->d()->data();
405 return var.metaType() == QMetaType::fromType<QUrl>()
406 ? engine->newUrlObject(var.value<QUrl>())->asReturnedValue()
407 : engine->newUrlObject()->asReturnedValue();
408 }
409 // Since URL properties are stored as string, we need to support the string conversion here.
410 if (const String *string = value.stringValue())
411 return engine->newUrlObject(QUrl(string->toQString()))->asReturnedValue();
412 return engine->newUrlObject()->asReturnedValue();
413#if QT_CONFIG(regularexpression)
414 case QMetaType::QRegularExpression:
415 if (value.as<RegExpObject>())
416 return value.asReturnedValue();
417 if (const VariantObject *varObject = value.as<VariantObject>()) {
418 const QVariant &var = varObject->d()->data();
419 if (var.metaType() == QMetaType::fromType<QRegularExpression>())
420 return engine->newRegExpObject(var.value<QRegularExpression>())->asReturnedValue();
421 }
422 return engine->newRegExpObject(QString(), 0)->asReturnedValue();
423#endif
424 default:
425 break;
426 }
427
428 if (metaType.flags() & QMetaType::PointerToQObject) {
429 return coerceQObject(value, qmlType)
430 ? value.asReturnedValue()
431 : Encode::null();
432 }
433
434 if (const QQmlValueTypeWrapper *wrapper = value.as<QQmlValueTypeWrapper>()) {
435 if (wrapper->type() == metaType)
436 return value.asReturnedValue();
437 }
438
439 if (void *target = QQmlValueTypeProvider::heapCreateValueType(qmlType, value, engine)) {
440 Heap::QQmlValueTypeWrapper *wrapper = engine->memoryManager->allocate<QQmlValueTypeWrapper>(
441 nullptr, metaType, qmlType.metaObjectForValueType(),
442 nullptr, -1, Heap::ReferenceObject::NoFlag);
443 Q_ASSERT(!wrapper->gadgetPtr());
444 wrapper->setGadgetPtr(target);
445 return wrapper->asReturnedValue();
446 }
447
448 return Encode::undefined();
449}
450
451template<typename Callable>
453 ExecutionEngine *engine,
454 const Function::JSTypedFunction *typedFunction, const CompiledData::Function *compiledFunction,
455 const Value *argv, int argc, Callable call)
456{
457 Scope scope(engine);
458
459 QV4::JSCallArguments jsCallData(scope, typedFunction->types.size() - 1);
460 const CompiledData::Parameter *formals = compiledFunction->formalsTable();
461 for (qsizetype i = 0; i < jsCallData.argc; ++i) {
462 jsCallData.args[i] = coerce(
463 engine, i < argc ? argv[i] : QV4::Value::fromReturnedValue(Encode::undefined()),
464 typedFunction->types[i + 1], formals[i].type.isList());
465 }
466
467 ScopedValue result(scope, call(jsCallData.args, jsCallData.argc));
468 return coerce(engine, result, typedFunction->types[0], compiledFunction->returnType.isList());
469}
470
471// Note: \a to is unininitialized here! This is in contrast to most other related functions.
472inline void coerce(
473 ExecutionEngine *engine, QMetaType fromType, const void *from, QMetaType toType, void *to)
474{
475 if ((fromType.flags() & QMetaType::PointerToQObject)
476 && (toType.flags() & QMetaType::PointerToQObject)) {
477 QObject *fromObj = *static_cast<QObject * const*>(from);
478 *static_cast<QObject **>(to)
479 = (fromObj && fromObj->metaObject()->inherits(toType.metaObject()))
480 ? fromObj
481 : nullptr;
482 return;
483 }
484
485 if (toType == QMetaType::fromType<QVariant>()) {
486 new (to) QVariant(fromType, from);
487 return;
488 }
489
490 if (toType == QMetaType::fromType<QJSPrimitiveValue>()) {
491 new (to) QJSPrimitiveValue(fromType, from);
492 return;
493 }
494
495 if (fromType == QMetaType::fromType<QVariant>()) {
496 const QVariant *fromVariant = static_cast<const QVariant *>(from);
497 if (fromVariant->metaType() == toType)
498 toType.construct(to, fromVariant->data());
499 else
500 coerce(engine, fromVariant->metaType(), fromVariant->data(), toType, to);
501 return;
502 }
503
504 if (fromType == QMetaType::fromType<QJSPrimitiveValue>()) {
505 const QJSPrimitiveValue *fromPrimitive = static_cast<const QJSPrimitiveValue *>(from);
506 if (fromPrimitive->metaType() == toType)
507 toType.construct(to, fromPrimitive->data());
508 else
509 coerce(engine, fromPrimitive->metaType(), fromPrimitive->data(), toType, to);
510 return;
511 }
512
513 // TODO: This is expensive. We might establish a direct C++-to-C++ type coercion, like we have
514 // for JS-to-JS. However, we shouldn't need this very often. Most of the time the compiler
515 // will generate code that passes the right arguments.
516 if (toType.flags() & QMetaType::NeedsConstruction)
517 toType.construct(to);
518 QV4::Scope scope(engine);
519 QV4::ScopedValue value(scope, engine->fromData(fromType, from));
520 if (!ExecutionEngine::metaTypeFromJS(value, toType, to))
521 QMetaType::convert(fromType, from, toType, to);
522}
523
524template<typename TypedFunction, typename Callable>
526 ExecutionEngine *engine, const TypedFunction *typedFunction,
527 void **argv, const QMetaType *types, int argc, Callable call)
528{
529 Q_ALLOCA_INIT();
530 const qsizetype numFunctionArguments = typedFunction->parameterCount();
531
532 Q_ALLOCA_DECLARE(void *, transformedArguments);
533 Q_ALLOCA_DECLARE(void, transformedResult);
534
535 const QMetaType returnType = typedFunction->returnMetaType();
536 const QMetaType frameReturn = types[0];
537 bool returnsQVariantWrapper = false;
538 if (argv[0] && returnType != frameReturn) {
539 Q_ALLOCA_ASSIGN(void *, transformedArguments, (numFunctionArguments + 1) * sizeof(void *));
540 memcpy(transformedArguments, argv, (argc + 1) * sizeof(void *));
541
542 if (frameReturn == QMetaType::fromType<QVariant>()) {
543 QVariant *returnValue = static_cast<QVariant *>(argv[0]);
544 *returnValue = QVariant(returnType);
545 transformedResult = transformedArguments[0] = returnValue->data();
546 returnsQVariantWrapper = true;
547 } else if (returnType.sizeOf() > 0) {
548 Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf());
549 transformedArguments[0] = transformedResult;
550 if (returnType.flags() & QMetaType::NeedsConstruction)
551 returnType.construct(transformedResult);
552 } else {
553 transformedResult = transformedArguments[0] = &argc; // Some non-null marker value
554 }
555 }
556
557 for (qsizetype i = 0; i < numFunctionArguments; ++i) {
558 const bool isValid = argc > i;
559 const QMetaType frameType = isValid ? types[i + 1] : QMetaType();
560
561 const QMetaType argumentType = typedFunction->parameterMetaType(i);
562 if (isValid && argumentType == frameType)
563 continue;
564
565 if (transformedArguments == nullptr) {
566 Q_ALLOCA_ASSIGN(void *, transformedArguments, (numFunctionArguments + 1) * sizeof(void *));
567 memcpy(transformedArguments, argv, (argc + 1) * sizeof(void *));
568 }
569
570 if (argumentType.sizeOf() == 0) {
571 transformedArguments[i + 1] = nullptr;
572 continue;
573 }
574
575 void *frameVal = isValid ? argv[i + 1] : nullptr;
576 if (isValid && frameType == QMetaType::fromType<QVariant>()) {
577 QVariant *variant = static_cast<QVariant *>(frameVal);
578
579 const QMetaType variantType = variant->metaType();
580 if (variantType == argumentType) {
581 // Slightly nasty, but we're allowed to do this.
582 // We don't want to destruct() the QVariant's data() below.
583 transformedArguments[i + 1] = argv[i + 1] = variant->data();
584 } else {
585 Q_ALLOCA_VAR(void, arg, argumentType.sizeOf());
586 coerce(engine, variantType, variant->constData(), argumentType, arg);
587 transformedArguments[i + 1] = arg;
588 }
589 continue;
590 }
591
592 Q_ALLOCA_VAR(void, arg, argumentType.sizeOf());
593
594 if (isValid)
595 coerce(engine, frameType, frameVal, argumentType, arg);
596 else
597 argumentType.construct(arg);
598
599 transformedArguments[i + 1] = arg;
600 }
601
602 if (!transformedArguments) {
603 call(argv, numFunctionArguments);
604 return;
605 }
606
607 call(transformedArguments, numFunctionArguments);
608
609 if (transformedResult && !returnsQVariantWrapper) {
610 if (frameReturn.sizeOf() > 0) {
611 if (frameReturn.flags() & QMetaType::NeedsDestruction)
612 frameReturn.destruct(argv[0]);
613 coerce(engine, returnType, transformedResult, frameReturn, argv[0]);
614 }
615 if (returnType.flags() & QMetaType::NeedsDestruction)
616 returnType.destruct(transformedResult);
617 }
618
619 for (qsizetype i = 0; i < numFunctionArguments; ++i) {
620 void *arg = transformedArguments[i + 1];
621 if (arg == nullptr)
622 continue;
623 if (i >= argc || arg != argv[i + 1]) {
624 const QMetaType argumentType = typedFunction->parameterMetaType(i);
625 if (argumentType.flags() & QMetaType::NeedsDestruction)
626 argumentType.destruct(arg);
627 }
628 }
629}
630
631} // namespace QV4
632
633QT_END_NAMESPACE
634
635#endif // QV4JSCALL_H
Combined button and popup list for selecting options.
Definition qjsvalue.h:24
QObject * cppThisObject(const Value *thisObject)
ReturnedValue coerceListType(ExecutionEngine *engine, const Value &value, const QQmlType &qmlType)
void coerce(ExecutionEngine *engine, QMetaType fromType, const void *from, QMetaType toType, void *to)
@ STRING_HINT
@ PREFERREDTYPE_HINT
@ NUMBER_HINT
CoercionProblem
@ InvalidListType
@ InsufficientAnnotation
ReturnedValue coerce(ExecutionEngine *engine, const Value &value, const QQmlType &qmlType, bool isList)
void populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc, void **args, const QMetaType *types)
Definition qv4jscall.cpp:19
uint Bool
ReturnedValue defaultConvertReturnValue(ExecutionEngine *engine, QMetaType returnType, void *returnValue)
Scoped< Object > ScopedObject
QObject * coerceQObject(const Value &value, const QQmlType &qmlType)
bool convertAndCall(ExecutionEngine *engine, QObject *thisObject, void **a, const QMetaType *types, int argc, Callable call)
void coerceAndCall(ExecutionEngine *engine, const TypedFunction *typedFunction, void **argv, const QMetaType *types, int argc, Callable call)
ReturnedValue coerceAndCall(ExecutionEngine *engine, const Function::JSTypedFunction *typedFunction, const CompiledData::Function *compiledFunction, const Value *argv, int argc, Callable call)
bool defaultConversionErrorHandler(QMetaType argumentType, void *argument, qsizetype i)
ReturnedValue convertAndCall(ExecutionEngine *engine, const QMetaType *types, int numTypes, const Value *argv, int argc, Callable &&call, ConstructReturnValue &&constructReturnValue=defaultConstructReturnValue, ConvertReturnValue &&convertReturnValue=defaultConvertReturnValue, ConversionErrorHandler &&errorHandler=defaultConversionErrorHandler)
Q_QML_EXPORT void warnAboutCoercionToVoid(ExecutionEngine *engine, const Value &value, CoercionProblem problem)
Definition qv4jscall.cpp:26
CallData * callDatafromJS(const Scope &scope, const Args *args, const FunctionObject *f)
Definition qv4jscall_p.h:41
void defaultConstructReturnValue(QMetaType returnType, void *returnValue)
Q_STATIC_ASSERT(sizeof(SharedImageHeader) % 4==0)
DEFINE_MANAGED_VTABLE(ArrayData)
JSCallArguments(const Scope &scope, int argc=0)
Definition qv4jscall_p.h:60
CallData * callData(const Scope &scope, const FunctionObject *f=nullptr) const
Definition qv4jscall_p.h:65
const int argc
Definition qv4jscall_p.h:94
CallData * callData(const Scope &scope, const FunctionObject *f=nullptr) const
Definition qv4jscall_p.h:87
const Value * thisObject
Definition qv4jscall_p.h:92
JSCallData(const Value *thisObject, const Value *argv, int argc)
Definition qv4jscall_p.h:77
const Value * args
Definition qv4jscall_p.h:93
static PropertyKey fromArrayIndex(uint idx)
Scope(ExecutionEngine *e)
ScopedValue(const Scope &scope)
const SparseArrayNode * end() const