aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp2
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp4
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h8
-rw-r--r--src/qml/jsruntime/qv4context.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp9
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp30
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/qml/qqmlbinding.cpp29
-rw-r--r--src/qml/qml/qqmlcontext.cpp79
-rw-r--r--src/qml/qml/qqmlcontext_p.h22
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp11
-rw-r--r--src/qml/qml/qqmlexpression.cpp4
-rw-r--r--src/qml/qml/qqmlimport.cpp2
-rw-r--r--src/qml/qml/qqmlinfo.cpp2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp9
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp88
-rw-r--r--src/qml/qml/qqmlmetatype_p.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp76
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h5
-rw-r--r--src/qml/qml/qqmlproperty.cpp6
-rw-r--r--src/qml/qml/qqmltypeloader.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp12
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h5
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp101
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h10
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
29 files changed, 311 insertions, 230 deletions
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index f3ba20538d..b37a7335a0 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -215,7 +215,7 @@ QList<QObject*> QQmlDebugService::objectForLocationInfo(const QString &filename,
} else {
QQmlData *ddata = QQmlData::get(iter.value());
if (ddata && ddata->outerContext) {
- if (QFileInfo(ddata->outerContext->urlString).fileName() == filename &&
+ if (QFileInfo(ddata->outerContext->urlString()).fileName() == filename &&
ddata->lineNumber == lineNumber &&
ddata->columnNumber >= columnNumber) {
objects << *iter;
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp
index b0c0995a44..da01d00f17 100644
--- a/src/qml/debugger/qqmlenginedebugservice.cpp
+++ b/src/qml/debugger/qqmlenginedebugservice.cpp
@@ -391,7 +391,7 @@ QQmlEngineDebugService::objectData(QObject *object)
QQmlData *ddata = QQmlData::get(object);
QQmlObjectData rv;
if (ddata && ddata->outerContext) {
- rv.url = ddata->outerContext->url;
+ rv.url = ddata->outerContext->url();
rv.lineNumber = ddata->lineNumber;
rv.columnNumber = ddata->columnNumber;
} else {
@@ -762,7 +762,7 @@ bool QQmlEngineDebugService::setMethodBody(int objectId, const QString &method,
int lineNumber = vmeMetaObject->vmeMethodLineNumber(prop->coreIndex);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(object)->handle());
QV4::Scope scope(v4);
- QV4::ScopedValue v(scope, QQmlExpressionPrivate::evalFunction(contextData, object, jsfunction, contextData->url.toString(), lineNumber));
+ QV4::ScopedValue v(scope, QQmlExpressionPrivate::evalFunction(contextData, object, jsfunction, contextData->urlString(), lineNumber));
vmeMetaObject->setVmeMethod(prop->coreIndex, v);
return true;
}
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index ba85a76277..5c994b112f 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -112,11 +112,11 @@ Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE);
class QQmlProfiler : public QObject, public QQmlProfilerDefinitions {
Q_OBJECT
public:
- void startBinding(const QString &fileName, int line, int column)
+ void startBinding(const QQmlSourceLocation &location)
{
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), 1 << Binding,
- fileName, line, column));
+ location.sourceFile, qmlSourceCoordinate(location.line), qmlSourceCoordinate(location.column)));
}
// Have toByteArrays() construct another RangeData event from the same QString later.
@@ -201,11 +201,11 @@ struct QQmlProfilerHelper : public QQmlProfilerDefinitions {
};
struct QQmlBindingProfiler : public QQmlProfilerHelper {
- QQmlBindingProfiler(QQmlProfiler *profiler, const QString &url, int line, int column) :
+ QQmlBindingProfiler(QQmlProfiler *profiler, const QV4::FunctionObject *function) :
QQmlProfilerHelper(profiler)
{
Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
- startBinding(url, line, column));
+ startBinding(function->sourceLocation()));
}
~QQmlBindingProfiler()
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 09d7393da9..9330f10780 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -166,7 +166,7 @@ Heap::CallContext::CallContext(ExecutionEngine *engine, QV4::Object *qml, QV4::F
callData->argc = 0;
callData->thisObject = Primitive::undefinedValue();
- strictMode = true;
+ strictMode = false;
outer = function->scope();
activation = qml->d();
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8c0df3ef04..cbfac86e9f 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -308,6 +308,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.asObject());
functionClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
+ simpleScriptFunctionClass = functionClass->addMember(id_name, Attr_ReadOnly, &index);
+ Q_ASSERT(index == Heap::SimpleScriptFunction::Index_Name);
+ simpleScriptFunctionClass = simpleScriptFunctionClass->addMember(id_length, Attr_ReadOnly, &index);
+ Q_ASSERT(index == Heap::SimpleScriptFunction::Index_Length);
protoClass = emptyClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
@@ -1738,9 +1742,8 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da
{
QV4::Scoped<QV4::QQmlValueTypeWrapper> vtw(scope, value);
- if (vtw && vtw->d()->metaType == type) {
- vtw->toGadget(data);
- return true;
+ if (vtw && vtw->typeId() == type) {
+ return vtw->toGadget(data);
}
}
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index bcb74ab694..f01579be71 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -169,6 +169,7 @@ public:
InternalClass *arrayClass;
InternalClass *functionClass;
+ InternalClass *simpleScriptFunctionClass;
InternalClass *protoClass;
InternalClass *regExpExecArrayClass;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 5be638e909..7006a8892d 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -210,6 +210,18 @@ bool FunctionObject::isBoundFunction() const
return d()->vtable == BoundFunction::staticVTable();
}
+QQmlSourceLocation FunctionObject::sourceLocation() const
+{
+ if (isBinding()) {
+ Q_ASSERT(as<const QV4::QQmlBindingFunction>());
+ return static_cast<QV4::Heap::QQmlBindingFunction *>(d())->bindingLocation;
+ }
+ QV4::Function *function = d()->function;
+ Q_ASSERT(function);
+
+ return QQmlSourceLocation(function->sourceFile(), function->compiledFunction->location.line, function->compiledFunction->location.column);
+}
+
DEFINE_OBJECT_VTABLE(FunctionCtor);
Heap::FunctionCtor::FunctionCtor(QV4::ExecutionContext *scope)
@@ -447,21 +459,27 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto)
- : Heap::FunctionObject(scope, function, createProto)
+ : Heap::FunctionObject(function->compilationUnit->engine->simpleScriptFunctionClass, function->compilationUnit->engine->functionPrototype.asObject())
{
+ this->scope = scope->d();
+
this->function = function;
function->compilationUnit->addref();
Q_ASSERT(function);
Q_ASSERT(function->code);
- // global function
- if (!scope)
- return;
-
Scope s(scope);
ScopedFunctionObject f(s, this);
- f->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(f->formalParameterCount()));
+ if (createProto) {
+ ScopedString name(s, function->name());
+ f->init(name, createProto);
+ f->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(f->formalParameterCount()));
+ } else {
+ f->ensureMemberIndex(s.engine, Index_Length);
+ memberData->data[Index_Name] = function->name();
+ memberData->data[Index_Length] = Primitive::fromInt32(f->formalParameterCount());
+ }
if (scope->d()->strictMode) {
ScopedProperty pd(s);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 3433e7b8ca..252ff40a1a 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -40,6 +40,8 @@
QT_BEGIN_NAMESPACE
+struct QQmlSourceLocation;
+
namespace QV4 {
namespace Heap {
@@ -87,6 +89,10 @@ struct IndexedBuiltinFunction : FunctionObject {
};
struct SimpleScriptFunction : FunctionObject {
+ enum {
+ Index_Name = FunctionObject::Index_Prototype + 1,
+ Index_Length
+ };
SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto);
};
@@ -140,6 +146,8 @@ struct Q_QML_EXPORT FunctionObject: Object {
bool isBinding() const;
bool isBoundFunction() const;
+ QQmlSourceLocation sourceLocation() const;
+
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 7a5890f8c4..50efff001d 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1835,7 +1835,7 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
if (!wrapper)
return Encode::undefined();
- object = QQmlObjectOrGadget(d()->propertyCache.data(), wrapper->d()->gadget());
+ object = QQmlObjectOrGadget(d()->propertyCache.data(), wrapper->d()->gadgetPtr);
}
QQmlPropertyData method;
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index ff794f5f09..f223d099e4 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -93,8 +93,8 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte
QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
- if (engine && ctxtdata && !ctxtdata->url.isEmpty() && ctxtdata->typeCompilationUnit) {
- url = ctxtdata->url.toString();
+ if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit) {
+ url = ctxtdata->urlString();
if (scriptPrivate->bindingId != QQmlBinding::Invalid)
runtimeFunction = ctxtdata->typeCompilationUnit->runtimeFunctions.at(scriptPrivate->bindingId);
}
@@ -165,34 +165,13 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
if (QQmlData::wasDeleted(object()))
return;
- QString url;
- quint16 lineNumber;
- quint16 columnNumber;
-
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
QV4::ScopedFunctionObject f(scope, v4function.value());
Q_ASSERT(f);
- if (f->isBinding()) {
- Q_ASSERT(f->as<QV4::QQmlBindingFunction>());
- QQmlSourceLocation loc = static_cast<QV4::Heap::QQmlBindingFunction *>(f->d())->bindingLocation;
- url = loc.sourceFile;
- lineNumber = loc.line;
- columnNumber = loc.column;
- } else {
- QV4::Function *function = f->asFunctionObject()->function();
- Q_ASSERT(function);
-
- url = function->sourceFile();
- lineNumber = function->compiledFunction->location.line;
- columnNumber = function->compiledFunction->location.column;
- }
-
- int lineNo = qmlSourceCoordinate(lineNumber);
- int columnNo = qmlSourceCoordinate(columnNumber);
if (!updatingFlag()) {
- QQmlBindingProfiler prof(ep->profiler, url, lineNo, columnNo);
+ QQmlBindingProfiler prof(ep->profiler, f);
setUpdatingFlag(true);
QQmlAbstractExpression::DeleteWatcher watcher(this);
@@ -222,7 +201,7 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
if (!watcher.wasDeleted()) {
if (needsErrorLocationData)
- delayedError()->setErrorLocation(QUrl(url), lineNumber, columnNumber);
+ delayedError()->setErrorLocation(f->sourceLocation());
if (hasError()) {
if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 1005d097d2..f08f650913 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -305,12 +305,10 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
}
}
- if (data->propertyNames.isEmpty())
- data->propertyNames = QV4::IdentifierHash<int>(QV8Engine::getV4(engine()->handle()));
-
- int idx = data->propertyNames.value(name);
+ QV4::IdentifierHash<int> &properties = data->propertyNames();
+ int idx = properties.value(name);
if (idx == -1) {
- data->propertyNames.add(name, data->idValueCount + d->propertyValues.count());
+ properties.add(name, data->idValueCount + d->propertyValues.count());
d->propertyValues.append(value);
data->refreshExpressions();
@@ -343,12 +341,11 @@ void QQmlContext::setContextProperty(const QString &name, QObject *value)
return;
}
- if (data->propertyNames.isEmpty())
- data->propertyNames = QV4::IdentifierHash<int>(QV8Engine::getV4(engine()->handle()));
- int idx = data->propertyNames.value(name);
+ QV4::IdentifierHash<int> &properties = data->propertyNames();
+ int idx = properties.value(name);
if (idx == -1) {
- data->propertyNames.add(name, data->idValueCount + d->propertyValues.count());
+ properties.add(name, data->idValueCount + d->propertyValues.count());
d->propertyValues.append(QVariant::fromValue(value));
data->refreshExpressions();
@@ -370,8 +367,9 @@ QVariant QQmlContext::contextProperty(const QString &name) const
QQmlContextData *data = d->data;
- if (data->propertyNames.count())
- idx = data->propertyNames.value(name);
+ const QV4::IdentifierHash<int> &properties = data->propertyNames();
+ if (properties.count())
+ idx = properties.value(name);
if (idx == -1) {
if (data->contextObject) {
@@ -428,14 +426,14 @@ QUrl QQmlContextData::resolvedUrl(const QUrl &src)
if (src.isRelative() && !src.isEmpty()) {
if (ctxt) {
while(ctxt) {
- if(ctxt->url.isValid())
+ if (ctxt->url().isValid())
break;
else
ctxt = ctxt->parent;
}
if (ctxt)
- resolved = ctxt->url.resolved(src);
+ resolved = ctxt->url().resolved(src);
else if (engine)
resolved = engine->baseUrl().resolved(src);
}
@@ -464,8 +462,8 @@ void QQmlContext::setBaseUrl(const QUrl &baseUrl)
{
Q_D(QQmlContext);
- d->data->url = baseUrl;
- d->data->urlString = baseUrl.toString();
+ d->data->baseUrl = baseUrl;
+ d->data->baseUrlString = baseUrl.toString();
}
/*!
@@ -476,11 +474,11 @@ QUrl QQmlContext::baseUrl() const
{
Q_D(const QQmlContext);
const QQmlContextData* data = d->data;
- while (data && data->url.isEmpty())
+ while (data && data->url().isEmpty())
data = data->parent;
if (data)
- return data->url;
+ return data->url();
else
return QUrl();
}
@@ -762,33 +760,31 @@ void QQmlContextData::setIdProperty(int idx, QObject *obj)
idValues[idx].context = this;
}
-void QQmlContextData::setIdPropertyData(const QVector<ObjectIdMapping> &data)
+void QQmlContextData::setIdPropertyData(const QHash<int, int> &data)
{
- Q_ASSERT(propertyNames.isEmpty());
- propertyNames = QV4::IdentifierHash<int>(QV8Engine::getV4(engine->handle()));
- for (QVector<ObjectIdMapping>::ConstIterator it = data.begin(), end = data.end();
- it != end; ++it)
- propertyNames.add(it->name, it->id);
-
+ Q_ASSERT(objectIndexToId.isEmpty());
+ objectIndexToId = data;
+ Q_ASSERT(propertyNameCache.isEmpty());
idValueCount = data.count();
idValues = new ContextGuard[idValueCount];
}
QString QQmlContextData::findObjectId(const QObject *obj) const
{
- if (propertyNames.isEmpty())
+ const QV4::IdentifierHash<int> &properties = propertyNames();
+ if (propertyNameCache.isEmpty())
return QString();
for (int ii = 0; ii < idValueCount; ii++) {
if (idValues[ii] == obj)
- return propertyNames.findId(ii);
+ return properties.findId(ii);
}
if (publicContext) {
QQmlContextPrivate *p = QQmlContextPrivate::get(publicContext);
for (int ii = 0; ii < p->propertyValues.count(); ++ii)
if (p->propertyValues.at(ii) == QVariant::fromValue((QObject *)obj))
- return propertyNames.findId(ii);
+ return properties.findId(ii);
}
if (linkedContext)
@@ -808,4 +804,33 @@ QQmlContextPrivate *QQmlContextData::asQQmlContextPrivate()
return QQmlContextPrivate::get(asQQmlContext());
}
+QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
+{
+ if (propertyNameCache.isEmpty()) {
+ propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine->handle()));
+ for (QHash<int, int>::ConstIterator it = objectIndexToId.begin(), end = objectIndexToId.end();
+ it != end; ++it) {
+ const QV4::CompiledData::Object *obj = typeCompilationUnit->data->objectAt(it.key());
+ const QString name = typeCompilationUnit->data->stringAt(obj->idIndex);
+ propertyNameCache.add(name, it.value());
+ }
+ objectIndexToId.clear();
+ }
+ return propertyNameCache;
+}
+
+QUrl QQmlContextData::url() const
+{
+ if (typeCompilationUnit)
+ return typeCompilationUnit->url();
+ return baseUrl;
+}
+
+QString QQmlContextData::urlString() const
+{
+ if (typeCompilationUnit)
+ return typeCompilationUnit->fileName();
+ return baseUrlString;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index f0e0ab26c6..f5fd7d0a5c 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -144,8 +144,9 @@ public:
// Compilation unit for contexts that belong to a compiled type.
QQmlRefPointer<QV4::CompiledData::CompilationUnit> typeCompilationUnit;
- // Property name cache
- QV4::IdentifierHash<int> propertyNames;
+ mutable QHash<int, int> objectIndexToId;
+ mutable QV4::IdentifierHash<int> propertyNameCache;
+ QV4::IdentifierHash<int> &propertyNames() const;
// Context object
QObject *contextObject;
@@ -153,9 +154,11 @@ public:
// Any script blocks that exist on this context
QV4::PersistentValue importedScripts; // This is a JS Array
- // Context base url
- QUrl url;
- QString urlString;
+ QUrl baseUrl;
+ QString baseUrlString;
+
+ QUrl url() const;
+ QString urlString() const;
// List of imports that apply to this context
QQmlTypeNameCache *imports;
@@ -188,17 +191,10 @@ public:
QFlagPointer<QQmlContextData> context;
QQmlNotifier bindings;
};
- struct ObjectIdMapping {
- ObjectIdMapping() : id(-1) {}
- ObjectIdMapping(const QString &name, int id)
- : name(name), id(id) {}
- QString name;
- int id;
- };
ContextGuard *idValues;
int idValueCount;
void setIdProperty(int, QObject *);
- void setIdPropertyData(const QVector<ObjectIdMapping> &);
+ void setIdPropertyData(const QHash<int, int> &);
// Linked contexts. this owns linkedContext.
QQmlContextData *linkedContext;
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 2498e5acc9..b2d03bc188 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -82,7 +82,8 @@ ReturnedValue QmlContextWrapper::urlScope(ExecutionEngine *v4, const QUrl &url)
Scope scope(v4);
QQmlContextData *context = new QQmlContextData;
- context->url = url;
+ context->baseUrl = url;
+ context->baseUrlString = url.toString();
context->isInternal = true;
context->isJSContext = true;
@@ -199,8 +200,9 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
while (context) {
// Search context properties
- if (context->propertyNames.count()) {
- int propertyIdx = context->propertyNames.value(name);
+ const QV4::IdentifierHash<int> &properties = context->propertyNames();
+ if (properties.count()) {
+ int propertyIdx = properties.value(name);
if (propertyIdx != -1) {
@@ -308,8 +310,9 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QObject *scopeObject = wrapper->getScopeObject();
while (context) {
+ const QV4::IdentifierHash<int> &properties = context->propertyNames();
// Search context properties
- if (context->propertyNames.count() && -1 != context->propertyNames.value(name))
+ if (properties.count() && properties.value(name) != -1)
return;
// Search scope object
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 18f882e1e0..35e0bc8c64 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -149,8 +149,8 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
if (scriptPrivate->context) {
QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
- if (engine && ctxtdata && !ctxtdata->url.isEmpty() && ctxtdata->typeCompilationUnit) {
- d->url = ctxtdata->url.toString();
+ if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit) {
+ d->url = ctxtdata->urlString();
d->line = scriptPrivate->lineNumber;
d->column = scriptPrivate->columnNumber;
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 6a5cab02fd..906e073cab 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1829,7 +1829,7 @@ bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &b
{
// Create a scope for QWriteLocker to keep it as narrow as possible, and
// to ensure that we release it before the call to initalizeEngine below
- QWriteLocker lock(QQmlMetaType::typeRegistrationLock());
+ QMutexLocker lock(QQmlMetaType::typeRegistrationLock());
if (!typeNamespace.isEmpty()) {
// This is an 'identified' module
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 85979b8dc0..b9f96a724c 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -140,7 +140,7 @@ QQmlInfo::~QQmlInfo()
QQmlData *ddata = QQmlData::get(object, false);
if (ddata && ddata->outerContext) {
- error.setUrl(ddata->outerContext->url);
+ error.setUrl(ddata->outerContext->url());
error.setLine(ddata->lineNumber);
error.setColumn(ddata->columnNumber);
}
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 3ac0f23e4d..02bd1c4b83 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -40,6 +40,7 @@
#include <private/qv4script_p.h>
#include <private/qv4errorobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qqmlglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -59,11 +60,11 @@ bool QQmlDelayedError::addError(QQmlEnginePrivate *e)
return true;
}
-void QQmlDelayedError::setErrorLocation(const QUrl &url, quint16 line, quint16 column)
+void QQmlDelayedError::setErrorLocation(const QQmlSourceLocation &sourceLocation)
{
- m_error.setUrl(url);
- m_error.setLine(line);
- m_error.setColumn(column);
+ m_error.setUrl(QUrl(sourceLocation.sourceFile));
+ m_error.setLine(sourceLocation.line);
+ m_error.setColumn(sourceLocation.column);
}
void QQmlDelayedError::setErrorDescription(const QString &description)
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 3f1a8c173d..cbbd88f1fc 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -52,6 +52,8 @@
QT_BEGIN_NAMESPACE
+class QQmlSourceLocation;
+
class QQmlDelayedError
{
public:
@@ -72,7 +74,7 @@ public:
inline const QQmlError &error() const { return m_error; }
inline void clearError() { m_error = QQmlError(); }
- void setErrorLocation(const QUrl &url, quint16 line, quint16 column);
+ void setErrorLocation(const QQmlSourceLocation &sourceLocation);
void setErrorDescription(const QString &description);
void setErrorObject(QObject *object);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 9779773b05..2f7834fa41 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -127,7 +127,7 @@ public:
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
-Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, metaTypeDataLock, (QReadWriteLock::Recursive))
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, metaTypeDataLock, (QMutex::Recursive))
static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
{
@@ -565,7 +565,7 @@ void QQmlTypePrivate::init() const
if (isSetup)
return;
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
if (isSetup)
return;
@@ -646,7 +646,7 @@ void QQmlTypePrivate::initEnums() const
init();
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
if (isEnumSetup) return;
if (baseMetaObject) // could be singleton type without metaobject
@@ -1000,7 +1000,7 @@ void QQmlTypeModulePrivate::add(QQmlType *type)
QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QList<QQmlType *> *types = d->typeHash.value(name);
if (!types) return 0;
@@ -1014,7 +1014,7 @@ QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor)
QQmlType *QQmlTypeModule::type(const QV4::String *name, int minor)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QList<QQmlType *> *types = d->typeHash.value(name);
if (!types) return 0;
@@ -1028,7 +1028,7 @@ QQmlType *QQmlTypeModule::type(const QV4::String *name, int minor)
QList<QQmlType*> QQmlTypeModule::singletonTypes(int minor) const
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QList<QQmlType *> retn;
for (int ii = 0; ii < d->types.count(); ++ii) {
@@ -1089,7 +1089,7 @@ QQmlType *QQmlTypeModuleVersion::type(const QV4::String *name) const
void qmlClearTypeRegistrations() // Declared in qqml.h
{
//Only cleans global static, assumed no running engine
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
for (int i = 0; i < data->types.count(); ++i)
@@ -1112,7 +1112,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
{
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
data->parentFunctions.append(autoparent.function);
@@ -1125,7 +1125,7 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
if (interface.version > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
int index = data->types.count();
@@ -1163,7 +1163,7 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
return typeStr;
}
-// NOTE: caller must hold a QWriteLocker on "data"
+// NOTE: caller must hold a QMutexLocker on "data"
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName, int majorVersion = -1)
{
if (!typeName.isEmpty()) {
@@ -1214,7 +1214,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
return true;
}
-// NOTE: caller must hold a QWriteLocker on "data"
+// NOTE: caller must hold a QMutexLocker on "data"
void addTypeToData(QQmlType* type, QQmlMetaTypeData *data)
{
if (!type->elementName().isEmpty())
@@ -1253,7 +1253,7 @@ void addTypeToData(QQmlType* type, QQmlMetaTypeData *data)
int registerType(const QQmlPrivate::RegisterType &type)
{
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString elementName = QString::fromUtf8(type.elementName);
if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
@@ -1273,7 +1273,7 @@ int registerType(const QQmlPrivate::RegisterType &type)
int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
{
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
@@ -1292,7 +1292,7 @@ int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
bool fileImport = false;
@@ -1317,7 +1317,7 @@ int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingleton
int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
bool fileImport = false;
@@ -1342,7 +1342,7 @@ int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRe
{
if (hookRegistration.version > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
return 0;
@@ -1375,7 +1375,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
//From qqml.h
bool qmlProtectModule(const char *uri, int majVersion)
{
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::VersionedUri versionedUri;
@@ -1424,7 +1424,7 @@ QStringList QQmlMetaType::typeRegistrationFailures()
return data->typeRegistrationFailures;
}
-QReadWriteLock *QQmlMetaType::typeRegistrationLock()
+QMutex *QQmlMetaType::typeRegistrationLock()
{
return metaTypeDataLock();
}
@@ -1434,7 +1434,7 @@ QReadWriteLock *QQmlMetaType::typeRegistrationLock()
*/
bool QQmlMetaType::isAnyModule(const QString &uri)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.begin();
@@ -1451,7 +1451,7 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
*/
bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::VersionedUri versionedUri;
@@ -1472,7 +1472,7 @@ bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion)
bool QQmlMetaType::isModule(const QString &module, int versionMajor, int versionMinor)
{
Q_ASSERT(versionMajor >= 0 && versionMinor >= 0);
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
@@ -1487,14 +1487,14 @@ bool QQmlMetaType::isModule(const QString &module, int versionMajor, int version
QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, int majorVersion)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, majorVersion));
}
QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->parentFunctions;
}
@@ -1516,7 +1516,7 @@ bool QQmlMetaType::isQObject(int userType)
if (userType == QMetaType::QObjectStar)
return true;
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return userType >= 0 && userType < data->objects.size() && data->objects.testBit(userType);
}
@@ -1526,7 +1526,7 @@ bool QQmlMetaType::isQObject(int userType)
*/
int QQmlMetaType::listType(int id)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->idToType.value(id);
if (type && type->qListTypeId() == id)
@@ -1537,7 +1537,7 @@ int QQmlMetaType::listType(int id)
int QQmlMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->metaObjectToType.value(mo);
@@ -1551,7 +1551,7 @@ QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(int id)
{
if (id < 0)
return 0;
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->types.at(id)->attachedPropertiesFunction();
}
@@ -1615,7 +1615,7 @@ QQmlMetaType::TypeCategory QQmlMetaType::typeCategory(int userType)
if (userType == QMetaType::QObjectStar)
return Object;
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
if (userType < data->objects.size() && data->objects.testBit(userType))
return Object;
@@ -1627,14 +1627,14 @@ QQmlMetaType::TypeCategory QQmlMetaType::typeCategory(int userType)
bool QQmlMetaType::isInterface(int userType)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return userType >= 0 && userType < data->interfaces.size() && data->interfaces.testBit(userType);
}
const char *QQmlMetaType::interfaceIId(int userType)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->idToType.value(userType);
lock.unlock();
@@ -1646,7 +1646,7 @@ const char *QQmlMetaType::interfaceIId(int userType)
bool QQmlMetaType::isList(int userType)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
}
@@ -1668,7 +1668,7 @@ bool QQmlMetaType::isList(int userType)
*/
void QQmlMetaType::registerCustomStringConverter(int type, StringConverter converter)
{
- QWriteLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
if (data->stringConverters.contains(type))
@@ -1682,7 +1682,7 @@ void QQmlMetaType::registerCustomStringConverter(int type, StringConverter conve
*/
QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->stringConverters.value(type);
@@ -1711,7 +1711,7 @@ QQmlType *QQmlMetaType::qmlType(const QString &qualifiedName, int version_major,
QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
@@ -1731,7 +1731,7 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin
*/
QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->metaObjectToType.value(metaObject);
@@ -1745,7 +1745,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject)
QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
@@ -1765,7 +1765,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
*/
QQmlType *QQmlMetaType::qmlType(int userType)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->idToType.value(userType);
@@ -1783,7 +1783,7 @@ QQmlType *QQmlMetaType::qmlType(int userType)
*/
QQmlType *QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->urlToType.value(url);
@@ -1803,7 +1803,7 @@ QQmlType *QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* =
*/
QQmlType *QQmlMetaType::qmlTypeFromIndex(int idx)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
if (idx < 0 || idx >= data->types.count())
@@ -1816,7 +1816,7 @@ QQmlType *QQmlMetaType::qmlTypeFromIndex(int idx)
*/
QList<QString> QQmlMetaType::qmlTypeNames()
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QList<QString> names;
@@ -1834,7 +1834,7 @@ QList<QString> QQmlMetaType::qmlTypeNames()
*/
QList<QQmlType*> QQmlMetaType::qmlTypes()
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->nameToType.values();
@@ -1845,7 +1845,7 @@ QList<QQmlType*> QQmlMetaType::qmlTypes()
*/
QList<QQmlType*> QQmlMetaType::qmlAllTypes()
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->types;
@@ -1856,7 +1856,7 @@ QList<QQmlType*> QQmlMetaType::qmlAllTypes()
*/
QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QList<QQmlType*> alltypes = data->nameToType.values();
@@ -1872,7 +1872,7 @@ QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
{
- QReadLocker lock(metaTypeDataLock());
+ QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
for (QVector<QQmlPrivate::QmlUnitCacheLookupFunction>::ConstIterator it = data->lookupCachedQmlUnit.constBegin(), end = data->lookupCachedQmlUnit.constEnd();
it != end; ++it) {
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 63e6e3bec8..e5ac20d314 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -62,7 +62,7 @@ class QQmlTypePrivate;
class QQmlTypeModule;
class QHashedString;
class QHashedStringRef;
-class QReadWriteLock;
+class QMutex;
namespace QV4 { struct String; }
@@ -121,7 +121,7 @@ public:
static void setTypeRegistrationNamespace(const QString &);
static QStringList typeRegistrationFailures();
- static QReadWriteLock *typeRegistrationLock();
+ static QMutex *typeRegistrationLock();
};
struct QQmlMetaTypeData;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index a32dc9e0a9..4c86e6a307 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -113,6 +113,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
{
parentContext = providedParentContext;
engine = parentContext->engine;
+ v4 = QV8Engine::getV4(engine);
if (!compiledData->isInitialized())
compiledData->initialize(engine);
@@ -126,7 +127,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
_ddata = 0;
_propertyCache = 0;
_vmeMetaObject = 0;
- _qmlContext = 0;
+ _qmlBindingWrapper = 0;
}
QQmlObjectCreator::~QQmlObjectCreator()
@@ -174,8 +175,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context = new QQmlContextData;
context->isInternal = true;
- context->url = compiledData->url();
- context->urlString = compiledData->fileName();
context->imports = compiledData->importCache;
context->imports->addref();
context->typeCompilationUnit = compiledData->compilationUnit;
@@ -187,26 +186,15 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
sharedState->rootContext->isRootObjectInCreation = true;
}
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
if (topLevelCreator)
sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount);
- QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
- for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd();
- it != end; ++it) {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(it.key());
+ context->setIdPropertyData(objectIndexToId);
- QQmlContextData::ObjectIdMapping m;
- m.id = it.value();
- m.name = stringAt(obj->idIndex);
- mapping[m.id] = m;
- }
- context->setIdPropertyData(mapping);
-
- if (subComponentIndex == -1) {
+ if (subComponentIndex == -1 && compiledData->scripts.count()) {
QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
context->importedScripts.set(v4, scripts);
for (int i = 0; i < compiledData->scripts.count(); ++i) {
@@ -256,20 +244,15 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
QObject *scopeObject = instance;
qSwap(_scopeObject, scopeObject);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope valueScope(v4);
Q_ASSERT(topLevelCreator);
Q_ASSERT(!sharedState->allJavaScriptObjects);
sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount);
- QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject));
- QV4::ScopedContext global(valueScope, valueScope.engine->rootContext());
- QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope));
- // ### GC
- QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context());
+ QV4::Value *qmlBindingWrapper = valueScope.alloc(1);
- qSwap(_qmlContext, qmlContext);
+ qSwap(_qmlBindingWrapper, qmlBindingWrapper);
qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
@@ -291,7 +274,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
qSwap(_qobject, instance);
qSwap(_propertyCache, cache);
- qSwap(_qmlContext, qmlContext);
+ qSwap(_qmlBindingWrapper, qmlBindingWrapper);
qSwap(_scopeObject, scopeObject);
phase = ObjectsCreated;
@@ -306,7 +289,6 @@ void QQmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::
int propertyWriteStatus = -1;
void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags };
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
int propertyType = property->propType;
@@ -826,8 +808,9 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4
if (binding->type == QV4::CompiledData::Binding::Type_Script) {
QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
- QV4::Scope scope(_qmlContext);
- QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction, /*createProto*/ false));
+ QV4::Scope scope(v4);
+ QV4::ScopedContext qmlContext(scope, currentQmlContext());
+ QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction, /*createProto*/ false));
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex);
@@ -946,7 +929,6 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4
}
} else if (property->propType == QMetaType::QVariant) {
if (property->isVarProperty()) {
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), createdSubObject));
_vmeMetaObject->setVMEProperty(property->coreIndex, wrappedObject);
@@ -993,8 +975,9 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4
void QQmlObjectCreator::setupFunctions()
{
- QV4::Scope scope(_qmlContext);
+ QV4::Scope scope(v4);
QV4::ScopedValue function(scope);
+ QV4::ScopedContext qmlContext(scope, currentQmlContext());
const quint32 *functionIdx = _compiledObject->functionOffsetTable();
for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
@@ -1005,7 +988,7 @@ void QQmlObjectCreator::setupFunctions()
if (!property->isVMEFunction())
continue;
- function = QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction);
+ function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction);
_vmeMetaObject->setVmeMethod(property->coreIndex, function);
}
}
@@ -1027,6 +1010,17 @@ void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject *
context->setIdProperty(idEntry.value(), instance);
}
+QV4::Heap::ExecutionContext *QQmlObjectCreator::currentQmlContext()
+{
+ if (!_qmlBindingWrapper->objectValue()) {
+ QV4::Scope valueScope(v4);
+ QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject));
+ QV4::ScopedContext global(valueScope, v4->rootContext());
+ *_qmlBindingWrapper = v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope);
+ }
+ return static_cast<QV4::QmlBindingWrapper*>(_qmlBindingWrapper->objectValue())->context();
+}
+
QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
{
QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler);
@@ -1044,7 +1038,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
isComponent = true;
QQmlComponent *component = new QQmlComponent(engine, compiledData, index, parent);
Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(QStringLiteral("<component>"),
- context->url, obj->location.line, obj->location.column));
+ context->url(), obj->location.line, obj->location.column));
QQmlComponentPrivate::get(component)->creationContext = context;
instance = component;
ddata = QQmlData::get(instance, /*create*/true);
@@ -1055,7 +1049,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QQmlType *type = typeRef->type;
if (type) {
Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(type->qmlTypeName(),
- context->url, obj->location.line, obj->location.column));
+ context->url(), obj->location.line, obj->location.column));
instance = type->create();
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
@@ -1078,7 +1072,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
} else {
Q_ASSERT(typeRef->component);
Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(typeRef->component->fileName(),
- context->url, obj->location.line, obj->location.column));
+ context->url(), obj->location.line, obj->location.column));
if (typeRef->component->compilationUnit->data->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
@@ -1166,24 +1160,18 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QObject *scopeObject = instance;
qSwap(_scopeObject, scopeObject);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
-
Q_ASSERT(sharedState->allJavaScriptObjects);
*sharedState->allJavaScriptObjects = QV4::QObjectWrapper::wrap(v4, instance);
++sharedState->allJavaScriptObjects;
QV4::Scope valueScope(v4);
- QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject));
- QV4::ScopedContext global(valueScope, valueScope.engine->rootContext());
- QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope));
- // ### GC
- QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context());
+ QV4::Value *qmlBindingWrapper = valueScope.alloc(1);
- qSwap(_qmlContext, qmlContext);
+ qSwap(_qmlBindingWrapper, qmlBindingWrapper);
bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0, bindingsToSkip);
- qSwap(_qmlContext, qmlContext);
+ qSwap(_qmlBindingWrapper, qmlBindingWrapper);
qSwap(_scopeObject, scopeObject);
return result ? instance : 0;
@@ -1287,7 +1275,6 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
qSwap(_ddata, declarativeData);
qSwap(_bindingTarget, bindingTarget);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope valueScope(v4);
QV4::ScopedValue scopeObjectProtector(valueScope);
@@ -1332,7 +1319,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
}
}
- setupFunctions();
+ if (_compiledObject->nFunctions > 0)
+ setupFunctions();
setupBindings(bindingSkipList);
qSwap(_vmeMetaObject, vmeMetaObject);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 3886155786..fcf247be5a 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -107,6 +107,8 @@ private:
void registerObjectWithContextById(int objectIndex, QObject *instance) const;
+ QV4::Heap::ExecutionContext *currentQmlContext();
+
enum Phase {
Startup,
CreatingObjects,
@@ -117,6 +119,7 @@ private:
} phase;
QQmlEngine *engine;
+ QV4::ExecutionEngine *v4;
QQmlCompiledData *compiledData;
const QV4::CompiledData::Unit *qmlUnit;
QQmlGuardedContextData parentContext;
@@ -139,7 +142,7 @@ private:
QQmlRefPointer<QQmlPropertyCache> _propertyCache;
QQmlVMEMetaObject *_vmeMetaObject;
QQmlListProperty<void> _currentList;
- QV4::ExecutionContext *_qmlContext;
+ QV4::Value *_qmlBindingWrapper;
friend struct QQmlObjectCreatorRecursionWatcher;
};
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 931adb9a13..ae452b727e 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -53,6 +53,7 @@
#include <QStringList>
#include <private/qmetaobject_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#include <QtCore/qdebug.h>
Q_DECLARE_METATYPE(QList<int>)
@@ -1519,6 +1520,11 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QUICK_STORE(QString, result.toQStringNoThrow())
break;
default:
+ if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) {
+ if (vtw->d()->valueType->typeId == core.propType) {
+ return vtw->write(object, core.coreIndex);
+ }
+ }
break;
}
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 0bf8043cdb..d713e9ee03 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2478,8 +2478,8 @@ QV4::PersistentValue QQmlScriptData::scriptValueForContext(QQmlContextData *pare
ctxt->isPragmaLibraryContext = true;
else
ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext;
- ctxt->url = url;
- ctxt->urlString = urlString;
+ ctxt->baseUrl = url;
+ ctxt->baseUrlString = urlString;
// For backward compatibility, if there are no imports, we need to use the
// imports from the parent context. See QTBUG-17518.
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 490ac66f1f..341ddf802d 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -38,6 +38,7 @@
#include <QtCore/qdebug.h>
#include <private/qmetaobjectbuilder_p.h>
#include <private/qqmlmodelindexvaluetype_p.h>
+#include <private/qmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -182,8 +183,9 @@ void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor,
}
QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
- : typeId(typeId)
- , gadgetPtr(QMetaType::create(typeId))
+ : gadgetPtr(QMetaType::create(typeId))
+ , typeId(typeId)
+ , metaType(typeId)
{
QObjectPrivate *op = QObjectPrivate::get(this);
Q_ASSERT(!op->metaObject);
@@ -201,7 +203,7 @@ QQmlValueType::~QQmlValueType()
Q_ASSERT(op->metaObject == this);
op->metaObject = 0;
::free((void*)_metaObject);
- QMetaType::destroy(typeId, gadgetPtr);
+ metaType.destroy(gadgetPtr);
}
void QQmlValueType::read(QObject *obj, int idx)
@@ -227,8 +229,8 @@ QVariant QQmlValueType::value()
void QQmlValueType::setValue(const QVariant &value)
{
Q_ASSERT(typeId == value.userType());
- QMetaType::destruct(typeId, gadgetPtr);
- QMetaType::construct(typeId, gadgetPtr, value.constData());
+ metaType.destruct(gadgetPtr);
+ metaType.construct(gadgetPtr, value.constData());
}
QAbstractDynamicMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index f534fedf5d..be453ae35a 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -75,8 +75,11 @@ public:
private:
const QMetaObject *_metaObject;
- int typeId;
void *gadgetPtr;
+
+public:
+ int typeId;
+ QMetaType metaType;
};
class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index d3a80f0ee2..397068f5d9 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -79,27 +79,31 @@ using namespace QV4;
Heap::QQmlValueTypeWrapper::QQmlValueTypeWrapper(ExecutionEngine *engine)
: Heap::Object(engine)
- , gadgetPtr(0)
{
}
Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper()
{
- if (gadgetPtr)
- QMetaType::destroy(metaType, gadgetPtr);
+ if (gadgetPtr) {
+ valueType->metaType.destruct(gadgetPtr);
+ ::operator delete(gadgetPtr);
+ }
}
void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const
{
- Q_ASSERT(metaType == value.userType());
- QMetaType::destruct(metaType, gadgetPtr);
- QMetaType::construct(metaType, gadgetPtr, value.constData());
+ Q_ASSERT(valueType->typeId == value.userType());
+ if (gadgetPtr)
+ valueType->metaType.destruct(gadgetPtr);
+ if (!gadgetPtr)
+ gadgetPtr = ::operator new(valueType->metaType.sizeOf());
+ valueType->metaType.construct(gadgetPtr, value.constData());
}
QVariant Heap::QQmlValueTypeWrapper::toVariant() const
{
Q_ASSERT(gadgetPtr);
- return QVariant(metaType, gadgetPtr);
+ return QVariant(valueType->typeId, gadgetPtr);
}
@@ -123,7 +127,7 @@ bool QQmlValueTypeReference::readReferenceValue() const
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, a);
int variantReferenceType = variantReferenceValue.userType();
- if (variantReferenceType != d()->metaType) {
+ if (variantReferenceType != typeId()) {
// This is a stale VariantReference. That is, the variant has been
// overwritten with a different type in the meantime.
// We need to modify this reference to the updated value type, if
@@ -132,24 +136,27 @@ bool QQmlValueTypeReference::readReferenceValue() const
QQmlPropertyCache *cache = 0;
if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType))
cache = QJSEnginePrivate::get(engine())->cache(mo);
- if (d()->gadgetPtr)
- QMetaType::destroy(d()->metaType, d()->gadgetPtr);
- d()->gadgetPtr = 0;
+ if (d()->gadgetPtr) {
+ d()->valueType->metaType.destruct(d()->gadgetPtr);
+ ::operator delete(d()->gadgetPtr);
+ }
+ d()->gadgetPtr =0;
d()->propertyCache = cache;
- d()->metaType = variantReferenceType;
- if (cache) {
- d()->gadgetPtr = QMetaType::create(d()->metaType);
- } else {
+ d()->valueType = QQmlValueTypeFactory::valueType(variantReferenceType);
+ if (!cache)
return false;
- }
} else {
return false;
}
}
d()->setValue(variantReferenceValue);
} else {
+ if (!d()->gadgetPtr) {
+ d()->gadgetPtr = ::operator new(d()->valueType->metaType.sizeOf());
+ d()->valueType->metaType.construct(d()->gadgetPtr, 0);
+ }
// value-type reference
- void *args[] = { d()->gadget(), 0 };
+ void *args[] = { d()->gadgetPtr, 0 };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, args);
}
return true;
@@ -176,8 +183,8 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj
r->setPrototype(proto);
r->d()->object = object; r->d()->property = property;
r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject);
- r->d()->metaType = typeId;
- r->d()->gadgetPtr = QMetaType::create(r->d()->metaType);
+ r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
+ r->d()->gadgetPtr = 0;
return r->asReturnedValue();
}
@@ -190,8 +197,8 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria
ScopedObject proto(scope, engine->qmlExtensions()->valueTypeWrapperPrototype);
r->setPrototype(proto);
r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject);
- r->d()->metaType = typeId;
- r->d()->gadgetPtr = QMetaType::create(r->d()->metaType);
+ r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
+ r->d()->gadgetPtr = 0;
r->d()->setValue(value);
return r->asReturnedValue();
}
@@ -204,11 +211,15 @@ QVariant QQmlValueTypeWrapper::toVariant() const
return d()->toVariant();
}
-void QQmlValueTypeWrapper::toGadget(void *data) const
+bool QQmlValueTypeWrapper::toGadget(void *data) const
{
- int typeId = d()->metaType;
+ if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>())
+ if (!ref->readReferenceValue())
+ return false;
+ const int typeId = d()->valueType->typeId;
QMetaType::destruct(typeId, data);
- QMetaType::construct(typeId, data, d()->gadget());
+ QMetaType::construct(typeId, data, d()->gadgetPtr);
+ return true;
}
void QQmlValueTypeWrapper::destroy(Heap::Base *that)
@@ -248,6 +259,36 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value)
return (value == d()->toVariant());
}
+int QQmlValueTypeWrapper::typeId() const
+{
+ return d()->valueType->typeId;
+}
+
+bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
+{
+ bool destructGadgetOnExit = false;
+ if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) {
+ if (!d()->gadgetPtr) {
+ d()->gadgetPtr = alloca(d()->valueType->metaType.sizeOf());
+ d()->valueType->metaType.construct(d()->gadgetPtr, 0);
+ destructGadgetOnExit = true;
+ }
+ if (!ref->readReferenceValue())
+ return false;
+ }
+
+ int flags = 0;
+ int status = -1;
+ void *a[] = { d()->gadgetPtr, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a);
+
+ if (destructGadgetOnExit) {
+ d()->valueType->metaType.destruct(d()->gadgetPtr);
+ d()->gadgetPtr = 0;
+ }
+ return true;
+}
+
ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
{
Object *o = ctx->thisObject().asObject();
@@ -265,15 +306,15 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
// Prepare a buffer to pass to QMetaType::convert()
QString convertResult;
convertResult.~QString();
- if (QMetaType::convert(w->d()->gadgetPtr, w->d()->metaType, &convertResult, QMetaType::QString)) {
+ if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->typeId, &convertResult, QMetaType::QString)) {
result = convertResult;
} else {
- result = QString::fromUtf8(QMetaType::typeName(w->d()->metaType));
+ result = QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId));
result += QLatin1Char('(');
const QMetaObject *mo = w->d()->propertyCache->metaObject();
const int propCount = mo->propertyCount();
for (int i = 0; i < propCount; ++i) {
- QVariant value = mo->property(i).readOnGadget(w->d()->gadget());
+ QVariant value = mo->property(i).readOnGadget(w->d()->gadgetPtr);
result += value.toString();
if (i < propCount - 1)
result += QStringLiteral(", ");
@@ -322,7 +363,7 @@ ReturnedValue QQmlValueTypeWrapper::get(Managed *m, String *name, bool *hasPrope
int index = result->coreIndex;
QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(QMetaObject::ReadProperty, &metaObject, &index);
- void *gadget = r->d()->gadget();
+ void *gadget = r->d()->gadgetPtr;
// These four types are the most common used by the value type wrappers
VALUE_TYPE_LOAD(QMetaType::QReal, qreal, qreal);
@@ -411,7 +452,7 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
- void *gadget = r->d()->gadget();
+ void *gadget = r->d()->gadgetPtr;
property.writeOnGadget(gadget, v);
@@ -427,7 +468,7 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
} else {
int flags = 0;
int status = -1;
- void *a[] = { r->d()->gadget(), 0, &status, &flags };
+ void *a[] = { r->d()->gadgetPtr, 0, &status, &flags };
QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
}
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 0b8c30d0d5..cad48e661c 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -54,6 +54,7 @@
QT_BEGIN_NAMESPACE
class QV8Engine;
+class QQmlValueType;
namespace QV4 {
@@ -62,13 +63,12 @@ namespace Heap {
struct QQmlValueTypeWrapper : Object {
QQmlValueTypeWrapper(ExecutionEngine *engine);
~QQmlValueTypeWrapper();
- mutable QQmlRefPointer<QQmlPropertyCache> propertyCache;
+ QQmlRefPointer<QQmlPropertyCache> propertyCache;
mutable void *gadgetPtr;
- mutable int metaType;
+ QQmlValueType *valueType;
void setValue(const QVariant &value) const;
QVariant toVariant() const;
- void *gadget() const { return gadgetPtr; }
};
}
@@ -84,8 +84,10 @@ public:
static ReturnedValue create(ExecutionEngine *engine, const QVariant &, const QMetaObject *metaObject, int typeId);
QVariant toVariant() const;
- void toGadget(void *data) const;
+ bool toGadget(void *data) const;
bool isEqual(const QVariant& value);
+ int typeId() const;
+ bool write(QObject *target, int propertyIndex) const;
static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 09a113dcc9..f53b9a0c7d 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1729,7 +1729,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
QV8Engine *v8engine = ctx->d()->engine->v8Engine;
QString context;
if (QQmlContextData *ctxt = v8engine->callingContext()) {
- QString path = ctxt->url.toString();
+ QString path = ctxt->urlString();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
int lastDot = path.lastIndexOf(QLatin1Char('.'));
int length = lastDot - (lastSlash + 1);