343ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
344 : executableAllocator(
new QV4::ExecutableAllocator)
345 , regExpAllocator(
new QV4::ExecutableAllocator)
346 , bumperPointerAllocator(
new WTF::BumpPointerAllocator)
347 , jsStack(
new WTF::PageAllocation)
348 , gcStack(
new WTF::PageAllocation)
349 , publicEngine(jsEngine)
350 , m_engineId(engineSerial.fetchAndAddOrdered(2))
351#if QT_CONFIG(qml_jit)
352 , m_canAllocateExecutableMemory(OSAllocator::canAllocateExecutableMemory())
355 if (m_engineId == 1) {
356 initializeStaticMembers();
357 engineSerial.storeRelease(2);
358 }
else if (Q_UNLIKELY(m_engineId & 1)) {
360 while (engineSerial.loadAcquire() & 1) {
361 QThread::yieldCurrentThread();
365 if (s_maxCallDepth < 0) {
366 const StackProperties stack = stackProperties();
367 cppStackBase = stack.base;
368 cppStackLimit = stack.softLimit;
374 const size_t guardPages = 2 * WTF::pageSize();
376 memoryManager =
new QV4::MemoryManager(
this);
378 GCCriticalSection gcCriticalSection(
this);
382 *jsStack = WTF::PageAllocation::allocate(
383 s_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages,
385 jsStackBase = (Value *)jsStack->base();
386#ifdef V4_USE_VALGRIND
387 VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, s_maxJSStackSize + 256*1024);
390 jsStackTop = jsStackBase;
392 *gcStack = WTF::PageAllocation::allocate(
393 s_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages,
396 exceptionValue = jsAlloca(1);
397 *exceptionValue = Encode::undefined();
398 globalObject =
static_cast<Object *>(jsAlloca(1));
399 jsObjects = jsAlloca(NJSObjects);
400 typedArrayPrototype =
static_cast<Object *>(jsAlloca(NTypedArrayTypes));
401 typedArrayCtors =
static_cast<FunctionObject *>(jsAlloca(NTypedArrayTypes));
402 jsStrings = jsAlloca(NJSStrings);
403 jsSymbols = jsAlloca(NJSSymbols);
406 jsStackLimit = jsStackBase + s_maxJSStackSize/
sizeof(Value);
408 identifierTable =
new IdentifierTable(
this);
410 memset(classes, 0,
sizeof(classes));
411 classes[Class_Empty] = memoryManager->allocIC<InternalClass>();
412 classes[Class_Empty]->init(
this);
414 classes[Class_MemberData] = classes[Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
415 classes[Class_SimpleArrayData] = classes[Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
416 classes[Class_SparseArrayData] = classes[Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
417 classes[Class_ExecutionContext] = classes[Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
418 classes[Class_CallContext] = classes[Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
419 classes[Class_QmlContext] = classes[Class_Empty]->changeVTable(QV4::QmlContext::staticVTable());
422 Scoped<InternalClass> ic(scope);
423 ic = classes[Class_Empty]->changeVTable(QV4::Object::staticVTable());
424 jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic->d());
425 classes[Class_Object] = ic->changePrototype(objectPrototype()->d());
426 classes[Class_QmlContextWrapper] = classes[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
428 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
429 jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(ic->d(),
false);
430 classes[Class_String] = classes[Class_Empty]->changeVTable(QV4::String::staticVTable())->changePrototype(stringPrototype()->d());
431 Q_ASSERT(stringPrototype()->d() && classes[Class_String]->prototype);
433 jsObjects[SymbolProto] = memoryManager->allocate<SymbolPrototype>();
434 classes[Class_Symbol] = classes[EngineBase::Class_Empty]->changeVTable(QV4::Symbol::staticVTable())->changePrototype(symbolPrototype()->d());
436 jsStrings[String_Empty] = newIdentifier(QString());
437 jsStrings[String_undefined] = newIdentifier(QStringLiteral(
"undefined"));
438 jsStrings[String_null] = newIdentifier(QStringLiteral(
"null"));
439 jsStrings[String_true] = newIdentifier(QStringLiteral(
"true"));
440 jsStrings[String_false] = newIdentifier(QStringLiteral(
"false"));
441 jsStrings[String_boolean] = newIdentifier(QStringLiteral(
"boolean"));
442 jsStrings[String_number] = newIdentifier(QStringLiteral(
"number"));
443 jsStrings[String_string] = newIdentifier(QStringLiteral(
"string"));
444 jsStrings[String_default] = newIdentifier(QStringLiteral(
"default"));
445 jsStrings[String_symbol] = newIdentifier(QStringLiteral(
"symbol"));
446 jsStrings[String_object] = newIdentifier(QStringLiteral(
"object"));
447 jsStrings[String_function] = newIdentifier(QStringLiteral(
"function"));
448 jsStrings[String_length] = newIdentifier(QStringLiteral(
"length"));
449 jsStrings[String_prototype] = newIdentifier(QStringLiteral(
"prototype"));
450 jsStrings[String_constructor] = newIdentifier(QStringLiteral(
"constructor"));
451 jsStrings[String_arguments] = newIdentifier(QStringLiteral(
"arguments"));
452 jsStrings[String_caller] = newIdentifier(QStringLiteral(
"caller"));
453 jsStrings[String_callee] = newIdentifier(QStringLiteral(
"callee"));
454 jsStrings[String_this] = newIdentifier(QStringLiteral(
"this"));
455 jsStrings[String___proto__] = newIdentifier(QStringLiteral(
"__proto__"));
456 jsStrings[String_enumerable] = newIdentifier(QStringLiteral(
"enumerable"));
457 jsStrings[String_configurable] = newIdentifier(QStringLiteral(
"configurable"));
458 jsStrings[String_writable] = newIdentifier(QStringLiteral(
"writable"));
459 jsStrings[String_value] = newIdentifier(QStringLiteral(
"value"));
460 jsStrings[String_get] = newIdentifier(QStringLiteral(
"get"));
461 jsStrings[String_set] = newIdentifier(QStringLiteral(
"set"));
462 jsStrings[String_eval] = newIdentifier(QStringLiteral(
"eval"));
463 jsStrings[String_uintMax] = newIdentifier(QStringLiteral(
"4294967295"));
464 jsStrings[String_name] = newIdentifier(QStringLiteral(
"name"));
465 jsStrings[String_index] = newIdentifier(QStringLiteral(
"index"));
466 jsStrings[String_input] = newIdentifier(QStringLiteral(
"input"));
467 jsStrings[String_toString] = newIdentifier(QStringLiteral(
"toString"));
468 jsStrings[String_toLocaleString] = newIdentifier(QStringLiteral(
"toLocaleString"));
469 jsStrings[String_destroy] = newIdentifier(QStringLiteral(
"destroy"));
470 jsStrings[String_valueOf] = newIdentifier(QStringLiteral(
"valueOf"));
471 jsStrings[String_byteLength] = newIdentifier(QStringLiteral(
"byteLength"));
472 jsStrings[String_byteOffset] = newIdentifier(QStringLiteral(
"byteOffset"));
473 jsStrings[String_buffer] = newIdentifier(QStringLiteral(
"buffer"));
474 jsStrings[String_lastIndex] = newIdentifier(QStringLiteral(
"lastIndex"));
475 jsStrings[String_next] = newIdentifier(QStringLiteral(
"next"));
476 jsStrings[String_done] = newIdentifier(QStringLiteral(
"done"));
477 jsStrings[String_return] = newIdentifier(QStringLiteral(
"return"));
478 jsStrings[String_throw] = newIdentifier(QStringLiteral(
"throw"));
479 jsStrings[String_global] = newIdentifier(QStringLiteral(
"global"));
480 jsStrings[String_ignoreCase] = newIdentifier(QStringLiteral(
"ignoreCase"));
481 jsStrings[String_multiline] = newIdentifier(QStringLiteral(
"multiline"));
482 jsStrings[String_unicode] = newIdentifier(QStringLiteral(
"unicode"));
483 jsStrings[String_sticky] = newIdentifier(QStringLiteral(
"sticky"));
484 jsStrings[String_source] = newIdentifier(QStringLiteral(
"source"));
485 jsStrings[String_flags] = newIdentifier(QStringLiteral(
"flags"));
487 jsSymbols[Symbol_hasInstance] = Symbol::create(
this, QStringLiteral(
"@Symbol.hasInstance"));
488 jsSymbols[Symbol_isConcatSpreadable] = Symbol::create(
this, QStringLiteral(
"@Symbol.isConcatSpreadable"));
489 jsSymbols[Symbol_iterator] = Symbol::create(
this, QStringLiteral(
"@Symbol.iterator"));
490 jsSymbols[Symbol_match] = Symbol::create(
this, QStringLiteral(
"@Symbol.match"));
491 jsSymbols[Symbol_replace] = Symbol::create(
this, QStringLiteral(
"@Symbol.replace"));
492 jsSymbols[Symbol_search] = Symbol::create(
this, QStringLiteral(
"@Symbol.search"));
493 jsSymbols[Symbol_species] = Symbol::create(
this, QStringLiteral(
"@Symbol.species"));
494 jsSymbols[Symbol_split] = Symbol::create(
this, QStringLiteral(
"@Symbol.split"));
495 jsSymbols[Symbol_toPrimitive] = Symbol::create(
this, QStringLiteral(
"@Symbol.toPrimitive"));
496 jsSymbols[Symbol_toStringTag] = Symbol::create(
this, QStringLiteral(
"@Symbol.toStringTag"));
497 jsSymbols[Symbol_unscopables] = Symbol::create(
this, QStringLiteral(
"@Symbol.unscopables"));
498 jsSymbols[Symbol_revokableProxy] = Symbol::create(
this, QStringLiteral(
"@Proxy.revokableProxy"));
500 ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
501 Q_ASSERT(ic->d()->prototype);
502 ic = ic->addMember(id_length()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
503 Q_ASSERT(ic->d()->prototype);
504 jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic->d());
505 classes[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d());
506 jsObjects[PropertyListProto] = memoryManager->allocate<PropertyListPrototype>();
508 Scoped<InternalClass> argsClass(scope);
509 argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
510 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
511 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
512 classes[Class_ArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Data|Attr_NotEnumerable);
513 argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
514 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
515 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
516 classes[Class_StrictArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
518 *
static_cast<Value *>(globalObject) = newObject();
519 Q_ASSERT(globalObject->d()->vtable());
522 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
523 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly);
524 classes[Class_StringObject] = ic->changePrototype(stringPrototype()->d());
525 Q_ASSERT(classes[Class_StringObject]->verifyIndex(id_length()->propertyKey(), Heap::StringObject::LengthPropertyIndex));
527 classes[Class_SymbolObject] = newInternalClass(QV4::SymbolObject::staticVTable(), symbolPrototype());
529 jsObjects[NumberProto] = memoryManager->allocate<NumberPrototype>();
530 jsObjects[BooleanProto] = memoryManager->allocate<BooleanPrototype>();
531 jsObjects[DateProto] = memoryManager->allocate<DatePrototype>();
533#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
534 InternalClassEntry *index =
nullptr;
536 InternalClassEntry _index;
537 auto *index = &_index;
539 ic = newInternalClass(QV4::FunctionPrototype::staticVTable(), objectPrototype());
540 auto addProtoHasInstance = [&] {
544 ic = ic->addMember(id_prototype()->propertyKey(), Attr_Invalid, index);
545 Q_ASSERT(index->index == Heap::FunctionObject::Index_Prototype);
549 ic = ic->addMember(symbol_hasInstance()->propertyKey(), Attr_Invalid, index);
550 Q_ASSERT(index->index == Heap::FunctionObject::Index_HasInstance);
552 addProtoHasInstance();
553 jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d());
554 ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype());
555 addProtoHasInstance();
556 classes[Class_FunctionObject] = ic->d();
557 ic = ic->addMember(id_name()->propertyKey(), Attr_ReadOnly, index);
558 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Name);
559 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly_ButConfigurable, index);
560 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Length);
561 classes[Class_ArrowFunction] = ic->changeVTable(ArrowFunction::staticVTable());
562 ic = ic->changeVTable(MemberFunction::staticVTable());
563 classes[Class_MemberFunction] = ic->d();
564 ic = ic->changeVTable(GeneratorFunction::staticVTable());
565 classes[Class_GeneratorFunction] = ic->d();
566 ic = ic->changeVTable(MemberGeneratorFunction::staticVTable());
567 classes[Class_MemberGeneratorFunction] = ic->d();
569 ic = ic->changeMember(id_prototype()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
570 ic = ic->changeVTable(ScriptFunction::staticVTable());
571 classes[Class_ScriptFunction] = ic->d();
572 ic = ic->changeVTable(ConstructorFunction::staticVTable());
573 classes[Class_ConstructorFunction] = ic->d();
575 classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->propertyKey(), Attr_NotEnumerable, index);
576 Q_ASSERT(index->index == Heap::FunctionObject::Index_ProtoConstructor);
578 jsObjects[GeneratorProto] = memoryManager->allocObject<GeneratorPrototype>(classes[Class_Object]);
579 classes[Class_GeneratorObject] = newInternalClass(QV4::GeneratorObject::staticVTable(), generatorPrototype());
581 ScopedString str(scope);
582 classes[Class_RegExp] = classes[Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
583 ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype());
584 ic = ic->addMember(id_lastIndex()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, index);
585 Q_ASSERT(index->index == RegExpObject::Index_LastIndex);
586 jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(classes[Class_Object]);
587 classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d());
589 ic = classes[Class_ArrayObject]->addMember(id_index()->propertyKey(), Attr_Data, index);
590 Q_ASSERT(index->index == RegExpObject::Index_ArrayIndex);
591 classes[Class_RegExpExecArray] = ic->addMember(id_input()->propertyKey(), Attr_Data, index);
592 Q_ASSERT(index->index == RegExpObject::Index_ArrayInput);
594 ic = newInternalClass(ErrorObject::staticVTable(),
nullptr);
595 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"stack")))->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, index);
596 Q_ASSERT(index->index == ErrorObject::Index_Stack);
597 Q_ASSERT(index->setterIndex == ErrorObject::Index_StackSetter);
598 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"fileName")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
599 Q_ASSERT(index->index == ErrorObject::Index_FileName);
600 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"lineNumber")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
601 classes[Class_ErrorObject] = ic->d();
602 Q_ASSERT(index->index == ErrorObject::Index_LineNumber);
603 classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
604 Q_ASSERT(index->index == ErrorObject::Index_Message);
605 ic = newInternalClass(Object::staticVTable(), objectPrototype());
606 ic = ic->addMember(id_constructor()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
607 Q_ASSERT(index->index == ErrorPrototype::Index_Constructor);
608 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
609 Q_ASSERT(index->index == ErrorPrototype::Index_Message);
610 classes[Class_ErrorProto] = ic->addMember(id_name()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
611 Q_ASSERT(index->index == ErrorPrototype::Index_Name);
613 classes[Class_ProxyObject] = classes[Class_Empty]->changeVTable(ProxyObject::staticVTable());
614 classes[Class_ProxyFunctionObject] = classes[Class_Empty]->changeVTable(ProxyFunctionObject::staticVTable());
616 jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(
this, str = newIdentifier(QStringLiteral(
"stack")), ErrorObject::method_get_stack, 0);
618 jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(classes[Class_ErrorProto]);
619 ic = classes[Class_ErrorProto]->changePrototype(errorPrototype()->d());
620 jsObjects[EvalErrorProto] = memoryManager->allocObject<EvalErrorPrototype>(ic->d());
621 jsObjects[RangeErrorProto] = memoryManager->allocObject<RangeErrorPrototype>(ic->d());
622 jsObjects[ReferenceErrorProto] = memoryManager->allocObject<ReferenceErrorPrototype>(ic->d());
623 jsObjects[SyntaxErrorProto] = memoryManager->allocObject<SyntaxErrorPrototype>(ic->d());
624 jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(ic->d());
625 jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(ic->d());
627 jsObjects[VariantProto] = memoryManager->allocate<VariantPrototype>();
628 Q_ASSERT(variantPrototype()->getPrototypeOf() == objectPrototype()->d());
630 jsObjects[VariantAssociationProto] = memoryManager->allocate<VariantAssociationPrototype>();
631 Q_ASSERT(variantAssociationPrototype()->getPrototypeOf() == objectPrototype()->d());
633 ic = newInternalClass(SequencePrototype::staticVTable(), SequencePrototype::defaultPrototype(
this));
634 jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(ic->d()));
636 jsObjects[Object_Ctor] = memoryManager->allocate<ObjectCtor>(
this);
637 jsObjects[String_Ctor] = memoryManager->allocate<StringCtor>(
this);
638 jsObjects[Symbol_Ctor] = memoryManager->allocate<SymbolCtor>(
this);
639 jsObjects[Number_Ctor] = memoryManager->allocate<NumberCtor>(
this);
640 jsObjects[Boolean_Ctor] = memoryManager->allocate<BooleanCtor>(
this);
641 jsObjects[Array_Ctor] = memoryManager->allocate<ArrayCtor>(
this);
642 jsObjects[Function_Ctor] = memoryManager->allocate<FunctionCtor>(
this);
643 jsObjects[GeneratorFunction_Ctor] = memoryManager->allocate<GeneratorFunctionCtor>(
this);
644 jsObjects[Date_Ctor] = memoryManager->allocate<DateCtor>(
this);
645 jsObjects[RegExp_Ctor] = memoryManager->allocate<RegExpCtor>(
this);
646 jsObjects[Error_Ctor] = memoryManager->allocate<ErrorCtor>(
this);
647 jsObjects[EvalError_Ctor] = memoryManager->allocate<EvalErrorCtor>(
this);
648 jsObjects[RangeError_Ctor] = memoryManager->allocate<RangeErrorCtor>(
this);
649 jsObjects[ReferenceError_Ctor] = memoryManager->allocate<ReferenceErrorCtor>(
this);
650 jsObjects[SyntaxError_Ctor] = memoryManager->allocate<SyntaxErrorCtor>(
this);
651 jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(
this);
652 jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(
this);
653 jsObjects[IteratorProto] = memoryManager->allocate<IteratorPrototype>();
655 ic = newInternalClass(ForInIteratorPrototype::staticVTable(), iteratorPrototype());
656 jsObjects[ForInIteratorProto] = memoryManager->allocObject<ForInIteratorPrototype>(ic);
657 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
658 jsObjects[MapIteratorProto] = memoryManager->allocObject<MapIteratorPrototype>(ic);
659 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
660 jsObjects[SetIteratorProto] = memoryManager->allocObject<SetIteratorPrototype>(ic);
661 ic = newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype());
662 jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(ic);
663 ic = newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype());
664 jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(ic);
670 jsObjects[Url_Ctor] = memoryManager->allocate<UrlCtor>(
this);
671 jsObjects[UrlProto] = memoryManager->allocate<UrlPrototype>();
672 jsObjects[UrlSearchParams_Ctor] = memoryManager->allocate<UrlSearchParamsCtor>(
this);
673 jsObjects[UrlSearchParamsProto] = memoryManager->allocate<UrlSearchParamsPrototype>();
675 str = newString(QStringLiteral(
"get [Symbol.species]"));
676 jsObjects[GetSymbolSpecies] = FunctionObject::createBuiltinFunction(
this, str, ArrayPrototype::method_get_species, 0);
678 static_cast<ObjectPrototype *>(objectPrototype())->init(
this, objectCtor());
679 static_cast<StringPrototype *>(stringPrototype())->init(
this, stringCtor());
680 static_cast<SymbolPrototype *>(symbolPrototype())->init(
this, symbolCtor());
681 static_cast<NumberPrototype *>(numberPrototype())->init(
this, numberCtor());
682 static_cast<BooleanPrototype *>(booleanPrototype())->init(
this, booleanCtor());
683 static_cast<ArrayPrototype *>(arrayPrototype())->init(
this, arrayCtor());
684 static_cast<PropertyListPrototype *>(propertyListPrototype())->init();
685 static_cast<DatePrototype *>(datePrototype())->init(
this, dateCtor());
686 static_cast<FunctionPrototype *>(functionPrototype())->init(
this, functionCtor());
687 static_cast<GeneratorPrototype *>(generatorPrototype())->init(
this, generatorFunctionCtor());
688 static_cast<RegExpPrototype *>(regExpPrototype())->init(
this, regExpCtor());
689 static_cast<ErrorPrototype *>(errorPrototype())->init(
this, errorCtor());
690 static_cast<EvalErrorPrototype *>(evalErrorPrototype())->init(
this, evalErrorCtor());
691 static_cast<RangeErrorPrototype *>(rangeErrorPrototype())->init(
this, rangeErrorCtor());
692 static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype())->init(
this, referenceErrorCtor());
693 static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(
this, syntaxErrorCtor());
694 static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(
this, typeErrorCtor());
695 static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(
this, uRIErrorCtor());
696 static_cast<UrlPrototype *>(urlPrototype())->init(
this, urlCtor());
697 static_cast<UrlSearchParamsPrototype *>(urlSearchParamsPrototype())->init(
this, urlSearchParamsCtor());
699 static_cast<IteratorPrototype *>(iteratorPrototype())->init(
this);
700 static_cast<ForInIteratorPrototype *>(forInIteratorPrototype())->init(
this);
701 static_cast<MapIteratorPrototype *>(mapIteratorPrototype())->init(
this);
702 static_cast<SetIteratorPrototype *>(setIteratorPrototype())->init(
this);
703 static_cast<ArrayIteratorPrototype *>(arrayIteratorPrototype())->init(
this);
704 static_cast<StringIteratorPrototype *>(stringIteratorPrototype())->init(
this);
706 static_cast<VariantPrototype *>(variantPrototype())->init();
708 sequencePrototype()->cast<SequencePrototype>()->init();
710 jsObjects[WeakMap_Ctor] = memoryManager->allocate<WeakMapCtor>(
this);
711 jsObjects[WeakMapProto] = memoryManager->allocate<WeakMapPrototype>();
712 static_cast<WeakMapPrototype *>(weakMapPrototype())->init(
this, weakMapCtor());
714 jsObjects[Map_Ctor] = memoryManager->allocate<MapCtor>(
this);
715 jsObjects[MapProto] = memoryManager->allocate<MapPrototype>();
716 static_cast<MapPrototype *>(mapPrototype())->init(
this, mapCtor());
718 jsObjects[WeakSet_Ctor] = memoryManager->allocate<WeakSetCtor>(
this);
719 jsObjects[WeakSetProto] = memoryManager->allocate<WeakSetPrototype>();
720 static_cast<WeakSetPrototype *>(weakSetPrototype())->init(
this, weakSetCtor());
722 jsObjects[Set_Ctor] = memoryManager->allocate<SetCtor>(
this);
723 jsObjects[SetProto] = memoryManager->allocate<SetPrototype>();
724 static_cast<SetPrototype *>(setPrototype())->init(
this, setCtor());
730 jsObjects[Promise_Ctor] = memoryManager->allocate<PromiseCtor>(
this);
731 jsObjects[PromiseProto] = memoryManager->allocate<PromisePrototype>();
732 static_cast<PromisePrototype *>(promisePrototype())->init(
this, promiseCtor());
736 jsObjects[SharedArrayBuffer_Ctor] = memoryManager->allocate<SharedArrayBufferCtor>(
this);
737 jsObjects[SharedArrayBufferProto] = memoryManager->allocate<SharedArrayBufferPrototype>();
738 static_cast<SharedArrayBufferPrototype *>(sharedArrayBufferPrototype())->init(
this, sharedArrayBufferCtor());
740 jsObjects[ArrayBuffer_Ctor] = memoryManager->allocate<ArrayBufferCtor>(
this);
741 jsObjects[ArrayBufferProto] = memoryManager->allocate<ArrayBufferPrototype>();
742 static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(
this, arrayBufferCtor());
744 jsObjects[DataView_Ctor] = memoryManager->allocate<DataViewCtor>(
this);
745 jsObjects[DataViewProto] = memoryManager->allocate<DataViewPrototype>();
746 static_cast<DataViewPrototype *>(dataViewPrototype())->init(
this, dataViewCtor());
747 jsObjects[ValueTypeProto] = (Heap::Base *)
nullptr;
748 jsObjects[SignalHandlerProto] = (Heap::Base *)
nullptr;
749 jsObjects[TypeWrapperProto] = (Heap::Base *)
nullptr;
751 jsObjects[IntrinsicTypedArray_Ctor] = memoryManager->allocate<IntrinsicTypedArrayCtor>(
this);
752 jsObjects[IntrinsicTypedArrayProto] = memoryManager->allocate<IntrinsicTypedArrayPrototype>();
753 static_cast<IntrinsicTypedArrayPrototype *>(intrinsicTypedArrayPrototype())
754 ->init(
this,
static_cast<IntrinsicTypedArrayCtor *>(intrinsicTypedArrayCtor()));
756 for (
int i = 0; i < NTypedArrayTypes; ++i) {
757 static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(
this, Heap::TypedArray::Type(i));
758 static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
759 typedArrayPrototype[i].as<TypedArrayPrototype>()->init(
this,
static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
765 rootContext()->d()->activation.set(scope.engine, globalObject->d());
766 Q_ASSERT(globalObject->d()->vtable());
768 globalObject->defineDefaultProperty(QStringLiteral(
"Object"), *objectCtor());
769 globalObject->defineDefaultProperty(QStringLiteral(
"String"), *stringCtor());
770 globalObject->defineDefaultProperty(QStringLiteral(
"Symbol"), *symbolCtor());
771 FunctionObject *numberObject = numberCtor();
772 globalObject->defineDefaultProperty(QStringLiteral(
"Number"), *numberObject);
773 globalObject->defineDefaultProperty(QStringLiteral(
"Boolean"), *booleanCtor());
774 globalObject->defineDefaultProperty(QStringLiteral(
"Array"), *arrayCtor());
775 globalObject->defineDefaultProperty(QStringLiteral(
"Function"), *functionCtor());
776 globalObject->defineDefaultProperty(QStringLiteral(
"Date"), *dateCtor());
777 globalObject->defineDefaultProperty(QStringLiteral(
"RegExp"), *regExpCtor());
778 globalObject->defineDefaultProperty(QStringLiteral(
"Error"), *errorCtor());
779 globalObject->defineDefaultProperty(QStringLiteral(
"EvalError"), *evalErrorCtor());
780 globalObject->defineDefaultProperty(QStringLiteral(
"RangeError"), *rangeErrorCtor());
781 globalObject->defineDefaultProperty(QStringLiteral(
"ReferenceError"), *referenceErrorCtor());
782 globalObject->defineDefaultProperty(QStringLiteral(
"SyntaxError"), *syntaxErrorCtor());
783 globalObject->defineDefaultProperty(QStringLiteral(
"TypeError"), *typeErrorCtor());
784 globalObject->defineDefaultProperty(QStringLiteral(
"URIError"), *uRIErrorCtor());
785 globalObject->defineDefaultProperty(QStringLiteral(
"Promise"), *promiseCtor());
786 globalObject->defineDefaultProperty(QStringLiteral(
"URL"), *urlCtor());
787 globalObject->defineDefaultProperty(QStringLiteral(
"URLSearchParams"), *urlSearchParamsCtor());
789 globalObject->defineDefaultProperty(QStringLiteral(
"SharedArrayBuffer"), *sharedArrayBufferCtor());
790 globalObject->defineDefaultProperty(QStringLiteral(
"ArrayBuffer"), *arrayBufferCtor());
791 globalObject->defineDefaultProperty(QStringLiteral(
"DataView"), *dataViewCtor());
792 globalObject->defineDefaultProperty(QStringLiteral(
"WeakSet"), *weakSetCtor());
793 globalObject->defineDefaultProperty(QStringLiteral(
"Set"), *setCtor());
794 globalObject->defineDefaultProperty(QStringLiteral(
"WeakMap"), *weakMapCtor());
795 globalObject->defineDefaultProperty(QStringLiteral(
"Map"), *mapCtor());
797 for (
int i = 0; i < NTypedArrayTypes; ++i)
798 globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name()), typedArrayCtors[i]);
799 ScopedObject o(scope);
800 globalObject->defineDefaultProperty(QStringLiteral(
"Atomics"), (o = memoryManager->allocate<Atomics>()));
801 globalObject->defineDefaultProperty(QStringLiteral(
"Math"), (o = memoryManager->allocate<MathObject>()));
802 globalObject->defineDefaultProperty(QStringLiteral(
"JSON"), (o = memoryManager->allocate<JsonObject>()));
803 globalObject->defineDefaultProperty(QStringLiteral(
"Reflect"), (o = memoryManager->allocate<Reflect>()));
804 globalObject->defineDefaultProperty(QStringLiteral(
"Proxy"), (o = memoryManager->allocate<Proxy>(
this)));
806 globalObject->defineReadonlyProperty(QStringLiteral(
"undefined"), Value::undefinedValue());
807 globalObject->defineReadonlyProperty(QStringLiteral(
"NaN"), Value::fromDouble(std::numeric_limits<
double>::quiet_NaN()));
808 globalObject->defineReadonlyProperty(QStringLiteral(
"Infinity"), Value::fromDouble(Q_INFINITY));
811 jsObjects[Eval_Function] = memoryManager->allocate<EvalFunction>(
this);
812 globalObject->defineDefaultProperty(QStringLiteral(
"eval"), *evalFunction());
818 QString piString(QStringLiteral(
"parseInt"));
819 QString pfString(QStringLiteral(
"parseFloat"));
821 ScopedString pi(scope, newIdentifier(piString));
822 ScopedString pf(scope, newIdentifier(pfString));
823 ScopedFunctionObject parseIntFn(scope, FunctionObject::createBuiltinFunction(
this, pi, GlobalFunctions::method_parseInt, 2));
824 ScopedFunctionObject parseFloatFn(scope, FunctionObject::createBuiltinFunction(
this, pf, GlobalFunctions::method_parseFloat, 1));
825 globalObject->defineDefaultProperty(piString, parseIntFn);
826 globalObject->defineDefaultProperty(pfString, parseFloatFn);
827 numberObject->defineDefaultProperty(piString, parseIntFn);
828 numberObject->defineDefaultProperty(pfString, parseFloatFn);
831 globalObject->defineDefaultProperty(QStringLiteral(
"isNaN"), GlobalFunctions::method_isNaN, 1);
832 globalObject->defineDefaultProperty(QStringLiteral(
"isFinite"), GlobalFunctions::method_isFinite, 1);
833 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURI"), GlobalFunctions::method_decodeURI, 1);
834 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1);
835 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURI"), GlobalFunctions::method_encodeURI, 1);
836 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1);
837 globalObject->defineDefaultProperty(QStringLiteral(
"escape"), GlobalFunctions::method_escape, 1);
838 globalObject->defineDefaultProperty(QStringLiteral(
"unescape"), GlobalFunctions::method_unescape, 1);
840 ScopedFunctionObject t(
842 memoryManager->allocate<DynamicFunctionObject>(
this,
nullptr, ::throwTypeError));
843 t->defineReadonlyProperty(id_length(), Value::fromInt32(0));
844 t->setInternalClass(t->internalClass()->cryopreserved());
845 jsObjects[ThrowerObject] = t;
847 ScopedProperty pd(scope);
848 pd->value = thrower();
850 functionPrototype()->insertMember(id_caller(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
851 functionPrototype()->insertMember(id_arguments(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
853 QV4::QObjectWrapper::initializeBindings(
this);
855 m_delayedCallQueue.init(
this);
856 isInitialized =
true;
1781QV4::ReturnedValue ExecutionEngine::fromData(
1782 QMetaType metaType,
const void *ptr,
1783 QV4::Heap::Object *container,
int property, uint flags)
1785 const auto createSequence = [&](
const QMetaSequence metaSequence) {
1786 QV4::Scope scope(
this);
1787 QV4::Scoped<Sequence> sequence(scope);
1789 return QV4::SequencePrototype::newSequence(
1790 this, metaType, metaSequence, ptr,
1791 container, property, Heap::ReferenceObject::Flags(flags));
1793 return QV4::SequencePrototype::fromData(
this, metaType, metaSequence, ptr);
1797 const int type = metaType.id();
1798 if (type < QMetaType::User) {
1799 switch (QMetaType::Type(type)) {
1800 case QMetaType::UnknownType:
1801 case QMetaType::Void:
1802 return QV4::Encode::undefined();
1803 case QMetaType::Nullptr:
1804 case QMetaType::VoidStar:
1805 return QV4::Encode::null();
1806 case QMetaType::Bool:
1807 return QV4::Encode(*
reinterpret_cast<
const bool*>(ptr));
1808 case QMetaType::Int:
1809 return QV4::Encode(*
reinterpret_cast<
const int*>(ptr));
1810 case QMetaType::UInt:
1811 return QV4::Encode(*
reinterpret_cast<
const uint*>(ptr));
1812 case QMetaType::Long:
1813 return QV4::Encode((
double)*
reinterpret_cast<
const long *>(ptr));
1814 case QMetaType::ULong:
1815 return QV4::Encode((
double)*
reinterpret_cast<
const ulong *>(ptr));
1816 case QMetaType::LongLong:
1817 return QV4::Encode((
double)*
reinterpret_cast<
const qlonglong*>(ptr));
1818 case QMetaType::ULongLong:
1819 return QV4::Encode((
double)*
reinterpret_cast<
const qulonglong*>(ptr));
1820 case QMetaType::Double:
1821 return QV4::Encode(*
reinterpret_cast<
const double*>(ptr));
1822 case QMetaType::QString:
1823 return newString(*
reinterpret_cast<
const QString*>(ptr))->asReturnedValue();
1824 case QMetaType::QByteArray:
1825 return newArrayBuffer(*
reinterpret_cast<
const QByteArray*>(ptr))->asReturnedValue();
1826 case QMetaType::Float:
1827 return QV4::Encode(*
reinterpret_cast<
const float*>(ptr));
1828 case QMetaType::Short:
1829 return QV4::Encode((
int)*
reinterpret_cast<
const short*>(ptr));
1830 case QMetaType::UShort:
1831 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned short*>(ptr));
1832 case QMetaType::Char:
1833 return QV4::Encode((
int)*
reinterpret_cast<
const char*>(ptr));
1834 case QMetaType::UChar:
1835 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned char*>(ptr));
1836 case QMetaType::SChar:
1837 return QV4::Encode((
int)*
reinterpret_cast<
const signed char*>(ptr));
1838 case QMetaType::QChar:
1839 return newString(*
reinterpret_cast<
const QChar *>(ptr))->asReturnedValue();
1840 case QMetaType::Char16:
1841 return newString(QChar(*
reinterpret_cast<
const char16_t *>(ptr)))->asReturnedValue();
1842 case QMetaType::QDateTime:
1843 return QV4::Encode(newDateObject(
1844 *
reinterpret_cast<
const QDateTime *>(ptr),
1845 container, property, flags));
1846 case QMetaType::QDate:
1847 return QV4::Encode(newDateObject(
1848 *
reinterpret_cast<
const QDate *>(ptr),
1849 container, property, flags));
1850 case QMetaType::QTime:
1851 return QV4::Encode(newDateObject(
1852 *
reinterpret_cast<
const QTime *>(ptr),
1853 container, property, flags));
1854#if QT_CONFIG(regularexpression)
1855 case QMetaType::QRegularExpression:
1856 return QV4::Encode(newRegExpObject(*
reinterpret_cast<
const QRegularExpression *>(ptr)));
1858 case QMetaType::QObjectStar:
1859 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1860 case QMetaType::QStringList:
1861 return createSequence(QMetaSequence::fromContainer<QStringList>());
1862 case QMetaType::QVariantList:
1863 return createSequence(QMetaSequence::fromContainer<QVariantList>());
1864 case QMetaType::QVariantMap:
1865 return VariantAssociationPrototype::fromQVariantMap(
1867 *
reinterpret_cast<
const QVariantMap *>(ptr),
1868 container, property, Heap::ReferenceObject::Flags(flags));
1869 case QMetaType::QVariantHash:
1870 return VariantAssociationPrototype::fromQVariantHash(
1872 *
reinterpret_cast<
const QVariantHash *>(ptr),
1873 container, property, Heap::ReferenceObject::Flags(flags));
1874 case QMetaType::QJsonValue:
1875 return QV4::JsonObject::fromJsonValue(
this, *
reinterpret_cast<
const QJsonValue *>(ptr));
1876 case QMetaType::QJsonObject:
1877 return QV4::JsonObject::fromJsonObject(
this, *
reinterpret_cast<
const QJsonObject *>(ptr));
1878 case QMetaType::QJsonArray:
1879 return QV4::JsonObject::fromJsonArray(
this, *
reinterpret_cast<
const QJsonArray *>(ptr));
1880 case QMetaType::QPixmap:
1881 case QMetaType::QImage:
1883 return QV4::Encode(newVariantObject(metaType, ptr));
1889 if (metaType.flags() & QMetaType::IsEnumeration)
1890 return fromData(metaType.underlyingType(), ptr, container, property, flags);
1892 QV4::Scope scope(
this);
1893 if (metaType == QMetaType::fromType<QQmlListReference>()) {
1894 typedef QQmlListReferencePrivate QDLRP;
1895 QDLRP *p = QDLRP::get((QQmlListReference*)
const_cast<
void *>(ptr));
1897 return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
1899 return QV4::Encode::null();
1900 }
else if (
auto flags = metaType.flags(); flags & QMetaType::IsQmlList) {
1903 const auto *p =
static_cast<
const QQmlListProperty<QObject> *>(ptr);
1905 return QV4::QmlListWrapper::create(scope.engine, *p, metaType);
1907 return QV4::Encode::null();
1908 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
1909 return QJSValuePrivate::convertToReturnedValue(
1910 this, *
reinterpret_cast<
const QJSValue *>(ptr));
1911 }
else if (metaType == QMetaType::fromType<QList<QObject *> >()) {
1914 const QList<QObject *> &list = *(
const QList<QObject *>*)ptr;
1915 QV4::ScopedArrayObject a(scope, newArrayObject());
1916 a->arrayReserve(list.size());
1917 QV4::ScopedValue v(scope);
1918 for (
int ii = 0; ii < list.size(); ++ii)
1919 a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(
this, list.at(ii))));
1920 a->setArrayLengthUnchecked(list.size());
1921 return a.asReturnedValue();
1922 }
else if (
auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
1923 if (flags.testFlag(QMetaType::IsConst))
1924 return QV4::QObjectWrapper::wrapConst(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1926 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1927 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1928 const QJSPrimitiveValue *primitive =
static_cast<
const QJSPrimitiveValue *>(ptr);
1929 switch (primitive->type()) {
1930 case QJSPrimitiveValue::Boolean:
1931 return Encode(primitive->asBoolean());
1932 case QJSPrimitiveValue::Integer:
1933 return Encode(primitive->asInteger());
1934 case QJSPrimitiveValue::String:
1935 return newString(primitive->asString())->asReturnedValue();
1936 case QJSPrimitiveValue::Undefined:
1937 return Encode::undefined();
1938 case QJSPrimitiveValue::Null:
1939 return Encode::null();
1940 case QJSPrimitiveValue::Double:
1941 return Encode(primitive->asDouble());
1945 if (
const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(metaType)) {
1947 return QV4::QQmlValueTypeWrapper::create(
1948 this, ptr, vtmo, metaType,
1949 container, property, Heap::ReferenceObject::Flags(flags));
1951 return QV4::QQmlValueTypeWrapper::create(
this, ptr, vtmo, metaType);
1955 const QQmlType listType = QQmlMetaType::qmlListType(metaType);
1956 if (listType.isSequentialContainer())
1957 return createSequence(listType.listMetaSequence());
1959 QSequentialIterable iterable;
1960 if (QMetaType::convert(metaType, ptr, QMetaType::fromType<QSequentialIterable>(), &iterable)) {
1963 const QMetaSequence sequence = iterable.metaContainer();
1964 if (sequence.hasSize() && sequence.canGetValueAtIndex())
1965 return createSequence(sequence);
1969 if (sequence.hasConstIterator() && sequence.canGetValueAtConstIterator()) {
1970 QV4::ScopedArrayObject a(scope, newArrayObject());
1971 QV4::ScopedValue v(scope);
1972 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it) {
1973 v = fromVariant(*it);
1976 return a.asReturnedValue();
1980 return QV4::Encode(newVariantObject(metaType, ptr));
2554bool ExecutionEngine::metaTypeFromJS(
const Value &value, QMetaType metaType,
void *data)
2557 switch (metaType.id()) {
2558 case QMetaType::Bool:
2559 *
reinterpret_cast<
bool*>(data) = value.toBoolean();
2561 case QMetaType::Int:
2562 *
reinterpret_cast<
int*>(data) = value.toInt32();
2564 case QMetaType::UInt:
2565 *
reinterpret_cast<uint*>(data) = value.toUInt32();
2567 case QMetaType::Long:
2568 *
reinterpret_cast<
long*>(data) =
long(value.toInteger());
2570 case QMetaType::ULong:
2571 *
reinterpret_cast<ulong*>(data) = ulong(value.toInteger());
2573 case QMetaType::LongLong:
2574 *
reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
2576 case QMetaType::ULongLong:
2577 *
reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
2579 case QMetaType::Double:
2580 *
reinterpret_cast<
double*>(data) = value.toNumber();
2582 case QMetaType::QString:
2583 if (value.isUndefined())
2584 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"undefined");
2585 else if (value.isNull())
2586 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"null");
2588 *
reinterpret_cast<QString*>(data) = value.toQString();
2590 case QMetaType::QByteArray:
2591 if (
const ArrayBuffer *ab = value.as<ArrayBuffer>()) {
2592 *
reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
2593 }
else if (
const String *string = value.as<String>()) {
2594 *
reinterpret_cast<QByteArray*>(data) = string->toQString().toUtf8();
2595 }
else if (
const ArrayObject *ao = value.as<ArrayObject>()) {
2598 const qint64 length = ao->getLength();
2599 result.reserve(length);
2600 QV4::Scope scope(ao->engine());
2601 QV4::ScopedValue v(scope);
2602 for (qint64 i = 0; i < length; ++i) {
2605 ExecutionEngine::metaTypeFromJS(v, QMetaType::fromType<
char>(), &value);
2606 result.push_back(value);
2608 *
reinterpret_cast<QByteArray*>(data) = std::move(result);
2610 *
reinterpret_cast<QByteArray*>(data) = QByteArray();
2613 case QMetaType::Float:
2614 *
reinterpret_cast<
float*>(data) = value.toNumber();
2616 case QMetaType::Short:
2617 *
reinterpret_cast<
short*>(data) =
short(value.toInt32());
2619 case QMetaType::UShort:
2620 *
reinterpret_cast<
unsigned short*>(data) = value.toUInt16();
2622 case QMetaType::Char:
2623 *
reinterpret_cast<
char*>(data) =
char(value.toInt32());
2625 case QMetaType::UChar:
2626 *
reinterpret_cast<
unsigned char*>(data) = (
unsigned char)(value.toInt32());
2628 case QMetaType::SChar:
2629 *
reinterpret_cast<
signed char*>(data) = (
signed char)(value.toInt32());
2631 case QMetaType::QChar:
2632 if (String *s = value.stringValue()) {
2633 QString str = s->toQString();
2634 *
reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
2636 *
reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
2639 case QMetaType::QDateTime:
2640 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2641 *
reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
2644 case QMetaType::QDate:
2645 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2646 *
reinterpret_cast<QDate *>(data) = DateObject::dateTimeToDate(d->toQDateTime());
2649 case QMetaType::QTime:
2650 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2651 *
reinterpret_cast<QTime *>(data) = d->toQDateTime().time();
2654 case QMetaType::QUrl:
2655 if (String *s = value.stringValue()) {
2656 *
reinterpret_cast<QUrl *>(data) = QUrl(s->toQString());
2658 }
else if (
const QV4::UrlObject *d = value.as<UrlObject>()) {
2659 *
reinterpret_cast<QUrl *>(data) = d->toQUrl();
2661 }
else if (
const QV4::VariantObject *d = value.as<VariantObject>()) {
2662 const QVariant *variant = &d->d()->data();
2663 if (variant->metaType() == QMetaType::fromType<QUrl>()) {
2664 *
reinterpret_cast<QUrl *>(data)
2665 = *
reinterpret_cast<
const QUrl *>(variant->constData());
2670#if QT_CONFIG(regularexpression)
2671 case QMetaType::QRegularExpression:
2672 if (
const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
2673 *
reinterpret_cast<QRegularExpression *>(data) = r->toQRegularExpression();
2677 case QMetaType::QObjectStar: {
2678 if (value.isNull()) {
2679 *
reinterpret_cast<QObject* *>(data) =
nullptr;
2682 if (value.as<QV4::QObjectWrapper>()) {
2683 *
reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
2688 case QMetaType::QStringList: {
2689 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2691 *
reinterpret_cast<QStringList *>(data) = a->toQStringList();
2696 case QMetaType::QVariantList: {
2697 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2699 *
reinterpret_cast<QVariantList *>(data) = ExecutionEngine::toVariant(
2700 *a, QMetaType{},
false)
2706 case QMetaType::QVariantMap: {
2707 const QV4::Object *o = value.as<QV4::Object>();
2709 *
reinterpret_cast<QVariantMap *>(data) = o->engine()->variantMapFromJS(o);
2714 case QMetaType::QVariant:
2715 if (value.as<QV4::Managed>()) {
2716 *
reinterpret_cast<QVariant*>(data) = ExecutionEngine::toVariant(
2717 value, QMetaType{},
false);
2718 }
else if (value.isNull()) {
2719 *
reinterpret_cast<QVariant*>(data) = QVariant::fromValue(
nullptr);
2720 }
else if (value.isUndefined()) {
2721 *
reinterpret_cast<QVariant*>(data) = QVariant();
2722 }
else if (value.isBoolean()) {
2723 *
reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue());
2724 }
else if (value.isInteger()) {
2725 *
reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue());
2726 }
else if (value.isDouble()) {
2727 *
reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue());
2730 case QMetaType::QJsonValue:
2731 *
reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
2733 case QMetaType::QJsonObject: {
2734 *
reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.as<Object>());
2737 case QMetaType::QJsonArray: {
2738 const QV4::ArrayObject *a = value.as<ArrayObject>();
2740 *
reinterpret_cast<QJsonArray *>(data) = JsonObject::toJsonArray(a);
2749 if (metaType.flags() & QMetaType::IsEnumeration) {
2750 *
reinterpret_cast<
int *>(data) = value.toInt32();
2754 if (
const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) {
2755 if (metaType == QMetaType::fromType<QQmlListReference>()) {
2756 *
reinterpret_cast<QQmlListReference *>(data) = wrapper->toListReference();
2760 const auto wrapperPrivate = wrapper->d();
2761 if (metaType == QMetaType::fromType<QQmlListProperty<QObject> *>()
2762 || metaType == wrapperPrivate->propertyType()) {
2763 *
reinterpret_cast<QQmlListProperty<QObject> *>(data) = *wrapperPrivate->property();
2767 if (metaType == QMetaType::fromType<QObjectList>()) {
2768 *
reinterpret_cast<QObjectList *>(data)
2769 = wrapperPrivate->property()->toList<QObjectList>();
2773 if (convertToIterable(metaType, data, wrapper))
2777 if (
const QQmlValueTypeWrapper *vtw = value.as<QQmlValueTypeWrapper>()) {
2778 const QMetaType valueType = vtw->type();
2779 if (valueType == metaType)
2780 return vtw->toGadget(data);
2782 Heap::QQmlValueTypeWrapper *d = vtw->d();
2783 if (d->isReference())
2786 if (
void *gadgetPtr = d->gadgetPtr()) {
2787 if (QQmlValueTypeProvider::populateValueType(
2788 metaType, data, valueType, gadgetPtr, vtw->engine())) {
2791 if (QMetaType::canConvert(valueType, metaType))
2792 return QMetaType::convert(valueType, gadgetPtr, metaType, data);
2794 QVariant empty(valueType);
2795 if (QQmlValueTypeProvider::populateValueType(
2796 metaType, data, valueType, empty.data(), vtw->engine())) {
2799 if (QMetaType::canConvert(valueType, metaType))
2800 return QMetaType::convert(valueType, empty.data(), metaType, data);
2806 if (convertToNativeQObject(value, metaType,
reinterpret_cast<
void **>(data)))
2809 const bool isPointer = (metaType.flags() & QMetaType::IsPointer);
2810 const QV4::VariantObject *variantObject = value.as<QV4::VariantObject>();
2811 if (variantObject) {
2814 QVariant &var = variantObject->d()->data();
2816 if (var.metaType() == metaType) {
2817 metaType.destruct(data);
2818 metaType.construct(data, var.data());
2823 const QByteArray pointedToTypeName = QByteArray(metaType.name()).chopped(1);
2824 const QMetaType valueType = QMetaType::fromName(pointedToTypeName);
2826 if (valueType == var.metaType()) {
2829 *
reinterpret_cast<
const void **>(data) = var.data();
2831 }
else if (Object *o = value.objectValue()) {
2833 QV4::Scope scope(o->engine());
2834 QV4::ScopedObject proto(scope, o->getPrototypeOf());
2836 bool canCast =
false;
2837 if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
2838 const QVariant &v = vo->d()->data();
2839 canCast = (metaType == v.metaType());
2841 else if (proto->as<QV4::QObjectWrapper>()) {
2842 QV4::ScopedObject p(scope, proto.getPointer());
2843 if (QObject *qobject = qtObjectFromJS(p)) {
2844 if (
const QMetaObject *metaObject = metaType.metaObject())
2845 canCast = metaObject->cast(qobject) !=
nullptr;
2847 canCast = qobject->qt_metacast(pointedToTypeName);
2851 const QMetaType varType = var.metaType();
2852 if (varType.flags() & QMetaType::IsPointer) {
2853 *
reinterpret_cast<
const void **>(data)
2854 = *
reinterpret_cast<
void *
const *>(var.data());
2856 *
reinterpret_cast<
const void **>(data) = var.data();
2860 proto = proto->getPrototypeOf();
2863 }
else if (QQmlValueTypeProvider::populateValueType(
2864 metaType, data, var.metaType(), var.data(), variantObject->engine())) {
2867 }
else if (value.isNull() && isPointer) {
2868 *
reinterpret_cast<
void* *>(data) =
nullptr;
2870 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
2871 QJSValuePrivate::setValue(
reinterpret_cast<QJSValue*>(data), value);
2873 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
2874 *
reinterpret_cast<QJSPrimitiveValue *>(data) = createPrimitive(&value);
2876 }
else if (!isPointer) {
2877 const QV4::Managed *managed = value.as<QV4::Managed>();
2878 if (QQmlValueTypeProvider::populateValueType(
2879 metaType, data, value, managed ? managed->engine() :
nullptr)) {
2884 if (
const QV4::Sequence *sequence = value.as<Sequence>()) {
2885 const QVariant result = QV4::SequencePrototype::toVariant(sequence);
2886 if (result.metaType() == metaType) {
2887 metaType.destruct(data);
2888 metaType.construct(data, result.constData());
2892 if (convertToIterable(metaType, data, sequence))
2896 if (
const QV4::ArrayObject *array = value.as<ArrayObject>()) {
2897 if (convertToIterable(metaType, data, array))