From: Simon Hausmann Date: Tue, 4 Jun 2013 14:35:00 +0000 (+0200) Subject: Move QV8QObjectWrapper::newQObject into QV4::QObjectWrapper X-Git-Tag: upstream/5.2.1~669^2~324 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0e32d311a791910acef672b1ab9a2ac4a80171e;p=platform%2Fupstream%2Fqtdeclarative.git Move QV8QObjectWrapper::newQObject into QV4::QObjectWrapper ...where it is just called wrap(), because it doesn't always create a new JS wrapper for the QObject. Change-Id: Ieed0fc97174eb51cd04df0149e715c234a5822bd Reviewed-by: Lars Knoll --- diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 9688f71..7e54927 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -242,7 +242,7 @@ void QQmlBoundSignalExpression::evaluate(void **a) if (!*reinterpret_cast(a[ii + 1])) args[ii] = QV4::Value::nullValue(); else - args[ii] = engine->newQObject(*reinterpret_cast(a[ii + 1])); + args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast(a[ii + 1])); } else { args[ii] = engine->fromVariant(QVariant(type, a[ii + 1])); } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index b580f6b..bfdce45 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1211,7 +1211,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) QQmlComponent_setQmlParent(rv, parent); - QV4::Value object = v8engine->newQObject(rv); + QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, rv); Q_ASSERT(object.asObject()); if (!valuemap.isEmpty()) { @@ -1356,7 +1356,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu QV8Engine *v8engine = ep->v8engine(); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); - QV4::Value object = v8engine->newQObject(toCreate); + QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, toCreate); Q_ASSERT(object.asObject()); if (!valuemap.isEmpty()) { @@ -1395,7 +1395,7 @@ QV4::Value QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx) if (!o) ctx->throwTypeError(); - return o->v8->newQObject(o->object()); + return QV4::QObjectWrapper::wrap(ctx->engine, o->object()); } QV4::Value QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx) @@ -1458,7 +1458,7 @@ void QmlIncubatorObject::setInitialState(QObject *o) QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8); QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()); - QV4::Value args[] = { v8->newQObject(o), valuemap }; + QV4::Value args[] = { QV4::QObjectWrapper::wrap(v4, o), valuemap }; f.asFunctionObject()->call(v4->current, QV4::Value::fromObject(v4->globalObject), args, 2); } } diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index cdbd6e7..4d8a8ac 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -204,7 +204,7 @@ Value QmlContextWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bo ep->captureProperty(&context->idValues[propertyIdx].bindings); if (hasProperty) *hasProperty = true; - return engine->newQObject(context->idValues[propertyIdx]); + return QV4::QObjectWrapper::wrap(ctx->engine, context->idValues[propertyIdx]); } else { QQmlContextPrivate *cp = context->asQQmlContextPrivate(); @@ -229,7 +229,7 @@ Value QmlContextWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bo // Search scope object if (scopeObject) { - if (QV4::QObjectWrapper *o = qobjectWrapper->newQObject(scopeObject)->v4Value().as()) { + if (QV4::QObjectWrapper *o = QV4::QObjectWrapper::wrap(ctx->engine, scopeObject).as()) { bool hasProp = false; QV4::Value result = o->getQmlProperty(o->engine()->current, propertystring.string().asString(), QV4::QObjectWrapper::CheckRevision, &hasProp); if (hasProp) { diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 39927c7..62e4ee9 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -152,6 +152,7 @@ public: int inProgressCreations; QV8Engine *v8engine() const { return q_func()->handle(); } + QV4::ExecutionEngine *v4engine() const { return QV8Engine::getV4(q_func()->handle()); } QQuickWorkerScriptEngine *getWorkerScriptEngine(); QQuickWorkerScriptEngine *workerScriptEngine; @@ -239,6 +240,7 @@ public: static void warning(QQmlEnginePrivate *, const QList &); inline static QV8Engine *getV8Engine(QQmlEngine *e); + inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e); inline static QQmlEnginePrivate *get(QQmlEngine *e); inline static const QQmlEnginePrivate *get(const QQmlEngine *e); inline static QQmlEnginePrivate *get(QQmlContext *c); @@ -465,7 +467,14 @@ QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e) { Q_ASSERT(e); - return e->d_func()->v8engine(); + return e->d_func()->v8engine(); +} + +QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) +{ + Q_ASSERT(e); + + return e->d_func()->v4engine(); } QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 863432b..6670948 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -160,7 +160,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, try { QV4::Value This = ep->v8engine()->global(); if (scopeObject() && requiresThisObject()) { - QV4::Value value = ep->v8engine()->newQObject(scopeObject()); + QV4::Value value = QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()); if (value.isObject()) This = value; } diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 6d49b54..ec34905 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -119,7 +119,7 @@ Value QmlListWrapper::getIndexed(Managed *m, ExecutionContext *ctx, uint index, quint32 count = w->property.count ? w->property.count(&w->property) : 0; if (index < count && w->property.at) - return w->v8->newQObject(w->property.at(&w->property, index)); + return QV4::QObjectWrapper::wrap(ctx->engine, w->property.at(&w->property, index)); return Value::undefinedValue(); } diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index f12f5dd..2e09cf4 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -369,7 +369,7 @@ QObject *QQmlVME::run(QList *errors, // Store a created object in a property. These all pop from the objects stack. QML_STORE_VALUE(StoreObject, QObject *, objects.pop()); QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop())); - QML_STORE_VAR(StoreVarObject, ep->v8engine()->newQObject(objects.pop())); + QML_STORE_VAR(StoreVarObject, QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop())); // Store a literal value in a corresponding property QML_STORE_VALUE(StoreFloat, float, instr.value); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 108fb79..233533e 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1207,8 +1207,8 @@ bool QQmlVMEMetaObject::ensureVarPropertiesAllocated() void QQmlVMEMetaObject::ensureQObjectWrapper() { QQmlEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QQmlEnginePrivate::get(ctxt->engine); - QV8Engine *v8e = (ep == 0) ? 0 : ep->v8engine(); - v8e->newQObject(object); + QV4::ExecutionEngine *v4 = (ep == 0) ? 0 : ep->v4engine(); + QV4::QObjectWrapper::wrap(v4, object); } void QQmlVMEMetaObject::mark() diff --git a/src/qml/qml/v4/qv4serialize.cpp b/src/qml/qml/v4/qv4serialize.cpp index 88119fb..a9b95ce 100644 --- a/src/qml/qml/v4/qv4serialize.cpp +++ b/src/qml/qml/v4/qv4serialize.cpp @@ -360,7 +360,7 @@ QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine) { void *ptr = popPtr(data); QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr; - QV4::Value rv = engine->newQObject(agent); + QV4::Value rv = QV4::QObjectWrapper::wrap(v4, agent); // ### Find a better solution then the ugly property QQmlListModelWorkerAgent::VariantRef ref(agent); QVariant var = qVariantFromValue(ref); diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp index d1a2c73..d072c3a 100644 --- a/src/qml/qml/v8/qjsengine.cpp +++ b/src/qml/qml/v8/qjsengine.cpp @@ -318,7 +318,8 @@ QJSValue QJSEngine::newArray(uint length) QJSValue QJSEngine::newQObject(QObject *object) { Q_D(QJSEngine); - return new QJSValuePrivate(QV8Engine::getV4(d), d->newQObject(object, QV8Engine::JavaScriptOwnership)); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(d); + return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object)); } /*! diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index ac2a2a0..058c9ca 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1037,7 +1037,7 @@ Value QtObject::method_createQmlObject(SimpleCallContext *ctx) Q_ASSERT(obj); - return v8engine->newQObject(obj); + return QV4::QObjectWrapper::wrap(ctx->engine, obj); } /*! @@ -1131,7 +1131,7 @@ Value QtObject::method_createComponent(SimpleCallContext *ctx) QQmlData::get(c, true)->explicitIndestructibleSet = false; QQmlData::get(c)->indestructible = false; - return v8engine->newQObject(c); + return QV4::QObjectWrapper::wrap(ctx->engine, c); } /*! @@ -1245,7 +1245,7 @@ Value QtObject::method_get_platform(SimpleCallContext *ctx) // Only allocate a platform object once qt->m_platform = new QQmlPlatform(ctx->engine->v8Engine->publicEngine()); - return ctx->engine->v8Engine->newQObject(qt->m_platform); + return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform); } Value QtObject::method_get_application(SimpleCallContext *ctx) @@ -1262,14 +1262,15 @@ Value QtObject::method_get_application(SimpleCallContext *ctx) // Only allocate an application object once qt->m_application = QQml_guiProvider()->application(ctx->engine->v8Engine->publicEngine()); - return ctx->engine->v8Engine->newQObject(qt->m_application); + return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application); } #ifndef QT_NO_IM Value QtObject::method_get_inputMethod(SimpleCallContext *ctx) { - QV8Engine *engine = ctx->engine->v8Engine; - return engine->newQObject(QQml_guiProvider()->inputMethod(), QV8Engine::CppOwnership); + QObject *o = QQml_guiProvider()->inputMethod(); + QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership); + return QV4::QObjectWrapper::wrap(ctx->engine, o); } #endif diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index f6b67fe..f37006b 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -275,7 +275,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) case QMetaType::QRegExp: return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(ptr))); case QMetaType::QObjectStar: - return newQObject(*reinterpret_cast(ptr)); + return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(ptr)); case QMetaType::QStringList: { bool succeeded = false; @@ -321,14 +321,14 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) QV4::ArrayObject *a = m_v4Engine->newArrayObject(); a->setArrayLength(list.count()); for (int ii = 0; ii < list.count(); ++ii) - a->arrayData[ii].value = newQObject(list.at(ii)); + a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)); return QV4::Value::fromObject(a); } bool objOk; QObject *obj = QQmlMetaType::toQObject(variant, &objOk); if (objOk) - return newQObject(obj); + return QV4::QObjectWrapper::wrap(m_v4Engine, obj); bool succeeded = false; v8::Handle retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded); @@ -703,7 +703,7 @@ QV4::Value QV8Engine::metaTypeToJS(int type, const void *data) result = QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(data))); break; case QMetaType::QObjectStar: - result = newQObject(*reinterpret_cast(data)); + result = QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(data)); break; case QMetaType::QVariant: result = variantToJS(*reinterpret_cast(data)); diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 1b06d7f..de64af1 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -256,10 +256,6 @@ public: QVariant toVariant(const QV4::Value &value, int typeHint); QV4::Value fromVariant(const QVariant &); - // Return a JS wrapper for the given QObject \a object - inline QV4::Value newQObject(QObject *object); - inline QV4::Value newQObject(QObject *object, const ObjectOwnership ownership); - // Return a JS string for the given QString \a string QV4::Value toString(const QString &string); @@ -344,25 +340,6 @@ private: Q_DISABLE_COPY(QV8Engine) }; -QV4::Value QV8Engine::newQObject(QObject *object) -{ - return m_qobjectWrapper.newQObject(object)->v4Value(); -} - -QV4::Value QV8Engine::newQObject(QObject *object, const ObjectOwnership ownership) -{ - if (!object) - return QV4::Value::nullValue(); - - QV4::Value result = newQObject(object); - QQmlData *ddata = QQmlData::get(object, true); - if (ownership == JavaScriptOwnership && ddata) { - ddata->indestructible = false; - ddata->explicitIndestructibleSet = true; - } - return result; -} - QV8Engine::Deletable *QV8Engine::extensionData(int index) const { if (index < m_extensionData.count()) diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 2f2dcd6..fb0db7c 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -176,7 +176,57 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, String *name, QObjec return QV4::Object::get(this, ctx, name, hasProperty); } -QV4::Value QObjectWrapper::wrap(ExecutionEngine *engine, QQmlData *ddata, QObject *object) +Value QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) +{ + if (QQmlData::wasDeleted(object)) + return QV4::Value::nullValue(); + + QQmlData *ddata = QQmlData::get(object, true); + if (!ddata) + return QV4::Value::undefinedValue(); + + if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isEmpty()) { + // We own the v8object + return ddata->jsWrapper.value(); + } else if (ddata->jsWrapper.isEmpty() && + (ddata->jsEngineId == engine->m_engineId || // We own the QObject + ddata->jsEngineId == 0 || // No one owns the QObject + !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted + + QV4::Value rv = create(engine, ddata, object); + ddata->jsWrapper = rv; + ddata->jsEngineId = engine->m_engineId; + return rv; + + } else { + // If this object is tainted, we have to check to see if it is in our + // tainted object list + Object *alternateWrapper = 0; + if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) + alternateWrapper = engine->m_multiplyWrappedQObjects->value(object); + + // If our tainted handle doesn't exist or has been collected, and there isn't + // a handle in the ddata, we can assume ownership of the ddata->v8object + if (ddata->jsWrapper.isEmpty() && !alternateWrapper) { + QV4::Value result = create(engine, ddata, object); + ddata->jsWrapper = result; + ddata->jsEngineId = engine->m_engineId; + return result; + } + + if (!alternateWrapper) { + alternateWrapper = create(engine, ddata, object).asObject(); + if (!engine->m_multiplyWrappedQObjects) + engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap; + engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper); + ddata->hasTaintedV8Object = true; + } + + return QV4::Value::fromObject(alternateWrapper); + } +} + +QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object) { QQmlEngine *qmlEngine = engine->v8Engine->engine(); if (!ddata->propertyCache && qmlEngine) { @@ -389,7 +439,7 @@ static inline QV4::Value valueToHandle(QV8Engine *, float v) static inline QV4::Value valueToHandle(QV8Engine *, double v) { return QV4::Value::fromDouble(v); } static inline QV4::Value valueToHandle(QV8Engine *e, QObject *v) -{ return e->newQObject(v); } +{ return QV4::QObjectWrapper::wrap(QV8Engine::getV4(e), v); } void QV8QObjectWrapper::init(QV8Engine *engine) { @@ -409,11 +459,12 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, QQmlNotifier **notifier) { Q_ASSERT(!property.isFunction()); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); if (property.isQObject()) { QObject *rv = 0; ReadFunction(object, property, &rv, notifier); - return engine->newQObject(rv); + return QV4::QObjectWrapper::wrap(v4, rv); } else if (property.isQList()) { return QmlListWrapper::create(engine, object, property.coreIndex, property.propType); } else if (property.propType == QMetaType::QReal) { @@ -451,7 +502,7 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, } else if (property.propType == qMetaTypeId()) { QJSValue v; ReadFunction(object, property, &v, notifier); - return QJSValuePrivate::get(v)->getValue(QV8Engine::getV4(engine)); + return QJSValuePrivate::get(v)->getValue(v4); } else if (property.isQVariant()) { QVariant v; ReadFunction(object, property, &v, notifier); @@ -472,7 +523,7 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, // see if it's a sequence type bool succeeded = false; - QV4::Value retn = QV4::SequencePrototype::newSequence(QV8Engine::getV4(engine), property.propType, object, property.coreIndex, &succeeded); + QV4::Value retn = QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded); if (succeeded) return retn; } @@ -763,73 +814,6 @@ static void FastValueSetterReadOnly(v8::Handle property, v8::Handle< v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); } -/* -As V8 doesn't support an equality callback, for QObject's we have to return exactly the same -V8 handle for subsequent calls to newQObject for the same QObject. To do this we have a two -pronged strategy: - 1. If there is no current outstanding V8 handle to the QObject, we create one and store a - persistent handle in QQmlData::v8object. We mark the QV8QObjectWrapper that - "owns" this handle by setting the QQmlData::v8objectid to the id of this - QV8QObjectWrapper. - 2. If another QV8QObjectWrapper has create the handle in QQmlData::v8object we create - an entry in the m_taintedObject hash where we store the handle and mark the object as - "tainted" in the QQmlData::hasTaintedV8Object flag. -We have to mark the object as tainted to ensure that we search our m_taintedObject hash even -in the case that the original QV8QObjectWrapper owner of QQmlData::v8object has -released the handle. -*/ -v8::Handle QV8QObjectWrapper::newQObject(QObject *object) -{ - if (QQmlData::wasDeleted(object)) - return QV4::Value::nullValue(); - - QQmlData *ddata = QQmlData::get(object, true); - if (!ddata) - return QV4::Value::undefinedValue(); - - QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_engine); - - if (ddata->jsEngineId == v4->m_engineId && !ddata->jsWrapper.isEmpty()) { - // We own the v8object - return ddata->jsWrapper.value(); - } else if (ddata->jsWrapper.isEmpty() && - (ddata->jsEngineId == v4->m_engineId || // We own the QObject - ddata->jsEngineId == 0 || // No one owns the QObject - !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted - - QV4::Value rv = QV4::QObjectWrapper::wrap(v4, ddata, object); - ddata->jsWrapper = rv; - ddata->jsEngineId = v4->m_engineId; - return rv; - - } else { - // If this object is tainted, we have to check to see if it is in our - // tainted object list - Object *alternateWrapper = 0; - if (v4->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) - alternateWrapper = v4->m_multiplyWrappedQObjects->value(object); - - // If our tainted handle doesn't exist or has been collected, and there isn't - // a handle in the ddata, we can assume ownership of the ddata->v8object - if (ddata->jsWrapper.isEmpty() && !alternateWrapper) { - QV4::Value result = QV4::QObjectWrapper::wrap(v4, ddata, object); - ddata->jsWrapper = result; - ddata->jsEngineId = v4->m_engineId; - return result; - } - - if (!alternateWrapper) { - alternateWrapper = QV4::QObjectWrapper::wrap(v4, ddata, object).asObject(); - if (!v4->m_multiplyWrappedQObjects) - v4->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap; - v4->m_multiplyWrappedQObjects->insert(object, alternateWrapper); - ddata->hasTaintedV8Object = true; - } - - return QV4::Value::fromObject(alternateWrapper); - } -} - QPair QV8QObjectWrapper::ExtractQtSignal(QV8Engine *engine, const Value &value) { if (QV4::FunctionObject *function = value.asFunctionObject()) @@ -1736,8 +1720,9 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value & QV4::Value CallArgument::toValue(QV8Engine *engine) { + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); if (type == qMetaTypeId()) { - return QJSValuePrivate::get(*qjsValuePtr)->getValue(QV8Engine::getV4(engine)); + return QJSValuePrivate::get(*qjsValuePtr)->getValue(v4); } else if (type == QMetaType::Int) { return QV4::Value::fromInt32(int(intValue)); } else if (type == QMetaType::UInt) { @@ -1754,26 +1739,26 @@ QV4::Value CallArgument::toValue(QV8Engine *engine) QObject *object = qobjectPtr; if (object) QQmlData::get(object, true)->setImplicitDestructible(); - return engine->newQObject(object); + return QV4::QObjectWrapper::wrap(v4, object); } else if (type == qMetaTypeId >()) { // XXX Can this be made more by using Array as a prototype and implementing // directly against QList? QList &list = *qlistPtr; - QV4::ArrayObject *array = QV8Engine::getV4(engine)->newArrayObject(); + QV4::ArrayObject *array = v4->newArrayObject(); array->arrayReserve(list.count()); for (int ii = 0; ii < list.count(); ++ii) - array->arrayData[ii].value = engine->newQObject(list.at(ii)); + array->arrayData[ii].value = QV4::QObjectWrapper::wrap(v4, list.at(ii)); array->arrayDataLen = list.count(); array->setArrayLengthUnchecked(list.count()); return QV4::Value::fromObject(array); } else if (type == qMetaTypeId()) { return handlePtr->toValue(); } else if (type == QMetaType::QJsonArray) { - return QV4::JsonObject::fromJsonArray(QV8Engine::getV4(engine), *jsonArrayPtr); + return QV4::JsonObject::fromJsonArray(v4, *jsonArrayPtr); } else if (type == QMetaType::QJsonObject) { - return QV4::JsonObject::fromJsonObject(QV8Engine::getV4(engine), *jsonObjectPtr); + return QV4::JsonObject::fromJsonObject(v4, *jsonObjectPtr); } else if (type == QMetaType::QJsonValue) { - return QV4::JsonObject::fromJsonValue(QV8Engine::getV4(engine), *jsonValuePtr); + return QV4::JsonObject::fromJsonValue(v4, *jsonValuePtr); } else if (type == -1 || type == qMetaTypeId()) { QVariant value = *qvariantPtr; QV4::Value rv = engine->fromVariant(value); diff --git a/src/qml/qml/v8/qv8qobjectwrapper_p.h b/src/qml/qml/v8/qv8qobjectwrapper_p.h index 17e50fd..a025420 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper_p.h +++ b/src/qml/qml/v8/qv8qobjectwrapper_p.h @@ -92,10 +92,11 @@ struct Q_QML_EXPORT QObjectWrapper : public QV4::Object Value getQmlProperty(ExecutionContext *ctx, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false); - // ### Make private when QV8QObjectWrapper is gone. - static Value wrap(ExecutionEngine *engine, QQmlData *ddata, QObject *object); + static Value wrap(ExecutionEngine *engine, QObject *object); private: + static Value create(ExecutionEngine *engine, QQmlData *ddata, QObject *object); + QObjectWrapper(ExecutionEngine *engine, QObject *object); QQmlGuard m_object; @@ -197,8 +198,6 @@ public: void init(QV8Engine *); void destroy(); - v8::Handle newQObject(QObject *object); - inline v8::Handle getProperty(QObject *, const QHashedV4String &, QQmlContextData *, QV4::QObjectWrapper::RevisionMode); inline bool setProperty(QObject *, const QHashedV4String &, QQmlContextData *, v8::Handle, QV4::QObjectWrapper::RevisionMode); diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index d8683f5..4cef103 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -2505,7 +2505,7 @@ void QQmlDelegateModelGroup::create(QQmlV4Function *args) model->m_cache.at(it.cacheIndex)->releaseObject(); } - args->setReturnValue(args->engine()->newQObject(object)); + args->setReturnValue(QV4::QObjectWrapper::wrap(QV8Engine::getV4(args->engine()), object)); model->emitChanges(); } diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 9311ad0..cb05464 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -138,7 +138,7 @@ public: int modelIndex() const { return index; } void setModelIndex(int idx) { index = idx; emit modelIndexChanged(); } - virtual v8::Handle get() { return engine->newQObject(this); } + virtual v8::Handle get() { return QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), this); } virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; } diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index f016a9a..8e18210 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -2103,14 +2103,14 @@ QQmlV4Handle QQmlListModel::get(int index) const QV4::Value result = QV4::Value::undefinedValue(); if (index >= 0 && index < count()) { - QV8Engine *v8engine = engine(); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine()); if (m_dynamicRoles) { DynamicRoleModelNode *object = m_modelObjects[index]; - result = v8engine->newQObject(object); + result = QV4::QObjectWrapper::wrap(v4, object); } else { ModelObject *object = m_listModel->getOrCreateModelObject(const_cast(this), index); - result = v8engine->newQObject(object); + result = QV4::QObjectWrapper::wrap(v4, object); } } diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 3d272c6..e754653 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -659,7 +659,8 @@ void QQuickCanvasItem::updatePolish() d->animationCallbacks.clear(); foreach (int key, animationCallbacks.keys()) { - QV4::Value self = QQmlEnginePrivate::getV8Engine(qmlEngine(this))->newQObject(this); + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this)); + QV4::Value self = QV4::QObjectWrapper::wrap(v4, this); QV4::Value args[] = { QV4::Value::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t()) }; QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject(); f->call(self, args, 1); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index e73ec33..7d1e391 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -478,7 +478,7 @@ static v8::Handle ctx2d_canvas(v8::Handle, const v8::Acce QV8Engine *engine = V8ENGINE_ACCESSOR(); - return engine->newQObject(r->context->canvas()); + return QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), r->context->canvas()); } /*! diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 261e0c2..14dc6d9 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -2247,7 +2247,7 @@ void tst_qqmlecmascript::callQtInvokables() QV8Engine *engine = ep->v8engine(); - v8::Handle object = engine->newQObject(o); + v8::Handle object = QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o); // Non-existent methods o->reset();