diff options
Diffstat (limited to 'src/qml/qml')
31 files changed, 383 insertions, 164 deletions
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp index 321e6ccb41..012412b6b5 100644 --- a/src/qml/qml/ftw/qhashedstring.cpp +++ b/src/qml/qml/ftw/qhashedstring.cpp @@ -195,20 +195,6 @@ bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length) return true; } -// Unicode stuff -static inline bool isUnicodeNonCharacter(uint ucs4) -{ - // Unicode has a couple of "non-characters" that one can use internally, - // but are not allowed to be used for text interchange. - // - // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, - // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and - // U+FDEF (inclusive) - - return (ucs4 & 0xfffe) == 0xfffe - || (ucs4 - 0xfdd0U) < 16; -} - QHashedStringRef QHashedStringRef::mid(int offset, int length) const { Q_ASSERT(offset < m_length); diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index b6c6fe840d..641209d1f3 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -467,7 +467,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } -static const int CurrentSingletonTypeRegistrationVersion = 2; +enum { QmlCurrentSingletonTypeRegistrationVersion = 2 }; template <typename T> inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *)) @@ -475,7 +475,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QML_GETTYPENAMES QQmlPrivate::RegisterSingletonType api = { - CurrentSingletonTypeRegistrationVersion, + QmlCurrentSingletonTypeRegistrationVersion, uri, versionMajor, versionMinor, typeName, diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 557267d808..9e2fb07066 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -50,6 +50,7 @@ #include <private/qqmltrace_p.h> #include <private/qqmlexpression_p.h> #include <private/qqmlscriptstring_p.h> +#include <private/qqmlcontextwrapper_p.h> #include <QVariant> #include <QtCore/qdebug.h> @@ -85,7 +86,14 @@ QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt, Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { - rv = new QQmlBinding(cdata->primitives.at(id), obj, ctxtdata, url, lineNumber, 0); + QV4::ExecutionEngine *v4 = engine->v4engine(); + QV4::Scope valueScope(v4); + QV4::ScopedObject scopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(v4->v8Engine, ctxtdata, obj)); + QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, scopeObject)); + QV4::ExecutionContext *qmlContext = wrapper->context(); + QV4::Function *runtimeFunction = cdata->compilationUnit->runtimeFunctions[cdata->customParserBindings[id]]; + QV4::ScopedValue function(valueScope, QV4::FunctionObject::creatScriptFunction(qmlContext, runtimeFunction)); + rv = new QQmlBinding(function, obj, ctxtdata, url, lineNumber, 0); } typeData->release(); diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 11dc873dd4..68160edf5e 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -89,8 +89,8 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::ValueRef &function) : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), m_v8function(function), - m_line(-1), - m_column(-1), + m_line(USHRT_MAX), + m_column(USHRT_MAX), m_target(target), m_index(index), m_expressionFunctionValid(true), diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp index 9fcef176ad..76bf24fe6b 100644 --- a/src/qml/qml/qqmlcompileddata.cpp +++ b/src/qml/qml/qqmlcompileddata.cpp @@ -45,6 +45,7 @@ #include "qqmlcomponent_p.h" #include "qqmlcontext.h" #include "qqmlcontext_p.h" +#include "qqmlpropertymap.h" #ifdef QML_THREADED_VME_INTERPRETER #include "qqmlvme_p.h" #endif @@ -173,6 +174,27 @@ QQmlPropertyCache *QQmlCompiledData::TypeReference::createPropertyCache(QQmlEngi } } +template <typename T> +bool qtTypeInherits(const QMetaObject *mo) { + while (mo) { + if (mo == &T::staticMetaObject) + return true; + mo = mo->superClass(); + } + return false; +} + +void QQmlCompiledData::TypeReference::doDynamicTypeCheck() +{ + const QMetaObject *mo = 0; + if (typePropertyCache) + mo = typePropertyCache->firstCppMetaObject(); + else if (type) + mo = type->metaObject(); + else + mo = component->rootPropertyCache->firstCppMetaObject(); + isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo); +} void QQmlCompiledData::dumpInstructions() { diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 187274890b..2e208f2f3b 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -62,7 +62,6 @@ #include "qqmlglobal_p.h" #include "qqmlbinding_p.h" #include "qqmlabstracturlinterceptor.h" -#include "qqmlcodegenerator_p.h" #include <QDebug> #include <QPointF> @@ -848,6 +847,8 @@ bool QQmlCompiler::compile(QQmlEngine *engine, } } + ref.doDynamicTypeCheck(); + out->types << ref; } @@ -859,6 +860,19 @@ bool QQmlCompiler::compile(QQmlEngine *engine, if (componentStats) dumpStats(); Q_ASSERT(out->rootPropertyCache); + + // Any QQmlPropertyMap instances for example need to have their property cache removed, + // because the class is too dynamic and allows adding properties at any point at run-time. + for (int i = 0; i < output->types.count(); ++i) { + QQmlCompiledData::TypeReference &tr = output->types[i]; + if (!tr.typePropertyCache) + continue; + + if (tr.isFullyDynamicType) { + tr.typePropertyCache->release(); + tr.typePropertyCache = 0; + } + } } else { reset(out); } @@ -919,7 +933,7 @@ void QQmlCompiler::compileTree(QQmlScript::Object *tree) if (!jsModule->functions.isEmpty()) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Compiler::JSUnitGenerator jsUnitGenerator(jsModule.data()); - QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(v4->executableAllocator, jsModule.data(), &jsUnitGenerator)); + QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(enginePrivate, v4->executableAllocator, jsModule.data(), &jsUnitGenerator)); isel->setUseFastLookups(false); QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/true); output->compilationUnit = jsUnit; @@ -1227,6 +1241,7 @@ void QQmlCompiler::genObject(QQmlScript::Object *obj, bool parentToSuper) // Setup the synthesized meta object if necessary if (!obj->synthdata.isEmpty()) { + Q_ASSERT(!output->types.at(obj->type).isFullyDynamicType); Instruction::StoreMetaObject meta; meta.aliasData = output->indexForByteArray(obj->synthdata); meta.propertyCache = output->propertyCaches.count(); @@ -2682,14 +2697,42 @@ const QMetaObject *QQmlCompiler::resolveType(const QString& name) const return qmltype->metaObject(); } -int QQmlCompiler::bindingIdentifier(const Variant &value) +int QQmlCompiler::bindingIdentifier(const QString &name, const Variant &value, const BindingContext &ctxt) { - return output->indexForString(value.asScript()); + JSBindingReference *reference = pool->New<JSBindingReference>(); + reference->expression = value; + reference->property = pool->New<Property>(); + reference->property->setName(name); + reference->value = 0; + reference->bindingContext = ctxt; + reference->bindingContext.owner++; + // Unfortunately this is required for example for PropertyChanges where the bindings + // will be executed in the dynamic scope of the target, so we can't resolve any lookups + // at run-time. + reference->disableLookupAcceleration = true; + + const int id = output->customParserBindings.count(); + output->customParserBindings.append(0); // Filled in later. + reference->customParserBindingsIndex = id; + + compileState->totalBindingsCount++; + compileState->bindings.prepend(reference); + + return id; } // Ensures that the dynamic meta specification on obj is valid bool QQmlCompiler::checkDynamicMeta(QQmlScript::Object *obj) { + if (output->types[obj->type].isFullyDynamicType) { + if (!obj->dynamicProperties.isEmpty()) + COMPILE_EXCEPTION(obj, tr("Fully dynamic types cannot declare new properties.")); + if (!obj->dynamicSignals.isEmpty()) + COMPILE_EXCEPTION(obj, tr("Fully dynamic types cannot declare new signals.")); + if (!obj->dynamicSlots.isEmpty()) + COMPILE_EXCEPTION(obj, tr("Fully Dynamic types cannot declare new functions.")); + } + bool seenDefaultProperty = false; // We use a coarse grain, 31 bit hash to check if there are duplicates. @@ -3644,11 +3687,14 @@ bool QQmlCompiler::completeComponentBuild() } ComponentCompileState::PerObjectCompileData *cd = &compileState->jsCompileData[b->bindingContext.object]; - cd->functionsToCompile.append(node); + QtQml::CompiledFunctionOrExpression f; + f.node = node; + f.name = binding.property->name().toString().prepend(QStringLiteral("expression for ")); + f.disableAcceleratedLookups = binding.disableLookupAcceleration; + cd->functionsToCompile.append(f); binding.compiledIndex = cd->functionsToCompile.count() - 1; - cd->expressionNames.insert(binding.compiledIndex, binding.property->name().toString().prepend(QStringLiteral("expression for "))); - if (componentStats) + if (componentStats && b->value) componentStats->componentStat.scriptBindings.append(b->value->location); } @@ -3656,7 +3702,7 @@ bool QQmlCompiler::completeComponentBuild() const QString &sourceCode = jsEngine->code(); AST::UiProgram *qmlRoot = parser.qmlRoot(); - JSCodeGen jsCodeGen(enginePrivate, unit->finalUrlString(), sourceCode, jsModule.data(), jsEngine, qmlRoot, output->importCache); + JSCodeGen jsCodeGen(unit->finalUrlString(), sourceCode, jsModule.data(), jsEngine, qmlRoot, output->importCache); JSCodeGen::ObjectIdMapping idMapping; if (compileState->ids.count() > 0) { @@ -3679,7 +3725,7 @@ bool QQmlCompiler::completeComponentBuild() jsCodeGen.beginObjectScope(scopeObject->metatype); - cd->runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(cd->functionsToCompile, cd->expressionNames); + cd->runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(cd->functionsToCompile); QList<QQmlError> errors = jsCodeGen.errors(); if (!errors.isEmpty()) { exceptions << errors; @@ -3697,6 +3743,10 @@ bool QQmlCompiler::completeComponentBuild() for (JSBindingReference *b = compileState->bindings.first(); b; b = b->nextReference) { JSBindingReference &binding = *b; binding.compiledIndex = compileState->jsCompileData[binding.bindingContext.object].runtimeFunctionIndices[binding.compiledIndex]; + if (!binding.value) { // Must be a binding requested from custom parser + Q_ASSERT(binding.customParserBindingsIndex >= 0 && binding.customParserBindingsIndex < output->customParserBindings.count()); + output->customParserBindings[binding.customParserBindingsIndex] = binding.compiledIndex; + } } } diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 3ca4566e41..516f6653ca 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -62,6 +62,7 @@ #include "qqmlpropertycache_p.h" #include "qqmltypenamecache_p.h" #include "qqmltypeloader_p.h" +#include <private/qqmlcodegenerator_p.h> #include "private/qv4identifier_p.h" #include <private/qqmljsastfwd_p.h> @@ -105,6 +106,7 @@ public: : type(0), typePropertyCache(0), component(0) , majorVersion(0) , minorVersion(0) + , isFullyDynamicType(false) {} QQmlType *type; @@ -113,9 +115,14 @@ public: int majorVersion; int minorVersion; + // Types such as QQmlPropertyMap can add properties dynamically at run-time and + // therefore cannot have a property cache installed when instantiated. + bool isFullyDynamicType; QQmlPropertyCache *propertyCache() const; QQmlPropertyCache *createPropertyCache(QQmlEngine *); + + void doDynamicTypeCheck(); }; // --- old compiler: QList<TypeReference> types; @@ -150,6 +157,7 @@ public: // index in first hash is component index, hash inside maps from object index in that scope to integer id QHash<int, QHash<int, int> > objectIndexToIdPerComponent; QHash<int, int> objectIndexToIdForRoot; + QVector<int> customParserBindings; // index is binding identifier, value is compiled function index. bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); } bool isCompositeType() const { return !datas.at(qmlUnit->indexOfRootObject).isEmpty(); } @@ -169,7 +177,7 @@ public: int addInstruction(const QQmlInstructionData<Instr> &data) { QQmlInstruction genericInstr; - QQmlInstructionMeta<Instr>::setData(genericInstr, data); + QQmlInstructionMeta<Instr>::setDataNoCommon(genericInstr, data); return addInstructionHelper(static_cast<QQmlInstruction::Type>(Instr), genericInstr); } int nextInstructionIndex(); @@ -224,14 +232,15 @@ namespace QQmlCompilerTypes { struct JSBindingReference : public QQmlPool::Class, public BindingReference { - JSBindingReference() : nextReference(0) {} + JSBindingReference() : disableLookupAcceleration(false), nextReference(0) {} QQmlScript::Variant expression; QQmlScript::Property *property; QQmlScript::Value *value; int compiledIndex : 16; - int sharedIndex : 16; + int customParserBindingsIndex : 15; + int disableLookupAcceleration: 1; BindingContext bindingContext; @@ -312,10 +321,9 @@ namespace QQmlCompilerTypes { QList<CompiledMetaMethod> compiledMetaMethods; struct PerObjectCompileData { - QList<QQmlJS::AST::Node*> functionsToCompile; + QList<QtQml::CompiledFunctionOrExpression> functionsToCompile; QVector<int> runtimeFunctionIndices; QVector<CompiledMetaMethod> compiledMetaMethods; - QHash<int, QString> expressionNames; }; QHash<QQmlScript::Object *, PerObjectCompileData> jsCompileData; }; @@ -340,7 +348,7 @@ public: int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const; // for QQmlCustomParser::evaluateEnum const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType - int bindingIdentifier(const QQmlScript::Variant& value); // for QQmlCustomParser::bindingIndex + int bindingIdentifier(const QString &name, const QQmlScript::Variant& value, const QQmlCompilerTypes::BindingContext &ctxt); // for QQmlCustomParser::bindingIndex private: typedef QQmlCompiledData::Instruction Instruction; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 2973944215..4a71c1a7e0 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -52,7 +52,6 @@ #include "qqmlbinding_p.h" #include "qqmlglobal_p.h" #include "qqmlscript_p.h" -#include <private/qqmlprofilerservice_p.h> #include <private/qqmlenginedebugservice_p.h> #include "qqmlincubator.h" #include "qqmlincubator_p.h" @@ -884,11 +883,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); - if (enginePriv->inProgressCreations == 0) { - // only track root, since further ones might not be properly nested - profiler = new QQmlObjectCreatingProfiler(); - } - enginePriv->inProgressCreations++; state.errors.clear(); state.completePending = true; @@ -924,13 +918,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) if (!context->isInternal) context->asQQmlContextPrivate()->instances.append(rv); QQmlEngineDebugService::instance()->objectCreated(engine, rv); - - if (profiler && profiler->enabled) { - profiler->setTypeName(buildTypeNameForDebug(rv->metaObject())); - QQmlData *data = QQmlData::get(rv); - Q_ASSERT(data); - profiler->setLocation(cc->url, data->lineNumber, data->columnNumber); - } } return rv; @@ -995,9 +982,6 @@ void QQmlComponentPrivate::completeCreate() if (state.completePending) { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); complete(ep, &state); - - delete profiler; - profiler = 0; } if (depthIncreased) { @@ -1507,7 +1491,7 @@ QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::Incubat { incubator.reset(new QQmlComponentIncubator(this, m)); v8 = engine; - vtbl = &static_vtbl; + setVTable(&static_vtbl); valuemap = QV4::Primitive::undefinedValue(); qmlGlobal = QV4::Primitive::undefinedValue(); @@ -1562,7 +1546,7 @@ void QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) QV4::ScopedFunctionObject f(scope, m_statusChanged); if (f) { - QV4::ExecutionContext *ctx = scope.engine->current; + QV4::ExecutionContext *ctx = scope.engine->currentContext(); QV4::ScopedCallData callData(scope, 1); callData->thisObject = this; callData->args[0] = QV4::Primitive::fromUInt32(s); diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index d9a2427cd5..8bf4005dd6 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -61,7 +61,6 @@ #include "qqmlvme_p.h" #include "qqmlerror.h" #include "qqml.h" -#include <private/qqmlprofilerservice_p.h> #include <private/qqmlobjectcreator_p.h> #include <QtCore/QString> @@ -85,7 +84,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public public: QQmlComponentPrivate() - : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), profiler(0), depthIncreased(false) {} + : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), depthIncreased(false) {} void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous); @@ -131,7 +130,6 @@ public: QQmlEngine *engine; QQmlGuardedContextData creationContext; - QQmlObjectCreatingProfiler *profiler; bool depthIncreased; void clear(); diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 406826a6f6..b3c2105e68 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -53,6 +53,7 @@ #include <private/qv4compileddata_p.h> #include <private/qqmltypewrapper_p.h> #include <private/qqmllistwrapper_p.h> +#include <private/qjsvalue_p.h> QT_BEGIN_NAMESPACE @@ -63,9 +64,9 @@ DEFINE_MANAGED_VTABLE(QmlContextWrapper); QmlContextWrapper::QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext) : Object(QV8Engine::getV4(engine)), v8(engine), readOnly(true), ownsContext(ownsContext), isNullWrapper(false), - context(context), scopeObject(scopeObject) + context(context), scopeObject(scopeObject), idObjectsWrapper(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlContextWrapper::~QmlContextWrapper() @@ -136,7 +137,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, const StringRef name, bool *has QV4::Scope scope(v4); QmlContextWrapper *resource = m->as<QmlContextWrapper>(); if (!resource) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); // In V8 the JS global object would come _before_ the QML global object, // so simulate that here. @@ -245,7 +246,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, const StringRef name, bool *has // Search scope object if (scopeObject) { bool hasProp = false; - QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject, + QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4->currentContext(), context, scopeObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, &hasProp)); if (hasProp) { if (hasProperty) @@ -259,7 +260,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, const StringRef name, bool *has // Search context object if (context->contextObject) { bool hasProp = false; - result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, context->contextObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, &hasProp); + result = QV4::QObjectWrapper::getQmlProperty(v4->currentContext(), context, context->contextObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, &hasProp); if (hasProp) { if (hasProperty) *hasProperty = true; @@ -283,7 +284,7 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val return; QV4::Scoped<QmlContextWrapper> wrapper(scope, m->as<QmlContextWrapper>()); if (!wrapper) { - v4->current->throwTypeError(); + v4->currentContext()->throwTypeError(); return; } @@ -291,8 +292,8 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val if (wrapper && wrapper->readOnly) { QString error = QLatin1String("Invalid write to global property \"") + name->toQString() + QLatin1Char('"'); - Scoped<String> e(scope, v4->current->engine->newString(error)); - v4->current->throwError(e); + Scoped<String> e(scope, v4->currentContext()->engine->newString(error)); + v4->currentContext()->throwError(e); return; } @@ -326,13 +327,13 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val // Search scope object if (scopeObject && - QV4::QObjectWrapper::setQmlProperty(v4->current, context, scopeObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, value)) + QV4::QObjectWrapper::setQmlProperty(v4->currentContext(), context, scopeObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, value)) return; scopeObject = 0; // Search context object if (context->contextObject && - QV4::QObjectWrapper::setQmlProperty(v4->current, context, context->contextObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, value)) + QV4::QObjectWrapper::setQmlProperty(v4->currentContext(), context, context->contextObject, name.getPointer(), QV4::QObjectWrapper::CheckRevision, value)) return; context = context->parent; @@ -343,7 +344,7 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val if (wrapper->readOnly) { QString error = QLatin1String("Invalid write to global property \"") + name->toQString() + QLatin1Char('"'); - v4->current->throwError(error); + v4->currentContext()->throwError(error); return; } @@ -355,6 +356,14 @@ void QmlContextWrapper::destroy(Managed *that) static_cast<QmlContextWrapper *>(that)->~QmlContextWrapper(); } +void QmlContextWrapper::markObjects(Managed *m, ExecutionEngine *engine) +{ + QmlContextWrapper *This = static_cast<QmlContextWrapper*>(m); + if (This->idObjectsWrapper) + This->idObjectsWrapper->mark(engine); + Object::markObjects(m, engine); +} + void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const CompiledData::Function *compiledFunction) { // Let the caller check and avoid the function call :) @@ -395,4 +404,72 @@ void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const C } +ReturnedValue QmlContextWrapper::idObjectsArray() +{ + if (!idObjectsWrapper) { + ExecutionEngine *v4 = engine(); + idObjectsWrapper = new (v4->memoryManager) QQmlIdObjectsArray(v4, this); + } + return idObjectsWrapper->asReturnedValue(); +} + +ReturnedValue QmlContextWrapper::qmlSingletonWrapper(const StringRef &name) +{ + if (!context->imports) + return Encode::undefined(); + // Search for attached properties, enums and imported scripts + QQmlTypeNameCache::Result r = context->imports->query(name); + + Q_ASSERT(r.isValid()); + Q_ASSERT(r.type); + Q_ASSERT(r.type->isSingleton()); + + QQmlEngine *e = v8->engine(); + QQmlType::SingletonInstanceInfo *siinfo = r.type->singletonInstanceInfo(); + siinfo->init(e); + + if (QObject *qobjectSingleton = siinfo->qobjectApi(e)) + return QV4::QObjectWrapper::wrap(engine(), qobjectSingleton); + return QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine()); +} + +DEFINE_MANAGED_VTABLE(QQmlIdObjectsArray); + +QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper) + : Object(engine) + , contextWrapper(contextWrapper) +{ + setVTable(&static_vtbl); +} + +ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasProperty) +{ + QQmlIdObjectsArray *This = static_cast<QQmlIdObjectsArray*>(m); + QQmlContextData *context = This->contextWrapper->getContext(); + if (!context) { + if (hasProperty) + *hasProperty = false; + return Encode::undefined(); + } + if (index >= (uint)context->idValueCount) { + if (hasProperty) + *hasProperty = false; + return Encode::undefined(); + } + + ExecutionEngine *v4 = m->engine(); + QQmlEnginePrivate *ep = v4->v8Engine->engine() ? QQmlEnginePrivate::get(v4->v8Engine->engine()) : 0; + if (ep) + ep->captureProperty(&context->idValues[index].bindings); + + return QObjectWrapper::wrap(This->engine(), context->idValues[index].data()); +} + +void QQmlIdObjectsArray::markObjects(Managed *that, ExecutionEngine *engine) +{ + QQmlIdObjectsArray *This = static_cast<QQmlIdObjectsArray*>(that); + This->contextWrapper->mark(engine); + Object::markObjects(that, engine); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h index d85f440b15..89ace7090c 100644 --- a/src/qml/qml/qqmlcontextwrapper_p.h +++ b/src/qml/qml/qqmlcontextwrapper_p.h @@ -69,6 +69,8 @@ namespace CompiledData { struct Function; } +struct QQmlIdObjectsArray; + struct Q_QML_EXPORT QmlContextWrapper : Object { Q_MANAGED @@ -90,9 +92,12 @@ struct Q_QML_EXPORT QmlContextWrapper : Object static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty); static void put(Managed *m, const StringRef name, const ValueRef value); static void destroy(Managed *that); + static void markObjects(Managed *m, ExecutionEngine *engine); static void registerQmlDependencies(ExecutionEngine *context, const CompiledData::Function *compiledFunction); + ReturnedValue idObjectsArray(); + ReturnedValue qmlSingletonWrapper(const StringRef &name); QV8Engine *v8; // ### temporary, remove bool readOnly; @@ -101,6 +106,19 @@ struct Q_QML_EXPORT QmlContextWrapper : Object QQmlGuardedContextData context; QPointer<QObject> scopeObject; +private: + QQmlIdObjectsArray *idObjectsWrapper; +}; + +struct QQmlIdObjectsArray : public Object +{ + Q_MANAGED + QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper); + + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); + static void markObjects(Managed *that, ExecutionEngine *engine); + + QmlContextWrapper *contextWrapper; }; } diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index eba2e14e51..19e49009ce 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -313,8 +313,7 @@ const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const */ QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QQmlScript::Variant &value, const QString& name) { - Q_UNUSED(name); - return compiler->bindingIdentifier(value); + return compiler->bindingIdentifier(name, value, QQmlCompilerTypes::BindingContext(object)); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 621b3d3c2e..982156ea15 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE template <class Key, class T> class QHash; +class QQmlEngine; class QQmlGuardImpl; class QQmlCompiledData; class QQmlAbstractBinding; @@ -222,6 +223,8 @@ public: static inline void flushPendingBinding(QObject *, int coreIndex); + static void ensurePropertyCache(QQmlEngine *engine, QObject *object); + private: // For attachedProperties mutable QQmlDataExtended *extendedData; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 1320f51d25..f8e5ad5874 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -101,6 +101,9 @@ #ifdef Q_OS_WIN // for %APPDATA% #include <qt_windows.h> +# if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +# include <shlobj.h> +# endif #include <qlibrary.h> #include <windows.h> @@ -556,7 +559,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e) workerScriptEngine(0), activeVME(0), activeObjectCreator(0), networkAccessManager(0), networkAccessManagerFactory(0), urlInterceptor(0), - scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1), + scarceResourcesRefCount(0), importDatabase(e), typeLoader(e), uniqueId(1), incubatorCount(0), incubationController(0), mutex(QMutex::Recursive) { useNewCompiler = qmlUseNewCompiler(); @@ -1339,14 +1342,6 @@ void qmlExecuteDeferred(QObject *object) QQmlData *data = QQmlData::get(object); if (data && data->deferredData && !data->wasDeleted(object)) { - QQmlObjectCreatingProfiler prof; - if (prof.enabled) { - QQmlType *type = QQmlMetaType::qmlType(object->metaObject()); - prof.setTypeName(type ? type->qmlTypeName() - : QString::fromUtf8(object->metaObject()->className())); - if (data->outerContext) - prof.setLocation(data->outerContext->url, data->lineNumber, data->columnNumber); - } QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine); QQmlComponentPrivate::ConstructionState state; @@ -1734,6 +1729,16 @@ void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex) QQmlData_setBit(this, obj, coreIndex * 2 + 1); } +void QQmlData::ensurePropertyCache(QQmlEngine *engine, QObject *object) +{ + Q_ASSERT(engine); + QQmlData *ddata = QQmlData::get(object, /*create*/true); + if (ddata->propertyCache) + return; + ddata->propertyCache = QQmlEnginePrivate::get(engine)->cache(object); + if (ddata->propertyCache) ddata->propertyCache->addref(); +} + void QQmlEnginePrivate::sendQuit() { Q_Q(QQmlEngine); @@ -2283,6 +2288,28 @@ bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const return typeLoader.isScriptLoaded(url); } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +// Normalize a file name using Shell API. As opposed to converting it +// to a short 8.3 name and back, this also works for drives where 8.3 notation +// is disabled (see 8dot3name options of fsutil.exe). +static inline QString shellNormalizeFileName(const QString &name) +{ + const QString nativeSeparatorName(QDir::toNativeSeparators(name)); + const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(nativeSeparatorName.utf16()); + PIDLIST_ABSOLUTE file; + if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL))) + return name; + TCHAR buffer[MAX_PATH]; + if (!SHGetPathFromIDList(file, buffer)) + return name; + QString canonicalName = QString::fromWCharArray(buffer); + // Upper case drive letter + if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':')) + canonicalName[0] = canonicalName.at(0).toUpper(); + return QDir::cleanPath(canonicalName); +} +#endif // Q_OS_WIN && !Q_OS_WINCE && !Q_OS_WINRT + bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) { #if defined(Q_OS_MAC) || defined(Q_OS_WIN) @@ -2292,14 +2319,7 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) #if defined(Q_OS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT) const QString canonical = info.canonicalFilePath(); #elif defined(Q_OS_WIN) - wchar_t buffer[1024]; - - DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024); - if (rv == 0 || rv >= 1024) return true; - rv = ::GetLongPathName(buffer, buffer, 1024); - if (rv == 0 || rv >= 1024) return true; - - const QString canonical = QString::fromWCharArray(buffer); + const QString canonical = shellNormalizeFileName(absolute); #endif const int absoluteLength = absolute.length(); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 5a2d6c4e00..19eb320fbe 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -186,8 +186,8 @@ public: void referenceScarceResources(); void dereferenceScarceResources(); - QQmlTypeLoader typeLoader; QQmlImportDatabase importDatabase; + QQmlTypeLoader typeLoader; QString offlineStoragePath; @@ -257,6 +257,7 @@ public: inline static QQmlEnginePrivate *get(QQmlContext *c); inline static QQmlEnginePrivate *get(QQmlContextData *c); inline static QQmlEngine *get(QQmlEnginePrivate *p); + inline static QQmlEnginePrivate *get(QV4::ExecutionEngine *e); static void registerBaseTypes(const char *uri, int versionMajor, int versionMinor); static void registerQtQuick2Types(const char *uri, int versionMajor, int versionMinor); @@ -516,7 +517,17 @@ QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p) { Q_ASSERT(p); - return p->q_func(); + return p->q_func(); +} + +QQmlEnginePrivate *QQmlEnginePrivate::get(QV4::ExecutionEngine *e) +{ + if (!e->v8Engine) + return 0; + QQmlEngine *qmlEngine = e->v8Engine->engine(); + if (!qmlEngine) + return 0; + return get(qmlEngine); } void QQmlEnginePrivate::captureProperty(QQmlNotifier *n) diff --git a/src/qml/qml/qqmlinstruction_p.h b/src/qml/qml/qqmlinstruction_p.h index 150ee8df19..bda8c3db0d 100644 --- a/src/qml/qml/qqmlinstruction_p.h +++ b/src/qml/qml/qqmlinstruction_p.h @@ -536,7 +536,11 @@ struct QQmlInstructionMeta { typedef QQmlInstruction::instr_##FMT DataType; \ static const DataType &data(const QQmlInstruction &instr) { return instr.FMT; } \ static void setData(QQmlInstruction &instr, const DataType &v) { memcpy(&instr.FMT, &v, Size); } \ - }; + static void setDataNoCommon(QQmlInstruction &instr, const DataType &v) \ + { memcpy(reinterpret_cast<char *>(&instr.FMT) + sizeof(QQmlInstruction::instr_common), \ + reinterpret_cast<const char *>(&v) + sizeof(QQmlInstruction::instr_common), \ + Size - sizeof(QQmlInstruction::instr_common)); } \ + }; FOR_EACH_QML_INSTR(QML_INSTR_META_TEMPLATE); #undef QML_INSTR_META_TEMPLATE diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 3fd0003656..499ade1ca5 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -155,7 +155,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); QV4::Scope scope(v4); QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue()); - QV4::ExecutionContext *ctx = v4->current; + QV4::ExecutionContext *ctx = v4->currentContext(); callData->thisObject = v4->globalObject; if (scopeObject()) { QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->engine, scopeObject())); @@ -294,7 +294,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); - QV4::ExecutionContext *ctx = v4->current; + QV4::ExecutionContext *ctx = v4->currentContext(); QV4::Scope scope(v4); QV4::ScopedObject qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scopeObject)); @@ -328,7 +328,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, Q QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); - QV4::ExecutionContext *ctx = v4->current; + QV4::ExecutionContext *ctx = v4->currentContext(); QV4::Scope scope(v4); QV4::ScopedObject qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, qmlScope)); diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 73dc3192aa..7b975c2cc8 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -56,7 +56,7 @@ QmlListWrapper::QmlListWrapper(QV8Engine *engine) : Object(QV8Engine::getV4(engine)), v8(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); flags &= ~SimpleArray; } @@ -106,7 +106,7 @@ ReturnedValue QmlListWrapper::get(Managed *m, const StringRef name, bool *hasPro QV4::ExecutionEngine *v4 = m->engine(); QmlListWrapper *w = m->as<QmlListWrapper>(); if (!w) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); if (name->equals(v4->id_length) && !w->object.isNull()) { quint32 count = w->property.count ? w->property.count(&w->property) : 0; @@ -127,7 +127,7 @@ ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProper QV4::ExecutionEngine *e = m->engine(); QmlListWrapper *w = m->as<QmlListWrapper>(); if (!w) - return e->current->throwTypeError(); + return e->currentContext()->throwTypeError(); quint32 count = w->property.count ? w->property.count(&w->property) : 0; if (index < count && w->property.at) diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 5e8130f407..36e0da5b60 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -61,7 +61,7 @@ public: QQmlLocaleData(QV4::ExecutionEngine *engine) : QV4::Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_Object; } @@ -872,7 +872,7 @@ QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &locale void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) { - engine->stringClass->prototype->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare); + engine->stringObjectClass->prototype->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare); } QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx) diff --git a/src/qml/qml/qqmlmemoryprofiler.cpp b/src/qml/qml/qqmlmemoryprofiler.cpp index e7b6653532..d93276fc17 100644 --- a/src/qml/qml/qqmlmemoryprofiler.cpp +++ b/src/qml/qml/qqmlmemoryprofiler.cpp @@ -100,8 +100,7 @@ static bool openLibrary() QQmlMemoryScope::QQmlMemoryScope(const QUrl &url) : pushed(false) { if (openLibrary() && memprofile_is_enabled()) { - const char *location = url.path().toUtf8().constData(); - memprofile_push_location(location, 0); + memprofile_push_location(url.path().toUtf8().constData(), 0); pushed = true; } } diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 342d1dc69c..ed0c0afd6f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -225,17 +225,21 @@ public: void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(e->handle()); - v4->pushGlobalContext(); if (scriptCallback && scriptApi(e).isUndefined()) { + v4->pushGlobalContext(); setScriptApi(e, scriptCallback(e, e)); + v4->popContext(); } else if (qobjectCallback && !qobjectApi(e)) { + v4->pushGlobalContext(); setQObjectApi(e, qobjectCallback(e, e)); + v4->popContext(); } else if (!url.isEmpty() && !qobjectApi(e)) { + v4->pushGlobalContext(); QQmlComponent component(e, url, QQmlComponent::PreferSynchronous); QObject *o = component.create(); setQObjectApi(e, o); + v4->popContext(); } - v4->popContext(); } void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 85d2fe41d9..6eda55e35b 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2371,13 +2371,12 @@ void QQmlTypeData::compile() // Compile JS binding expressions and signal handlers - JSCodeGen jsCodeGen(enginePrivate, finalUrlString(), parsedQML->code, &parsedQML->jsModule, &parsedQML->jsParserEngine, parsedQML->program, m_compiledData->importCache); - QHash<int, QString> expressionNames; // ### TODO - const QVector<int> runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(parsedQML->functions, expressionNames); + JSCodeGen jsCodeGen(finalUrlString(), parsedQML->code, &parsedQML->jsModule, &parsedQML->jsParserEngine, parsedQML->program, m_compiledData->importCache); + const QVector<int> runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(parsedQML->functions); QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine()); - QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(v4->executableAllocator, &parsedQML->jsModule, &parsedQML->jsGenerator)); + QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(enginePrivate, v4->executableAllocator, &parsedQML->jsModule, &parsedQML->jsGenerator)); isel->setUseFastLookups(false); QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/false); @@ -2806,7 +2805,7 @@ QV4::PersistentValue QQmlScriptData::scriptValueForContext(QQmlContextData *pare QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0)); QV4::QmlContextWrapper::takeContextOwnership(qmlglobal); - QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current; + QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->currentContext(); m_program->qml = qmlglobal; m_program->run(); if (scope.engine->hasException) { diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 258442bc1d..9c350a54a5 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -60,7 +60,7 @@ QmlTypeWrapper::QmlTypeWrapper(QV8Engine *engine) : Object(QV8Engine::getV4(engine)), v8(engine), mode(IncludeEnums), type(0), typeNamespace(0), importNamespace(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlTypeWrapper::~QmlTypeWrapper() @@ -126,7 +126,7 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, const StringRef name, bool *hasPro Scoped<QmlTypeWrapper> w(scope, m->as<QmlTypeWrapper>()); if (!w) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); if (hasProperty) @@ -165,7 +165,7 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, const StringRef name, bool *hasPro } // check for property. - return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, hasProperty); + return QV4::QObjectWrapper::getQmlProperty(v4->currentContext(), context, qobjectSingleton, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, hasProperty); } else if (!siinfo->scriptApi(e).isUndefined()) { // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. QV4::ScopedObject o(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(v4)); @@ -188,7 +188,7 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, const StringRef name, bool *hasPro } else if (w->object) { QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) - return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, hasProperty); + return QV4::QObjectWrapper::getQmlProperty(v4->currentContext(), context, ao, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, hasProperty); // Fall through to base implementation } @@ -236,7 +236,7 @@ void QmlTypeWrapper::put(Managed *m, const StringRef name, const ValueRef value) if (v4->hasException) return; if (!w) { - v4->current->throwTypeError(); + v4->currentContext()->throwTypeError(); return; } @@ -249,7 +249,7 @@ void QmlTypeWrapper::put(Managed *m, const StringRef name, const ValueRef value) QObject *object = w->object; QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) - QV4::QObjectWrapper::setQmlProperty(v4->current, context, ao, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value); + QV4::QObjectWrapper::setQmlProperty(v4->currentContext(), context, ao, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value); } else if (type && type->isSingleton()) { QQmlEngine *e = v8engine->engine(); QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); @@ -257,12 +257,12 @@ void QmlTypeWrapper::put(Managed *m, const StringRef name, const ValueRef value) QObject *qobjectSingleton = siinfo->qobjectApi(e); if (qobjectSingleton) { - QV4::QObjectWrapper::setQmlProperty(v4->current, context, qobjectSingleton, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value); + QV4::QObjectWrapper::setQmlProperty(v4->currentContext(), context, qobjectSingleton, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value); } else if (!siinfo->scriptApi(e).isUndefined()) { QV4::ScopedObject apiprivate(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->value); if (!apiprivate) { QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"'); - v4->current->throwError(error); + v4->currentContext()->throwError(error); return; } else { apiprivate->put(name, value); diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index c55b86b55a..bd44dfb0cf 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -169,8 +169,8 @@ public: class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueTypeBase<QPointF> { - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal x READ x WRITE setX FINAL) + Q_PROPERTY(qreal y READ y WRITE setY FINAL) Q_OBJECT public: QQmlPointFValueType(QObject *parent = 0); @@ -185,8 +185,8 @@ public: class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueTypeBase<QPoint> { - Q_PROPERTY(int x READ x WRITE setX) - Q_PROPERTY(int y READ y WRITE setY) + Q_PROPERTY(int x READ x WRITE setX FINAL) + Q_PROPERTY(int y READ y WRITE setY FINAL) Q_OBJECT public: QQmlPointValueType(QObject *parent = 0); @@ -201,8 +201,8 @@ public: class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueTypeBase<QSizeF> { - Q_PROPERTY(qreal width READ width WRITE setWidth) - Q_PROPERTY(qreal height READ height WRITE setHeight) + Q_PROPERTY(qreal width READ width WRITE setWidth FINAL) + Q_PROPERTY(qreal height READ height WRITE setHeight FINAL) Q_OBJECT public: QQmlSizeFValueType(QObject *parent = 0); @@ -217,8 +217,8 @@ public: class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueTypeBase<QSize> { - Q_PROPERTY(int width READ width WRITE setWidth) - Q_PROPERTY(int height READ height WRITE setHeight) + Q_PROPERTY(int width READ width WRITE setWidth FINAL) + Q_PROPERTY(int height READ height WRITE setHeight FINAL) Q_OBJECT public: QQmlSizeValueType(QObject *parent = 0); @@ -233,10 +233,10 @@ public: class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueTypeBase<QRectF> { - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) - Q_PROPERTY(qreal width READ width WRITE setWidth) - Q_PROPERTY(qreal height READ height WRITE setHeight) + Q_PROPERTY(qreal x READ x WRITE setX FINAL) + Q_PROPERTY(qreal y READ y WRITE setY FINAL) + Q_PROPERTY(qreal width READ width WRITE setWidth FINAL) + Q_PROPERTY(qreal height READ height WRITE setHeight FINAL) Q_OBJECT public: QQmlRectFValueType(QObject *parent = 0); @@ -256,10 +256,10 @@ public: class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueTypeBase<QRect> { - Q_PROPERTY(int x READ x WRITE setX) - Q_PROPERTY(int y READ y WRITE setY) - Q_PROPERTY(int width READ width WRITE setWidth) - Q_PROPERTY(int height READ height WRITE setHeight) + Q_PROPERTY(int x READ x WRITE setX FINAL) + Q_PROPERTY(int y READ y WRITE setY FINAL) + Q_PROPERTY(int width READ width WRITE setWidth FINAL) + Q_PROPERTY(int height READ height WRITE setHeight FINAL) Q_OBJECT public: QQmlRectValueType(QObject *parent = 0); @@ -282,11 +282,11 @@ class Q_QML_PRIVATE_EXPORT QQmlEasingValueType : public QQmlValueTypeBase<QEasin Q_OBJECT Q_ENUMS(Type) - Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType) - Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude) - Q_PROPERTY(qreal overshoot READ overshoot WRITE setOvershoot) - Q_PROPERTY(qreal period READ period WRITE setPeriod) - Q_PROPERTY(QVariantList bezierCurve READ bezierCurve WRITE setBezierCurve) + Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL) + Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude FINAL) + Q_PROPERTY(qreal overshoot READ overshoot WRITE setOvershoot FINAL) + Q_PROPERTY(qreal period READ period WRITE setPeriod FINAL) + Q_PROPERTY(QVariantList bezierCurve READ bezierCurve WRITE setBezierCurve FINAL) public: enum Type { Linear = QEasingCurve::Linear, diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index d733694923..50d7cbcc5e 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -79,7 +79,7 @@ QmlValueTypeWrapper::QmlValueTypeWrapper(QV8Engine *engine, ObjectType objectTyp : Object(QV8Engine::getV4(engine)), objectType(objectType) { v8 = engine; - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlValueTypeWrapper::~QmlValueTypeWrapper() @@ -209,7 +209,7 @@ PropertyAttributes QmlValueTypeWrapper::query(const Managed *m, StringRef name) const QmlValueTypeWrapper *r = m->as<const QmlValueTypeWrapper>(); QV4::ExecutionEngine *v4 = m->engine(); if (!r) { - v4->current->throwTypeError(); + v4->currentContext()->throwTypeError(); return PropertyAttributes(); } @@ -273,7 +273,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, const StringRef name, bool *h QmlValueTypeWrapper *r = m->as<QmlValueTypeWrapper>(); QV4::ExecutionEngine *v4 = m->engine(); if (!r) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); // Note: readReferenceValue() can change the reference->type. if (r->objectType == QmlValueTypeWrapper::Reference) { @@ -306,7 +306,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, const StringRef name, bool *h if (result->isFunction()) { // calling a Q_INVOKABLE function of a value type QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); - return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision); + return QV4::QObjectWrapper::getQmlProperty(v4->currentContext(), qmlContext, r->type, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision); } #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ @@ -339,7 +339,7 @@ void QmlValueTypeWrapper::put(Managed *m, const StringRef name, const ValueRef v Scoped<QmlValueTypeWrapper> r(scope, m->as<QmlValueTypeWrapper>()); if (!r) { - v4->current->throwTypeError(); + v4->currentContext()->throwTypeError(); return; } @@ -365,7 +365,7 @@ void QmlValueTypeWrapper::put(Managed *m, const StringRef name, const ValueRef v // assigning a JS function to a non-var-property is not allowed. QString error = QLatin1String("Cannot assign JavaScript function to value-type property"); Scoped<String> e(scope, r->v8->toString(error)); - v4->current->throwError(e); + v4->currentContext()->throwError(e); return; } diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 983136a846..ad1e9d862e 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -503,6 +503,12 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type); Q_ASSERT(type.component); + if (profiler.enabled) { + profiler.start(); + profiler.updateTypeName(type.component->name); + profiler.background(); + } + states.push(State()); State *cState = &states[states.count() - 2]; @@ -524,6 +530,11 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_END_INSTR(CreateQMLObject) QML_BEGIN_INSTR(CompleteQMLObject) + if (profiler.enabled) { + profiler.foreground(); + profiler.updateLocation(CTXT->url, instr.line, instr.column); + } + QObject *o = objects.top(); Q_ASSERT(o); @@ -566,6 +577,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_BEGIN_INSTR(CreateCppObject) const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type); Q_ASSERT(type.type); + if (profiler.enabled) + profiler.start(CTXT->url, instr.line, instr.column, type.type->qmlTypeName()); QObject *o = 0; void *memory = 0; @@ -637,12 +650,14 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_END_INSTR(CreateCppObject) QML_BEGIN_INSTR(CreateSimpleObject) + const QQmlCompiledData::TypeReference &ref = TYPES.at(instr.type); + if (profiler.enabled) + profiler.start(CTXT->url, instr.line, instr.column, ref.type->qmlTypeName()); QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QQmlData)); ::memset(static_cast<void *>(o), 0, instr.typeSize + sizeof(QQmlData)); instr.create(o); QQmlData *ddata = (QQmlData *)(((const char *)o) + instr.typeSize); - const QQmlCompiledData::TypeReference &ref = TYPES.at(instr.type); if (!ddata->propertyCache && ref.typePropertyCache) { ddata->propertyCache = ref.typePropertyCache; ddata->propertyCache->addref(); @@ -817,6 +832,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_END_INSTR(StoreScriptString) QML_BEGIN_INSTR(BeginObject) + if (profiler.enabled) + profiler.push(); QObject *target = objects.top(); QQmlParserStatus *status = reinterpret_cast<QQmlParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue); parserStatus.push(status); @@ -1074,6 +1091,8 @@ normalExit: objects.deallocate(); lists.deallocate(); states.clear(); + if (profiler.enabled) + profiler.stop(); return rv; } @@ -1111,6 +1130,8 @@ void QQmlVME::reset() states.clear(); rootContext = 0; creationContext = 0; + if (profiler.enabled) + profiler.clear(); } #ifdef QML_THREADED_VME_INTERPRETER @@ -1170,6 +1191,8 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt) if (componentCompleteEnabled()) { // the qml designer does the component complete later QQmlTrace trace("VME Component Complete"); while (!parserStatus.isEmpty()) { + if (profiler.enabled) + profiler.pop(); QQmlParserStatus *status = parserStatus.pop(); #ifdef QML_ENABLE_TRACE QQmlData *data = parserStatusData.pop(); @@ -1189,6 +1212,8 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt) return 0; } parserStatus.deallocate(); + if (profiler.enabled) + profiler.clear(); } { diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h index e76b485a5c..d5afd4c67a 100644 --- a/src/qml/qml/qqmlvme_p.h +++ b/src/qml/qml/qqmlvme_p.h @@ -68,6 +68,7 @@ #include <private/qfinitestack_p.h> #include <private/qqmltrace_p.h> +#include <private/qqmlprofilerservice_p.h> QT_BEGIN_NAMESPACE @@ -171,6 +172,7 @@ private: #ifdef QML_ENABLE_TRACE QFiniteStack<QQmlData *> parserStatusData; #endif + QQmlVmeProfiler profiler; QQmlGuardedContextData rootContext; QQmlGuardedContextData creationContext; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 4b34792421..ebe72b2ff6 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -956,7 +956,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) callData->args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]); QV4::ScopedValue result(scope); - QV4::ExecutionContext *ctx = function->engine()->current; + QV4::ExecutionContext *ctx = function->engine()->currentContext(); result = function->call(callData); if (scope.hasException()) { QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 18e3e33c4b..ad231d0769 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -192,7 +192,7 @@ public: , list(list) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -226,7 +226,7 @@ public: : Object(engine) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -258,7 +258,7 @@ public: NodePrototype(ExecutionEngine *engine) : Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine); ScopedObject protectThis(scope, this); @@ -312,7 +312,7 @@ class Node : public Object : Object(engine) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -906,7 +906,7 @@ ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty QV4::ExecutionEngine *v4 = m->engine(); NamedNodeMap *r = m->as<NamedNodeMap>(); if (!r) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); QV8Engine *engine = v4->v8Engine; @@ -925,7 +925,7 @@ ReturnedValue NamedNodeMap::get(Managed *m, const StringRef name, bool *hasPrope NamedNodeMap *r = m->as<NamedNodeMap>(); QV4::ExecutionEngine *v4 = m->engine(); if (!r) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); name->makeIdentifier(); if (name->equals(v4->id_length)) @@ -961,7 +961,7 @@ ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty) QV4::ExecutionEngine *v4 = m->engine(); NodeList *r = m->as<NodeList>(); if (!r) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); QV8Engine *engine = v4->v8Engine; @@ -980,7 +980,7 @@ ReturnedValue NodeList::get(Managed *m, const StringRef name, bool *hasProperty) QV4::ExecutionEngine *v4 = m->engine(); NodeList *r = m->as<NodeList>(); if (!r) - return v4->current->throwTypeError(); + return v4->currentContext()->throwTypeError(); name->makeIdentifier(); @@ -1535,7 +1535,7 @@ const QByteArray &QQmlXMLHttpRequest::rawResponseBody() const void QQmlXMLHttpRequest::dispatchCallbackImpl(const ValueRef me) { - ExecutionContext *ctx = v4->current; + ExecutionContext *ctx = v4->currentContext(); QV4::Scope scope(v4); Scoped<Object> o(scope, me); if (!o) { @@ -1560,7 +1560,7 @@ void QQmlXMLHttpRequest::dispatchCallbackImpl(const ValueRef me) s = v4->newString(QStringLiteral("ActivationObject")); Scoped<Object> activationObject(scope, o->get(s)); if (!activationObject) { - v4->current->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject")); + v4->currentContext()->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject")); return; } @@ -1580,7 +1580,7 @@ void QQmlXMLHttpRequest::dispatchCallbackImpl(const ValueRef me) void QQmlXMLHttpRequest::dispatchCallback(const ValueRef me) { - ExecutionContext *ctx = v4->current; + ExecutionContext *ctx = v4->currentContext(); dispatchCallbackImpl(me); if (v4->hasException) { QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); @@ -1605,7 +1605,7 @@ struct QQmlXMLHttpRequestWrapper : public Object : Object(engine) , request(request) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ~QQmlXMLHttpRequestWrapper() { delete request; @@ -1626,7 +1626,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject QQmlXMLHttpRequestCtor(ExecutionEngine *engine) : FunctionObject(engine->rootContext, QStringLiteral("XMLHttpRequest")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine); ScopedValue protectThis(scope, this); @@ -1656,7 +1656,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject Scope scope(that->engine()); Scoped<QQmlXMLHttpRequestCtor> ctor(scope, that->as<QQmlXMLHttpRequestCtor>()); if (!ctor) - return that->engine()->current->throwTypeError(); + return that->engine()->currentContext()->throwTypeError(); QV8Engine *engine = that->engine()->v8Engine; QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(engine, engine->networkAccessManager()); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index c80a742af0..41d5de0862 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -90,7 +90,7 @@ QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine) , m_platform(0) , m_application(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(v4); ScopedObject protectThis(scope, this); @@ -1183,7 +1183,7 @@ struct BindingFunction : public QV4::FunctionObject : QV4::FunctionObject(originalFunction->scope, originalFunction->name) , originalFunction(originalFunction) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); bindingKeyFlag = true; } @@ -1608,7 +1608,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject) globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt); // string prototype extension - v4->stringClass->prototype->defineDefaultProperty(QStringLiteral("arg"), method_string_arg); + v4->stringObjectClass->prototype->defineDefaultProperty(QStringLiteral("arg"), method_string_arg); } @@ -1726,7 +1726,9 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx) QString path = ctxt->url.toString(); int lastSlash = path.lastIndexOf(QLatin1Char('/')); - QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString(); + int lastDot = path.lastIndexOf(QLatin1Char('.')); + int length = lastDot - (lastSlash + 1); + QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString(); QString text = ctx->callData->args[0].toQStringNoThrow(); QString comment; diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index d0fc1b1295..33f5a00a6c 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -95,7 +95,7 @@ QV8Engine::QV8Engine(QJSEngine* qq) , m_listModelData(0) { #ifdef Q_PROCESSOR_X86_32 - if (!(qCpuFeatures() & SSE2)) { + if (!qCpuHasFeature(SSE2)) { qFatal("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer"); } #endif @@ -256,7 +256,7 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant) case QMetaType::Double: return QV4::Encode(*reinterpret_cast<const double*>(ptr)); case QMetaType::QString: - return m_v4Engine->current->engine->newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue(); + return m_v4Engine->currentContext()->engine->newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue(); case QMetaType::Float: return QV4::Encode(*reinterpret_cast<const float*>(ptr)); case QMetaType::Short: @@ -667,7 +667,7 @@ QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) case QMetaType::Double: return QV4::Encode(*reinterpret_cast<const double*>(data)); case QMetaType::QString: - return m_v4Engine->current->engine->newString(*reinterpret_cast<const QString*>(data))->asReturnedValue(); + return m_v4Engine->currentContext()->engine->newString(*reinterpret_cast<const QString*>(data))->asReturnedValue(); case QMetaType::Float: return QV4::Encode(*reinterpret_cast<const float*>(data)); case QMetaType::Short: @@ -750,7 +750,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::ValueRef value, int type, void *data) if (value->isUndefined() || value->isNull()) *reinterpret_cast<QString*>(data) = QString(); else - *reinterpret_cast<QString*>(data) = value->toString(m_v4Engine->current)->toQString(); + *reinterpret_cast<QString*>(data) = value->toString(m_v4Engine->currentContext())->toQString(); return true; case QMetaType::Float: *reinterpret_cast<float*>(data) = value->toNumber(); |