367ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
368 : executableAllocator(
new QV4::ExecutableAllocator)
369 , regExpAllocator(
new QV4::ExecutableAllocator)
370 , bumperPointerAllocator(
new WTF::BumpPointerAllocator)
371 , jsStack(
new WTF::PageAllocation)
372 , gcStack(
new WTF::PageAllocation)
373 , publicEngine(jsEngine)
374 , m_engineId(engineSerial.fetchAndAddOrdered(2))
375#if QT_CONFIG(qml_jit)
376 , m_canAllocateExecutableMemory(OSAllocator::canAllocateExecutableMemory())
379 if (m_engineId == 1) {
380 initializeStaticMembers();
381 engineSerial.storeRelease(2);
382 }
else if (Q_UNLIKELY(m_engineId & 1)) {
384 while (engineSerial.loadAcquire() & 1) {
385 QThread::yieldCurrentThread();
389 if (s_maxCallDepth < 0)
390 setCppStackProperties();
395 const size_t guardPages = 2 * WTF::pageSize();
397 memoryManager =
new QV4::MemoryManager(
this);
399 GCCriticalSection gcCriticalSection(
this);
403 *jsStack = WTF::PageAllocation::allocate(
404 s_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages,
406 jsStackBase = (Value *)jsStack->base();
407#ifdef V4_USE_VALGRIND
408 VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, s_maxJSStackSize + 256*1024);
411 jsStackTop = jsStackBase;
413 *gcStack = WTF::PageAllocation::allocate(
414 s_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages,
417 exceptionValue = jsAlloca(1);
418 *exceptionValue = Encode::undefined();
419 globalObject =
static_cast<Object *>(jsAlloca(1));
420 jsObjects = jsAlloca(NJSObjects);
421 typedArrayPrototype =
static_cast<Object *>(jsAlloca(NTypedArrayTypes));
422 typedArrayCtors =
static_cast<FunctionObject *>(jsAlloca(NTypedArrayTypes));
423 jsStrings = jsAlloca(NJSStrings);
424 jsSymbols = jsAlloca(NJSSymbols);
427 jsStackLimit = jsStackBase + s_maxJSStackSize/
sizeof(Value);
429 identifierTable =
new IdentifierTable(
this);
431 memset(classes, 0,
sizeof(classes));
432 classes[Class_Empty] = memoryManager->allocIC<InternalClass>();
433 classes[Class_Empty]->init(
this);
435 classes[Class_MemberData] = classes[Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
436 classes[Class_SimpleArrayData] = classes[Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
437 classes[Class_SparseArrayData] = classes[Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
438 classes[Class_ExecutionContext] = classes[Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
439 classes[Class_CallContext] = classes[Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
440 classes[Class_QmlContext] = classes[Class_Empty]->changeVTable(QV4::QmlContext::staticVTable());
443 Scoped<InternalClass> ic(scope);
444 ic = classes[Class_Empty]->changeVTable(QV4::Object::staticVTable());
445 jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic->d());
446 classes[Class_Object] = ic->changePrototype(objectPrototype()->d());
447 classes[Class_QmlContextWrapper] = classes[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
449 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
450 jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(ic->d(),
false);
451 classes[Class_String] = classes[Class_Empty]->changeVTable(QV4::String::staticVTable())->changePrototype(stringPrototype()->d());
452 Q_ASSERT(stringPrototype()->d() && classes[Class_String]->prototype);
454 jsObjects[SymbolProto] = memoryManager->allocate<SymbolPrototype>();
455 classes[Class_Symbol] = classes[EngineBase::Class_Empty]->changeVTable(QV4::Symbol::staticVTable())->changePrototype(symbolPrototype()->d());
457 jsStrings[String_Empty] = newIdentifier(QString());
458 jsStrings[String_undefined] = newIdentifier(QStringLiteral(
"undefined"));
459 jsStrings[String_null] = newIdentifier(QStringLiteral(
"null"));
460 jsStrings[String_true] = newIdentifier(QStringLiteral(
"true"));
461 jsStrings[String_false] = newIdentifier(QStringLiteral(
"false"));
462 jsStrings[String_boolean] = newIdentifier(QStringLiteral(
"boolean"));
463 jsStrings[String_number] = newIdentifier(QStringLiteral(
"number"));
464 jsStrings[String_string] = newIdentifier(QStringLiteral(
"string"));
465 jsStrings[String_default] = newIdentifier(QStringLiteral(
"default"));
466 jsStrings[String_symbol] = newIdentifier(QStringLiteral(
"symbol"));
467 jsStrings[String_object] = newIdentifier(QStringLiteral(
"object"));
468 jsStrings[String_function] = newIdentifier(QStringLiteral(
"function"));
469 jsStrings[String_length] = newIdentifier(QStringLiteral(
"length"));
470 jsStrings[String_prototype] = newIdentifier(QStringLiteral(
"prototype"));
471 jsStrings[String_constructor] = newIdentifier(QStringLiteral(
"constructor"));
472 jsStrings[String_arguments] = newIdentifier(QStringLiteral(
"arguments"));
473 jsStrings[String_caller] = newIdentifier(QStringLiteral(
"caller"));
474 jsStrings[String_callee] = newIdentifier(QStringLiteral(
"callee"));
475 jsStrings[String_this] = newIdentifier(QStringLiteral(
"this"));
476 jsStrings[String___proto__] = newIdentifier(QStringLiteral(
"__proto__"));
477 jsStrings[String_enumerable] = newIdentifier(QStringLiteral(
"enumerable"));
478 jsStrings[String_configurable] = newIdentifier(QStringLiteral(
"configurable"));
479 jsStrings[String_writable] = newIdentifier(QStringLiteral(
"writable"));
480 jsStrings[String_value] = newIdentifier(QStringLiteral(
"value"));
481 jsStrings[String_get] = newIdentifier(QStringLiteral(
"get"));
482 jsStrings[String_set] = newIdentifier(QStringLiteral(
"set"));
483 jsStrings[String_eval] = newIdentifier(QStringLiteral(
"eval"));
484 jsStrings[String_uintMax] = newIdentifier(QStringLiteral(
"4294967295"));
485 jsStrings[String_name] = newIdentifier(QStringLiteral(
"name"));
486 jsStrings[String_index] = newIdentifier(QStringLiteral(
"index"));
487 jsStrings[String_input] = newIdentifier(QStringLiteral(
"input"));
488 jsStrings[String_toString] = newIdentifier(QStringLiteral(
"toString"));
489 jsStrings[String_toLocaleString] = newIdentifier(QStringLiteral(
"toLocaleString"));
490 jsStrings[String_destroy] = newIdentifier(QStringLiteral(
"destroy"));
491 jsStrings[String_valueOf] = newIdentifier(QStringLiteral(
"valueOf"));
492 jsStrings[String_byteLength] = newIdentifier(QStringLiteral(
"byteLength"));
493 jsStrings[String_byteOffset] = newIdentifier(QStringLiteral(
"byteOffset"));
494 jsStrings[String_buffer] = newIdentifier(QStringLiteral(
"buffer"));
495 jsStrings[String_lastIndex] = newIdentifier(QStringLiteral(
"lastIndex"));
496 jsStrings[String_next] = newIdentifier(QStringLiteral(
"next"));
497 jsStrings[String_done] = newIdentifier(QStringLiteral(
"done"));
498 jsStrings[String_return] = newIdentifier(QStringLiteral(
"return"));
499 jsStrings[String_throw] = newIdentifier(QStringLiteral(
"throw"));
500 jsStrings[String_global] = newIdentifier(QStringLiteral(
"global"));
501 jsStrings[String_ignoreCase] = newIdentifier(QStringLiteral(
"ignoreCase"));
502 jsStrings[String_multiline] = newIdentifier(QStringLiteral(
"multiline"));
503 jsStrings[String_unicode] = newIdentifier(QStringLiteral(
"unicode"));
504 jsStrings[String_sticky] = newIdentifier(QStringLiteral(
"sticky"));
505 jsStrings[String_source] = newIdentifier(QStringLiteral(
"source"));
506 jsStrings[String_flags] = newIdentifier(QStringLiteral(
"flags"));
508 jsSymbols[Symbol_hasInstance] = Symbol::create(
this, QStringLiteral(
"@Symbol.hasInstance"));
509 jsSymbols[Symbol_isConcatSpreadable] = Symbol::create(
this, QStringLiteral(
"@Symbol.isConcatSpreadable"));
510 jsSymbols[Symbol_iterator] = Symbol::create(
this, QStringLiteral(
"@Symbol.iterator"));
511 jsSymbols[Symbol_match] = Symbol::create(
this, QStringLiteral(
"@Symbol.match"));
512 jsSymbols[Symbol_replace] = Symbol::create(
this, QStringLiteral(
"@Symbol.replace"));
513 jsSymbols[Symbol_search] = Symbol::create(
this, QStringLiteral(
"@Symbol.search"));
514 jsSymbols[Symbol_species] = Symbol::create(
this, QStringLiteral(
"@Symbol.species"));
515 jsSymbols[Symbol_split] = Symbol::create(
this, QStringLiteral(
"@Symbol.split"));
516 jsSymbols[Symbol_toPrimitive] = Symbol::create(
this, QStringLiteral(
"@Symbol.toPrimitive"));
517 jsSymbols[Symbol_toStringTag] = Symbol::create(
this, QStringLiteral(
"@Symbol.toStringTag"));
518 jsSymbols[Symbol_unscopables] = Symbol::create(
this, QStringLiteral(
"@Symbol.unscopables"));
519 jsSymbols[Symbol_revokableProxy] = Symbol::create(
this, QStringLiteral(
"@Proxy.revokableProxy"));
521 ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
522 Q_ASSERT(ic->d()->prototype);
523 ic = ic->addMember(id_length()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
524 Q_ASSERT(ic->d()->prototype);
525 jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic->d());
526 classes[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d());
527 jsObjects[PropertyListProto] = memoryManager->allocate<PropertyListPrototype>();
529 Scoped<InternalClass> argsClass(scope);
530 argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
531 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
532 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
533 classes[Class_ArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Data|Attr_NotEnumerable);
534 argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
535 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
536 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
537 classes[Class_StrictArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
539 *
static_cast<Value *>(globalObject) = newObject();
540 Q_ASSERT(globalObject->d()->vtable());
543 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
544 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly);
545 classes[Class_StringObject] = ic->changePrototype(stringPrototype()->d());
546 Q_ASSERT(classes[Class_StringObject]->verifyIndex(id_length()->propertyKey(), Heap::StringObject::LengthPropertyIndex));
548 classes[Class_SymbolObject] = newInternalClass(QV4::SymbolObject::staticVTable(), symbolPrototype());
550 jsObjects[NumberProto] = memoryManager->allocate<NumberPrototype>();
551 jsObjects[BooleanProto] = memoryManager->allocate<BooleanPrototype>();
552 jsObjects[DateProto] = memoryManager->allocate<DatePrototype>();
554#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
555 InternalClassEntry *index =
nullptr;
557 InternalClassEntry _index;
558 auto *index = &_index;
560 ic = newInternalClass(QV4::FunctionPrototype::staticVTable(), objectPrototype());
561 auto addProtoHasInstance = [&] {
565 ic = ic->addMember(id_prototype()->propertyKey(), Attr_Invalid, index);
566 Q_ASSERT(index->index == Heap::FunctionObject::Index_Prototype);
570 ic = ic->addMember(symbol_hasInstance()->propertyKey(), Attr_Invalid, index);
571 Q_ASSERT(index->index == Heap::FunctionObject::Index_HasInstance);
573 addProtoHasInstance();
574 jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d());
575 ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype());
576 addProtoHasInstance();
577 classes[Class_FunctionObject] = ic->d();
578 ic = ic->addMember(id_name()->propertyKey(), Attr_ReadOnly, index);
579 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Name);
580 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly_ButConfigurable, index);
581 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Length);
582 classes[Class_ArrowFunction] = ic->changeVTable(ArrowFunction::staticVTable());
583 ic = ic->changeVTable(MemberFunction::staticVTable());
584 classes[Class_MemberFunction] = ic->d();
585 ic = ic->changeVTable(GeneratorFunction::staticVTable());
586 classes[Class_GeneratorFunction] = ic->d();
587 ic = ic->changeVTable(MemberGeneratorFunction::staticVTable());
588 classes[Class_MemberGeneratorFunction] = ic->d();
590 ic = ic->changeMember(id_prototype()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
591 ic = ic->changeVTable(ScriptFunction::staticVTable());
592 classes[Class_ScriptFunction] = ic->d();
593 ic = ic->changeVTable(ConstructorFunction::staticVTable());
594 classes[Class_ConstructorFunction] = ic->d();
596 classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->propertyKey(), Attr_NotEnumerable, index);
597 Q_ASSERT(index->index == Heap::FunctionObject::Index_ProtoConstructor);
599 jsObjects[GeneratorProto] = memoryManager->allocObject<GeneratorPrototype>(classes[Class_Object]);
600 classes[Class_GeneratorObject] = newInternalClass(QV4::GeneratorObject::staticVTable(), generatorPrototype());
602 ScopedString str(scope);
603 classes[Class_RegExp] = classes[Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
604 ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype());
605 ic = ic->addMember(id_lastIndex()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, index);
606 Q_ASSERT(index->index == RegExpObject::Index_LastIndex);
607 jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(classes[Class_Object]);
608 classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d());
610 ic = classes[Class_ArrayObject]->addMember(id_index()->propertyKey(), Attr_Data, index);
611 Q_ASSERT(index->index == RegExpObject::Index_ArrayIndex);
612 classes[Class_RegExpExecArray] = ic->addMember(id_input()->propertyKey(), Attr_Data, index);
613 Q_ASSERT(index->index == RegExpObject::Index_ArrayInput);
615 ic = newInternalClass(ErrorObject::staticVTable(),
nullptr);
616 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"stack")))->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, index);
617 Q_ASSERT(index->index == ErrorObject::Index_Stack);
618 Q_ASSERT(index->setterIndex == ErrorObject::Index_StackSetter);
619 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"fileName")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
620 Q_ASSERT(index->index == ErrorObject::Index_FileName);
621 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"lineNumber")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
622 classes[Class_ErrorObject] = ic->d();
623 Q_ASSERT(index->index == ErrorObject::Index_LineNumber);
624 classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
625 Q_ASSERT(index->index == ErrorObject::Index_Message);
626 ic = newInternalClass(Object::staticVTable(), objectPrototype());
627 ic = ic->addMember(id_constructor()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
628 Q_ASSERT(index->index == ErrorPrototype::Index_Constructor);
629 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
630 Q_ASSERT(index->index == ErrorPrototype::Index_Message);
631 classes[Class_ErrorProto] = ic->addMember(id_name()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
632 Q_ASSERT(index->index == ErrorPrototype::Index_Name);
634 classes[Class_ProxyObject] = classes[Class_Empty]->changeVTable(ProxyObject::staticVTable());
635 classes[Class_ProxyFunctionObject] = classes[Class_Empty]->changeVTable(ProxyFunctionObject::staticVTable());
637 jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(
this, str = newIdentifier(QStringLiteral(
"stack")), ErrorObject::method_get_stack, 0);
639 jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(classes[Class_ErrorProto]);
640 ic = classes[Class_ErrorProto]->changePrototype(errorPrototype()->d());
641 jsObjects[EvalErrorProto] = memoryManager->allocObject<EvalErrorPrototype>(ic->d());
642 jsObjects[RangeErrorProto] = memoryManager->allocObject<RangeErrorPrototype>(ic->d());
643 jsObjects[ReferenceErrorProto] = memoryManager->allocObject<ReferenceErrorPrototype>(ic->d());
644 jsObjects[SyntaxErrorProto] = memoryManager->allocObject<SyntaxErrorPrototype>(ic->d());
645 jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(ic->d());
646 jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(ic->d());
648 jsObjects[VariantProto] = memoryManager->allocate<VariantPrototype>();
649 Q_ASSERT(variantPrototype()->getPrototypeOf() == objectPrototype()->d());
651 jsObjects[VariantAssociationProto] = memoryManager->allocate<VariantAssociationPrototype>();
652 Q_ASSERT(variantAssociationPrototype()->getPrototypeOf() == objectPrototype()->d());
654 ic = newInternalClass(SequencePrototype::staticVTable(), SequencePrototype::defaultPrototype(
this));
655 jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(ic->d()));
657 jsObjects[Object_Ctor] = memoryManager->allocate<ObjectCtor>(
this);
658 jsObjects[String_Ctor] = memoryManager->allocate<StringCtor>(
this);
659 jsObjects[Symbol_Ctor] = memoryManager->allocate<SymbolCtor>(
this);
660 jsObjects[Number_Ctor] = memoryManager->allocate<NumberCtor>(
this);
661 jsObjects[Boolean_Ctor] = memoryManager->allocate<BooleanCtor>(
this);
662 jsObjects[Array_Ctor] = memoryManager->allocate<ArrayCtor>(
this);
663 jsObjects[Function_Ctor] = memoryManager->allocate<FunctionCtor>(
this);
664 jsObjects[GeneratorFunction_Ctor] = memoryManager->allocate<GeneratorFunctionCtor>(
this);
665 jsObjects[Date_Ctor] = memoryManager->allocate<DateCtor>(
this);
666 jsObjects[RegExp_Ctor] = memoryManager->allocate<RegExpCtor>(
this);
667 jsObjects[Error_Ctor] = memoryManager->allocate<ErrorCtor>(
this);
668 jsObjects[EvalError_Ctor] = memoryManager->allocate<EvalErrorCtor>(
this);
669 jsObjects[RangeError_Ctor] = memoryManager->allocate<RangeErrorCtor>(
this);
670 jsObjects[ReferenceError_Ctor] = memoryManager->allocate<ReferenceErrorCtor>(
this);
671 jsObjects[SyntaxError_Ctor] = memoryManager->allocate<SyntaxErrorCtor>(
this);
672 jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(
this);
673 jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(
this);
674 jsObjects[IteratorProto] = memoryManager->allocate<IteratorPrototype>();
676 ic = newInternalClass(ForInIteratorPrototype::staticVTable(), iteratorPrototype());
677 jsObjects[ForInIteratorProto] = memoryManager->allocObject<ForInIteratorPrototype>(ic);
678 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
679 jsObjects[MapIteratorProto] = memoryManager->allocObject<MapIteratorPrototype>(ic);
680 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
681 jsObjects[SetIteratorProto] = memoryManager->allocObject<SetIteratorPrototype>(ic);
682 ic = newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype());
683 jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(ic);
684 ic = newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype());
685 jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(ic);
691 jsObjects[Url_Ctor] = memoryManager->allocate<UrlCtor>(
this);
692 jsObjects[UrlProto] = memoryManager->allocate<UrlPrototype>();
693 jsObjects[UrlSearchParams_Ctor] = memoryManager->allocate<UrlSearchParamsCtor>(
this);
694 jsObjects[UrlSearchParamsProto] = memoryManager->allocate<UrlSearchParamsPrototype>();
696 str = newString(QStringLiteral(
"get [Symbol.species]"));
697 jsObjects[GetSymbolSpecies] = FunctionObject::createBuiltinFunction(
this, str, ArrayPrototype::method_get_species, 0);
699 static_cast<ObjectPrototype *>(objectPrototype())->init(
this, objectCtor());
700 static_cast<StringPrototype *>(stringPrototype())->init(
this, stringCtor());
701 static_cast<SymbolPrototype *>(symbolPrototype())->init(
this, symbolCtor());
702 static_cast<NumberPrototype *>(numberPrototype())->init(
this, numberCtor());
703 static_cast<BooleanPrototype *>(booleanPrototype())->init(
this, booleanCtor());
704 static_cast<ArrayPrototype *>(arrayPrototype())->init(
this, arrayCtor());
705 static_cast<PropertyListPrototype *>(propertyListPrototype())->init();
706 static_cast<DatePrototype *>(datePrototype())->init(
this, dateCtor());
707 static_cast<FunctionPrototype *>(functionPrototype())->init(
this, functionCtor());
708 static_cast<GeneratorPrototype *>(generatorPrototype())->init(
this, generatorFunctionCtor());
709 static_cast<RegExpPrototype *>(regExpPrototype())->init(
this, regExpCtor());
710 static_cast<ErrorPrototype *>(errorPrototype())->init(
this, errorCtor());
711 static_cast<EvalErrorPrototype *>(evalErrorPrototype())->init(
this, evalErrorCtor());
712 static_cast<RangeErrorPrototype *>(rangeErrorPrototype())->init(
this, rangeErrorCtor());
713 static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype())->init(
this, referenceErrorCtor());
714 static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(
this, syntaxErrorCtor());
715 static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(
this, typeErrorCtor());
716 static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(
this, uRIErrorCtor());
717 static_cast<UrlPrototype *>(urlPrototype())->init(
this, urlCtor());
718 static_cast<UrlSearchParamsPrototype *>(urlSearchParamsPrototype())->init(
this, urlSearchParamsCtor());
720 static_cast<IteratorPrototype *>(iteratorPrototype())->init(
this);
721 static_cast<ForInIteratorPrototype *>(forInIteratorPrototype())->init(
this);
722 static_cast<MapIteratorPrototype *>(mapIteratorPrototype())->init(
this);
723 static_cast<SetIteratorPrototype *>(setIteratorPrototype())->init(
this);
724 static_cast<ArrayIteratorPrototype *>(arrayIteratorPrototype())->init(
this);
725 static_cast<StringIteratorPrototype *>(stringIteratorPrototype())->init(
this);
727 static_cast<VariantPrototype *>(variantPrototype())->init();
729 sequencePrototype()->cast<SequencePrototype>()->init();
731 jsObjects[WeakMap_Ctor] = memoryManager->allocate<WeakMapCtor>(
this);
732 jsObjects[WeakMapProto] = memoryManager->allocate<WeakMapPrototype>();
733 static_cast<WeakMapPrototype *>(weakMapPrototype())->init(
this, weakMapCtor());
735 jsObjects[Map_Ctor] = memoryManager->allocate<MapCtor>(
this);
736 jsObjects[MapProto] = memoryManager->allocate<MapPrototype>();
737 static_cast<MapPrototype *>(mapPrototype())->init(
this, mapCtor());
739 jsObjects[WeakSet_Ctor] = memoryManager->allocate<WeakSetCtor>(
this);
740 jsObjects[WeakSetProto] = memoryManager->allocate<WeakSetPrototype>();
741 static_cast<WeakSetPrototype *>(weakSetPrototype())->init(
this, weakSetCtor());
743 jsObjects[Set_Ctor] = memoryManager->allocate<SetCtor>(
this);
744 jsObjects[SetProto] = memoryManager->allocate<SetPrototype>();
745 static_cast<SetPrototype *>(setPrototype())->init(
this, setCtor());
751 jsObjects[Promise_Ctor] = memoryManager->allocate<PromiseCtor>(
this);
752 jsObjects[PromiseProto] = memoryManager->allocate<PromisePrototype>();
753 static_cast<PromisePrototype *>(promisePrototype())->init(
this, promiseCtor());
757 jsObjects[SharedArrayBuffer_Ctor] = memoryManager->allocate<SharedArrayBufferCtor>(
this);
758 jsObjects[SharedArrayBufferProto] = memoryManager->allocate<SharedArrayBufferPrototype>();
759 static_cast<SharedArrayBufferPrototype *>(sharedArrayBufferPrototype())->init(
this, sharedArrayBufferCtor());
761 jsObjects[ArrayBuffer_Ctor] = memoryManager->allocate<ArrayBufferCtor>(
this);
762 jsObjects[ArrayBufferProto] = memoryManager->allocate<ArrayBufferPrototype>();
763 static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(
this, arrayBufferCtor());
765 jsObjects[DataView_Ctor] = memoryManager->allocate<DataViewCtor>(
this);
766 jsObjects[DataViewProto] = memoryManager->allocate<DataViewPrototype>();
767 static_cast<DataViewPrototype *>(dataViewPrototype())->init(
this, dataViewCtor());
768 jsObjects[ValueTypeProto] = (Heap::Base *)
nullptr;
769 jsObjects[SignalHandlerProto] = (Heap::Base *)
nullptr;
770 jsObjects[TypeWrapperProto] = (Heap::Base *)
nullptr;
772 jsObjects[IntrinsicTypedArray_Ctor] = memoryManager->allocate<IntrinsicTypedArrayCtor>(
this);
773 jsObjects[IntrinsicTypedArrayProto] = memoryManager->allocate<IntrinsicTypedArrayPrototype>();
774 static_cast<IntrinsicTypedArrayPrototype *>(intrinsicTypedArrayPrototype())
775 ->init(
this,
static_cast<IntrinsicTypedArrayCtor *>(intrinsicTypedArrayCtor()));
777 for (
int i = 0; i < NTypedArrayTypes; ++i) {
778 static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(
this, Heap::TypedArray::Type(i));
779 static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
780 typedArrayPrototype[i].as<TypedArrayPrototype>()->init(
this,
static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
786 rootContext()->d()->activation.set(scope.engine, globalObject->d());
787 Q_ASSERT(globalObject->d()->vtable());
789 globalObject->defineDefaultProperty(QStringLiteral(
"Object"), *objectCtor());
790 globalObject->defineDefaultProperty(QStringLiteral(
"String"), *stringCtor());
791 globalObject->defineDefaultProperty(QStringLiteral(
"Symbol"), *symbolCtor());
792 FunctionObject *numberObject = numberCtor();
793 globalObject->defineDefaultProperty(QStringLiteral(
"Number"), *numberObject);
794 globalObject->defineDefaultProperty(QStringLiteral(
"Boolean"), *booleanCtor());
795 globalObject->defineDefaultProperty(QStringLiteral(
"Array"), *arrayCtor());
796 globalObject->defineDefaultProperty(QStringLiteral(
"Function"), *functionCtor());
797 globalObject->defineDefaultProperty(QStringLiteral(
"Date"), *dateCtor());
798 globalObject->defineDefaultProperty(QStringLiteral(
"RegExp"), *regExpCtor());
799 globalObject->defineDefaultProperty(QStringLiteral(
"Error"), *errorCtor());
800 globalObject->defineDefaultProperty(QStringLiteral(
"EvalError"), *evalErrorCtor());
801 globalObject->defineDefaultProperty(QStringLiteral(
"RangeError"), *rangeErrorCtor());
802 globalObject->defineDefaultProperty(QStringLiteral(
"ReferenceError"), *referenceErrorCtor());
803 globalObject->defineDefaultProperty(QStringLiteral(
"SyntaxError"), *syntaxErrorCtor());
804 globalObject->defineDefaultProperty(QStringLiteral(
"TypeError"), *typeErrorCtor());
805 globalObject->defineDefaultProperty(QStringLiteral(
"URIError"), *uRIErrorCtor());
806 globalObject->defineDefaultProperty(QStringLiteral(
"Promise"), *promiseCtor());
807 globalObject->defineDefaultProperty(QStringLiteral(
"URL"), *urlCtor());
808 globalObject->defineDefaultProperty(QStringLiteral(
"URLSearchParams"), *urlSearchParamsCtor());
810 globalObject->defineDefaultProperty(QStringLiteral(
"SharedArrayBuffer"), *sharedArrayBufferCtor());
811 globalObject->defineDefaultProperty(QStringLiteral(
"ArrayBuffer"), *arrayBufferCtor());
812 globalObject->defineDefaultProperty(QStringLiteral(
"DataView"), *dataViewCtor());
813 globalObject->defineDefaultProperty(QStringLiteral(
"WeakSet"), *weakSetCtor());
814 globalObject->defineDefaultProperty(QStringLiteral(
"Set"), *setCtor());
815 globalObject->defineDefaultProperty(QStringLiteral(
"WeakMap"), *weakMapCtor());
816 globalObject->defineDefaultProperty(QStringLiteral(
"Map"), *mapCtor());
818 for (
int i = 0; i < NTypedArrayTypes; ++i)
819 globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name()), typedArrayCtors[i]);
820 ScopedObject o(scope);
821 globalObject->defineDefaultProperty(QStringLiteral(
"Atomics"), (o = memoryManager->allocate<Atomics>()));
822 globalObject->defineDefaultProperty(QStringLiteral(
"Math"), (o = memoryManager->allocate<MathObject>()));
823 globalObject->defineDefaultProperty(QStringLiteral(
"JSON"), (o = memoryManager->allocate<JsonObject>()));
824 globalObject->defineDefaultProperty(QStringLiteral(
"Reflect"), (o = memoryManager->allocate<Reflect>()));
825 globalObject->defineDefaultProperty(QStringLiteral(
"Proxy"), (o = memoryManager->allocate<Proxy>(
this)));
827 globalObject->defineReadonlyProperty(QStringLiteral(
"undefined"), Value::undefinedValue());
828 globalObject->defineReadonlyProperty(QStringLiteral(
"NaN"), Value::fromDouble(std::numeric_limits<
double>::quiet_NaN()));
829 globalObject->defineReadonlyProperty(QStringLiteral(
"Infinity"), Value::fromDouble(Q_INFINITY));
832 jsObjects[Eval_Function] = memoryManager->allocate<EvalFunction>(
this);
833 globalObject->defineDefaultProperty(QStringLiteral(
"eval"), *evalFunction());
839 QString piString(QStringLiteral(
"parseInt"));
840 QString pfString(QStringLiteral(
"parseFloat"));
842 ScopedString pi(scope, newIdentifier(piString));
843 ScopedString pf(scope, newIdentifier(pfString));
844 ScopedFunctionObject parseIntFn(scope, FunctionObject::createBuiltinFunction(
this, pi, GlobalFunctions::method_parseInt, 2));
845 ScopedFunctionObject parseFloatFn(scope, FunctionObject::createBuiltinFunction(
this, pf, GlobalFunctions::method_parseFloat, 1));
846 globalObject->defineDefaultProperty(piString, parseIntFn);
847 globalObject->defineDefaultProperty(pfString, parseFloatFn);
848 numberObject->defineDefaultProperty(piString, parseIntFn);
849 numberObject->defineDefaultProperty(pfString, parseFloatFn);
852 globalObject->defineDefaultProperty(QStringLiteral(
"isNaN"), GlobalFunctions::method_isNaN, 1);
853 globalObject->defineDefaultProperty(QStringLiteral(
"isFinite"), GlobalFunctions::method_isFinite, 1);
854 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURI"), GlobalFunctions::method_decodeURI, 1);
855 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1);
856 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURI"), GlobalFunctions::method_encodeURI, 1);
857 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1);
858 globalObject->defineDefaultProperty(QStringLiteral(
"escape"), GlobalFunctions::method_escape, 1);
859 globalObject->defineDefaultProperty(QStringLiteral(
"unescape"), GlobalFunctions::method_unescape, 1);
861 ScopedFunctionObject t(
863 memoryManager->allocate<DynamicFunctionObject>(
this,
nullptr, ::throwTypeError));
864 t->defineReadonlyProperty(id_length(), Value::fromInt32(0));
865 t->setInternalClass(t->internalClass()->cryopreserved());
866 jsObjects[ThrowerObject] = t;
868 ScopedProperty pd(scope);
869 pd->value = thrower();
871 functionPrototype()->insertMember(id_caller(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
872 functionPrototype()->insertMember(id_arguments(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
874 QV4::QObjectWrapper::initializeBindings(
this);
876 m_delayedCallQueue.init(
this);
877 isInitialized =
true;
1820QV4::ReturnedValue ExecutionEngine::fromData(
1821 QMetaType metaType,
const void *ptr,
1822 QV4::Heap::Object *container,
int property, uint flags)
1824 const auto createSequence = [&](
const QMetaSequence metaSequence) {
1825 QV4::Scope scope(
this);
1826 QV4::Scoped<Sequence> sequence(scope);
1828 return QV4::SequencePrototype::newSequence(
1829 this, metaType, metaSequence, ptr,
1830 container, property, Heap::ReferenceObject::Flags(flags));
1832 return QV4::SequencePrototype::fromData(
this, metaType, metaSequence, ptr);
1836 const int type = metaType.id();
1837 if (type < QMetaType::User) {
1838 switch (QMetaType::Type(type)) {
1839 case QMetaType::UnknownType:
1840 case QMetaType::Void:
1841 return QV4::Encode::undefined();
1842 case QMetaType::Nullptr:
1843 case QMetaType::VoidStar:
1844 return QV4::Encode::null();
1845 case QMetaType::Bool:
1846 return QV4::Encode(*
reinterpret_cast<
const bool*>(ptr));
1847 case QMetaType::Int:
1848 return QV4::Encode(*
reinterpret_cast<
const int*>(ptr));
1849 case QMetaType::UInt:
1850 return QV4::Encode(*
reinterpret_cast<
const uint*>(ptr));
1851 case QMetaType::Long:
1852 return QV4::Encode((
double)*
reinterpret_cast<
const long *>(ptr));
1853 case QMetaType::ULong:
1854 return QV4::Encode((
double)*
reinterpret_cast<
const ulong *>(ptr));
1855 case QMetaType::LongLong:
1856 return QV4::Encode((
double)*
reinterpret_cast<
const qlonglong*>(ptr));
1857 case QMetaType::ULongLong:
1858 return QV4::Encode((
double)*
reinterpret_cast<
const qulonglong*>(ptr));
1859 case QMetaType::Double:
1860 return QV4::Encode(*
reinterpret_cast<
const double*>(ptr));
1861 case QMetaType::QString:
1862 return newString(*
reinterpret_cast<
const QString*>(ptr))->asReturnedValue();
1863 case QMetaType::QByteArray:
1864 return newArrayBuffer(*
reinterpret_cast<
const QByteArray*>(ptr))->asReturnedValue();
1865 case QMetaType::Float:
1866 return QV4::Encode(*
reinterpret_cast<
const float*>(ptr));
1867 case QMetaType::Short:
1868 return QV4::Encode((
int)*
reinterpret_cast<
const short*>(ptr));
1869 case QMetaType::UShort:
1870 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned short*>(ptr));
1871 case QMetaType::Char:
1872 return QV4::Encode((
int)*
reinterpret_cast<
const char*>(ptr));
1873 case QMetaType::UChar:
1874 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned char*>(ptr));
1875 case QMetaType::SChar:
1876 return QV4::Encode((
int)*
reinterpret_cast<
const signed char*>(ptr));
1877 case QMetaType::QChar:
1878 return newString(*
reinterpret_cast<
const QChar *>(ptr))->asReturnedValue();
1879 case QMetaType::Char16:
1880 return newString(QChar(*
reinterpret_cast<
const char16_t *>(ptr)))->asReturnedValue();
1881 case QMetaType::QDateTime:
1882 return QV4::Encode(newDateObject(
1883 *
reinterpret_cast<
const QDateTime *>(ptr),
1884 container, property, flags));
1885 case QMetaType::QDate:
1886 return QV4::Encode(newDateObject(
1887 *
reinterpret_cast<
const QDate *>(ptr),
1888 container, property, flags));
1889 case QMetaType::QTime:
1890 return QV4::Encode(newDateObject(
1891 *
reinterpret_cast<
const QTime *>(ptr),
1892 container, property, flags));
1893#if QT_CONFIG(regularexpression)
1894 case QMetaType::QRegularExpression:
1895 return QV4::Encode(newRegExpObject(*
reinterpret_cast<
const QRegularExpression *>(ptr)));
1897 case QMetaType::QObjectStar:
1898 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1899 case QMetaType::QStringList:
1900 return createSequence(QMetaSequence::fromContainer<QStringList>());
1901 case QMetaType::QVariantList:
1902 return createSequence(QMetaSequence::fromContainer<QVariantList>());
1903 case QMetaType::QVariantMap:
1904 return VariantAssociationPrototype::fromQVariantMap(
1906 *
reinterpret_cast<
const QVariantMap *>(ptr),
1907 container, property, Heap::ReferenceObject::Flags(flags));
1908 case QMetaType::QVariantHash:
1909 return VariantAssociationPrototype::fromQVariantHash(
1911 *
reinterpret_cast<
const QVariantHash *>(ptr),
1912 container, property, Heap::ReferenceObject::Flags(flags));
1913 case QMetaType::QJsonValue:
1914 return QV4::JsonObject::fromJsonValue(
this, *
reinterpret_cast<
const QJsonValue *>(ptr));
1915 case QMetaType::QJsonObject:
1916 return QV4::JsonObject::fromJsonObject(
this, *
reinterpret_cast<
const QJsonObject *>(ptr));
1917 case QMetaType::QJsonArray:
1918 return QV4::JsonObject::fromJsonArray(
this, *
reinterpret_cast<
const QJsonArray *>(ptr));
1919 case QMetaType::QPixmap:
1920 case QMetaType::QImage:
1922 return QV4::Encode(newVariantObject(metaType, ptr));
1928 if (metaType.flags() & QMetaType::IsEnumeration)
1929 return fromData(metaType.underlyingType(), ptr, container, property, flags);
1931 QV4::Scope scope(
this);
1932 if (metaType == QMetaType::fromType<QQmlListReference>()) {
1933 typedef QQmlListReferencePrivate QDLRP;
1934 QDLRP *p = QDLRP::get((QQmlListReference*)
const_cast<
void *>(ptr));
1936 return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
1938 return QV4::Encode::null();
1939 }
else if (
auto flags = metaType.flags(); flags & QMetaType::IsQmlList) {
1942 const auto *p =
static_cast<
const QQmlListProperty<QObject> *>(ptr);
1944 return QV4::QmlListWrapper::create(scope.engine, *p, metaType);
1946 return QV4::Encode::null();
1947 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
1948 return QJSValuePrivate::convertToReturnedValue(
1949 this, *
reinterpret_cast<
const QJSValue *>(ptr));
1950 }
else if (metaType == QMetaType::fromType<QList<QObject *> >()) {
1953 const QList<QObject *> &list = *(
const QList<QObject *>*)ptr;
1954 QV4::ScopedArrayObject a(scope, newArrayObject());
1955 a->arrayReserve(list.size());
1956 QV4::ScopedValue v(scope);
1957 for (
int ii = 0; ii < list.size(); ++ii)
1958 a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(
this, list.at(ii))));
1959 a->setArrayLengthUnchecked(list.size());
1960 return a.asReturnedValue();
1961 }
else if (
auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
1962 if (flags.testFlag(QMetaType::IsConst))
1963 return QV4::QObjectWrapper::wrapConst(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1965 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1966 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1967 const QJSPrimitiveValue *primitive =
static_cast<
const QJSPrimitiveValue *>(ptr);
1968 switch (primitive->type()) {
1969 case QJSPrimitiveValue::Boolean:
1970 return Encode(primitive->asBoolean());
1971 case QJSPrimitiveValue::Integer:
1972 return Encode(primitive->asInteger());
1973 case QJSPrimitiveValue::String:
1974 return newString(primitive->asString())->asReturnedValue();
1975 case QJSPrimitiveValue::Undefined:
1976 return Encode::undefined();
1977 case QJSPrimitiveValue::Null:
1978 return Encode::null();
1979 case QJSPrimitiveValue::Double:
1980 return Encode(primitive->asDouble());
1984 if (
const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(metaType)) {
1986 return QV4::QQmlValueTypeWrapper::create(
1987 this, ptr, vtmo, metaType,
1988 container, property, Heap::ReferenceObject::Flags(flags));
1990 return QV4::QQmlValueTypeWrapper::create(
this, ptr, vtmo, metaType);
1994 const QQmlType listType = QQmlMetaType::qmlListType(metaType);
1995 if (listType.isSequentialContainer())
1996 return createSequence(listType.listMetaSequence());
1998 QMetaSequence::Iterable iterable;
1999 if (QMetaType::convert(metaType, ptr, QMetaType::fromType<QMetaSequence::Iterable>(), &iterable)) {
2002 const QMetaSequence sequence = iterable.metaContainer();
2003 if (sequence.hasSize() && sequence.canGetValueAtIndex())
2004 return createSequence(sequence);
2008 if (sequence.hasConstIterator() && sequence.canGetValueAtConstIterator()) {
2009 QV4::ScopedArrayObject a(scope, newArrayObject());
2010 QV4::ScopedValue v(scope);
2011 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it) {
2012 v = fromVariant(*it);
2015 return a.asReturnedValue();
2019 return QV4::Encode(newVariantObject(metaType, ptr));
2575bool ExecutionEngine::metaTypeFromJS(
const Value &value, QMetaType metaType,
void *data)
2578 switch (metaType.id()) {
2579 case QMetaType::Bool:
2580 *
reinterpret_cast<
bool*>(data) = value.toBoolean();
2582 case QMetaType::Int:
2583 *
reinterpret_cast<
int*>(data) = value.toInt32();
2585 case QMetaType::UInt:
2586 *
reinterpret_cast<uint*>(data) = value.toUInt32();
2588 case QMetaType::Long:
2589 *
reinterpret_cast<
long*>(data) =
long(value.toInteger());
2591 case QMetaType::ULong:
2592 *
reinterpret_cast<ulong*>(data) = ulong(value.toInteger());
2594 case QMetaType::LongLong:
2595 *
reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
2597 case QMetaType::ULongLong:
2598 *
reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
2600 case QMetaType::Double:
2601 *
reinterpret_cast<
double*>(data) = value.toNumber();
2603 case QMetaType::QString:
2604 if (value.isUndefined())
2605 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"undefined");
2606 else if (value.isNull())
2607 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"null");
2609 *
reinterpret_cast<QString*>(data) = value.toQString();
2611 case QMetaType::QByteArray:
2612 if (
const ArrayBuffer *ab = value.as<ArrayBuffer>()) {
2613 *
reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
2614 }
else if (
const String *string = value.as<String>()) {
2615 *
reinterpret_cast<QByteArray*>(data) = string->toQString().toUtf8();
2616 }
else if (
const ArrayObject *ao = value.as<ArrayObject>()) {
2619 const qint64 length = ao->getLength();
2620 result.reserve(length);
2621 QV4::Scope scope(ao->engine());
2622 QV4::ScopedValue v(scope);
2623 for (qint64 i = 0; i < length; ++i) {
2626 ExecutionEngine::metaTypeFromJS(v, QMetaType::fromType<
char>(), &value);
2627 result.push_back(value);
2629 *
reinterpret_cast<QByteArray*>(data) = std::move(result);
2631 *
reinterpret_cast<QByteArray*>(data) = QByteArray();
2634 case QMetaType::Float:
2635 *
reinterpret_cast<
float*>(data) = value.toNumber();
2637 case QMetaType::Short:
2638 *
reinterpret_cast<
short*>(data) =
short(value.toInt32());
2640 case QMetaType::UShort:
2641 *
reinterpret_cast<
unsigned short*>(data) = value.toUInt16();
2643 case QMetaType::Char:
2644 *
reinterpret_cast<
char*>(data) =
char(value.toInt32());
2646 case QMetaType::UChar:
2647 *
reinterpret_cast<
unsigned char*>(data) = (
unsigned char)(value.toInt32());
2649 case QMetaType::SChar:
2650 *
reinterpret_cast<
signed char*>(data) = (
signed char)(value.toInt32());
2652 case QMetaType::QChar:
2653 if (String *s = value.stringValue()) {
2654 QString str = s->toQString();
2655 *
reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
2657 *
reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
2660 case QMetaType::QDateTime:
2661 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2662 *
reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
2665 case QMetaType::QDate:
2666 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2667 *
reinterpret_cast<QDate *>(data) = DateObject::dateTimeToDate(d->toQDateTime());
2670 case QMetaType::QTime:
2671 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2672 *
reinterpret_cast<QTime *>(data) = d->toQDateTime().time();
2675 case QMetaType::QUrl:
2676 if (String *s = value.stringValue()) {
2677 *
reinterpret_cast<QUrl *>(data) = QUrl(s->toQString());
2679 }
else if (
const QV4::UrlObject *d = value.as<UrlObject>()) {
2680 *
reinterpret_cast<QUrl *>(data) = d->toQUrl();
2682 }
else if (
const QV4::VariantObject *d = value.as<VariantObject>()) {
2683 const QVariant *variant = &d->d()->data();
2684 if (variant->metaType() == QMetaType::fromType<QUrl>()) {
2685 *
reinterpret_cast<QUrl *>(data)
2686 = *
reinterpret_cast<
const QUrl *>(variant->constData());
2691#if QT_CONFIG(regularexpression)
2692 case QMetaType::QRegularExpression:
2693 if (
const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
2694 *
reinterpret_cast<QRegularExpression *>(data) = r->toQRegularExpression();
2698 case QMetaType::QObjectStar: {
2699 if (value.isNull()) {
2700 *
reinterpret_cast<QObject* *>(data) =
nullptr;
2703 if (value.as<QV4::QObjectWrapper>()) {
2704 *
reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
2709 case QMetaType::QStringList: {
2710 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2712 *
reinterpret_cast<QStringList *>(data) = a->toQStringList();
2717 case QMetaType::QVariantList: {
2718 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2720 *
reinterpret_cast<QVariantList *>(data) = ExecutionEngine::toVariant(
2721 *a, QMetaType{},
false)
2727 case QMetaType::QVariantMap: {
2728 const QV4::Object *o = value.as<QV4::Object>();
2730 *
reinterpret_cast<QVariantMap *>(data) = o->engine()->variantMapFromJS(o);
2735 case QMetaType::QVariant:
2736 if (value.as<QV4::Managed>()) {
2737 *
reinterpret_cast<QVariant*>(data) = ExecutionEngine::toVariant(
2738 value, QMetaType{},
false);
2739 }
else if (value.isNull()) {
2740 *
reinterpret_cast<QVariant*>(data) = QVariant::fromValue(
nullptr);
2741 }
else if (value.isUndefined()) {
2742 *
reinterpret_cast<QVariant*>(data) = QVariant();
2743 }
else if (value.isBoolean()) {
2744 *
reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue());
2745 }
else if (value.isInteger()) {
2746 *
reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue());
2747 }
else if (value.isDouble()) {
2748 *
reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue());
2751 case QMetaType::QJsonValue:
2752 *
reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
2754 case QMetaType::QJsonObject: {
2755 *
reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.as<Object>());
2758 case QMetaType::QJsonArray: {
2759 *
reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(value.as<Object>());
2766 if (metaType.flags() & QMetaType::IsEnumeration) {
2767 *
reinterpret_cast<
int *>(data) = value.toInt32();
2771 if (
const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) {
2772 if (metaType == QMetaType::fromType<QQmlListReference>()) {
2773 *
reinterpret_cast<QQmlListReference *>(data) = wrapper->toListReference();
2777 const auto wrapperPrivate = wrapper->d();
2778 if (metaType == QMetaType::fromType<QQmlListProperty<QObject> *>()
2779 || metaType == wrapperPrivate->propertyType()) {
2780 *
reinterpret_cast<QQmlListProperty<QObject> *>(data) = *wrapperPrivate->property();
2784 if (metaType == QMetaType::fromType<QObjectList>()) {
2785 *
reinterpret_cast<QObjectList *>(data)
2786 = wrapperPrivate->property()->toList<QObjectList>();
2790 if (convertToIterable(metaType, data, wrapper))
2794 if (
const QQmlValueTypeWrapper *vtw = value.as<QQmlValueTypeWrapper>()) {
2795 const QMetaType valueType = vtw->type();
2796 if (valueType == metaType)
2797 return vtw->toGadget(data);
2799 Heap::QQmlValueTypeWrapper *d = vtw->d();
2800 if (d->isReference())
2803 if (
void *gadgetPtr = d->gadgetPtr()) {
2804 if (QQmlValueTypeProvider::populateValueType(
2805 metaType, data, valueType, gadgetPtr, vtw->engine())) {
2808 if (QMetaType::canConvert(valueType, metaType))
2809 return QMetaType::convert(valueType, gadgetPtr, metaType, data);
2811 QVariant empty(valueType);
2812 if (QQmlValueTypeProvider::populateValueType(
2813 metaType, data, valueType, empty.data(), vtw->engine())) {
2816 if (QMetaType::canConvert(valueType, metaType))
2817 return QMetaType::convert(valueType, empty.data(), metaType, data);
2823 if (convertToNativeQObject(value, metaType,
reinterpret_cast<
void **>(data)))
2826 const bool isPointer = (metaType.flags() & QMetaType::IsPointer);
2827 const QV4::VariantObject *variantObject = value.as<QV4::VariantObject>();
2828 if (variantObject) {
2831 QVariant &var = variantObject->d()->data();
2833 if (var.metaType() == metaType) {
2834 metaType.destruct(data);
2835 metaType.construct(data, var.data());
2840 const QByteArray pointedToTypeName = QByteArray(metaType.name()).chopped(1);
2841 const QMetaType valueType = QMetaType::fromName(pointedToTypeName);
2843 if (valueType == var.metaType()) {
2846 *
reinterpret_cast<
const void **>(data) = var.data();
2848 }
else if (Object *o = value.objectValue()) {
2850 QV4::Scope scope(o->engine());
2851 QV4::ScopedObject proto(scope, o->getPrototypeOf());
2853 bool canCast =
false;
2854 if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
2855 const QVariant &v = vo->d()->data();
2856 canCast = (metaType == v.metaType());
2858 else if (proto->as<QV4::QObjectWrapper>()) {
2859 QV4::ScopedObject p(scope, proto.getPointer());
2860 if (QObject *qobject = qtObjectFromJS(p)) {
2861 if (
const QMetaObject *metaObject = metaType.metaObject())
2862 canCast = metaObject->cast(qobject) !=
nullptr;
2864 canCast = qobject->qt_metacast(pointedToTypeName);
2868 const QMetaType varType = var.metaType();
2869 if (varType.flags() & QMetaType::IsPointer) {
2870 *
reinterpret_cast<
const void **>(data)
2871 = *
reinterpret_cast<
void *
const *>(var.data());
2873 *
reinterpret_cast<
const void **>(data) = var.data();
2877 proto = proto->getPrototypeOf();
2880 }
else if (QQmlValueTypeProvider::populateValueType(
2881 metaType, data, var.metaType(), var.data(), variantObject->engine())) {
2884 }
else if (value.isNull() && isPointer) {
2885 *
reinterpret_cast<
void* *>(data) =
nullptr;
2887 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
2888 QJSValuePrivate::setValue(
reinterpret_cast<QJSValue*>(data), value);
2890 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
2891 *
reinterpret_cast<QJSPrimitiveValue *>(data) = createPrimitive(&value);
2893 }
else if (metaType == QMetaType::fromType<QJSManagedValue>()) {
2894 QJSManagedValue *managedData =
reinterpret_cast<QJSManagedValue *>(data);
2896 const Managed *managedValue = value.as<Managed>();
2897 if (Value *d = QJSManagedValuePrivate::member(managedData)) {
2900 if (!managedValue) {
2906 if (
reinterpret_cast<
const Managed *>(d)->engine() == managedValue->engine()) {
2915 *managedData = QJSManagedValuePrivate::create(*managedValue);
2921 if (value.isUndefined())
2926 }
else if (!isPointer) {
2927 const QV4::Managed *managed = value.as<QV4::Managed>();
2928 if (QQmlValueTypeProvider::populateValueType(
2929 metaType, data, value, managed ? managed->engine() :
nullptr)) {
2934 if (
const QV4::Sequence *sequence = value.as<Sequence>()) {
2935 const QVariant result = QV4::SequencePrototype::toVariant(sequence);
2936 if (result.metaType() == metaType) {
2937 metaType.destruct(data);
2938 metaType.construct(data, result.constData());
2942 if (convertToIterable(metaType, data, sequence))
2946 if (
const QV4::ArrayObject *array = value.as<ArrayObject>()) {
2947 if (convertToIterable(metaType, data, array))