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;
1802QV4::ReturnedValue ExecutionEngine::fromData(
1803 QMetaType metaType,
const void *ptr,
1804 QV4::Heap::Object *container,
int property, uint flags)
1806 const auto createSequence = [&](
const QMetaSequence metaSequence) {
1807 QV4::Scope scope(
this);
1808 QV4::Scoped<Sequence> sequence(scope);
1810 return QV4::SequencePrototype::newSequence(
1811 this, metaType, metaSequence, ptr,
1812 container, property, Heap::ReferenceObject::Flags(flags));
1814 return QV4::SequencePrototype::fromData(
this, metaType, metaSequence, ptr);
1818 const int type = metaType.id();
1819 if (type < QMetaType::User) {
1820 switch (QMetaType::Type(type)) {
1821 case QMetaType::UnknownType:
1822 case QMetaType::Void:
1823 return QV4::Encode::undefined();
1824 case QMetaType::Nullptr:
1825 case QMetaType::VoidStar:
1826 return QV4::Encode::null();
1827 case QMetaType::Bool:
1828 return QV4::Encode(*
reinterpret_cast<
const bool*>(ptr));
1829 case QMetaType::Int:
1830 return QV4::Encode(*
reinterpret_cast<
const int*>(ptr));
1831 case QMetaType::UInt:
1832 return QV4::Encode(*
reinterpret_cast<
const uint*>(ptr));
1833 case QMetaType::Long:
1834 return QV4::Encode((
double)*
reinterpret_cast<
const long *>(ptr));
1835 case QMetaType::ULong:
1836 return QV4::Encode((
double)*
reinterpret_cast<
const ulong *>(ptr));
1837 case QMetaType::LongLong:
1838 return QV4::Encode((
double)*
reinterpret_cast<
const qlonglong*>(ptr));
1839 case QMetaType::ULongLong:
1840 return QV4::Encode((
double)*
reinterpret_cast<
const qulonglong*>(ptr));
1841 case QMetaType::Double:
1842 return QV4::Encode(*
reinterpret_cast<
const double*>(ptr));
1843 case QMetaType::QString:
1844 return newString(*
reinterpret_cast<
const QString*>(ptr))->asReturnedValue();
1845 case QMetaType::QByteArray:
1846 return newArrayBuffer(*
reinterpret_cast<
const QByteArray*>(ptr))->asReturnedValue();
1847 case QMetaType::Float:
1848 return QV4::Encode(*
reinterpret_cast<
const float*>(ptr));
1849 case QMetaType::Short:
1850 return QV4::Encode((
int)*
reinterpret_cast<
const short*>(ptr));
1851 case QMetaType::UShort:
1852 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned short*>(ptr));
1853 case QMetaType::Char:
1854 return QV4::Encode((
int)*
reinterpret_cast<
const char*>(ptr));
1855 case QMetaType::UChar:
1856 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned char*>(ptr));
1857 case QMetaType::SChar:
1858 return QV4::Encode((
int)*
reinterpret_cast<
const signed char*>(ptr));
1859 case QMetaType::QChar:
1860 return newString(*
reinterpret_cast<
const QChar *>(ptr))->asReturnedValue();
1861 case QMetaType::Char16:
1862 return newString(QChar(*
reinterpret_cast<
const char16_t *>(ptr)))->asReturnedValue();
1863 case QMetaType::QDateTime:
1864 return QV4::Encode(newDateObject(
1865 *
reinterpret_cast<
const QDateTime *>(ptr),
1866 container, property, flags));
1867 case QMetaType::QDate:
1868 return QV4::Encode(newDateObject(
1869 *
reinterpret_cast<
const QDate *>(ptr),
1870 container, property, flags));
1871 case QMetaType::QTime:
1872 return QV4::Encode(newDateObject(
1873 *
reinterpret_cast<
const QTime *>(ptr),
1874 container, property, flags));
1875#if QT_CONFIG(regularexpression)
1876 case QMetaType::QRegularExpression:
1877 return QV4::Encode(newRegExpObject(*
reinterpret_cast<
const QRegularExpression *>(ptr)));
1879 case QMetaType::QObjectStar:
1880 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1881 case QMetaType::QStringList:
1882 return createSequence(QMetaSequence::fromContainer<QStringList>());
1883 case QMetaType::QVariantList:
1884 return createSequence(QMetaSequence::fromContainer<QVariantList>());
1885 case QMetaType::QVariantMap:
1886 return VariantAssociationPrototype::fromQVariantMap(
1888 *
reinterpret_cast<
const QVariantMap *>(ptr),
1889 container, property, Heap::ReferenceObject::Flags(flags));
1890 case QMetaType::QVariantHash:
1891 return VariantAssociationPrototype::fromQVariantHash(
1893 *
reinterpret_cast<
const QVariantHash *>(ptr),
1894 container, property, Heap::ReferenceObject::Flags(flags));
1895 case QMetaType::QJsonValue:
1896 return QV4::JsonObject::fromJsonValue(
this, *
reinterpret_cast<
const QJsonValue *>(ptr));
1897 case QMetaType::QJsonObject:
1898 return QV4::JsonObject::fromJsonObject(
this, *
reinterpret_cast<
const QJsonObject *>(ptr));
1899 case QMetaType::QJsonArray:
1900 return QV4::JsonObject::fromJsonArray(
this, *
reinterpret_cast<
const QJsonArray *>(ptr));
1901 case QMetaType::QPixmap:
1902 case QMetaType::QImage:
1904 return QV4::Encode(newVariantObject(metaType, ptr));
1910 if (metaType.flags() & QMetaType::IsEnumeration)
1911 return fromData(metaType.underlyingType(), ptr, container, property, flags);
1913 QV4::Scope scope(
this);
1914 if (metaType == QMetaType::fromType<QQmlListReference>()) {
1915 typedef QQmlListReferencePrivate QDLRP;
1916 QDLRP *p = QDLRP::get((QQmlListReference*)
const_cast<
void *>(ptr));
1918 return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
1920 return QV4::Encode::null();
1921 }
else if (
auto flags = metaType.flags(); flags & QMetaType::IsQmlList) {
1924 const auto *p =
static_cast<
const QQmlListProperty<QObject> *>(ptr);
1926 return QV4::QmlListWrapper::create(scope.engine, *p, metaType);
1928 return QV4::Encode::null();
1929 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
1930 return QJSValuePrivate::convertToReturnedValue(
1931 this, *
reinterpret_cast<
const QJSValue *>(ptr));
1932 }
else if (metaType == QMetaType::fromType<QList<QObject *> >()) {
1935 const QList<QObject *> &list = *(
const QList<QObject *>*)ptr;
1936 QV4::ScopedArrayObject a(scope, newArrayObject());
1937 a->arrayReserve(list.size());
1938 QV4::ScopedValue v(scope);
1939 for (
int ii = 0; ii < list.size(); ++ii)
1940 a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(
this, list.at(ii))));
1941 a->setArrayLengthUnchecked(list.size());
1942 return a.asReturnedValue();
1943 }
else if (
auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
1944 if (flags.testFlag(QMetaType::IsConst))
1945 return QV4::QObjectWrapper::wrapConst(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1947 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1948 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1949 const QJSPrimitiveValue *primitive =
static_cast<
const QJSPrimitiveValue *>(ptr);
1950 switch (primitive->type()) {
1951 case QJSPrimitiveValue::Boolean:
1952 return Encode(primitive->asBoolean());
1953 case QJSPrimitiveValue::Integer:
1954 return Encode(primitive->asInteger());
1955 case QJSPrimitiveValue::String:
1956 return newString(primitive->asString())->asReturnedValue();
1957 case QJSPrimitiveValue::Undefined:
1958 return Encode::undefined();
1959 case QJSPrimitiveValue::Null:
1960 return Encode::null();
1961 case QJSPrimitiveValue::Double:
1962 return Encode(primitive->asDouble());
1966 if (
const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(metaType)) {
1968 return QV4::QQmlValueTypeWrapper::create(
1969 this, ptr, vtmo, metaType,
1970 container, property, Heap::ReferenceObject::Flags(flags));
1972 return QV4::QQmlValueTypeWrapper::create(
this, ptr, vtmo, metaType);
1976 const QQmlType listType = QQmlMetaType::qmlListType(metaType);
1977 if (listType.isSequentialContainer())
1978 return createSequence(listType.listMetaSequence());
1980 QMetaSequence::Iterable iterable;
1981 if (QMetaType::convert(metaType, ptr, QMetaType::fromType<QMetaSequence::Iterable>(), &iterable)) {
1984 const QMetaSequence sequence = iterable.metaContainer();
1985 if (sequence.hasSize() && sequence.canGetValueAtIndex())
1986 return createSequence(sequence);
1990 if (sequence.hasConstIterator() && sequence.canGetValueAtConstIterator()) {
1991 QV4::ScopedArrayObject a(scope, newArrayObject());
1992 QV4::ScopedValue v(scope);
1993 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it) {
1994 v = fromVariant(*it);
1997 return a.asReturnedValue();
2001 return QV4::Encode(newVariantObject(metaType, ptr));
2557bool ExecutionEngine::metaTypeFromJS(
const Value &value, QMetaType metaType,
void *data)
2560 switch (metaType.id()) {
2561 case QMetaType::Bool:
2562 *
reinterpret_cast<
bool*>(data) = value.toBoolean();
2564 case QMetaType::Int:
2565 *
reinterpret_cast<
int*>(data) = value.toInt32();
2567 case QMetaType::UInt:
2568 *
reinterpret_cast<uint*>(data) = value.toUInt32();
2570 case QMetaType::Long:
2571 *
reinterpret_cast<
long*>(data) =
long(value.toInteger());
2573 case QMetaType::ULong:
2574 *
reinterpret_cast<ulong*>(data) = ulong(value.toInteger());
2576 case QMetaType::LongLong:
2577 *
reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
2579 case QMetaType::ULongLong:
2580 *
reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
2582 case QMetaType::Double:
2583 *
reinterpret_cast<
double*>(data) = value.toNumber();
2585 case QMetaType::QString:
2586 if (value.isUndefined())
2587 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"undefined");
2588 else if (value.isNull())
2589 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"null");
2591 *
reinterpret_cast<QString*>(data) = value.toQString();
2593 case QMetaType::QByteArray:
2594 if (
const ArrayBuffer *ab = value.as<ArrayBuffer>()) {
2595 *
reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
2596 }
else if (
const String *string = value.as<String>()) {
2597 *
reinterpret_cast<QByteArray*>(data) = string->toQString().toUtf8();
2598 }
else if (
const ArrayObject *ao = value.as<ArrayObject>()) {
2601 const qint64 length = ao->getLength();
2602 result.reserve(length);
2603 QV4::Scope scope(ao->engine());
2604 QV4::ScopedValue v(scope);
2605 for (qint64 i = 0; i < length; ++i) {
2608 ExecutionEngine::metaTypeFromJS(v, QMetaType::fromType<
char>(), &value);
2609 result.push_back(value);
2611 *
reinterpret_cast<QByteArray*>(data) = std::move(result);
2613 *
reinterpret_cast<QByteArray*>(data) = QByteArray();
2616 case QMetaType::Float:
2617 *
reinterpret_cast<
float*>(data) = value.toNumber();
2619 case QMetaType::Short:
2620 *
reinterpret_cast<
short*>(data) =
short(value.toInt32());
2622 case QMetaType::UShort:
2623 *
reinterpret_cast<
unsigned short*>(data) = value.toUInt16();
2625 case QMetaType::Char:
2626 *
reinterpret_cast<
char*>(data) =
char(value.toInt32());
2628 case QMetaType::UChar:
2629 *
reinterpret_cast<
unsigned char*>(data) = (
unsigned char)(value.toInt32());
2631 case QMetaType::SChar:
2632 *
reinterpret_cast<
signed char*>(data) = (
signed char)(value.toInt32());
2634 case QMetaType::QChar:
2635 if (String *s = value.stringValue()) {
2636 QString str = s->toQString();
2637 *
reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
2639 *
reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
2642 case QMetaType::QDateTime:
2643 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2644 *
reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
2647 case QMetaType::QDate:
2648 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2649 *
reinterpret_cast<QDate *>(data) = DateObject::dateTimeToDate(d->toQDateTime());
2652 case QMetaType::QTime:
2653 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2654 *
reinterpret_cast<QTime *>(data) = d->toQDateTime().time();
2657 case QMetaType::QUrl:
2658 if (String *s = value.stringValue()) {
2659 *
reinterpret_cast<QUrl *>(data) = QUrl(s->toQString());
2661 }
else if (
const QV4::UrlObject *d = value.as<UrlObject>()) {
2662 *
reinterpret_cast<QUrl *>(data) = d->toQUrl();
2664 }
else if (
const QV4::VariantObject *d = value.as<VariantObject>()) {
2665 const QVariant *variant = &d->d()->data();
2666 if (variant->metaType() == QMetaType::fromType<QUrl>()) {
2667 *
reinterpret_cast<QUrl *>(data)
2668 = *
reinterpret_cast<
const QUrl *>(variant->constData());
2673#if QT_CONFIG(regularexpression)
2674 case QMetaType::QRegularExpression:
2675 if (
const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
2676 *
reinterpret_cast<QRegularExpression *>(data) = r->toQRegularExpression();
2680 case QMetaType::QObjectStar: {
2681 if (value.isNull()) {
2682 *
reinterpret_cast<QObject* *>(data) =
nullptr;
2685 if (value.as<QV4::QObjectWrapper>()) {
2686 *
reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
2691 case QMetaType::QStringList: {
2692 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2694 *
reinterpret_cast<QStringList *>(data) = a->toQStringList();
2699 case QMetaType::QVariantList: {
2700 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2702 *
reinterpret_cast<QVariantList *>(data) = ExecutionEngine::toVariant(
2703 *a, QMetaType{},
false)
2709 case QMetaType::QVariantMap: {
2710 const QV4::Object *o = value.as<QV4::Object>();
2712 *
reinterpret_cast<QVariantMap *>(data) = o->engine()->variantMapFromJS(o);
2717 case QMetaType::QVariant:
2718 if (value.as<QV4::Managed>()) {
2719 *
reinterpret_cast<QVariant*>(data) = ExecutionEngine::toVariant(
2720 value, QMetaType{},
false);
2721 }
else if (value.isNull()) {
2722 *
reinterpret_cast<QVariant*>(data) = QVariant::fromValue(
nullptr);
2723 }
else if (value.isUndefined()) {
2724 *
reinterpret_cast<QVariant*>(data) = QVariant();
2725 }
else if (value.isBoolean()) {
2726 *
reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue());
2727 }
else if (value.isInteger()) {
2728 *
reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue());
2729 }
else if (value.isDouble()) {
2730 *
reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue());
2733 case QMetaType::QJsonValue:
2734 *
reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
2736 case QMetaType::QJsonObject: {
2737 *
reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.as<Object>());
2740 case QMetaType::QJsonArray: {
2741 *
reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(value.as<Object>());
2748 if (metaType.flags() & QMetaType::IsEnumeration) {
2749 *
reinterpret_cast<
int *>(data) = value.toInt32();
2753 if (
const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) {
2754 if (metaType == QMetaType::fromType<QQmlListReference>()) {
2755 *
reinterpret_cast<QQmlListReference *>(data) = wrapper->toListReference();
2759 const auto wrapperPrivate = wrapper->d();
2760 if (metaType == QMetaType::fromType<QQmlListProperty<QObject> *>()
2761 || metaType == wrapperPrivate->propertyType()) {
2762 *
reinterpret_cast<QQmlListProperty<QObject> *>(data) = *wrapperPrivate->property();
2766 if (metaType == QMetaType::fromType<QObjectList>()) {
2767 *
reinterpret_cast<QObjectList *>(data)
2768 = wrapperPrivate->property()->toList<QObjectList>();
2772 if (convertToIterable(metaType, data, wrapper))
2776 if (
const QQmlValueTypeWrapper *vtw = value.as<QQmlValueTypeWrapper>()) {
2777 const QMetaType valueType = vtw->type();
2778 if (valueType == metaType)
2779 return vtw->toGadget(data);
2781 Heap::QQmlValueTypeWrapper *d = vtw->d();
2782 if (d->isReference())
2785 if (
void *gadgetPtr = d->gadgetPtr()) {
2786 if (QQmlValueTypeProvider::populateValueType(
2787 metaType, data, valueType, gadgetPtr, vtw->engine())) {
2790 if (QMetaType::canConvert(valueType, metaType))
2791 return QMetaType::convert(valueType, gadgetPtr, metaType, data);
2793 QVariant empty(valueType);
2794 if (QQmlValueTypeProvider::populateValueType(
2795 metaType, data, valueType, empty.data(), vtw->engine())) {
2798 if (QMetaType::canConvert(valueType, metaType))
2799 return QMetaType::convert(valueType, empty.data(), metaType, data);
2805 if (convertToNativeQObject(value, metaType,
reinterpret_cast<
void **>(data)))
2808 const bool isPointer = (metaType.flags() & QMetaType::IsPointer);
2809 const QV4::VariantObject *variantObject = value.as<QV4::VariantObject>();
2810 if (variantObject) {
2813 QVariant &var = variantObject->d()->data();
2815 if (var.metaType() == metaType) {
2816 metaType.destruct(data);
2817 metaType.construct(data, var.data());
2822 const QByteArray pointedToTypeName = QByteArray(metaType.name()).chopped(1);
2823 const QMetaType valueType = QMetaType::fromName(pointedToTypeName);
2825 if (valueType == var.metaType()) {
2828 *
reinterpret_cast<
const void **>(data) = var.data();
2830 }
else if (Object *o = value.objectValue()) {
2832 QV4::Scope scope(o->engine());
2833 QV4::ScopedObject proto(scope, o->getPrototypeOf());
2835 bool canCast =
false;
2836 if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
2837 const QVariant &v = vo->d()->data();
2838 canCast = (metaType == v.metaType());
2840 else if (proto->as<QV4::QObjectWrapper>()) {
2841 QV4::ScopedObject p(scope, proto.getPointer());
2842 if (QObject *qobject = qtObjectFromJS(p)) {
2843 if (
const QMetaObject *metaObject = metaType.metaObject())
2844 canCast = metaObject->cast(qobject) !=
nullptr;
2846 canCast = qobject->qt_metacast(pointedToTypeName);
2850 const QMetaType varType = var.metaType();
2851 if (varType.flags() & QMetaType::IsPointer) {
2852 *
reinterpret_cast<
const void **>(data)
2853 = *
reinterpret_cast<
void *
const *>(var.data());
2855 *
reinterpret_cast<
const void **>(data) = var.data();
2859 proto = proto->getPrototypeOf();
2862 }
else if (QQmlValueTypeProvider::populateValueType(
2863 metaType, data, var.metaType(), var.data(), variantObject->engine())) {
2866 }
else if (value.isNull() && isPointer) {
2867 *
reinterpret_cast<
void* *>(data) =
nullptr;
2869 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
2870 QJSValuePrivate::setValue(
reinterpret_cast<QJSValue*>(data), value);
2872 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
2873 *
reinterpret_cast<QJSPrimitiveValue *>(data) = createPrimitive(&value);
2875 }
else if (metaType == QMetaType::fromType<QJSManagedValue>()) {
2876 QJSManagedValue *managedData =
reinterpret_cast<QJSManagedValue *>(data);
2878 const Managed *managedValue = value.as<Managed>();
2879 if (Value *d = QJSManagedValuePrivate::member(managedData)) {
2882 if (!managedValue) {
2888 if (
reinterpret_cast<
const Managed *>(d)->engine() == managedValue->engine()) {
2897 *managedData = QJSManagedValuePrivate::create(*managedValue);
2903 if (value.isUndefined())
2908 }
else if (!isPointer) {
2909 const QV4::Managed *managed = value.as<QV4::Managed>();
2910 if (QQmlValueTypeProvider::populateValueType(
2911 metaType, data, value, managed ? managed->engine() :
nullptr)) {
2916 if (
const QV4::Sequence *sequence = value.as<Sequence>()) {
2917 const QVariant result = QV4::SequencePrototype::toVariant(sequence);
2918 if (result.metaType() == metaType) {
2919 metaType.destruct(data);
2920 metaType.construct(data, result.constData());
2924 if (convertToIterable(metaType, data, sequence))
2928 if (
const QV4::ArrayObject *array = value.as<ArrayObject>()) {
2929 if (convertToIterable(metaType, data, array))