diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-05-30 13:16:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-05-30 16:40:54 +0200 |
commit | 35ab04c907a1cefa23eff2d7c853350fb5d27178 (patch) | |
tree | 1386ad29598e3e0a38d8a70dd5536ffd91dd0576 /src | |
parent | 2ce60b9fd8a01496d405fcc898e88da6f967e15e (diff) |
Port the type wrapper over to v4
Change-Id: Id442281a366914be818b068f70ebe5200c527254
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qml.pri | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp (renamed from src/qml/qml/v8/qv8typewrapper.cpp) | 219 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper_p.h (renamed from src/qml/qml/v8/qv8typewrapper_p.h) | 51 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4managed_p.h | 9 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8contextwrapper.cpp | 180 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8objectresource_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8qobjectwrapper.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/v8/v8.pri | 2 |
10 files changed, 230 insertions, 255 deletions
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index 24e7f5b2e4..fbd738b22c 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -51,7 +51,8 @@ SOURCES += \ $$PWD/qqmlmemoryprofiler.cpp \ $$PWD/qqmlplatform.cpp \ $$PWD/qqmlbinding.cpp \ - $$PWD/qqmlapplicationengine.cpp + $$PWD/qqmlapplicationengine.cpp \ + $$PWD/qqmltypewrapper.cpp HEADERS += \ $$PWD/qqmlglobal_p.h \ @@ -124,7 +125,8 @@ HEADERS += \ $$PWD/qqmlbinding_p.h \ $$PWD/qqmlextensionplugin_p.h \ $$PWD/qqmlapplicationengine_p.h \ - $$PWD/qqmlapplicationengine.h + $$PWD/qqmlapplicationengine.h \ + $$PWD/qqmltypewrapper_p.h JS_CLASS_SOURCES += \ $$PWD/qqmllocale.cpp diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index c9699767a4..322a7e31c4 100644 --- a/src/qml/qml/v8/qv8typewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -39,131 +39,100 @@ ** ****************************************************************************/ -#include "qv8contextwrapper_p.h" -#include "qv8engine_p.h" +#include "qqmltypewrapper_p.h" +#include <private/qv8contextwrapper_p.h> +#include <private/qv8engine_p.h> #include <private/qqmlengine_p.h> #include <private/qqmlcontext_p.h> #include <private/qjsvalue_p.h> #include <private/qv4functionobject_p.h> +#include <private/qv4objectproto_p.h> QT_BEGIN_NAMESPACE -class QV8TypeResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(TypeType); - -public: - QV8TypeResource(QV8Engine *engine); - virtual ~QV8TypeResource(); - - QV8TypeWrapper::TypeNameMode mode; - - QQmlGuard<QObject> object; - - QQmlType *type; - QQmlTypeNameCache *typeNamespace; - const void *importNamespace; -}; +using namespace QV4; -QV8TypeResource::QV8TypeResource(QV8Engine *engine) -: QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0), importNamespace(0) -{ -} +DEFINE_MANAGED_VTABLE(QmlTypeWrapper); -QV8TypeResource::~QV8TypeResource() +QmlTypeWrapper::QmlTypeWrapper(QV8Engine *engine) + : Object(QV8Engine::getV4(engine)), + v8(engine), mode(IncludeEnums), type(0), typeNamespace(0), importNamespace(0) { - if (typeNamespace) typeNamespace->release(); + Managed::type = Type_QmlTypeWrapper; + vtbl = &static_vtbl; } -QV8TypeWrapper::QV8TypeWrapper() -: m_engine(0) +QmlTypeWrapper::~QmlTypeWrapper() { + if (typeNamespace) + typeNamespace->release(); } -QV8TypeWrapper::~QV8TypeWrapper() +QVariant QmlTypeWrapper::toVariant() const { -} + if (type && type->isSingleton()) { + QQmlEngine *e = v8->engine(); + QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); + siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required. + QObject *qobjectSingleton = siinfo->qobjectApi(e); + if (qobjectSingleton) { + return QVariant::fromValue<QObject*>(qobjectSingleton); + } + } -void QV8TypeWrapper::destroy() -{ + // only QObject Singleton Type can be converted to a variant. + return QVariant(); } -void QV8TypeWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - m_constructor = ft->GetFunction()->v4Value(); -} // Returns a type wrapper for type t on o. This allows access of enums, and attached properties. -v8::Handle<v8::Object> QV8TypeWrapper::newObject(QObject *o, QQmlType *t, TypeNameMode mode) +Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode) { Q_ASSERT(t); - // XXX NewInstance() should be optimized - v8::Handle<v8::Object> rv = m_constructor.value().asFunctionObject()->newInstance(); - QV8TypeResource *r = new QV8TypeResource(m_engine); - r->mode = mode; r->object = o; r->type = t; - rv->SetExternalResource(r); - return rv; + ExecutionEngine *v4 = QV8Engine::getV4(v8); + + QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); + w->prototype = v4->objectPrototype; + w->mode = mode; w->object = o; w->type = t; + return Value::fromObject(w); } -// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a +// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a // namespace. -v8::Handle<v8::Object> QV8TypeWrapper::newObject(QObject *o, QQmlTypeNameCache *t, - const void *importNamespace, TypeNameMode mode) +Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode) { Q_ASSERT(t); Q_ASSERT(importNamespace); - // XXX NewInstance() should be optimized - v8::Handle<v8::Object> rv = m_constructor.value().asFunctionObject()->newInstance(); - QV8TypeResource *r = new QV8TypeResource(m_engine); + ExecutionEngine *v4 = QV8Engine::getV4(v8); + + QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); + w->prototype = v4->objectPrototype; + w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace; t->addref(); - r->mode = mode; r->object = o; r->typeNamespace = t; r->importNamespace = importNamespace; - rv->SetExternalResource(r); - return rv; + return Value::fromObject(w); } -QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::TypeType); - QV8TypeResource *resource = static_cast<QV8TypeResource *>(r); - QV8Engine *v8engine = resource->engine; - if (resource->type && resource->type->isSingleton()) { - QQmlEngine *e = v8engine->engine(); - QQmlType::SingletonInstanceInfo *siinfo = resource->type->singletonInstanceInfo(); - siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required. - QObject *qobjectSingleton = siinfo->qobjectApi(e); - if (qobjectSingleton) { - return QVariant::fromValue<QObject*>(qobjectSingleton); - } - } - - // only QObject Singleton Type can be converted to a variant. - return QVariant(); -} - -v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Handle<v8::String> property, - const v8::AccessorInfo &info) +Value QmlTypeWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty) { - QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This()); + QmlTypeWrapper *w = m->asQmlTypeWrapper(); + if (!m) + ctx->throwTypeError(); - if (!resource) - return QV4::Value::undefinedValue(); + if (hasProperty) + *hasProperty = true; - QV8Engine *v8engine = resource->engine; + QV8Engine *v8engine = w->v8; QQmlContextData *context = v8engine->callingContext(); - QObject *object = resource->object; + QObject *object = w->object; - QHashedV4String propertystring(property->v4Value()); + QHashedV4String propertystring(Value::fromString(name)); - if (resource->type) { - QQmlType *type = resource->type; + if (w->type) { + QQmlType *type = w->type; // singleton types are handled differently to other types. if (type->isSingleton()) { @@ -174,12 +143,10 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Handle<v8::String> property, QObject *qobjectSingleton = siinfo->qobjectApi(e); if (qobjectSingleton) { // check for enum value - if (property->v4Value().asString()->startsWithUpper()) { - if (resource->mode == IncludeEnums) { - QString name = property->v4Value().toQString(); - + if (name->startsWithUpper()) { + if (w->mode == IncludeEnums) { // ### Optimize - QByteArray enumName = name.toUtf8(); + QByteArray enumName = name->toQString().toUtf8(); const QMetaObject *metaObject = qobjectSingleton->metaObject(); for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { QMetaEnum e = metaObject->enumerator(ii); @@ -192,90 +159,89 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Handle<v8::String> property, } // check for property. - v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(qobjectSingleton, propertystring, context, QV8QObjectWrapper::IgnoreRevision); - return rv; + return v8engine->qobjectWrapper()->getProperty(qobjectSingleton, propertystring, context, QV8QObjectWrapper::IgnoreRevision)->v4Value(); } else if (!siinfo->scriptApi(e).isUndefined()) { QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. QV4::Object *o = QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine).asObject(); - if (!o) - return v8::Handle<v8::Value>(); - return v8::Value::fromV4Value(o->get(engine->current, property.get()->v4Value().toString(engine->current))); + if (o) + return o->get(engine->current, name); } - // Fall through to return empty handle + // Fall through to base implementation } else { - if (property->v4Value().asString()->startsWithUpper()) { + if (name->startsWithUpper()) { bool ok = false; int value = type->enumValue(propertystring, &ok); if (ok) return QV4::Value::fromInt32(value); - // Fall through to return empty handle + // Fall through to base implementation - } else if (resource->object) { + } else if (w->object) { QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) return v8engine->qobjectWrapper()->getProperty(ao, propertystring, context, - QV8QObjectWrapper::IgnoreRevision); + QV8QObjectWrapper::IgnoreRevision)->v4Value(); - // Fall through to return empty handle + // Fall through to base implementation } - // Fall through to return empty handle + // Fall through to base implementation } - // Fall through to return empty handle + // Fall through to base implementation - } else if (resource->typeNamespace) { - Q_ASSERT(resource->importNamespace); - QQmlTypeNameCache::Result r = resource->typeNamespace->query(propertystring, - resource->importNamespace); + } else if (w->typeNamespace) { + Q_ASSERT(w->importNamespace); + QQmlTypeNameCache::Result r = w->typeNamespace->query(propertystring, + w->importNamespace); if (r.isValid()) { QQmlContextData *context = v8engine->callingContext(); if (r.type) { - return v8engine->typeWrapper()->newObject(object, r.type, resource->mode); + return create(w->v8, object, r.type, w->mode); } else if (r.scriptIndex != -1) { int index = r.scriptIndex; if (index < context->importedScripts.count()) return context->importedScripts.at(index).value(); } else if (r.importNamespace) { - return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace); + return create(w->v8, object, context->imports, r.importNamespace); } return QV4::Value::undefinedValue(); } - // Fall through to return empty handle + // Fall through to base implementation } else { Q_ASSERT(!"Unreachable"); } - return v8::Handle<v8::Value>(); + if (hasProperty) + *hasProperty = false; + return Object::get(m, ctx, name, hasProperty); } -v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Handle<v8::String> property, - v8::Handle<v8::Value> value, - const v8::AccessorInfo &info) + +void QmlTypeWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value) { - QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This()); + QmlTypeWrapper *w = m->asQmlTypeWrapper(); - if (!resource) - return value; + if (!w) + ctx->throwTypeError(); - QV8Engine *v8engine = resource->engine; + QV8Engine *v8engine = w->v8; QQmlContextData *context = v8engine->callingContext(); - QHashedV4String propertystring(property->v4Value()); + QHashedV4String propertystring(Value::fromString(name)); - QQmlType *type = resource->type; - if (type && !type->isSingleton() && resource->object) { - QObject *object = resource->object; + QQmlType *type = w->type; + if (type && !type->isSingleton() && w->object) { + QObject *object = w->object; QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) v8engine->qobjectWrapper()->setProperty(ao, propertystring, context, value, @@ -290,20 +256,21 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Handle<v8::String> property, v8engine->qobjectWrapper()->setProperty(qobjectSingleton, propertystring, context, value, QV8QObjectWrapper::IgnoreRevision); } else if (!siinfo->scriptApi(e).isUndefined()) { - QV4::Value setVal = value.get()->v4Value(); QV4::Object *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e))->value.asObject(); if (!apiprivate) { - QString error = QLatin1String("Cannot assign to read-only property \"") + - property->v4Value().toQString() + QLatin1Char('\"'); - v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); + QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"'); + ctx->throwError(error); } else { QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); - apiprivate->put(engine->current, property.get()->v4Value().stringValue(), setVal); + apiprivate->put(engine->current, name, value); } } } +} - return value; +void QmlTypeWrapper::destroy(Managed *that) +{ + static_cast<QmlTypeWrapper *>(that)->~QmlTypeWrapper(); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8typewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 8ea1aef2d2..dc86991605 100644 --- a/src/qml/qml/v8/qv8typewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -54,42 +54,51 @@ // #include <QtCore/qglobal.h> -#include <private/qv8_p.h> +#include <private/qqmlguard_p.h> #include <private/qv4value_p.h> +#include <private/qv4object_p.h> QT_BEGIN_NAMESPACE -class QObject; class QV8Engine; -class QQmlType; class QQmlTypeNameCache; -class QV8TypeWrapper + +namespace QV4 { + +struct Q_QML_EXPORT QmlTypeWrapper : Object { +private: + QmlTypeWrapper(QV8Engine *engine); + ~QmlTypeWrapper(); + public: - QV8TypeWrapper(); - ~QV8TypeWrapper(); + enum TypeNameMode { IncludeEnums, ExcludeEnums }; - void init(QV8Engine *); - void destroy(); + QVariant toVariant() const; - enum TypeNameMode { IncludeEnums, ExcludeEnums }; - v8::Handle<v8::Object> newObject(QObject *, QQmlType *, TypeNameMode = IncludeEnums); - v8::Handle<v8::Object> newObject(QObject *, QQmlTypeNameCache *, const void *, - TypeNameMode = IncludeEnums); - QVariant toVariant(QV8ObjectResource *); + static QV4::Value create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums); + static QV4::Value create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums); + + + static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty); + static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value); + static void destroy(Managed *that); private: - static v8::Handle<v8::Value> Getter(v8::Handle<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Handle<v8::String> property, - v8::Handle<v8::Value> value, - const v8::AccessorInfo &info); - - QV8Engine *m_engine; - QV4::PersistentValue m_constructor; + QV8Engine *v8; + TypeNameMode mode; + QQmlGuard<QObject> object; + + QQmlType *type; + QQmlTypeNameCache *typeNamespace; + const void *importNamespace; + + const static ManagedVTable static_vtbl; }; +} + QT_END_NAMESPACE #endif // QV8TYPEWRAPPER_P_H diff --git a/src/qml/qml/v4/qv4managed_p.h b/src/qml/qml/v4/qv4managed_p.h index 5112cecfc0..fdcbcd49ce 100644 --- a/src/qml/qml/v4/qv4managed_p.h +++ b/src/qml/qml/v4/qv4managed_p.h @@ -82,6 +82,7 @@ struct VariantObject; struct QObjectWrapper; struct QtObject; struct QmlContextWrapper; +struct QmlTypeWrapper; struct ManagedVTable { @@ -186,7 +187,8 @@ public: // Qt Object Type_QtObject, - Type_QmlContext + Type_QmlContext, + Type_QmlTypeWrapper }; ExecutionEngine *engine() const; @@ -219,8 +221,9 @@ public: QQmlSequence<QStringList, Type_QmlQStringList> *asQmlQStringList() { return type == Type_QmlQStringList ? reinterpret_cast<QQmlSequence<QStringList, Type_QmlQStringList> *>(this): 0; } QQmlSequence<QList<QUrl>, Type_QmlUrlList> *asQmlUrlList() { return type == Type_QmlUrlList ? reinterpret_cast<QQmlSequence<QList<QUrl>, Type_QmlUrlList> *>(this): 0; } - QtObject *asQtObject() {return type == Type_QtObject ? reinterpret_cast<QtObject *>(this) : 0; } - QmlContextWrapper *asQmlContext() {return type == Type_QmlContext ? reinterpret_cast<QmlContextWrapper *>(this) : 0; } + QtObject *asQtObject() { return type == Type_QtObject ? reinterpret_cast<QtObject *>(this) : 0; } + QmlContextWrapper *asQmlContext() { return type == Type_QmlContext ? reinterpret_cast<QmlContextWrapper *>(this) : 0; } + QmlTypeWrapper *asQmlTypeWrapper() { return type == Type_QmlTypeWrapper ? reinterpret_cast<QmlTypeWrapper *>(this) : 0; } bool isListType() const { return type >= Type_QmlIntList && type <= Type_QmlUrlList; } diff --git a/src/qml/qml/v8/qv8contextwrapper.cpp b/src/qml/qml/v8/qv8contextwrapper.cpp index f95eba945c..b5f75f79f8 100644 --- a/src/qml/qml/v8/qv8contextwrapper.cpp +++ b/src/qml/qml/v8/qv8contextwrapper.cpp @@ -50,6 +50,7 @@ #include <private/qv4functionobject_p.h> #include <private/qv4objectproto_p.h> #include <private/qv4mm_p.h> +#include <private/qqmltypewrapper_p.h> QT_BEGIN_NAMESPACE @@ -115,82 +116,6 @@ QmlContextWrapper::~QmlContextWrapper() context->destroy(); } - - -QV8ContextWrapper::QV8ContextWrapper() - : m_engine(0), v4(0) -{ -} - -QV8ContextWrapper::~QV8ContextWrapper() -{ -} - -void QV8ContextWrapper::destroy() -{ -} - -void QV8ContextWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - v4 = QV8Engine::getV4(engine); -} - -QV4::Value QV8ContextWrapper::qmlScope(QQmlContextData *ctxt, QObject *scope) -{ - QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(m_engine, ctxt, scope); - w->prototype = v4->objectPrototype; - return Value::fromObject(w); -} - -QV4::Value QV8ContextWrapper::urlScope(const QUrl &url) -{ - QQmlContextData *context = new QQmlContextData; - context->url = url; - context->isInternal = true; - context->isJSContext = true; - - QmlContextWrapper *w = new (v4->memoryManager) QmlContextNullWrapper(m_engine, context, 0); - w->prototype = v4->objectPrototype; - return Value::fromObject(w); -} - -void QV8ContextWrapper::setReadOnly(const Value &qmlglobal, bool readOnly) -{ - Object *o = qmlglobal.asObject(); - QmlContextWrapper *c = o ? o->asQmlContext() : 0; - assert(c); - c->readOnly = readOnly; -} - -QQmlContextData *QV8ContextWrapper::callingContext() -{ - QV4::Object *qmlglobal = QV8Engine::getV4(m_engine)->qmlContextObject(); - if (!qmlglobal) - return 0; - - QmlContextWrapper *c = qmlglobal->asQmlContext(); - return c ? c->getContext() : 0; -} - -QQmlContextData *QV8ContextWrapper::context(const Value &value) -{ - Object *o = value.asObject(); - QmlContextWrapper *c = o ? o->asQmlContext() : 0; - if (!c) - return 0; - - return c ? c->getContext():0; -} - -void QV8ContextWrapper::takeContextOwnership(const Value &qmlglobal) -{ - Object *o = qmlglobal.asObject(); - QmlContextWrapper *c = o ? o->asQmlContext() : 0; - assert(c); - c->ownsContext = true; -} - Value QmlContextWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty) { QmlContextWrapper *resource = m->asQmlContext(); @@ -244,9 +169,9 @@ Value QmlContextWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bo else return QV4::Value::undefinedValue(); } else if (r.type) { - return engine->typeWrapper()->newObject(scopeObject, r.type)->v4Value(); + return QmlTypeWrapper::create(engine, scopeObject, r.type); } else if (r.importNamespace) { - return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace)->v4Value(); + return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace); } Q_ASSERT(!"Unreachable"); } @@ -327,18 +252,6 @@ Value QmlContextWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bo return Value::undefinedValue(); } -void QmlContextNullWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value) -{ - QmlContextWrapper *w = m->asQmlContext(); - if (w && w->readOnly) { - QString error = QLatin1String("Invalid write to global property \"") + name->toQString() + - QLatin1Char('"'); - ctx->throwError(Value::fromString(ctx->engine->newString(error))); - } - - Object::put(m, ctx, name, value); -} - void QmlContextWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value) { QmlContextWrapper *wrapper = m->asQmlContext(); @@ -405,5 +318,92 @@ void QmlContextWrapper::destroy(Managed *that) static_cast<QmlContextWrapper *>(that)->~QmlContextWrapper(); } +void QmlContextNullWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value) +{ + QmlContextWrapper *w = m->asQmlContext(); + if (w && w->readOnly) { + QString error = QLatin1String("Invalid write to global property \"") + name->toQString() + + QLatin1Char('"'); + ctx->throwError(Value::fromString(ctx->engine->newString(error))); + } + + Object::put(m, ctx, name, value); +} + + + +QV8ContextWrapper::QV8ContextWrapper() + : m_engine(0), v4(0) +{ +} + +QV8ContextWrapper::~QV8ContextWrapper() +{ +} + +void QV8ContextWrapper::destroy() +{ +} + +void QV8ContextWrapper::init(QV8Engine *engine) +{ + m_engine = engine; + v4 = QV8Engine::getV4(engine); +} + +QV4::Value QV8ContextWrapper::qmlScope(QQmlContextData *ctxt, QObject *scope) +{ + QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(m_engine, ctxt, scope); + w->prototype = v4->objectPrototype; + return Value::fromObject(w); +} + +QV4::Value QV8ContextWrapper::urlScope(const QUrl &url) +{ + QQmlContextData *context = new QQmlContextData; + context->url = url; + context->isInternal = true; + context->isJSContext = true; + + QmlContextWrapper *w = new (v4->memoryManager) QmlContextNullWrapper(m_engine, context, 0); + w->prototype = v4->objectPrototype; + return Value::fromObject(w); +} + +void QV8ContextWrapper::setReadOnly(const Value &qmlglobal, bool readOnly) +{ + Object *o = qmlglobal.asObject(); + QmlContextWrapper *c = o ? o->asQmlContext() : 0; + assert(c); + c->readOnly = readOnly; +} + +QQmlContextData *QV8ContextWrapper::callingContext() +{ + QV4::Object *qmlglobal = QV8Engine::getV4(m_engine)->qmlContextObject(); + if (!qmlglobal) + return 0; + + QmlContextWrapper *c = qmlglobal->asQmlContext(); + return c ? c->getContext() : 0; +} + +QQmlContextData *QV8ContextWrapper::context(const Value &value) +{ + Object *o = value.asObject(); + QmlContextWrapper *c = o ? o->asQmlContext() : 0; + if (!c) + return 0; + + return c ? c->getContext():0; +} + +void QV8ContextWrapper::takeContextOwnership(const Value &qmlglobal) +{ + Object *o = qmlglobal.asObject(); + QmlContextWrapper *c = o ? o->asQmlContext() : 0; + assert(c); + c->ownsContext = true; +} QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 7f12d984fa..272a7f0309 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -55,6 +55,7 @@ #include <private/qqmlmemoryprofiler_p.h> #include <private/qqmlplatform_p.h> #include <private/qjsvalue_p.h> +#include <private/qqmltypewrapper_p.h> #include "qv4domerrors_p.h" #include "qv4sqlerrors_p.h" @@ -153,7 +154,6 @@ QV8Engine::QV8Engine(QJSEngine* qq) m_contextWrapper.init(this); m_qobjectWrapper.init(this); - m_typeWrapper.init(this); m_listWrapper.init(this); m_valueTypeWrapper.init(this); m_jsonWrapper.init(m_v4Engine); @@ -174,7 +174,6 @@ QV8Engine::~QV8Engine() m_jsonWrapper.destroy(); m_valueTypeWrapper.destroy(); m_listWrapper.destroy(); - m_typeWrapper.destroy(); m_qobjectWrapper.destroy(); m_contextWrapper.destroy(); @@ -215,8 +214,6 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) case QV8ObjectResource::ParticleDataType: case QV8ObjectResource::ChangeSetArrayType: return QVariant(); - case QV8ObjectResource::TypeType: - return m_typeWrapper.toVariant(r); case QV8ObjectResource::ListType: return m_listWrapper.toVariant(r); case QV8ObjectResource::ValueTypeType: @@ -229,6 +226,8 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) return qVariantFromValue<QObject *>(wrapper->object); } else if (QV4::QmlContextWrapper *wrapper = object->asQmlContext()) { return QVariant(); + } else if (QV4::QmlTypeWrapper *w = object->asQmlTypeWrapper()) { + return w->toVariant(); } else if (object->isListType()) return QV4::SequencePrototype::toVariant(object); } diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 51c9f1accc..5f5df4ffcd 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -73,7 +73,6 @@ #include "qv8objectresource_p.h" #include "qv8contextwrapper_p.h" #include "qv8qobjectwrapper_p.h" -#include "qv8typewrapper_p.h" #include "qv8listwrapper_p.h" #include "qv8valuetypewrapper_p.h" #include <private/qv4sequenceobject_p.h> @@ -276,7 +275,6 @@ public: QV8ContextWrapper *contextWrapper() { return &m_contextWrapper; } QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; } - QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; } QV8ListWrapper *listWrapper() { return &m_listWrapper; } QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; } @@ -398,7 +396,6 @@ protected: QV8ContextWrapper m_contextWrapper; QV8QObjectWrapper m_qobjectWrapper; - QV8TypeWrapper m_typeWrapper; QV8ListWrapper m_listWrapper; QV8ValueTypeWrapper m_valueTypeWrapper; QV4JsonWrapper m_jsonWrapper; diff --git a/src/qml/qml/v8/qv8objectresource_p.h b/src/qml/qml/v8/qv8objectresource_p.h index ae648553bc..d6471188bb 100644 --- a/src/qml/qml/v8/qv8objectresource_p.h +++ b/src/qml/qml/v8/qv8objectresource_p.h @@ -69,7 +69,7 @@ class QV8ObjectResource : public v8::Object::ExternalResource { public: QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } - enum ResourceType { TypeType, ListType, + enum ResourceType { ListType, ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType, ListModelType, Context2DStyleType, Context2DPixelArrayType, ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType, diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 5277b37a78..fbe0461397 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -52,6 +52,7 @@ #include <private/qqmlaccessors_p.h> #include <private/qqmlexpression_p.h> #include <private/qqmlglobal_p.h> +#include <private/qqmltypewrapper_p.h> #include <private/qv4functionobject_p.h> #include <private/qv4runtime_p.h> @@ -157,10 +158,9 @@ QV4::Value QObjectWrapper::get(Managed *m, ExecutionContext *ctx, String *name, if (r.scriptIndex != -1) { return QV4::Value::undefinedValue(); } else if (r.type) { - return v8engine->typeWrapper()->newObject(object, r.type, QV8TypeWrapper::ExcludeEnums)->v4Value(); + return QmlTypeWrapper::create(v8engine, object, r.type, QmlTypeWrapper::ExcludeEnums); } else if (r.importNamespace) { - return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace, - QV8TypeWrapper::ExcludeEnums)->v4Value(); + return QmlTypeWrapper::create(v8engine, object, context->imports, r.importNamespace, QmlTypeWrapper::ExcludeEnums); } Q_ASSERT(!"Unreachable"); } diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri index 73feebb46d..6b1c0e9e73 100644 --- a/src/qml/qml/v8/v8.pri +++ b/src/qml/qml/v8/v8.pri @@ -7,7 +7,6 @@ HEADERS += \ $$PWD/qv8engine_p.h \ $$PWD/qv8contextwrapper_p.h \ $$PWD/qv8qobjectwrapper_p.h \ - $$PWD/qv8typewrapper_p.h \ $$PWD/qv8listwrapper_p.h \ $$PWD/qv8valuetypewrapper_p.h \ $$PWD/qv4jsonwrapper_p.h \ @@ -20,7 +19,6 @@ SOURCES += \ $$PWD/qv8engine.cpp \ $$PWD/qv8contextwrapper.cpp \ $$PWD/qv8qobjectwrapper.cpp \ - $$PWD/qv8typewrapper.cpp \ $$PWD/qv8listwrapper.cpp \ $$PWD/qv8valuetypewrapper.cpp \ $$PWD/qv4jsonwrapper.cpp \ |