355ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
356 : executableAllocator(
new QV4::ExecutableAllocator)
357 , regExpAllocator(
new QV4::ExecutableAllocator)
358 , bumperPointerAllocator(
new WTF::BumpPointerAllocator)
359 , jsStack(
new WTF::PageAllocation)
360 , gcStack(
new WTF::PageAllocation)
361 , publicEngine(jsEngine)
362 , m_engineId(engineSerial.fetchAndAddOrdered(2))
363#if QT_CONFIG(qml_jit)
364 , m_canAllocateExecutableMemory(OSAllocator::canAllocateExecutableMemory())
367 if (m_engineId == 1) {
368 initializeStaticMembers();
369 engineSerial.storeRelease(2);
370 }
else if (Q_UNLIKELY(m_engineId & 1)) {
372 while (engineSerial.loadAcquire() & 1) {
373 QThread::yieldCurrentThread();
377 if (s_maxCallDepth < 0)
378 setCppStackProperties();
383 const size_t guardPages = 2 * WTF::pageSize();
385 memoryManager =
new QV4::MemoryManager(
this);
387 GCCriticalSection gcCriticalSection(
this);
391 *jsStack = WTF::PageAllocation::allocate(
392 s_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages,
394 jsStackBase = (Value *)jsStack->base();
395#ifdef V4_USE_VALGRIND
396 VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, s_maxJSStackSize + 256*1024);
399 jsStackTop = jsStackBase;
401 *gcStack = WTF::PageAllocation::allocate(
402 s_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages,
405 exceptionValue = jsAlloca(1);
406 *exceptionValue = Encode::undefined();
407 globalObject =
static_cast<Object *>(jsAlloca(1));
408 jsObjects = jsAlloca(NJSObjects);
409 typedArrayPrototype =
static_cast<Object *>(jsAlloca(NTypedArrayTypes));
410 typedArrayCtors =
static_cast<FunctionObject *>(jsAlloca(NTypedArrayTypes));
411 jsStrings = jsAlloca(NJSStrings);
412 jsSymbols = jsAlloca(NJSSymbols);
415 jsStackLimit = jsStackBase + s_maxJSStackSize/
sizeof(Value);
417 identifierTable =
new IdentifierTable(
this);
419 memset(classes, 0,
sizeof(classes));
420 classes[Class_Empty] = memoryManager->allocIC<InternalClass>();
421 classes[Class_Empty]->init(
this);
423 classes[Class_MemberData] = classes[Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
424 classes[Class_SimpleArrayData] = classes[Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
425 classes[Class_SparseArrayData] = classes[Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
426 classes[Class_ExecutionContext] = classes[Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
427 classes[Class_CallContext] = classes[Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
428 classes[Class_QmlContext] = classes[Class_Empty]->changeVTable(QV4::QmlContext::staticVTable());
431 Scoped<InternalClass> ic(scope);
432 ic = classes[Class_Empty]->changeVTable(QV4::Object::staticVTable());
433 jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic->d());
434 classes[Class_Object] = ic->changePrototype(objectPrototype()->d());
435 classes[Class_QmlContextWrapper] = classes[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
437 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
438 jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(ic->d(),
false);
439 classes[Class_String] = classes[Class_Empty]->changeVTable(QV4::String::staticVTable())->changePrototype(stringPrototype()->d());
440 Q_ASSERT(stringPrototype()->d() && classes[Class_String]->prototype);
442 jsObjects[SymbolProto] = memoryManager->allocate<SymbolPrototype>();
443 classes[Class_Symbol] = classes[EngineBase::Class_Empty]->changeVTable(QV4::Symbol::staticVTable())->changePrototype(symbolPrototype()->d());
445 jsStrings[String_Empty] = newIdentifier(QString());
446 jsStrings[String_undefined] = newIdentifier(QStringLiteral(
"undefined"));
447 jsStrings[String_null] = newIdentifier(QStringLiteral(
"null"));
448 jsStrings[String_true] = newIdentifier(QStringLiteral(
"true"));
449 jsStrings[String_false] = newIdentifier(QStringLiteral(
"false"));
450 jsStrings[String_boolean] = newIdentifier(QStringLiteral(
"boolean"));
451 jsStrings[String_number] = newIdentifier(QStringLiteral(
"number"));
452 jsStrings[String_string] = newIdentifier(QStringLiteral(
"string"));
453 jsStrings[String_default] = newIdentifier(QStringLiteral(
"default"));
454 jsStrings[String_symbol] = newIdentifier(QStringLiteral(
"symbol"));
455 jsStrings[String_object] = newIdentifier(QStringLiteral(
"object"));
456 jsStrings[String_function] = newIdentifier(QStringLiteral(
"function"));
457 jsStrings[String_length] = newIdentifier(QStringLiteral(
"length"));
458 jsStrings[String_prototype] = newIdentifier(QStringLiteral(
"prototype"));
459 jsStrings[String_constructor] = newIdentifier(QStringLiteral(
"constructor"));
460 jsStrings[String_arguments] = newIdentifier(QStringLiteral(
"arguments"));
461 jsStrings[String_caller] = newIdentifier(QStringLiteral(
"caller"));
462 jsStrings[String_callee] = newIdentifier(QStringLiteral(
"callee"));
463 jsStrings[String_this] = newIdentifier(QStringLiteral(
"this"));
464 jsStrings[String___proto__] = newIdentifier(QStringLiteral(
"__proto__"));
465 jsStrings[String_enumerable] = newIdentifier(QStringLiteral(
"enumerable"));
466 jsStrings[String_configurable] = newIdentifier(QStringLiteral(
"configurable"));
467 jsStrings[String_writable] = newIdentifier(QStringLiteral(
"writable"));
468 jsStrings[String_value] = newIdentifier(QStringLiteral(
"value"));
469 jsStrings[String_get] = newIdentifier(QStringLiteral(
"get"));
470 jsStrings[String_set] = newIdentifier(QStringLiteral(
"set"));
471 jsStrings[String_eval] = newIdentifier(QStringLiteral(
"eval"));
472 jsStrings[String_uintMax] = newIdentifier(QStringLiteral(
"4294967295"));
473 jsStrings[String_name] = newIdentifier(QStringLiteral(
"name"));
474 jsStrings[String_index] = newIdentifier(QStringLiteral(
"index"));
475 jsStrings[String_input] = newIdentifier(QStringLiteral(
"input"));
476 jsStrings[String_toString] = newIdentifier(QStringLiteral(
"toString"));
477 jsStrings[String_toLocaleString] = newIdentifier(QStringLiteral(
"toLocaleString"));
478 jsStrings[String_destroy] = newIdentifier(QStringLiteral(
"destroy"));
479 jsStrings[String_valueOf] = newIdentifier(QStringLiteral(
"valueOf"));
480 jsStrings[String_byteLength] = newIdentifier(QStringLiteral(
"byteLength"));
481 jsStrings[String_byteOffset] = newIdentifier(QStringLiteral(
"byteOffset"));
482 jsStrings[String_buffer] = newIdentifier(QStringLiteral(
"buffer"));
483 jsStrings[String_lastIndex] = newIdentifier(QStringLiteral(
"lastIndex"));
484 jsStrings[String_next] = newIdentifier(QStringLiteral(
"next"));
485 jsStrings[String_done] = newIdentifier(QStringLiteral(
"done"));
486 jsStrings[String_return] = newIdentifier(QStringLiteral(
"return"));
487 jsStrings[String_throw] = newIdentifier(QStringLiteral(
"throw"));
488 jsStrings[String_global] = newIdentifier(QStringLiteral(
"global"));
489 jsStrings[String_ignoreCase] = newIdentifier(QStringLiteral(
"ignoreCase"));
490 jsStrings[String_multiline] = newIdentifier(QStringLiteral(
"multiline"));
491 jsStrings[String_unicode] = newIdentifier(QStringLiteral(
"unicode"));
492 jsStrings[String_sticky] = newIdentifier(QStringLiteral(
"sticky"));
493 jsStrings[String_source] = newIdentifier(QStringLiteral(
"source"));
494 jsStrings[String_flags] = newIdentifier(QStringLiteral(
"flags"));
496 jsSymbols[Symbol_hasInstance] = Symbol::create(
this, QStringLiteral(
"@Symbol.hasInstance"));
497 jsSymbols[Symbol_isConcatSpreadable] = Symbol::create(
this, QStringLiteral(
"@Symbol.isConcatSpreadable"));
498 jsSymbols[Symbol_iterator] = Symbol::create(
this, QStringLiteral(
"@Symbol.iterator"));
499 jsSymbols[Symbol_match] = Symbol::create(
this, QStringLiteral(
"@Symbol.match"));
500 jsSymbols[Symbol_replace] = Symbol::create(
this, QStringLiteral(
"@Symbol.replace"));
501 jsSymbols[Symbol_search] = Symbol::create(
this, QStringLiteral(
"@Symbol.search"));
502 jsSymbols[Symbol_species] = Symbol::create(
this, QStringLiteral(
"@Symbol.species"));
503 jsSymbols[Symbol_split] = Symbol::create(
this, QStringLiteral(
"@Symbol.split"));
504 jsSymbols[Symbol_toPrimitive] = Symbol::create(
this, QStringLiteral(
"@Symbol.toPrimitive"));
505 jsSymbols[Symbol_toStringTag] = Symbol::create(
this, QStringLiteral(
"@Symbol.toStringTag"));
506 jsSymbols[Symbol_unscopables] = Symbol::create(
this, QStringLiteral(
"@Symbol.unscopables"));
507 jsSymbols[Symbol_revokableProxy] = Symbol::create(
this, QStringLiteral(
"@Proxy.revokableProxy"));
509 ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
510 Q_ASSERT(ic->d()->prototype);
511 ic = ic->addMember(id_length()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
512 Q_ASSERT(ic->d()->prototype);
513 jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic->d());
514 classes[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d());
515 jsObjects[PropertyListProto] = memoryManager->allocate<PropertyListPrototype>();
517 Scoped<InternalClass> argsClass(scope);
518 argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
519 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
520 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
521 classes[Class_ArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Data|Attr_NotEnumerable);
522 argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
523 argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable);
524 argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable);
525 classes[Class_StrictArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
527 *
static_cast<Value *>(globalObject) = newObject();
528 Q_ASSERT(globalObject->d()->vtable());
531 ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
532 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly);
533 classes[Class_StringObject] = ic->changePrototype(stringPrototype()->d());
534 Q_ASSERT(classes[Class_StringObject]->verifyIndex(id_length()->propertyKey(), Heap::StringObject::LengthPropertyIndex));
536 classes[Class_SymbolObject] = newInternalClass(QV4::SymbolObject::staticVTable(), symbolPrototype());
538 jsObjects[NumberProto] = memoryManager->allocate<NumberPrototype>();
539 jsObjects[BooleanProto] = memoryManager->allocate<BooleanPrototype>();
540 jsObjects[DateProto] = memoryManager->allocate<DatePrototype>();
542#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
543 InternalClassEntry *index =
nullptr;
545 InternalClassEntry _index;
546 auto *index = &_index;
548 ic = newInternalClass(QV4::FunctionPrototype::staticVTable(), objectPrototype());
549 auto addProtoHasInstance = [&] {
553 ic = ic->addMember(id_prototype()->propertyKey(), Attr_Invalid, index);
554 Q_ASSERT(index->index == Heap::FunctionObject::Index_Prototype);
558 ic = ic->addMember(symbol_hasInstance()->propertyKey(), Attr_Invalid, index);
559 Q_ASSERT(index->index == Heap::FunctionObject::Index_HasInstance);
561 addProtoHasInstance();
562 jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d());
563 ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype());
564 addProtoHasInstance();
565 classes[Class_FunctionObject] = ic->d();
566 ic = ic->addMember(id_name()->propertyKey(), Attr_ReadOnly, index);
567 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Name);
568 ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly_ButConfigurable, index);
569 Q_ASSERT(index->index == Heap::ArrowFunction::Index_Length);
570 classes[Class_ArrowFunction] = ic->changeVTable(ArrowFunction::staticVTable());
571 ic = ic->changeVTable(MemberFunction::staticVTable());
572 classes[Class_MemberFunction] = ic->d();
573 ic = ic->changeVTable(GeneratorFunction::staticVTable());
574 classes[Class_GeneratorFunction] = ic->d();
575 ic = ic->changeVTable(MemberGeneratorFunction::staticVTable());
576 classes[Class_MemberGeneratorFunction] = ic->d();
578 ic = ic->changeMember(id_prototype()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
579 ic = ic->changeVTable(ScriptFunction::staticVTable());
580 classes[Class_ScriptFunction] = ic->d();
581 ic = ic->changeVTable(ConstructorFunction::staticVTable());
582 classes[Class_ConstructorFunction] = ic->d();
584 classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->propertyKey(), Attr_NotEnumerable, index);
585 Q_ASSERT(index->index == Heap::FunctionObject::Index_ProtoConstructor);
587 jsObjects[GeneratorProto] = memoryManager->allocObject<GeneratorPrototype>(classes[Class_Object]);
588 classes[Class_GeneratorObject] = newInternalClass(QV4::GeneratorObject::staticVTable(), generatorPrototype());
590 ScopedString str(scope);
591 classes[Class_RegExp] = classes[Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
592 ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype());
593 ic = ic->addMember(id_lastIndex()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, index);
594 Q_ASSERT(index->index == RegExpObject::Index_LastIndex);
595 jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(classes[Class_Object]);
596 classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d());
598 ic = classes[Class_ArrayObject]->addMember(id_index()->propertyKey(), Attr_Data, index);
599 Q_ASSERT(index->index == RegExpObject::Index_ArrayIndex);
600 classes[Class_RegExpExecArray] = ic->addMember(id_input()->propertyKey(), Attr_Data, index);
601 Q_ASSERT(index->index == RegExpObject::Index_ArrayInput);
603 ic = newInternalClass(ErrorObject::staticVTable(),
nullptr);
604 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"stack")))->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, index);
605 Q_ASSERT(index->index == ErrorObject::Index_Stack);
606 Q_ASSERT(index->setterIndex == ErrorObject::Index_StackSetter);
607 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"fileName")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
608 Q_ASSERT(index->index == ErrorObject::Index_FileName);
609 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"lineNumber")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
610 classes[Class_ErrorObject] = ic->d();
611 Q_ASSERT(index->index == ErrorObject::Index_LineNumber);
612 classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
613 Q_ASSERT(index->index == ErrorObject::Index_Message);
614 ic = newInternalClass(Object::staticVTable(), objectPrototype());
615 ic = ic->addMember(id_constructor()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
616 Q_ASSERT(index->index == ErrorPrototype::Index_Constructor);
617 ic = ic->addMember((str = newIdentifier(QStringLiteral(
"message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
618 Q_ASSERT(index->index == ErrorPrototype::Index_Message);
619 classes[Class_ErrorProto] = ic->addMember(id_name()->propertyKey(), Attr_Data|Attr_NotEnumerable, index);
620 Q_ASSERT(index->index == ErrorPrototype::Index_Name);
622 classes[Class_ProxyObject] = classes[Class_Empty]->changeVTable(ProxyObject::staticVTable());
623 classes[Class_ProxyFunctionObject] = classes[Class_Empty]->changeVTable(ProxyFunctionObject::staticVTable());
625 jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(
this, str = newIdentifier(QStringLiteral(
"stack")), ErrorObject::method_get_stack, 0);
627 jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(classes[Class_ErrorProto]);
628 ic = classes[Class_ErrorProto]->changePrototype(errorPrototype()->d());
629 jsObjects[EvalErrorProto] = memoryManager->allocObject<EvalErrorPrototype>(ic->d());
630 jsObjects[RangeErrorProto] = memoryManager->allocObject<RangeErrorPrototype>(ic->d());
631 jsObjects[ReferenceErrorProto] = memoryManager->allocObject<ReferenceErrorPrototype>(ic->d());
632 jsObjects[SyntaxErrorProto] = memoryManager->allocObject<SyntaxErrorPrototype>(ic->d());
633 jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(ic->d());
634 jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(ic->d());
636 jsObjects[VariantProto] = memoryManager->allocate<VariantPrototype>();
637 Q_ASSERT(variantPrototype()->getPrototypeOf() == objectPrototype()->d());
639 jsObjects[VariantAssociationProto] = memoryManager->allocate<VariantAssociationPrototype>();
640 Q_ASSERT(variantAssociationPrototype()->getPrototypeOf() == objectPrototype()->d());
642 ic = newInternalClass(SequencePrototype::staticVTable(), SequencePrototype::defaultPrototype(
this));
643 jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(ic->d()));
645 jsObjects[Object_Ctor] = memoryManager->allocate<ObjectCtor>(
this);
646 jsObjects[String_Ctor] = memoryManager->allocate<StringCtor>(
this);
647 jsObjects[Symbol_Ctor] = memoryManager->allocate<SymbolCtor>(
this);
648 jsObjects[Number_Ctor] = memoryManager->allocate<NumberCtor>(
this);
649 jsObjects[Boolean_Ctor] = memoryManager->allocate<BooleanCtor>(
this);
650 jsObjects[Array_Ctor] = memoryManager->allocate<ArrayCtor>(
this);
651 jsObjects[Function_Ctor] = memoryManager->allocate<FunctionCtor>(
this);
652 jsObjects[GeneratorFunction_Ctor] = memoryManager->allocate<GeneratorFunctionCtor>(
this);
653 jsObjects[Date_Ctor] = memoryManager->allocate<DateCtor>(
this);
654 jsObjects[RegExp_Ctor] = memoryManager->allocate<RegExpCtor>(
this);
655 jsObjects[Error_Ctor] = memoryManager->allocate<ErrorCtor>(
this);
656 jsObjects[EvalError_Ctor] = memoryManager->allocate<EvalErrorCtor>(
this);
657 jsObjects[RangeError_Ctor] = memoryManager->allocate<RangeErrorCtor>(
this);
658 jsObjects[ReferenceError_Ctor] = memoryManager->allocate<ReferenceErrorCtor>(
this);
659 jsObjects[SyntaxError_Ctor] = memoryManager->allocate<SyntaxErrorCtor>(
this);
660 jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(
this);
661 jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(
this);
662 jsObjects[IteratorProto] = memoryManager->allocate<IteratorPrototype>();
664 ic = newInternalClass(ForInIteratorPrototype::staticVTable(), iteratorPrototype());
665 jsObjects[ForInIteratorProto] = memoryManager->allocObject<ForInIteratorPrototype>(ic);
666 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
667 jsObjects[MapIteratorProto] = memoryManager->allocObject<MapIteratorPrototype>(ic);
668 ic = newInternalClass(SetIteratorPrototype::staticVTable(), iteratorPrototype());
669 jsObjects[SetIteratorProto] = memoryManager->allocObject<SetIteratorPrototype>(ic);
670 ic = newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype());
671 jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(ic);
672 ic = newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype());
673 jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(ic);
679 jsObjects[Url_Ctor] = memoryManager->allocate<UrlCtor>(
this);
680 jsObjects[UrlProto] = memoryManager->allocate<UrlPrototype>();
681 jsObjects[UrlSearchParams_Ctor] = memoryManager->allocate<UrlSearchParamsCtor>(
this);
682 jsObjects[UrlSearchParamsProto] = memoryManager->allocate<UrlSearchParamsPrototype>();
684 str = newString(QStringLiteral(
"get [Symbol.species]"));
685 jsObjects[GetSymbolSpecies] = FunctionObject::createBuiltinFunction(
this, str, ArrayPrototype::method_get_species, 0);
687 static_cast<ObjectPrototype *>(objectPrototype())->init(
this, objectCtor());
688 static_cast<StringPrototype *>(stringPrototype())->init(
this, stringCtor());
689 static_cast<SymbolPrototype *>(symbolPrototype())->init(
this, symbolCtor());
690 static_cast<NumberPrototype *>(numberPrototype())->init(
this, numberCtor());
691 static_cast<BooleanPrototype *>(booleanPrototype())->init(
this, booleanCtor());
692 static_cast<ArrayPrototype *>(arrayPrototype())->init(
this, arrayCtor());
693 static_cast<PropertyListPrototype *>(propertyListPrototype())->init();
694 static_cast<DatePrototype *>(datePrototype())->init(
this, dateCtor());
695 static_cast<FunctionPrototype *>(functionPrototype())->init(
this, functionCtor());
696 static_cast<GeneratorPrototype *>(generatorPrototype())->init(
this, generatorFunctionCtor());
697 static_cast<RegExpPrototype *>(regExpPrototype())->init(
this, regExpCtor());
698 static_cast<ErrorPrototype *>(errorPrototype())->init(
this, errorCtor());
699 static_cast<EvalErrorPrototype *>(evalErrorPrototype())->init(
this, evalErrorCtor());
700 static_cast<RangeErrorPrototype *>(rangeErrorPrototype())->init(
this, rangeErrorCtor());
701 static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype())->init(
this, referenceErrorCtor());
702 static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(
this, syntaxErrorCtor());
703 static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(
this, typeErrorCtor());
704 static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(
this, uRIErrorCtor());
705 static_cast<UrlPrototype *>(urlPrototype())->init(
this, urlCtor());
706 static_cast<UrlSearchParamsPrototype *>(urlSearchParamsPrototype())->init(
this, urlSearchParamsCtor());
708 static_cast<IteratorPrototype *>(iteratorPrototype())->init(
this);
709 static_cast<ForInIteratorPrototype *>(forInIteratorPrototype())->init(
this);
710 static_cast<MapIteratorPrototype *>(mapIteratorPrototype())->init(
this);
711 static_cast<SetIteratorPrototype *>(setIteratorPrototype())->init(
this);
712 static_cast<ArrayIteratorPrototype *>(arrayIteratorPrototype())->init(
this);
713 static_cast<StringIteratorPrototype *>(stringIteratorPrototype())->init(
this);
715 static_cast<VariantPrototype *>(variantPrototype())->init();
717 sequencePrototype()->cast<SequencePrototype>()->init();
719 jsObjects[WeakMap_Ctor] = memoryManager->allocate<WeakMapCtor>(
this);
720 jsObjects[WeakMapProto] = memoryManager->allocate<WeakMapPrototype>();
721 static_cast<WeakMapPrototype *>(weakMapPrototype())->init(
this, weakMapCtor());
723 jsObjects[Map_Ctor] = memoryManager->allocate<MapCtor>(
this);
724 jsObjects[MapProto] = memoryManager->allocate<MapPrototype>();
725 static_cast<MapPrototype *>(mapPrototype())->init(
this, mapCtor());
727 jsObjects[WeakSet_Ctor] = memoryManager->allocate<WeakSetCtor>(
this);
728 jsObjects[WeakSetProto] = memoryManager->allocate<WeakSetPrototype>();
729 static_cast<WeakSetPrototype *>(weakSetPrototype())->init(
this, weakSetCtor());
731 jsObjects[Set_Ctor] = memoryManager->allocate<SetCtor>(
this);
732 jsObjects[SetProto] = memoryManager->allocate<SetPrototype>();
733 static_cast<SetPrototype *>(setPrototype())->init(
this, setCtor());
739 jsObjects[Promise_Ctor] = memoryManager->allocate<PromiseCtor>(
this);
740 jsObjects[PromiseProto] = memoryManager->allocate<PromisePrototype>();
741 static_cast<PromisePrototype *>(promisePrototype())->init(
this, promiseCtor());
745 jsObjects[SharedArrayBuffer_Ctor] = memoryManager->allocate<SharedArrayBufferCtor>(
this);
746 jsObjects[SharedArrayBufferProto] = memoryManager->allocate<SharedArrayBufferPrototype>();
747 static_cast<SharedArrayBufferPrototype *>(sharedArrayBufferPrototype())->init(
this, sharedArrayBufferCtor());
749 jsObjects[ArrayBuffer_Ctor] = memoryManager->allocate<ArrayBufferCtor>(
this);
750 jsObjects[ArrayBufferProto] = memoryManager->allocate<ArrayBufferPrototype>();
751 static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(
this, arrayBufferCtor());
753 jsObjects[DataView_Ctor] = memoryManager->allocate<DataViewCtor>(
this);
754 jsObjects[DataViewProto] = memoryManager->allocate<DataViewPrototype>();
755 static_cast<DataViewPrototype *>(dataViewPrototype())->init(
this, dataViewCtor());
756 jsObjects[ValueTypeProto] = (Heap::Base *)
nullptr;
757 jsObjects[SignalHandlerProto] = (Heap::Base *)
nullptr;
758 jsObjects[TypeWrapperProto] = (Heap::Base *)
nullptr;
760 jsObjects[IntrinsicTypedArray_Ctor] = memoryManager->allocate<IntrinsicTypedArrayCtor>(
this);
761 jsObjects[IntrinsicTypedArrayProto] = memoryManager->allocate<IntrinsicTypedArrayPrototype>();
762 static_cast<IntrinsicTypedArrayPrototype *>(intrinsicTypedArrayPrototype())
763 ->init(
this,
static_cast<IntrinsicTypedArrayCtor *>(intrinsicTypedArrayCtor()));
765 for (
int i = 0; i < NTypedArrayTypes; ++i) {
766 static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(
this, Heap::TypedArray::Type(i));
767 static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
768 typedArrayPrototype[i].as<TypedArrayPrototype>()->init(
this,
static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
774 rootContext()->d()->activation.set(scope.engine, globalObject->d());
775 Q_ASSERT(globalObject->d()->vtable());
777 globalObject->defineDefaultProperty(QStringLiteral(
"Object"), *objectCtor());
778 globalObject->defineDefaultProperty(QStringLiteral(
"String"), *stringCtor());
779 globalObject->defineDefaultProperty(QStringLiteral(
"Symbol"), *symbolCtor());
780 FunctionObject *numberObject = numberCtor();
781 globalObject->defineDefaultProperty(QStringLiteral(
"Number"), *numberObject);
782 globalObject->defineDefaultProperty(QStringLiteral(
"Boolean"), *booleanCtor());
783 globalObject->defineDefaultProperty(QStringLiteral(
"Array"), *arrayCtor());
784 globalObject->defineDefaultProperty(QStringLiteral(
"Function"), *functionCtor());
785 globalObject->defineDefaultProperty(QStringLiteral(
"Date"), *dateCtor());
786 globalObject->defineDefaultProperty(QStringLiteral(
"RegExp"), *regExpCtor());
787 globalObject->defineDefaultProperty(QStringLiteral(
"Error"), *errorCtor());
788 globalObject->defineDefaultProperty(QStringLiteral(
"EvalError"), *evalErrorCtor());
789 globalObject->defineDefaultProperty(QStringLiteral(
"RangeError"), *rangeErrorCtor());
790 globalObject->defineDefaultProperty(QStringLiteral(
"ReferenceError"), *referenceErrorCtor());
791 globalObject->defineDefaultProperty(QStringLiteral(
"SyntaxError"), *syntaxErrorCtor());
792 globalObject->defineDefaultProperty(QStringLiteral(
"TypeError"), *typeErrorCtor());
793 globalObject->defineDefaultProperty(QStringLiteral(
"URIError"), *uRIErrorCtor());
794 globalObject->defineDefaultProperty(QStringLiteral(
"Promise"), *promiseCtor());
795 globalObject->defineDefaultProperty(QStringLiteral(
"URL"), *urlCtor());
796 globalObject->defineDefaultProperty(QStringLiteral(
"URLSearchParams"), *urlSearchParamsCtor());
798 globalObject->defineDefaultProperty(QStringLiteral(
"SharedArrayBuffer"), *sharedArrayBufferCtor());
799 globalObject->defineDefaultProperty(QStringLiteral(
"ArrayBuffer"), *arrayBufferCtor());
800 globalObject->defineDefaultProperty(QStringLiteral(
"DataView"), *dataViewCtor());
801 globalObject->defineDefaultProperty(QStringLiteral(
"WeakSet"), *weakSetCtor());
802 globalObject->defineDefaultProperty(QStringLiteral(
"Set"), *setCtor());
803 globalObject->defineDefaultProperty(QStringLiteral(
"WeakMap"), *weakMapCtor());
804 globalObject->defineDefaultProperty(QStringLiteral(
"Map"), *mapCtor());
806 for (
int i = 0; i < NTypedArrayTypes; ++i)
807 globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name()), typedArrayCtors[i]);
808 ScopedObject o(scope);
809 globalObject->defineDefaultProperty(QStringLiteral(
"Atomics"), (o = memoryManager->allocate<Atomics>()));
810 globalObject->defineDefaultProperty(QStringLiteral(
"Math"), (o = memoryManager->allocate<MathObject>()));
811 globalObject->defineDefaultProperty(QStringLiteral(
"JSON"), (o = memoryManager->allocate<JsonObject>()));
812 globalObject->defineDefaultProperty(QStringLiteral(
"Reflect"), (o = memoryManager->allocate<Reflect>()));
813 globalObject->defineDefaultProperty(QStringLiteral(
"Proxy"), (o = memoryManager->allocate<Proxy>(
this)));
815 globalObject->defineReadonlyProperty(QStringLiteral(
"undefined"), Value::undefinedValue());
816 globalObject->defineReadonlyProperty(QStringLiteral(
"NaN"), Value::fromDouble(std::numeric_limits<
double>::quiet_NaN()));
817 globalObject->defineReadonlyProperty(QStringLiteral(
"Infinity"), Value::fromDouble(Q_INFINITY));
820 jsObjects[Eval_Function] = memoryManager->allocate<EvalFunction>(
this);
821 globalObject->defineDefaultProperty(QStringLiteral(
"eval"), *evalFunction());
827 QString piString(QStringLiteral(
"parseInt"));
828 QString pfString(QStringLiteral(
"parseFloat"));
830 ScopedString pi(scope, newIdentifier(piString));
831 ScopedString pf(scope, newIdentifier(pfString));
832 ScopedFunctionObject parseIntFn(scope, FunctionObject::createBuiltinFunction(
this, pi, GlobalFunctions::method_parseInt, 2));
833 ScopedFunctionObject parseFloatFn(scope, FunctionObject::createBuiltinFunction(
this, pf, GlobalFunctions::method_parseFloat, 1));
834 globalObject->defineDefaultProperty(piString, parseIntFn);
835 globalObject->defineDefaultProperty(pfString, parseFloatFn);
836 numberObject->defineDefaultProperty(piString, parseIntFn);
837 numberObject->defineDefaultProperty(pfString, parseFloatFn);
840 globalObject->defineDefaultProperty(QStringLiteral(
"isNaN"), GlobalFunctions::method_isNaN, 1);
841 globalObject->defineDefaultProperty(QStringLiteral(
"isFinite"), GlobalFunctions::method_isFinite, 1);
842 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURI"), GlobalFunctions::method_decodeURI, 1);
843 globalObject->defineDefaultProperty(QStringLiteral(
"decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1);
844 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURI"), GlobalFunctions::method_encodeURI, 1);
845 globalObject->defineDefaultProperty(QStringLiteral(
"encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1);
846 globalObject->defineDefaultProperty(QStringLiteral(
"escape"), GlobalFunctions::method_escape, 1);
847 globalObject->defineDefaultProperty(QStringLiteral(
"unescape"), GlobalFunctions::method_unescape, 1);
849 ScopedFunctionObject t(
851 memoryManager->allocate<DynamicFunctionObject>(
this,
nullptr, ::throwTypeError));
852 t->defineReadonlyProperty(id_length(), Value::fromInt32(0));
853 t->setInternalClass(t->internalClass()->cryopreserved());
854 jsObjects[ThrowerObject] = t;
856 ScopedProperty pd(scope);
857 pd->value = thrower();
859 functionPrototype()->insertMember(id_caller(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
860 functionPrototype()->insertMember(id_arguments(), pd, Attr_Accessor|Attr_ReadOnly_ButConfigurable);
862 QV4::QObjectWrapper::initializeBindings(
this);
864 m_delayedCallQueue.init(
this);
865 isInitialized =
true;
1790QV4::ReturnedValue ExecutionEngine::fromData(
1791 QMetaType metaType,
const void *ptr,
1792 QV4::Heap::Object *container,
int property, uint flags)
1794 const auto createSequence = [&](
const QMetaSequence metaSequence) {
1795 QV4::Scope scope(
this);
1796 QV4::Scoped<Sequence> sequence(scope);
1798 return QV4::SequencePrototype::newSequence(
1799 this, metaType, metaSequence, ptr,
1800 container, property, Heap::ReferenceObject::Flags(flags));
1802 return QV4::SequencePrototype::fromData(
this, metaType, metaSequence, ptr);
1806 const int type = metaType.id();
1807 if (type < QMetaType::User) {
1808 switch (QMetaType::Type(type)) {
1809 case QMetaType::UnknownType:
1810 case QMetaType::Void:
1811 return QV4::Encode::undefined();
1812 case QMetaType::Nullptr:
1813 case QMetaType::VoidStar:
1814 return QV4::Encode::null();
1815 case QMetaType::Bool:
1816 return QV4::Encode(*
reinterpret_cast<
const bool*>(ptr));
1817 case QMetaType::Int:
1818 return QV4::Encode(*
reinterpret_cast<
const int*>(ptr));
1819 case QMetaType::UInt:
1820 return QV4::Encode(*
reinterpret_cast<
const uint*>(ptr));
1821 case QMetaType::Long:
1822 return QV4::Encode((
double)*
reinterpret_cast<
const long *>(ptr));
1823 case QMetaType::ULong:
1824 return QV4::Encode((
double)*
reinterpret_cast<
const ulong *>(ptr));
1825 case QMetaType::LongLong:
1826 return QV4::Encode((
double)*
reinterpret_cast<
const qlonglong*>(ptr));
1827 case QMetaType::ULongLong:
1828 return QV4::Encode((
double)*
reinterpret_cast<
const qulonglong*>(ptr));
1829 case QMetaType::Double:
1830 return QV4::Encode(*
reinterpret_cast<
const double*>(ptr));
1831 case QMetaType::QString:
1832 return newString(*
reinterpret_cast<
const QString*>(ptr))->asReturnedValue();
1833 case QMetaType::QByteArray:
1834 return newArrayBuffer(*
reinterpret_cast<
const QByteArray*>(ptr))->asReturnedValue();
1835 case QMetaType::Float:
1836 return QV4::Encode(*
reinterpret_cast<
const float*>(ptr));
1837 case QMetaType::Short:
1838 return QV4::Encode((
int)*
reinterpret_cast<
const short*>(ptr));
1839 case QMetaType::UShort:
1840 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned short*>(ptr));
1841 case QMetaType::Char:
1842 return QV4::Encode((
int)*
reinterpret_cast<
const char*>(ptr));
1843 case QMetaType::UChar:
1844 return QV4::Encode((
int)*
reinterpret_cast<
const unsigned char*>(ptr));
1845 case QMetaType::SChar:
1846 return QV4::Encode((
int)*
reinterpret_cast<
const signed char*>(ptr));
1847 case QMetaType::QChar:
1848 return newString(*
reinterpret_cast<
const QChar *>(ptr))->asReturnedValue();
1849 case QMetaType::Char16:
1850 return newString(QChar(*
reinterpret_cast<
const char16_t *>(ptr)))->asReturnedValue();
1851 case QMetaType::QDateTime:
1852 return QV4::Encode(newDateObject(
1853 *
reinterpret_cast<
const QDateTime *>(ptr),
1854 container, property, flags));
1855 case QMetaType::QDate:
1856 return QV4::Encode(newDateObject(
1857 *
reinterpret_cast<
const QDate *>(ptr),
1858 container, property, flags));
1859 case QMetaType::QTime:
1860 return QV4::Encode(newDateObject(
1861 *
reinterpret_cast<
const QTime *>(ptr),
1862 container, property, flags));
1863#if QT_CONFIG(regularexpression)
1864 case QMetaType::QRegularExpression:
1865 return QV4::Encode(newRegExpObject(*
reinterpret_cast<
const QRegularExpression *>(ptr)));
1867 case QMetaType::QObjectStar:
1868 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1869 case QMetaType::QStringList:
1870 return createSequence(QMetaSequence::fromContainer<QStringList>());
1871 case QMetaType::QVariantList:
1872 return createSequence(QMetaSequence::fromContainer<QVariantList>());
1873 case QMetaType::QVariantMap:
1874 return VariantAssociationPrototype::fromQVariantMap(
1876 *
reinterpret_cast<
const QVariantMap *>(ptr),
1877 container, property, Heap::ReferenceObject::Flags(flags));
1878 case QMetaType::QVariantHash:
1879 return VariantAssociationPrototype::fromQVariantHash(
1881 *
reinterpret_cast<
const QVariantHash *>(ptr),
1882 container, property, Heap::ReferenceObject::Flags(flags));
1883 case QMetaType::QJsonValue:
1884 return QV4::JsonObject::fromJsonValue(
this, *
reinterpret_cast<
const QJsonValue *>(ptr));
1885 case QMetaType::QJsonObject:
1886 return QV4::JsonObject::fromJsonObject(
this, *
reinterpret_cast<
const QJsonObject *>(ptr));
1887 case QMetaType::QJsonArray:
1888 return QV4::JsonObject::fromJsonArray(
this, *
reinterpret_cast<
const QJsonArray *>(ptr));
1889 case QMetaType::QPixmap:
1890 case QMetaType::QImage:
1892 return QV4::Encode(newVariantObject(metaType, ptr));
1898 if (metaType.flags() & QMetaType::IsEnumeration)
1899 return fromData(metaType.underlyingType(), ptr, container, property, flags);
1901 QV4::Scope scope(
this);
1902 if (metaType == QMetaType::fromType<QQmlListReference>()) {
1903 typedef QQmlListReferencePrivate QDLRP;
1904 QDLRP *p = QDLRP::get((QQmlListReference*)
const_cast<
void *>(ptr));
1906 return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
1908 return QV4::Encode::null();
1909 }
else if (
auto flags = metaType.flags(); flags & QMetaType::IsQmlList) {
1912 const auto *p =
static_cast<
const QQmlListProperty<QObject> *>(ptr);
1914 return QV4::QmlListWrapper::create(scope.engine, *p, metaType);
1916 return QV4::Encode::null();
1917 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
1918 return QJSValuePrivate::convertToReturnedValue(
1919 this, *
reinterpret_cast<
const QJSValue *>(ptr));
1920 }
else if (metaType == QMetaType::fromType<QList<QObject *> >()) {
1923 const QList<QObject *> &list = *(
const QList<QObject *>*)ptr;
1924 QV4::ScopedArrayObject a(scope, newArrayObject());
1925 a->arrayReserve(list.size());
1926 QV4::ScopedValue v(scope);
1927 for (
int ii = 0; ii < list.size(); ++ii)
1928 a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(
this, list.at(ii))));
1929 a->setArrayLengthUnchecked(list.size());
1930 return a.asReturnedValue();
1931 }
else if (
auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
1932 if (flags.testFlag(QMetaType::IsConst))
1933 return QV4::QObjectWrapper::wrapConst(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1935 return QV4::QObjectWrapper::wrap(
this, *
reinterpret_cast<QObject*
const *>(ptr));
1936 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1937 const QJSPrimitiveValue *primitive =
static_cast<
const QJSPrimitiveValue *>(ptr);
1938 switch (primitive->type()) {
1939 case QJSPrimitiveValue::Boolean:
1940 return Encode(primitive->asBoolean());
1941 case QJSPrimitiveValue::Integer:
1942 return Encode(primitive->asInteger());
1943 case QJSPrimitiveValue::String:
1944 return newString(primitive->asString())->asReturnedValue();
1945 case QJSPrimitiveValue::Undefined:
1946 return Encode::undefined();
1947 case QJSPrimitiveValue::Null:
1948 return Encode::null();
1949 case QJSPrimitiveValue::Double:
1950 return Encode(primitive->asDouble());
1954 if (
const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(metaType)) {
1956 return QV4::QQmlValueTypeWrapper::create(
1957 this, ptr, vtmo, metaType,
1958 container, property, Heap::ReferenceObject::Flags(flags));
1960 return QV4::QQmlValueTypeWrapper::create(
this, ptr, vtmo, metaType);
1964 const QQmlType listType = QQmlMetaType::qmlListType(metaType);
1965 if (listType.isSequentialContainer())
1966 return createSequence(listType.listMetaSequence());
1968 QSequentialIterable iterable;
1969 if (QMetaType::convert(metaType, ptr, QMetaType::fromType<QSequentialIterable>(), &iterable)) {
1972 const QMetaSequence sequence = iterable.metaContainer();
1973 if (sequence.hasSize() && sequence.canGetValueAtIndex())
1974 return createSequence(sequence);
1978 if (sequence.hasConstIterator() && sequence.canGetValueAtConstIterator()) {
1979 QV4::ScopedArrayObject a(scope, newArrayObject());
1980 QV4::ScopedValue v(scope);
1981 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it) {
1982 v = fromVariant(*it);
1985 return a.asReturnedValue();
1989 return QV4::Encode(newVariantObject(metaType, ptr));
2574bool ExecutionEngine::metaTypeFromJS(
const Value &value, QMetaType metaType,
void *data)
2577 switch (metaType.id()) {
2578 case QMetaType::Bool:
2579 *
reinterpret_cast<
bool*>(data) = value.toBoolean();
2581 case QMetaType::Int:
2582 *
reinterpret_cast<
int*>(data) = value.toInt32();
2584 case QMetaType::UInt:
2585 *
reinterpret_cast<uint*>(data) = value.toUInt32();
2587 case QMetaType::Long:
2588 *
reinterpret_cast<
long*>(data) =
long(value.toInteger());
2590 case QMetaType::ULong:
2591 *
reinterpret_cast<ulong*>(data) = ulong(value.toInteger());
2593 case QMetaType::LongLong:
2594 *
reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
2596 case QMetaType::ULongLong:
2597 *
reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
2599 case QMetaType::Double:
2600 *
reinterpret_cast<
double*>(data) = value.toNumber();
2602 case QMetaType::QString:
2603 if (value.isUndefined())
2604 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"undefined");
2605 else if (value.isNull())
2606 *
reinterpret_cast<QString*>(data) = QStringLiteral(
"null");
2608 *
reinterpret_cast<QString*>(data) = value.toQString();
2610 case QMetaType::QByteArray:
2611 if (
const ArrayBuffer *ab = value.as<ArrayBuffer>()) {
2612 *
reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
2613 }
else if (
const String *string = value.as<String>()) {
2614 *
reinterpret_cast<QByteArray*>(data) = string->toQString().toUtf8();
2615 }
else if (
const ArrayObject *ao = value.as<ArrayObject>()) {
2618 const qint64 length = ao->getLength();
2619 result.reserve(length);
2620 QV4::Scope scope(ao->engine());
2621 QV4::ScopedValue v(scope);
2622 for (qint64 i = 0; i < length; ++i) {
2625 ExecutionEngine::metaTypeFromJS(v, QMetaType::fromType<
char>(), &value);
2626 result.push_back(value);
2628 *
reinterpret_cast<QByteArray*>(data) = std::move(result);
2630 *
reinterpret_cast<QByteArray*>(data) = QByteArray();
2633 case QMetaType::Float:
2634 *
reinterpret_cast<
float*>(data) = value.toNumber();
2636 case QMetaType::Short:
2637 *
reinterpret_cast<
short*>(data) =
short(value.toInt32());
2639 case QMetaType::UShort:
2640 *
reinterpret_cast<
unsigned short*>(data) = value.toUInt16();
2642 case QMetaType::Char:
2643 *
reinterpret_cast<
char*>(data) =
char(value.toInt32());
2645 case QMetaType::UChar:
2646 *
reinterpret_cast<
unsigned char*>(data) = (
unsigned char)(value.toInt32());
2648 case QMetaType::SChar:
2649 *
reinterpret_cast<
signed char*>(data) = (
signed char)(value.toInt32());
2651 case QMetaType::QChar:
2652 if (String *s = value.stringValue()) {
2653 QString str = s->toQString();
2654 *
reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
2656 *
reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
2659 case QMetaType::QDateTime:
2660 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2661 *
reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
2664 case QMetaType::QDate:
2665 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2666 *
reinterpret_cast<QDate *>(data) = DateObject::dateTimeToDate(d->toQDateTime());
2669 case QMetaType::QTime:
2670 if (
const QV4::DateObject *d = value.as<DateObject>()) {
2671 *
reinterpret_cast<QTime *>(data) = d->toQDateTime().time();
2674 case QMetaType::QUrl:
2675 if (String *s = value.stringValue()) {
2676 *
reinterpret_cast<QUrl *>(data) = QUrl(s->toQString());
2678 }
else if (
const QV4::UrlObject *d = value.as<UrlObject>()) {
2679 *
reinterpret_cast<QUrl *>(data) = d->toQUrl();
2681 }
else if (
const QV4::VariantObject *d = value.as<VariantObject>()) {
2682 const QVariant *variant = &d->d()->data();
2683 if (variant->metaType() == QMetaType::fromType<QUrl>()) {
2684 *
reinterpret_cast<QUrl *>(data)
2685 = *
reinterpret_cast<
const QUrl *>(variant->constData());
2690#if QT_CONFIG(regularexpression)
2691 case QMetaType::QRegularExpression:
2692 if (
const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
2693 *
reinterpret_cast<QRegularExpression *>(data) = r->toQRegularExpression();
2697 case QMetaType::QObjectStar: {
2698 if (value.isNull()) {
2699 *
reinterpret_cast<QObject* *>(data) =
nullptr;
2702 if (value.as<QV4::QObjectWrapper>()) {
2703 *
reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
2708 case QMetaType::QStringList: {
2709 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2711 *
reinterpret_cast<QStringList *>(data) = a->toQStringList();
2716 case QMetaType::QVariantList: {
2717 const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
2719 *
reinterpret_cast<QVariantList *>(data) = ExecutionEngine::toVariant(
2720 *a, QMetaType{},
false)
2726 case QMetaType::QVariantMap: {
2727 const QV4::Object *o = value.as<QV4::Object>();
2729 *
reinterpret_cast<QVariantMap *>(data) = o->engine()->variantMapFromJS(o);
2734 case QMetaType::QVariant:
2735 if (value.as<QV4::Managed>()) {
2736 *
reinterpret_cast<QVariant*>(data) = ExecutionEngine::toVariant(
2737 value, QMetaType{},
false);
2738 }
else if (value.isNull()) {
2739 *
reinterpret_cast<QVariant*>(data) = QVariant::fromValue(
nullptr);
2740 }
else if (value.isUndefined()) {
2741 *
reinterpret_cast<QVariant*>(data) = QVariant();
2742 }
else if (value.isBoolean()) {
2743 *
reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue());
2744 }
else if (value.isInteger()) {
2745 *
reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue());
2746 }
else if (value.isDouble()) {
2747 *
reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue());
2750 case QMetaType::QJsonValue:
2751 *
reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
2753 case QMetaType::QJsonObject: {
2754 *
reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.as<Object>());
2757 case QMetaType::QJsonArray: {
2758 const QV4::ArrayObject *a = value.as<ArrayObject>();
2760 *
reinterpret_cast<QJsonArray *>(data) = JsonObject::toJsonArray(a);
2769 if (metaType.flags() & QMetaType::IsEnumeration) {
2770 *
reinterpret_cast<
int *>(data) = value.toInt32();
2774 if (
const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) {
2775 if (metaType == QMetaType::fromType<QQmlListReference>()) {
2776 *
reinterpret_cast<QQmlListReference *>(data) = wrapper->toListReference();
2780 const auto wrapperPrivate = wrapper->d();
2781 if (metaType == QMetaType::fromType<QQmlListProperty<QObject> *>()
2782 || metaType == wrapperPrivate->propertyType()) {
2783 *
reinterpret_cast<QQmlListProperty<QObject> *>(data) = *wrapperPrivate->property();
2787 if (metaType == QMetaType::fromType<QObjectList>()) {
2788 *
reinterpret_cast<QObjectList *>(data)
2789 = wrapperPrivate->property()->toList<QObjectList>();
2793 if (convertToIterable(metaType, data, wrapper))
2797 if (
const QQmlValueTypeWrapper *vtw = value.as<QQmlValueTypeWrapper>()) {
2798 const QMetaType valueType = vtw->type();
2799 if (valueType == metaType)
2800 return vtw->toGadget(data);
2802 Heap::QQmlValueTypeWrapper *d = vtw->d();
2803 if (d->isReference())
2806 if (
void *gadgetPtr = d->gadgetPtr()) {
2807 if (QQmlValueTypeProvider::populateValueType(
2808 metaType, data, valueType, gadgetPtr, vtw->engine())) {
2811 if (QMetaType::canConvert(valueType, metaType))
2812 return QMetaType::convert(valueType, gadgetPtr, metaType, data);
2814 QVariant empty(valueType);
2815 if (QQmlValueTypeProvider::populateValueType(
2816 metaType, data, valueType, empty.data(), vtw->engine())) {
2819 if (QMetaType::canConvert(valueType, metaType))
2820 return QMetaType::convert(valueType, empty.data(), metaType, data);
2826 if (convertToNativeQObject(value, metaType,
reinterpret_cast<
void **>(data)))
2829 const bool isPointer = (metaType.flags() & QMetaType::IsPointer);
2830 const QV4::VariantObject *variantObject = value.as<QV4::VariantObject>();
2831 if (variantObject) {
2834 QVariant &var = variantObject->d()->data();
2836 if (var.metaType() == metaType) {
2837 metaType.destruct(data);
2838 metaType.construct(data, var.data());
2843 const QByteArray pointedToTypeName = QByteArray(metaType.name()).chopped(1);
2844 const QMetaType valueType = QMetaType::fromName(pointedToTypeName);
2846 if (valueType == var.metaType()) {
2849 *
reinterpret_cast<
const void **>(data) = var.data();
2851 }
else if (Object *o = value.objectValue()) {
2853 QV4::Scope scope(o->engine());
2854 QV4::ScopedObject proto(scope, o->getPrototypeOf());
2856 bool canCast =
false;
2857 if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
2858 const QVariant &v = vo->d()->data();
2859 canCast = (metaType == v.metaType());
2861 else if (proto->as<QV4::QObjectWrapper>()) {
2862 QV4::ScopedObject p(scope, proto.getPointer());
2863 if (QObject *qobject = qtObjectFromJS(p)) {
2864 if (
const QMetaObject *metaObject = metaType.metaObject())
2865 canCast = metaObject->cast(qobject) !=
nullptr;
2867 canCast = qobject->qt_metacast(pointedToTypeName);
2871 const QMetaType varType = var.metaType();
2872 if (varType.flags() & QMetaType::IsPointer) {
2873 *
reinterpret_cast<
const void **>(data)
2874 = *
reinterpret_cast<
void *
const *>(var.data());
2876 *
reinterpret_cast<
const void **>(data) = var.data();
2880 proto = proto->getPrototypeOf();
2883 }
else if (QQmlValueTypeProvider::populateValueType(
2884 metaType, data, var.metaType(), var.data(), variantObject->engine())) {
2887 }
else if (value.isNull() && isPointer) {
2888 *
reinterpret_cast<
void* *>(data) =
nullptr;
2890 }
else if (metaType == QMetaType::fromType<QJSValue>()) {
2891 QJSValuePrivate::setValue(
reinterpret_cast<QJSValue*>(data), value);
2893 }
else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) {
2894 *
reinterpret_cast<QJSPrimitiveValue *>(data) = createPrimitive(&value);
2896 }
else if (!isPointer) {
2897 const QV4::Managed *managed = value.as<QV4::Managed>();
2898 if (QQmlValueTypeProvider::populateValueType(
2899 metaType, data, value, managed ? managed->engine() :
nullptr)) {
2904 if (
const QV4::Sequence *sequence = value.as<Sequence>()) {
2905 const QVariant result = QV4::SequencePrototype::toVariant(sequence);
2906 if (result.metaType() == metaType) {
2907 metaType.destruct(data);
2908 metaType.construct(data, result.constData());
2912 if (convertToIterable(metaType, data, sequence))
2916 if (
const QV4::ArrayObject *array = value.as<ArrayObject>()) {
2917 if (convertToIterable(metaType, data, array))