diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-05-31 22:59:42 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-06-01 11:18:16 +0200 |
commit | 3dffcfd4f19b029f842848a7a08f0fe888a01956 (patch) | |
tree | cf626e4aedebace48df20cb5de7dc6e882623ded | |
parent | 4fee3da5a6057f1fc4b546def91ca0d5b55c04c0 (diff) |
Convert qqmlcomponent to use v4 API
Change-Id: I070053d6d66e289d6d737f2a33e18b5c41a49843
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 246 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8objectresource_p.h | 2 |
5 files changed, 127 insertions, 127 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 40503de179..c0c5abe7d4 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -99,8 +99,7 @@ public: QQmlComponentExtension(QV8Engine *); virtual ~QQmlComponentExtension(); - QV4::PersistentValue incubationConstructor; - QV4::PersistentValue forceCompletion; + QV4::PersistentValue incubationProto; }; V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); @@ -1079,37 +1078,33 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, enginePriv->incubate(incubator, forContextData); } -class QV8IncubatorResource : public QV8ObjectResource, - public QQmlIncubator +class QmlIncubatorObject : public QV4::Object, public QQmlIncubator { -V8_RESOURCE_TYPE(IncubatorType) + Q_MANAGED public: - QV8IncubatorResource(QV8Engine *engine, IncubationMode = Asynchronous); + QmlIncubatorObject(QV8Engine *engine, IncubationMode = Asynchronous); - static v8::Handle<v8::Value> StatusChangedGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info); - static v8::Handle<v8::Value> StatusGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info); - static v8::Handle<v8::Value> ObjectGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info); - static v8::Handle<v8::Value> ForceCompletionGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info); - static QV4::Value ForceCompletion(const v8::Arguments &args); + static QV4::Value method_get_statusChanged(QV4::SimpleCallContext *ctx); + static QV4::Value method_set_statusChanged(QV4::SimpleCallContext *ctx); + static QV4::Value method_get_status(QV4::SimpleCallContext *ctx); + static QV4::Value method_get_object(QV4::SimpleCallContext *ctx); + static QV4::Value method_forceCompletion(QV4::SimpleCallContext *ctx); - static void StatusChangedSetter(v8::Handle<v8::String>, v8::Handle<v8::Value> value, - const v8::AccessorInfo& info); + static void destroy(Managed *that); + static void markObjects(Managed *that); - void dispose(); - - QV4::PersistentValue me; + QV8Engine *v8; QQmlGuard<QObject> parent; - QV4::PersistentValue valuemap; - QV4::PersistentValue qmlGlobal; + QV4::Value valuemap; + QV4::Value qmlGlobal; + QV4::Value m_statusChanged; protected: virtual void statusChanged(Status); virtual void setInitialState(QObject *); }; +DEFINE_MANAGED_VTABLE(QmlIncubatorObject); + static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) { if (parent) { @@ -1184,19 +1179,19 @@ void QQmlComponent::createObject(QQmlV4Function *args) Q_ASSERT(args); QObject *parent = 0; - v8::Handle<v8::Object> valuemap; + QV4::Value valuemap = QV4::Value::emptyValue(); if (args->length() >= 1) parent = args->engine()->toQObject((*args)[0]); if (args->length() >= 2) { - v8::Handle<v8::Value> v = (*args)[1]; - if (!v->IsObject() || v->IsArray()) { + QV4::Value v = (*args)[1]; + if (!v.asObject() || v.asArrayObject()) { qmlInfo(this) << tr("createObject: value is not an object"); args->setReturnValue(QV4::Value::nullValue()); return; } - valuemap = v8::Handle<v8::Object>::Cast(v); + valuemap = v; } QV8Engine *v8engine = args->engine(); @@ -1214,14 +1209,13 @@ void QQmlComponent::createObject(QQmlV4Function *args) QQmlComponent_setQmlParent(rv, parent); - v8::Handle<v8::Value> ov = v8engine->newQObject(rv); - Q_ASSERT(ov->IsObject()); - v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov); + QV4::Value object = v8engine->newQObject(rv); + Q_ASSERT(object.asObject()); - if (!valuemap.IsEmpty()) { + if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()); - QV4::Value args[] = { object->v4Value(), valuemap->v4Value() }; + QV4::Value args[] = { object, valuemap }; f.asFunctionObject()->call(v4engine->current, QV4::Value::fromObject(v4engine->globalObject), args, 2); } @@ -1234,7 +1228,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) if (!rv) args->setReturnValue(QV4::Value::nullValue()); else - args->setReturnValue(object->v4Value()); + args->setReturnValue(object); } /*! @@ -1244,8 +1238,8 @@ void QQmlComponent::createObject(QQmlV4Function *args) instances to be instantiated asynchronously and not cause freezes in the UI. The \a parent argument specifies the parent the created instance will have. Omitting the - parameter or passing null will create anobject with no parent. In this case, a reference - to the created object must be maintained by the application of the object will eventually + parameter or passing null will create an object with no parent. In this case, a reference + to the created object must be maintained by the application or the object will eventually be garbage collected. The \a properties argument is specified as a map of property-value items which will be @@ -1304,21 +1298,21 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) Q_ASSERT(args); QObject *parent = 0; - v8::Handle<v8::Object> valuemap; + QV4::Value valuemap = QV4::Value::emptyValue(); QQmlIncubator::IncubationMode mode = QQmlIncubator::Asynchronous; if (args->length() >= 1) parent = args->engine()->toQObject((*args)[0]); if (args->length() >= 2) { - v8::Handle<v8::Value> v = (*args)[1]; - if (v->IsNull()) { - } else if (!v->IsObject() || v->IsArray()) { + QV4::Value v = (*args)[1]; + if (v.isNull()) { + } else if (!v.asObject() || v.asArrayObject()) { qmlInfo(this) << tr("createObject: value is not an object"); args->setReturnValue(QV4::Value::nullValue()); return; } else { - valuemap = v8::Handle<v8::Object>::Cast(v); + valuemap = v; } } @@ -1332,42 +1326,39 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) QQmlComponentExtension *e = componentExtension(args->engine()); - QV8IncubatorResource *r = new QV8IncubatorResource(args->engine(), mode); - v8::Handle<v8::Object> o = e->incubationConstructor.value().asFunctionObject()->newInstance(); - o->SetExternalResource(r); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(args->engine()); + QmlIncubatorObject *r = new (v4->memoryManager) QmlIncubatorObject(args->engine(), mode); + r->prototype = e->incubationProto.value().asObject(); - if (!valuemap.IsEmpty()) { - r->valuemap = valuemap->v4Value(); + if (!valuemap.isEmpty()) { + r->valuemap = valuemap; r->qmlGlobal = args->qmlGlobal(); } r->parent = parent; - r->me = o->v4Value(); create(*r, creationContext()); if (r->status() == QQmlIncubator::Null) { - r->dispose(); args->setReturnValue(QV4::Value::nullValue()); } else { - args->setReturnValue(o->v4Value()); + args->setReturnValue(QV4::Value::fromObject(r)); } } // XXX used by QSGLoader -void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate) +void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Value &qmlGlobal, const QV4::Value &valuemap, QObject *toCreate) { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV8Engine *v8engine = ep->v8engine(); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); - v8::Handle<v8::Value> ov = v8engine->newQObject(toCreate); - Q_ASSERT(ov->IsObject()); - v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov); + QV4::Value object = v8engine->newQObject(toCreate); + Q_ASSERT(object.asObject()); - if (!valuemap.IsEmpty()) { + if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); - QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal->v4Value().asObject()); - QV4::Value args[] = { object->v4Value(), valuemap->v4Value() }; + QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()); + QV4::Value args[] = { object, valuemap }; f.asFunctionObject()->call(v4engine->current, QV4::Value::fromObject(v4engine->globalObject), args, 2); } } @@ -1375,98 +1366,114 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handle<v8:: QQmlComponentExtension::QQmlComponentExtension(QV8Engine *engine) { - forceCompletion = (V8FUNCTION(QV8IncubatorResource::ForceCompletion, engine))->v4Value(); - - { - v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->SetInternalFieldCount(1); - ft->InstanceTemplate()->SetAccessor(v8::String::New("onStatusChanged"), - QV8IncubatorResource::StatusChangedGetter, - QV8IncubatorResource::StatusChangedSetter); - ft->InstanceTemplate()->SetAccessor(v8::String::New("status"), - QV8IncubatorResource::StatusGetter); - ft->InstanceTemplate()->SetAccessor(v8::String::New("object"), - QV8IncubatorResource::ObjectGetter); - ft->InstanceTemplate()->SetAccessor(v8::String::New("forceCompletion"), - QV8IncubatorResource::ForceCompletionGetter); - incubationConstructor = ft->GetFunction()->v4Value(); - } + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Object *proto = v4->newObject(); + QV4::Property *s = proto->insertMember(v4->newString(QStringLiteral("onStatusChanged")), + QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); + s->setGetter(V4FUNCTION(QmlIncubatorObject::method_get_statusChanged, v4)); + s->setSetter(V4FUNCTION(QmlIncubatorObject::method_set_statusChanged, v4)); + s = proto->insertMember(v4->newString(QStringLiteral("status")), + QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); + s->setGetter(V4FUNCTION(QmlIncubatorObject::method_get_status, v4)); + s = proto->insertMember(v4->newString(QStringLiteral("object")), + QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); + s->setGetter(V4FUNCTION(QmlIncubatorObject::method_get_object, v4)); + proto->defineDefaultProperty(v4, QStringLiteral("forceCompletion"), QmlIncubatorObject::method_forceCompletion); + + incubationProto = QV4::Value::fromObject(proto); } -v8::Handle<v8::Value> QV8IncubatorResource::ObjectGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info) +QV4::Value QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx) { - QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This()); - return r->engine->newQObject(r->object()); -} + QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>(); + if (!o) + ctx->throwTypeError(); -v8::Handle<v8::Value> QV8IncubatorResource::ForceCompletionGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info) -{ - QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This()); - return componentExtension(r->engine)->forceCompletion.value(); + return o->v8->newQObject(o->object()); } -QV4::Value QV8IncubatorResource::ForceCompletion(const v8::Arguments &args) +QV4::Value QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx) { - QV8IncubatorResource *r = v8_resource_cast<QV8IncubatorResource>(args.This()); - if (!r) - V4THROW_TYPE("Not an incubator object"); + QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>(); + if (!o) + ctx->throwTypeError(); - r->forceCompletion(); + o->forceCompletion(); return QV4::Value::undefinedValue(); } -v8::Handle<v8::Value> QV8IncubatorResource::StatusGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info) +QV4::Value QmlIncubatorObject::method_get_status(QV4::SimpleCallContext *ctx) { - QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This()); - return QV4::Value::fromUInt32(r->status()); + QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>(); + if (!o) + ctx->throwTypeError(); + + return QV4::Value::fromUInt32(o->status()); } -v8::Handle<v8::Value> QV8IncubatorResource::StatusChangedGetter(v8::Handle<v8::String>, - const v8::AccessorInfo& info) +QV4::Value QmlIncubatorObject::method_get_statusChanged(QV4::SimpleCallContext *ctx) { - return info.This()->GetInternalField(0); + QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>(); + if (!o) + ctx->throwTypeError(); + + return o->m_statusChanged; } -void QV8IncubatorResource::StatusChangedSetter(v8::Handle<v8::String>, v8::Handle<v8::Value> value, - const v8::AccessorInfo& info) +QV4::Value QmlIncubatorObject::method_set_statusChanged(QV4::SimpleCallContext *ctx) { - info.This()->SetInternalField(0, value); + QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>(); + if (!o || ctx->argumentCount < 1) + ctx->throwTypeError(); + + o->m_statusChanged = ctx->arguments[0]; + return QV4::Value::undefinedValue(); } QQmlComponentExtension::~QQmlComponentExtension() { } -QV8IncubatorResource::QV8IncubatorResource(QV8Engine *engine, IncubationMode m) -: QV8ObjectResource(engine), QQmlIncubator(m) +QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, IncubationMode m) + : Object(QV8Engine::getV4(engine)), QQmlIncubator(m) { + v8 = engine; + vtbl = &static_vtbl; } -void QV8IncubatorResource::setInitialState(QObject *o) +void QmlIncubatorObject::setInitialState(QObject *o) { QQmlComponent_setQmlParent(o, parent); if (!valuemap.isEmpty()) { - QQmlComponentExtension *e = componentExtension(engine); + QQmlComponentExtension *e = componentExtension(v8); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8); - QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.value().asObject()); - QV4::Value args[] = { engine->newQObject(o), valuemap }; + QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()); + QV4::Value args[] = { v8->newQObject(o), valuemap }; f.asFunctionObject()->call(v4->current, QV4::Value::fromObject(v4->globalObject), args, 2); } } -void QV8IncubatorResource::dispose() +void QmlIncubatorObject::destroy(Managed *that) { + QmlIncubatorObject *o = that->as<QmlIncubatorObject>(); + assert(o); + o->~QmlIncubatorObject(); } -void QV8IncubatorResource::statusChanged(Status s) +void QmlIncubatorObject::markObjects(QV4::Managed *that) +{ + QmlIncubatorObject *o = that->as<QmlIncubatorObject>(); + assert(o); + o->valuemap.mark(); + o->qmlGlobal.mark(); + o->m_statusChanged.mark(); +} + +void QmlIncubatorObject::statusChanged(Status s) { if (s == Ready) { Q_ASSERT(QQmlData::get(object())); @@ -1474,25 +1481,20 @@ void QV8IncubatorResource::statusChanged(Status s) QQmlData::get(object())->indestructible = false; } - if (!me.isEmpty()) { // Will be false in synchronous mode - QV4::Value callback = v8::Handle<v8::Object>(me)->GetInternalField(0)->v4Value(); - - if (QV4::FunctionObject *f = callback.asFunctionObject()) { - QV4::ExecutionContext *ctx = f->engine()->current; - QV4::Value args[] = { QV4::Value::fromUInt32(s) }; - try { - f->call(me.value(), args, 1); - } catch (QV4::Exception &e) { - e.accept(ctx); - QQmlError error; - QQmlJavaScriptExpression::exceptionToError(e, error); - QQmlEnginePrivate::warning(QQmlEnginePrivate::get(engine->engine()), error); - } + QV4::Value callback = m_statusChanged; + + if (QV4::FunctionObject *f = callback.asFunctionObject()) { + QV4::ExecutionContext *ctx = f->engine()->current; + QV4::Value args[] = { QV4::Value::fromUInt32(s) }; + try { + f->call(QV4::Value::fromObject(this), args, 1); + } catch (QV4::Exception &e) { + e.accept(ctx); + QQmlError error; + QQmlJavaScriptExpression::exceptionToError(e, error); + QQmlEnginePrivate::warning(QQmlEnginePrivate::get(v8->engine()), error); } } - - if (s == Ready || s == Error) - dispose(); } #undef INITIALPROPERTIES_SOURCE diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 37cb234d42..439f1fcdd9 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -55,7 +55,6 @@ #include "qqmlcomponent.h" -#include <private/qv8_p.h> #include "qqmlengine_p.h" #include "qqmltypeloader_p.h" #include <private/qbitfield_p.h> @@ -91,7 +90,7 @@ public: QObject *beginCreate(QQmlContextData *); void completeCreate(); - void initializeObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate); + void initializeObjectWithInitialProperties(const QV4::Value &qmlGlobal, const QV4::Value &valuemap, QObject *toCreate); QQmlTypeData *typeData; virtual void typeDataReady(QQmlTypeData *); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 0506118956..b52d85efc8 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -146,7 +146,6 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) case QV8ObjectResource::Context2DStyleType: case QV8ObjectResource::Context2DPixelArrayType: case QV8ObjectResource::SignalHandlerType: - case QV8ObjectResource::IncubatorType: case QV8ObjectResource::VisualDataItemType: case QV8ObjectResource::XMLHttpRequestType: case QV8ObjectResource::DOMNodeType: diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 17a31f2f91..b50c46244e 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -84,7 +84,7 @@ namespace QV4 { struct Value; } -#define V4FUNCTION(function, engine) new QV4::BuiltinFunctionOld(engine->rootContext, engine->id_undefined, function) +#define V4FUNCTION(function, engine) new (engine->memoryManager) QV4::BuiltinFunctionOld(engine->rootContext, engine->id_undefined, function) // Uncomment the following line to enable global handle debugging. When enabled, all the persistent // handles allocated using qPersistentNew() (or registered with qPersistentRegsiter()) and disposed diff --git a/src/qml/qml/v8/qv8objectresource_p.h b/src/qml/qml/v8/qv8objectresource_p.h index e477bba2d4..382259700c 100644 --- a/src/qml/qml/v8/qv8objectresource_p.h +++ b/src/qml/qml/v8/qv8objectresource_p.h @@ -71,7 +71,7 @@ public: QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } enum ResourceType { XMLHttpRequestType, DOMNodeType, SQLDatabaseType, ListModelType, Context2DStyleType, Context2DPixelArrayType, - ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType, + ParticleDataType, SignalHandlerType, VisualDataItemType, ChangeSetArrayType }; virtual ResourceType resourceType() const = 0; |