diff options
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 620 |
1 files changed, 282 insertions, 338 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index e1282eeca9..caf07e8b0b 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include <qv4engine_p.h> #include <qv4context_p.h> -#include <qv4value_inl_p.h> +#include <qv4value_p.h> #include <qv4object_p.h> #include <qv4objectproto_p.h> #include <qv4objectiterator_p.h> @@ -48,7 +48,7 @@ #include <qv4regexp_p.h> #include <qv4variantobject_p.h> #include <qv4runtime_p.h> -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include <qv4argumentsobject_p.h> #include <qv4dateobject_p.h> #include <qv4jsonobject_p.h> @@ -59,7 +59,6 @@ #include "qv4executableallocator_p.h" #include "qv4sequenceobject_p.h" #include "qv4qobjectwrapper_p.h" -#include "qv4qmlextensions_p.h" #include "qv4memberdata_p.h" #include "qv4arraybuffer_p.h" #include "qv4dataview_p.h" @@ -197,6 +196,7 @@ QQmlEngine *ExecutionEngine::qmlEngine() const ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) : current(0) + , hasException(false) , memoryManager(new QV4::MemoryManager(this)) , executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) @@ -211,13 +211,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , m_engineId(engineSerial.fetchAndAddOrdered(1)) , regExpCache(0) , m_multiplyWrappedQObjects(0) - , m_qmlExtensions(0) { MemoryManager::GCBlocker gcBlocker(memoryManager); - exceptionValue = Encode::undefined(); - hasException = false; - if (!factory) { #ifdef V4_ENABLE_JIT @@ -241,6 +237,13 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) jsStackBase = (Value *)jsStack->base(); jsStackTop = jsStackBase; + exceptionValue = jsAlloca(1); + globalObject = static_cast<Object *>(jsAlloca(1)); + jsObjects = jsAlloca(NJSObjects); + typedArrayPrototype = static_cast<Object *>(jsAlloca(NTypedArrayTypes)); + typedArrayCtors = static_cast<FunctionObject *>(jsAlloca(NTypedArrayTypes)); + jsStrings = jsAlloca(NJSStrings); + #ifdef V4_USE_VALGRIND VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, 2*JSStackLimit); #endif @@ -251,208 +254,208 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) if (!recheckCStackLimits()) qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize); - Scope scope(this); - identifierTable = new IdentifierTable(this); classPool = new InternalClassPool; emptyClass = new (classPool) InternalClass(this); - id_empty = newIdentifier(QString()); - id_undefined = newIdentifier(QStringLiteral("undefined")); - id_null = newIdentifier(QStringLiteral("null")); - id_true = newIdentifier(QStringLiteral("true")); - id_false = newIdentifier(QStringLiteral("false")); - id_boolean = newIdentifier(QStringLiteral("boolean")); - id_number = newIdentifier(QStringLiteral("number")); - id_string = newIdentifier(QStringLiteral("string")); - id_object = newIdentifier(QStringLiteral("object")); - id_function = newIdentifier(QStringLiteral("function")); - id_length = newIdentifier(QStringLiteral("length")); - id_prototype = newIdentifier(QStringLiteral("prototype")); - id_constructor = newIdentifier(QStringLiteral("constructor")); - id_arguments = newIdentifier(QStringLiteral("arguments")); - id_caller = newIdentifier(QStringLiteral("caller")); - id_callee = newIdentifier(QStringLiteral("callee")); - id_this = newIdentifier(QStringLiteral("this")); - id___proto__ = newIdentifier(QStringLiteral("__proto__")); - id_enumerable = newIdentifier(QStringLiteral("enumerable")); - id_configurable = newIdentifier(QStringLiteral("configurable")); - id_writable = newIdentifier(QStringLiteral("writable")); - id_value = newIdentifier(QStringLiteral("value")); - id_get = newIdentifier(QStringLiteral("get")); - id_set = newIdentifier(QStringLiteral("set")); - id_eval = newIdentifier(QStringLiteral("eval")); - id_uintMax = newIdentifier(QStringLiteral("4294967295")); - id_name = newIdentifier(QStringLiteral("name")); - id_index = newIdentifier(QStringLiteral("index")); - id_input = newIdentifier(QStringLiteral("input")); - id_toString = newIdentifier(QStringLiteral("toString")); - id_destroy = newIdentifier(QStringLiteral("destroy")); - id_valueOf = newIdentifier(QStringLiteral("valueOf")); - id_byteLength = newIdentifier(QStringLiteral("byteLength")); - id_byteOffset = newIdentifier(QStringLiteral("byteOffset")); - id_buffer = newIdentifier(QStringLiteral("buffer")); - id_lastIndex = newIdentifier(QStringLiteral("lastIndex")); - - objectPrototype = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0); - - arrayClass = emptyClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable); - arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.asObject()); - - InternalClass *argsClass = emptyClass->addMember(id_length, Attr_NotEnumerable); - argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable); - strictArgumentsObjectClass = argsClass->addMember(id_callee, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); - strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); - - m_globalObject = newObject(); - Q_ASSERT(globalObject()->d()->vtable); + jsStrings[String_Empty] = newIdentifier(QString()); + jsStrings[String_undefined] = newIdentifier(QStringLiteral("undefined")); + jsStrings[String_null] = newIdentifier(QStringLiteral("null")); + jsStrings[String_true] = newIdentifier(QStringLiteral("true")); + jsStrings[String_false] = newIdentifier(QStringLiteral("false")); + jsStrings[String_boolean] = newIdentifier(QStringLiteral("boolean")); + jsStrings[String_number] = newIdentifier(QStringLiteral("number")); + jsStrings[String_string] = newIdentifier(QStringLiteral("string")); + jsStrings[String_object] = newIdentifier(QStringLiteral("object")); + jsStrings[String_function] = newIdentifier(QStringLiteral("function")); + jsStrings[String_length] = newIdentifier(QStringLiteral("length")); + jsStrings[String_prototype] = newIdentifier(QStringLiteral("prototype")); + jsStrings[String_constructor] = newIdentifier(QStringLiteral("constructor")); + jsStrings[String_arguments] = newIdentifier(QStringLiteral("arguments")); + jsStrings[String_caller] = newIdentifier(QStringLiteral("caller")); + jsStrings[String_callee] = newIdentifier(QStringLiteral("callee")); + jsStrings[String_this] = newIdentifier(QStringLiteral("this")); + jsStrings[String___proto__] = newIdentifier(QStringLiteral("__proto__")); + jsStrings[String_enumerable] = newIdentifier(QStringLiteral("enumerable")); + jsStrings[String_configurable] = newIdentifier(QStringLiteral("configurable")); + jsStrings[String_writable] = newIdentifier(QStringLiteral("writable")); + jsStrings[String_value] = newIdentifier(QStringLiteral("value")); + jsStrings[String_get] = newIdentifier(QStringLiteral("get")); + jsStrings[String_set] = newIdentifier(QStringLiteral("set")); + jsStrings[String_eval] = newIdentifier(QStringLiteral("eval")); + jsStrings[String_uintMax] = newIdentifier(QStringLiteral("4294967295")); + jsStrings[String_name] = newIdentifier(QStringLiteral("name")); + jsStrings[String_index] = newIdentifier(QStringLiteral("index")); + jsStrings[String_input] = newIdentifier(QStringLiteral("input")); + jsStrings[String_toString] = newIdentifier(QStringLiteral("toString")); + jsStrings[String_destroy] = newIdentifier(QStringLiteral("destroy")); + jsStrings[String_valueOf] = newIdentifier(QStringLiteral("valueOf")); + jsStrings[String_byteLength] = newIdentifier(QStringLiteral("byteLength")); + jsStrings[String_byteOffset] = newIdentifier(QStringLiteral("byteOffset")); + jsStrings[String_buffer] = newIdentifier(QStringLiteral("buffer")); + jsStrings[String_lastIndex] = newIdentifier(QStringLiteral("lastIndex")); + + jsObjects[ObjectProto] = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0); + + arrayClass = emptyClass->addMember(id_length(), Attr_NotConfigurable|Attr_NotEnumerable); + jsObjects[ArrayProto] = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype()); + + InternalClass *argsClass = emptyClass->addMember(id_length(), Attr_NotEnumerable); + argumentsObjectClass = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable); + strictArgumentsObjectClass = argsClass->addMember(id_callee(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); + strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); + + *static_cast<Value *>(globalObject) = newObject(); + Q_ASSERT(globalObject->d()->vtable()); initRootContext(); - stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype.asObject()); - numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype.asObject()); - booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype.asObject()); - datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype.asObject()); + jsObjects[StringProto] = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype()); + jsObjects[NumberProto] = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype()); + jsObjects[BooleanProto] = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype()); + jsObjects[DateProto] = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype()); uint index; - InternalClass *functionProtoClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable, &index); + InternalClass *functionProtoClass = emptyClass->addMember(id_prototype(), Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); - functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.asObject()); - functionClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index); + jsObjects[FunctionProto] = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype()); + functionClass = emptyClass->addMember(id_prototype(), Attr_NotEnumerable|Attr_NotConfigurable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); - simpleScriptFunctionClass = functionClass->addMember(id_name, Attr_ReadOnly, &index); + simpleScriptFunctionClass = functionClass->addMember(id_name(), Attr_ReadOnly, &index); Q_ASSERT(index == Heap::SimpleScriptFunction::Index_Name); - simpleScriptFunctionClass = simpleScriptFunctionClass->addMember(id_length, Attr_ReadOnly, &index); + simpleScriptFunctionClass = simpleScriptFunctionClass->addMember(id_length(), Attr_ReadOnly, &index); Q_ASSERT(index == Heap::SimpleScriptFunction::Index_Length); - protoClass = emptyClass->addMember(id_constructor, Attr_NotEnumerable, &index); + protoClass = emptyClass->addMember(id_constructor(), Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor); - regExpPrototype = memoryManager->alloc<RegExpPrototype>(this); - regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index); + jsObjects[RegExpProto] = memoryManager->alloc<RegExpPrototype>(this); + regExpExecArrayClass = arrayClass->addMember(id_index(), Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayIndex); - regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index); + regExpExecArrayClass = regExpExecArrayClass->addMember(id_input(), Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayInput); - errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype.asObject()); - evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype.asObject()); - rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype.asObject()); - referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype.asObject()); - syntaxErrorPrototype = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype.asObject()); - typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype.asObject()); - uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype.asObject()); + jsObjects[ErrorProto] = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype()); + jsObjects[EvalErrorProto] = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype()); + jsObjects[RangeErrorProto] = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype()); + jsObjects[ReferenceErrorProto] = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype()); + jsObjects[SyntaxErrorProto] = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype()); + jsObjects[TypeErrorProto] = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype()); + jsObjects[URIErrorProto] = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype()); - variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype.asObject()); - Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject()->d()); + jsObjects[VariantProto] = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype()); + Q_ASSERT(variantPrototype()->prototype() == objectPrototype()->d()); - sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject())); + Scope scope(this); + jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype())); ScopedContext global(scope, rootContext()); - objectCtor = memoryManager->alloc<ObjectCtor>(global); - stringCtor = memoryManager->alloc<StringCtor>(global); - numberCtor = memoryManager->alloc<NumberCtor>(global); - booleanCtor = memoryManager->alloc<BooleanCtor>(global); - arrayCtor = memoryManager->alloc<ArrayCtor>(global); - functionCtor = memoryManager->alloc<FunctionCtor>(global); - dateCtor = memoryManager->alloc<DateCtor>(global); - regExpCtor = memoryManager->alloc<RegExpCtor>(global); - errorCtor = memoryManager->alloc<ErrorCtor>(global); - evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(global); - rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(global); - referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(global); - syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(global); - typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(global); - uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(global); - - static_cast<ObjectPrototype *>(objectPrototype.asObject())->init(this, objectCtor.asObject()); - static_cast<StringPrototype *>(stringPrototype.asObject())->init(this, stringCtor.asObject()); - static_cast<NumberPrototype *>(numberPrototype.asObject())->init(this, numberCtor.asObject()); - static_cast<BooleanPrototype *>(booleanPrototype.asObject())->init(this, booleanCtor.asObject()); - static_cast<ArrayPrototype *>(arrayPrototype.asObject())->init(this, arrayCtor.asObject()); - static_cast<DatePrototype *>(datePrototype.asObject())->init(this, dateCtor.asObject()); - static_cast<FunctionPrototype *>(functionPrototype.asObject())->init(this, functionCtor.asObject()); - static_cast<RegExpPrototype *>(regExpPrototype.asObject())->init(this, regExpCtor.asObject()); - static_cast<ErrorPrototype *>(errorPrototype.asObject())->init(this, errorCtor.asObject()); - static_cast<EvalErrorPrototype *>(evalErrorPrototype.asObject())->init(this, evalErrorCtor.asObject()); - static_cast<RangeErrorPrototype *>(rangeErrorPrototype.asObject())->init(this, rangeErrorCtor.asObject()); - static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.asObject())->init(this, referenceErrorCtor.asObject()); - static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.asObject())->init(this, syntaxErrorCtor.asObject()); - static_cast<TypeErrorPrototype *>(typeErrorPrototype.asObject())->init(this, typeErrorCtor.asObject()); - static_cast<URIErrorPrototype *>(uRIErrorPrototype.asObject())->init(this, uRIErrorCtor.asObject()); - - static_cast<VariantPrototype *>(variantPrototype.asObject())->init(); - sequencePrototype.cast<SequencePrototype>()->init(); + jsObjects[Object_Ctor] = memoryManager->alloc<ObjectCtor>(global); + jsObjects[String_Ctor] = memoryManager->alloc<StringCtor>(global); + jsObjects[Number_Ctor] = memoryManager->alloc<NumberCtor>(global); + jsObjects[Boolean_Ctor] = memoryManager->alloc<BooleanCtor>(global); + jsObjects[Array_Ctor] = memoryManager->alloc<ArrayCtor>(global); + jsObjects[Function_Ctor] = memoryManager->alloc<FunctionCtor>(global); + jsObjects[Date_Ctor] = memoryManager->alloc<DateCtor>(global); + jsObjects[RegExp_Ctor] = memoryManager->alloc<RegExpCtor>(global); + jsObjects[Error_Ctor] = memoryManager->alloc<ErrorCtor>(global); + jsObjects[EvalError_Ctor] = memoryManager->alloc<EvalErrorCtor>(global); + jsObjects[RangeError_Ctor] = memoryManager->alloc<RangeErrorCtor>(global); + jsObjects[ReferenceError_Ctor] = memoryManager->alloc<ReferenceErrorCtor>(global); + jsObjects[SyntaxError_Ctor] = memoryManager->alloc<SyntaxErrorCtor>(global); + jsObjects[TypeError_Ctor] = memoryManager->alloc<TypeErrorCtor>(global); + jsObjects[URIError_Ctor] = memoryManager->alloc<URIErrorCtor>(global); + + static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor()); + static_cast<StringPrototype *>(stringPrototype())->init(this, stringCtor()); + static_cast<NumberPrototype *>(numberPrototype())->init(this, numberCtor()); + static_cast<BooleanPrototype *>(booleanPrototype())->init(this, booleanCtor()); + static_cast<ArrayPrototype *>(arrayPrototype())->init(this, arrayCtor()); + static_cast<DatePrototype *>(datePrototype())->init(this, dateCtor()); + static_cast<FunctionPrototype *>(functionPrototype())->init(this, functionCtor()); + static_cast<RegExpPrototype *>(regExpPrototype())->init(this, regExpCtor()); + static_cast<ErrorPrototype *>(errorPrototype())->init(this, errorCtor()); + static_cast<EvalErrorPrototype *>(evalErrorPrototype())->init(this, evalErrorCtor()); + static_cast<RangeErrorPrototype *>(rangeErrorPrototype())->init(this, rangeErrorCtor()); + static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype())->init(this, referenceErrorCtor()); + static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(this, syntaxErrorCtor()); + static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(this, typeErrorCtor()); + static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor()); + + static_cast<VariantPrototype *>(variantPrototype())->init(); + sequencePrototype()->cast<SequencePrototype>()->init(); // typed arrays - arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(global); - arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype.asObject()); - static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.asObject())->init(this, arrayBufferCtor.asObject()); + jsObjects[ArrayBuffer_Ctor] = memoryManager->alloc<ArrayBufferCtor>(global); + jsObjects[ArrayBufferProto] = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype()); + static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(this, arrayBufferCtor()); - dataViewCtor = memoryManager->alloc<DataViewCtor>(global); - dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype.asObject()); - static_cast<DataViewPrototype *>(dataViewPrototype.asObject())->init(this, dataViewCtor.asObject()); + jsObjects[DataView_Ctor] = memoryManager->alloc<DataViewCtor>(global); + jsObjects[DataViewProto] = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype()); + static_cast<DataViewPrototype *>(dataViewPrototype())->init(this, dataViewCtor()); + jsObjects[ValueTypeProto] = (Heap::Base *) 0; for (int i = 0; i < Heap::TypedArray::NTypes; ++i) { - typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i)); - typedArrayPrototype[i] = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i)); - typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject())); + static_cast<Value &>(typedArrayCtors[i]) = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i)); + static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i)); + typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>())); } // // set up the global object // - rootContext()->global = globalObject()->d(); - rootContext()->callData->thisObject = globalObject(); - Q_ASSERT(globalObject()->d()->vtable); - - globalObject()->defineDefaultProperty(QStringLiteral("Object"), objectCtor); - globalObject()->defineDefaultProperty(QStringLiteral("String"), stringCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Number"), numberCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Boolean"), booleanCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Array"), arrayCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Function"), functionCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Date"), dateCtor); - globalObject()->defineDefaultProperty(QStringLiteral("RegExp"), regExpCtor); - globalObject()->defineDefaultProperty(QStringLiteral("Error"), errorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("EvalError"), evalErrorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("RangeError"), rangeErrorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("ReferenceError"), referenceErrorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("SyntaxError"), syntaxErrorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor); - globalObject()->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor); - - globalObject()->defineDefaultProperty(QStringLiteral("ArrayBuffer"), arrayBufferCtor); - globalObject()->defineDefaultProperty(QStringLiteral("DataView"), dataViewCtor); + rootContext()->d()->global = globalObject->d(); + rootContext()->d()->callData->thisObject = globalObject; + Q_ASSERT(globalObject->d()->vtable()); + + globalObject->defineDefaultProperty(QStringLiteral("Object"), *objectCtor()); + globalObject->defineDefaultProperty(QStringLiteral("String"), *stringCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Number"), *numberCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Boolean"), *booleanCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Array"), *arrayCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Function"), *functionCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Date"), *dateCtor()); + globalObject->defineDefaultProperty(QStringLiteral("RegExp"), *regExpCtor()); + globalObject->defineDefaultProperty(QStringLiteral("Error"), *errorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("EvalError"), *evalErrorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("RangeError"), *rangeErrorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("ReferenceError"), *referenceErrorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("SyntaxError"), *syntaxErrorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("TypeError"), *typeErrorCtor()); + globalObject->defineDefaultProperty(QStringLiteral("URIError"), *uRIErrorCtor()); + + globalObject->defineDefaultProperty(QStringLiteral("ArrayBuffer"), *arrayBufferCtor()); + globalObject->defineDefaultProperty(QStringLiteral("DataView"), *dataViewCtor()); ScopedString str(scope); for (int i = 0; i < Heap::TypedArray::NTypes; ++i) - globalObject()->defineDefaultProperty((str = typedArrayCtors[i].asFunctionObject()->name())->toQString(), typedArrayCtors[i]); + globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]); ScopedObject o(scope); - globalObject()->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this))); - globalObject()->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this))); + globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this))); + globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this))); - globalObject()->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue()); - globalObject()->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN())); - globalObject()->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY)); + globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue()); + globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN())); + globalObject->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY)); - evalFunction = memoryManager->alloc<EvalFunction>(global); - globalObject()->defineDefaultProperty(QStringLiteral("eval"), (o = evalFunction)); + jsObjects[Eval_Function] = memoryManager->alloc<EvalFunction>(global); + globalObject->defineDefaultProperty(QStringLiteral("eval"), *evalFunction()); - globalObject()->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2); - globalObject()->defineDefaultProperty(QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1); - globalObject()->defineDefaultProperty(QStringLiteral("isNaN"), GlobalFunctions::method_isNaN, 1); - globalObject()->defineDefaultProperty(QStringLiteral("isFinite"), GlobalFunctions::method_isFinite, 1); - globalObject()->defineDefaultProperty(QStringLiteral("decodeURI"), GlobalFunctions::method_decodeURI, 1); - globalObject()->defineDefaultProperty(QStringLiteral("decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1); - globalObject()->defineDefaultProperty(QStringLiteral("encodeURI"), GlobalFunctions::method_encodeURI, 1); - globalObject()->defineDefaultProperty(QStringLiteral("encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1); - globalObject()->defineDefaultProperty(QStringLiteral("escape"), GlobalFunctions::method_escape, 1); - globalObject()->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1); + globalObject->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2); + globalObject->defineDefaultProperty(QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1); + globalObject->defineDefaultProperty(QStringLiteral("isNaN"), GlobalFunctions::method_isNaN, 1); + globalObject->defineDefaultProperty(QStringLiteral("isFinite"), GlobalFunctions::method_isFinite, 1); + globalObject->defineDefaultProperty(QStringLiteral("decodeURI"), GlobalFunctions::method_decodeURI, 1); + globalObject->defineDefaultProperty(QStringLiteral("decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1); + globalObject->defineDefaultProperty(QStringLiteral("encodeURI"), GlobalFunctions::method_encodeURI, 1); + globalObject->defineDefaultProperty(QStringLiteral("encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1); + globalObject->defineDefaultProperty(QStringLiteral("escape"), GlobalFunctions::method_escape, 1); + globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1); ScopedString name(scope, newString(QStringLiteral("thrower"))); - thrower = BuiltinFunction::create(global, name, ::throwTypeError); + jsObjects[ThrowerObject] = BuiltinFunction::create(global, name, ::throwTypeError); } ExecutionEngine::~ExecutionEngine() @@ -471,7 +474,6 @@ ExecutionEngine::~ExecutionEngine() foreach (QV4::CompiledData::CompilationUnit *unit, remainingUnits) unit->unlink(); - delete m_qmlExtensions; emptyClass->destroy(); delete classPool; delete bumperPointerAllocator; @@ -504,10 +506,10 @@ void ExecutionEngine::initRootContext() r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1); r->d()->callData->tag = QV4::Value::_Integer_Type; r->d()->callData->argc = 0; - r->d()->callData->thisObject = globalObject(); + r->d()->callData->thisObject = globalObject; r->d()->callData->args[0] = Encode::undefined(); - m_rootContext = r->d(); + jsObjects[RootContect] = r; } InternalClass *ExecutionEngine::newClass(const InternalClass &other) @@ -519,7 +521,7 @@ Heap::ExecutionContext *ExecutionEngine::pushGlobalContext() { Scope scope(this); Scoped<GlobalContext> g(scope, memoryManager->alloc<GlobalContext>(this)); - g->d()->callData = rootContext()->callData; + g->d()->callData = rootContext()->d()->callData; Q_ASSERT(currentContext() == g->d()); return g->d(); @@ -551,10 +553,10 @@ Heap::String *ExecutionEngine::newIdentifier(const QString &text) return identifierTable->insertString(text); } -Heap::Object *ExecutionEngine::newStringObject(const Value &value) +Heap::Object *ExecutionEngine::newStringObject(const String *string) { Scope scope(this); - Scoped<StringObject> object(scope, memoryManager->alloc<StringObject>(this, value)); + Scoped<StringObject> object(scope, memoryManager->alloc<StringObject>(this, string)); return object->d(); } @@ -653,7 +655,7 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re) Heap::Object *ExecutionEngine::newErrorObject(const Value &value) { Scope scope(this); - ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype.asObject(), value)); + ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype(), value)); return object->d(); } @@ -723,7 +725,7 @@ Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o) return obj->d(); } -Heap::Object *ExecutionEngine::qmlContextObject() const +Heap::QmlContext *ExecutionEngine::qmlContext() const { Heap::ExecutionContext *ctx = currentContext(); @@ -740,8 +742,49 @@ Heap::Object *ExecutionEngine::qmlContextObject() const if (ctx->type != Heap::ExecutionContext::Type_QmlContext) return 0; - Q_ASSERT(static_cast<Heap::CallContext *>(ctx)->activation); - return static_cast<Heap::CallContext *>(ctx)->activation; + return static_cast<Heap::QmlContext *>(ctx); +} + +Heap::QmlContextWrapper *ExecutionEngine::qmlContextObject() const +{ + Heap::QmlContext *ctx = qmlContext(); + if (!ctx) + return 0; + Q_ASSERT(ctx->qml); + return ctx->qml; +} + +QObject *ExecutionEngine::qmlScopeObject() const +{ + return qmlContextObject()->scopeObject; +} + +ReturnedValue ExecutionEngine::qmlSingletonWrapper(String *name) +{ + QQmlContextData *ctx = callingQmlContext(); + if (!ctx->imports) + return Encode::undefined(); + // Search for attached properties, enums and imported scripts + QQmlTypeNameCache::Result r = ctx->imports->query(name); + + Q_ASSERT(r.isValid()); + Q_ASSERT(r.type); + Q_ASSERT(r.type->isSingleton()); + + QQmlType::SingletonInstanceInfo *siinfo = r.type->singletonInstanceInfo(); + QQmlEngine *e = qmlEngine(); + siinfo->init(e); + + if (QObject *qobjectSingleton = siinfo->qobjectApi(e)) + return QV4::QObjectWrapper::wrap(this, qobjectSingleton); + return QJSValuePrivate::convertedToValue(this, siinfo->scriptApi(e)); +} + +QQmlContextData *ExecutionEngine::callingQmlContext() const +{ + Heap::QmlContextWrapper *w = qmlContextObject(); + + return w ? w->context.contextData() : 0; } QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const @@ -777,7 +820,7 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const StackFrame frame; frame.source = globalCode->sourceFile(); frame.function = globalCode->name()->toQString(); - frame.line = rootContext()->lineNumber; + frame.line = rootContext()->d()->lineNumber; frame.column = -1; stack.append(frame); @@ -889,8 +932,6 @@ void ExecutionEngine::markObjects() { identifierTable->mark(this); - globalObject()->mark(this); - for (int i = 0; i < nArgumentsAccessors; ++i) { const Property &pd = argumentsAccessors[i]; if (Heap::FunctionObject *getter = pd.getter()) @@ -904,98 +945,11 @@ void ExecutionEngine::markObjects() Q_ASSERT(c->inUse()); if (!c->isMarked()) { c->setMarkBit(); - c->gcGetVtable()->markObjects(c, this); + c->vtable()->markObjects(c, this); } c = c->parent; } - id_empty->mark(this); - id_undefined->mark(this); - id_null->mark(this); - id_true->mark(this); - id_false->mark(this); - id_boolean->mark(this); - id_number->mark(this); - id_string->mark(this); - id_object->mark(this); - id_function->mark(this); - id_length->mark(this); - id_prototype->mark(this); - id_constructor->mark(this); - id_arguments->mark(this); - id_caller->mark(this); - id_callee->mark(this); - id_this->mark(this); - id___proto__->mark(this); - id_enumerable->mark(this); - id_configurable->mark(this); - id_writable->mark(this); - id_value->mark(this); - id_get->mark(this); - id_set->mark(this); - id_eval->mark(this); - id_uintMax->mark(this); - id_name->mark(this); - id_index->mark(this); - id_input->mark(this); - id_toString->mark(this); - id_destroy->mark(this); - id_valueOf->mark(this); - id_byteLength->mark(this); - id_byteOffset->mark(this); - id_buffer->mark(this); - id_lastIndex->mark(this); - - objectCtor.mark(this); - stringCtor.mark(this); - numberCtor.mark(this); - booleanCtor.mark(this); - arrayCtor.mark(this); - functionCtor.mark(this); - dateCtor.mark(this); - regExpCtor.mark(this); - errorCtor.mark(this); - evalErrorCtor.mark(this); - rangeErrorCtor.mark(this); - referenceErrorCtor.mark(this); - syntaxErrorCtor.mark(this); - typeErrorCtor.mark(this); - uRIErrorCtor.mark(this); - arrayBufferCtor.mark(this); - dataViewCtor.mark(this); - for (int i = 0; i < Heap::TypedArray::NTypes; ++i) - typedArrayCtors[i].mark(this); - - objectPrototype.mark(this); - arrayPrototype.mark(this); - stringPrototype.mark(this); - numberPrototype.mark(this); - booleanPrototype.mark(this); - datePrototype.mark(this); - functionPrototype.mark(this); - regExpPrototype.mark(this); - errorPrototype.mark(this); - evalErrorPrototype.mark(this); - rangeErrorPrototype.mark(this); - referenceErrorPrototype.mark(this); - syntaxErrorPrototype.mark(this); - typeErrorPrototype.mark(this); - uRIErrorPrototype.mark(this); - variantPrototype.mark(this); - sequencePrototype.mark(this); - - arrayBufferPrototype.mark(this); - dataViewPrototype.mark(this); - for (int i = 0; i < Heap::TypedArray::NTypes; ++i) - typedArrayPrototype[i].mark(this); - - exceptionValue.mark(this); - - thrower->mark(this); - - if (m_qmlExtensions) - m_qmlExtensions->markObjects(this); - classPool->markObjects(this); for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd(); @@ -1003,13 +957,6 @@ void ExecutionEngine::markObjects() (*it)->markObjects(this); } -QmlExtensions *ExecutionEngine::qmlExtensions() -{ - if (!m_qmlExtensions) - m_qmlExtensions = new QmlExtensions; - return m_qmlExtensions; -} - ReturnedValue ExecutionEngine::throwError(const Value &value) { // we can get in here with an exception already set, as the runtime @@ -1020,7 +967,7 @@ ReturnedValue ExecutionEngine::throwError(const Value &value) return Encode::undefined(); hasException = true; - exceptionValue = value; + *exceptionValue = value; QV4::Scope scope(this); QV4::Scoped<ErrorObject> error(scope, value); if (!!error) @@ -1041,8 +988,8 @@ ReturnedValue ExecutionEngine::catchException(StackTrace *trace) *trace = exceptionStackTrace; exceptionStackTrace.clear(); hasException = false; - ReturnedValue res = exceptionValue.asReturnedValue(); - exceptionValue = Primitive::emptyValue(); + ReturnedValue res = exceptionValue->asReturnedValue(); + *exceptionValue = Primitive::emptyValue(); return res; } @@ -1175,7 +1122,7 @@ bool ExecutionEngine::recheckCStackLimits() typedef QSet<QV4::Heap::Object *> V4ObjectSet; static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects); static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &value); -static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4ObjectSet *visitedObjects = 0); +static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = 0); static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &value, const QByteArray &targetType, void **result); @@ -1198,7 +1145,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int Q_ASSERT (!value.isEmpty()); QV4::Scope scope(e); - if (QV4::VariantObject *v = value.as<QV4::VariantObject>()) + if (const QV4::VariantObject *v = value.as<QV4::VariantObject>()) return v->d()->data; if (typeHint == QVariant::Bool) @@ -1210,10 +1157,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int if (typeHint == qMetaTypeId<QJSValue>()) return QVariant::fromValue(QJSValue(e, value.asReturnedValue())); - if (value.asObject()) { + if (value.as<Object>()) { QV4::ScopedObject object(scope, value); if (typeHint == QMetaType::QJsonObject - && !value.asArrayObject() && !value.asFunctionObject()) { + && !value.as<ArrayObject>() && !value.as<FunctionObject>()) { return QVariant::fromValue(QV4::JsonObject::toJsonObject(object)); } else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) { return qVariantFromValue<QObject *>(wrapper->object()); @@ -1229,7 +1176,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return QV4::SequencePrototype::toVariant(object); } - if (value.asArrayObject()) { + if (value.as<ArrayObject>()) { QV4::ScopedArrayObject a(scope, value); if (typeHint == qMetaTypeId<QList<QObject *> >()) { QList<QObject *> list; @@ -1267,11 +1214,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return value.asDouble(); if (value.isString()) return value.stringValue()->toQString(); - if (QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) + if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) return ld->d()->locale; - if (QV4::DateObject *d = value.asDateObject()) + if (const QV4::DateObject *d = value.as<DateObject>()) return d->toQDateTime(); - if (QV4::ArrayBuffer *d = value.as<ArrayBuffer>()) + if (const QV4::ArrayBuffer *d = value.as<ArrayBuffer>()) return d->asByteArray(); // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! @@ -1287,7 +1234,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return objectToVariant(e, o, visitedObjects); } -static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4ObjectSet *visitedObjects) +static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects) { Q_ASSERT(o); @@ -1298,7 +1245,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an // empty object (and no error is thrown). - if (o->asArrayObject()) + if (o->as<ArrayObject>()) return QVariantList(); return QVariantMap(); } @@ -1306,7 +1253,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec QVariant result; - if (o->asArrayObject()) { + if (o->as<ArrayObject>()) { QV4::Scope scope(e); QV4::ScopedArrayObject a(scope, o->asReturnedValue()); QV4::ScopedValue v(scope); @@ -1319,7 +1266,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec } result = list; - } else if (!o->asFunctionObject()) { + } else if (!o->as<FunctionObject>()) { QVariantMap map; QV4::Scope scope(e); QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); @@ -1497,7 +1444,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) return QV4::Encode(newVariantObject(variant)); } -QVariantMap ExecutionEngine::variantMapFromJS(Object *o) +QVariantMap ExecutionEngine::variantMapFromJS(const Object *o) { return objectToVariant(this, o).toMap(); } @@ -1630,93 +1577,90 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return 0; } -void ExecutionEngine::assertObjectBelongsToEngine(const Value &v) +void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject) { - Q_UNUSED(v); - Q_ASSERT(!v.isObject() || v.objectValue()->engine() == this); - Q_UNUSED(v); + Q_ASSERT(!baseObject.vtable()->isObject || static_cast<const Heap::Object&>(baseObject).internalClass->engine == this); + Q_UNUSED(baseObject); } // Converts a JS value to a meta-type. // data must point to a place that can store a value of the given type. // Returns true if conversion succeeded, false otherwise. -bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *data) +bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) { - QV4::Scope scope(this); - // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Bool: - *reinterpret_cast<bool*>(data) = value.toBoolean(); + *reinterpret_cast<bool*>(data) = value->toBoolean(); return true; case QMetaType::Int: - *reinterpret_cast<int*>(data) = value.toInt32(); + *reinterpret_cast<int*>(data) = value->toInt32(); return true; case QMetaType::UInt: - *reinterpret_cast<uint*>(data) = value.toUInt32(); + *reinterpret_cast<uint*>(data) = value->toUInt32(); return true; case QMetaType::LongLong: - *reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger()); + *reinterpret_cast<qlonglong*>(data) = qlonglong(value->toInteger()); return true; case QMetaType::ULongLong: - *reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger()); + *reinterpret_cast<qulonglong*>(data) = qulonglong(value->toInteger()); return true; case QMetaType::Double: - *reinterpret_cast<double*>(data) = value.toNumber(); + *reinterpret_cast<double*>(data) = value->toNumber(); return true; case QMetaType::QString: - if (value.isUndefined() || value.isNull()) + if (value->isUndefined() || value->isNull()) *reinterpret_cast<QString*>(data) = QString(); else - *reinterpret_cast<QString*>(data) = value.toQString(); + *reinterpret_cast<QString*>(data) = value->toQString(); return true; case QMetaType::Float: - *reinterpret_cast<float*>(data) = value.toNumber(); + *reinterpret_cast<float*>(data) = value->toNumber(); return true; case QMetaType::Short: - *reinterpret_cast<short*>(data) = short(value.toInt32()); + *reinterpret_cast<short*>(data) = short(value->toInt32()); return true; case QMetaType::UShort: - *reinterpret_cast<unsigned short*>(data) = value.toUInt16(); + *reinterpret_cast<unsigned short*>(data) = value->toUInt16(); return true; case QMetaType::Char: - *reinterpret_cast<char*>(data) = char(value.toInt32()); + *reinterpret_cast<char*>(data) = char(value->toInt32()); return true; case QMetaType::UChar: - *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value.toInt32()); + *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->toInt32()); return true; case QMetaType::QChar: - if (value.isString()) { - QString str = value.stringValue()->toQString(); + if (value->isString()) { + QString str = value->stringValue()->toQString(); *reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0); } else { - *reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16())); + *reinterpret_cast<QChar*>(data) = QChar(ushort(value->toUInt16())); } return true; case QMetaType::QDateTime: - if (QV4::DateObject *d = value.asDateObject()) { + if (const QV4::DateObject *d = value->as<DateObject>()) { *reinterpret_cast<QDateTime *>(data) = d->toQDateTime(); return true; } break; case QMetaType::QDate: - if (QV4::DateObject *d = value.asDateObject()) { + if (const QV4::DateObject *d = value->as<DateObject>()) { *reinterpret_cast<QDate *>(data) = d->toQDateTime().date(); return true; } break; case QMetaType::QRegExp: - if (QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) { + if (const QV4::RegExpObject *r = value->as<QV4::RegExpObject>()) { *reinterpret_cast<QRegExp *>(data) = r->toQRegExp(); return true; } break; case QMetaType::QObjectStar: { - QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>(); - if (qobjectWrapper || value.isNull()) { - *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(scope.engine, value); + const QV4::QObjectWrapper *qobjectWrapper = value->as<QV4::QObjectWrapper>(); + if (qobjectWrapper || value->isNull()) { + *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(this, *value); return true; } break; } case QMetaType::QStringList: { - QV4::ScopedArrayObject a(scope, value); + const QV4::ArrayObject *a = value->as<QV4::ArrayObject>(); if (a) { *reinterpret_cast<QStringList *>(data) = a->toQStringList(); return true; @@ -1724,15 +1668,15 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da break; } case QMetaType::QVariantList: { - QV4::ScopedArrayObject a(scope, value); + const QV4::ArrayObject *a = value->as<QV4::ArrayObject>(); if (a) { - *reinterpret_cast<QVariantList *>(data) = scope.engine->toVariant(a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList(); + *reinterpret_cast<QVariantList *>(data) = toVariant(*a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList(); return true; } break; } case QMetaType::QVariantMap: { - QV4::ScopedObject o(scope, value); + const QV4::Object *o = value->as<QV4::Object>(); if (o) { *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(o); return true; @@ -1740,20 +1684,19 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da break; } case QMetaType::QVariant: - *reinterpret_cast<QVariant*>(data) = scope.engine->toVariant(value, /*typeHint*/-1, /*createJSValueForObjects*/false); + *reinterpret_cast<QVariant*>(data) = toVariant(*value, /*typeHint*/-1, /*createJSValueForObjects*/false); return true; case QMetaType::QJsonValue: - *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value); + *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(*value); return true; case QMetaType::QJsonObject: { - QV4::ScopedObject o(scope, value); - *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(o); + *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value->as<Object>()); return true; } case QMetaType::QJsonArray: { - QV4::ScopedArrayObject a(scope, value); + const QV4::ArrayObject *a = value->as<ArrayObject>(); if (a) { - *reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(a); + *reinterpret_cast<QJsonArray *>(data) = JsonObject::toJsonArray(a); return true; } break; @@ -1763,7 +1706,7 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da } { - QV4::Scoped<QV4::QQmlValueTypeWrapper> vtw(scope, value); + const QQmlValueTypeWrapper *vtw = value->as<QQmlValueTypeWrapper>(); if (vtw && vtw->typeId() == type) { return vtw->toGadget(data); } @@ -1788,21 +1731,22 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da } #endif - // Try to use magic; for compatibility with qscriptvalue_cast. + // Try to use magic; for compatibility with qjsvalue_cast. QByteArray name = QMetaType::typeName(type); - if (convertToNativeQObject(this, value, name, reinterpret_cast<void* *>(data))) + if (convertToNativeQObject(this, *value, name, reinterpret_cast<void* *>(data))) return true; - if (value.as<QV4::VariantObject>() && name.endsWith('*')) { + if (value->as<QV4::VariantObject>() && name.endsWith('*')) { int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = value.as<QV4::VariantObject>()->d()->data; + QVariant &var = value->as<QV4::VariantObject>()->d()->data; if (valueType == var.userType()) { // We have T t, T* is requested, so return &t. *reinterpret_cast<void* *>(data) = var.data(); return true; - } else if (value.isObject()) { + } else if (value->isObject()) { // Look in the prototype chain. - QV4::ScopedObject proto(scope, value.objectValue()->prototype()); + QV4::Scope scope(this); + QV4::ScopedObject proto(scope, value->objectValue()->prototype()); while (proto) { bool canCast = false; if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) { @@ -1812,7 +1756,7 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da else if (proto->as<QV4::QObjectWrapper>()) { QByteArray className = name.left(name.size()-1); QV4::ScopedObject p(scope, proto.getPointer()); - if (QObject *qobject = qtObjectFromJS(scope.engine, p)) + if (QObject *qobject = qtObjectFromJS(this, p)) canCast = qobject->qt_metacast(className) != 0; } if (canCast) { @@ -1826,11 +1770,11 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da proto = proto->prototype(); } } - } else if (value.isNull() && name.endsWith('*')) { + } else if (value->isNull() && name.endsWith('*')) { *reinterpret_cast<void* *>(data) = 0; return true; } else if (type == qMetaTypeId<QJSValue>()) { - *reinterpret_cast<QJSValue*>(data) = QJSValue(this, value.asReturnedValue()); + *reinterpret_cast<QJSValue*>(data) = QJSValue(this, value->asReturnedValue()); return true; } |