aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp14
-rw-r--r--src/qml/qml/qqml.h4
-rw-r--r--src/qml/qml/qqmlbinding.cpp10
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp4
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp22
-rw-r--r--src/qml/qml/qqmlcompiler.cpp68
-rw-r--r--src/qml/qml/qqmlcompiler_p.h20
-rw-r--r--src/qml/qml/qqmlcomponent.cpp20
-rw-r--r--src/qml/qml/qqmlcomponent_p.h4
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp99
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h18
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp3
-rw-r--r--src/qml/qml/qqmldata_p.h3
-rw-r--r--src/qml/qml/qqmlengine.cpp54
-rw-r--r--src/qml/qml/qqmlengine_p.h15
-rw-r--r--src/qml/qml/qqmlinstruction_p.h6
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp6
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp6
-rw-r--r--src/qml/qml/qqmllocale.cpp4
-rw-r--r--src/qml/qml/qqmlmemoryprofiler.cpp3
-rw-r--r--src/qml/qml/qqmlmetatype.cpp8
-rw-r--r--src/qml/qml/qqmltypeloader.cpp9
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp16
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h42
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp12
-rw-r--r--src/qml/qml/qqmlvme.cpp27
-rw-r--r--src/qml/qml/qqmlvme_p.h2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp28
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp10
-rw-r--r--src/qml/qml/v8/qv8engine.cpp8
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();