From: Lars Knoll Date: Sat, 27 Apr 2013 14:01:41 +0000 (-0700) Subject: Convert some code in qqmlcomponent over to use v4 X-Git-Tag: upstream/5.2.1~669^2~600 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7c4159556945117ef57c5021eca12b6f96a969cc;p=platform%2Fupstream%2Fqtdeclarative.git Convert some code in qqmlcomponent over to use v4 Add an evaluateScript() method to qv8engine, that replaces the v8::Script class Change-Id: I00e0e18d4e3dbcba26632ca3492749a6b0f1a7f0 Reviewed-by: Simon Hausmann --- diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 5c123a6..70e4ec2 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -61,6 +61,8 @@ #include #include +#include + #include #include #include @@ -68,6 +70,23 @@ #include #include "qqmlmemoryprofiler_p.h" +#define INITIALPROPERTIES_SOURCE \ + "(function(object, values) {"\ + "try {"\ + "for (var property in values) {" \ + "try {"\ + "var properties = property.split(\".\");"\ + "var o = object;"\ + "for (var ii = 0; ii < properties.length - 1; ++ii) {"\ + "o = o[properties[ii]];"\ + "}"\ + "o[properties[properties.length - 1]] = values[property];"\ + "} catch(e) {}"\ + "}"\ + "} catch(e) {}"\ + "})" + + namespace { QThreadStorage creationDepth; } @@ -81,7 +100,6 @@ public: virtual ~QQmlComponentExtension(); v8::Persistent incubationConstructor; - v8::Persistent initialProperties; v8::Persistent forceCompletion; }; V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); @@ -1182,6 +1200,7 @@ void QQmlComponent::createObject(QQmlV8Function *args) } QV8Engine *v8engine = args->engine(); + QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); QQmlContext *ctxt = creationContext(); if (!ctxt) ctxt = d->engine->rootContext(); @@ -1201,10 +1220,9 @@ void QQmlComponent::createObject(QQmlV8Function *args) if (!valuemap.IsEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); - // Try catch isn't needed as the function itself is loaded with try/catch - v8::Handle function = e->initialProperties->Run(args->qmlGlobal()); - v8::Handle args[] = { object, valuemap }; - v8::Handle::Cast(function)->Call(v8engine->global(), 2, args); + QV4::Value f = v8engine->evaluateScript(QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal()->v4Value().asObject()); + QV4::Value args[] = { object->v4Value(), valuemap->v4Value() }; + f.asFunctionObject()->call(v4engine->current, QV4::Value::fromObject(v4engine->globalObject), args, 2); } d->completeCreate(); @@ -1340,6 +1358,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handlev8engine(); + QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); v8::HandleScope handle_scope; v8::Context::Scope scope(v8engine->context()); @@ -1349,10 +1368,9 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handle function = e->initialProperties->Run(qmlGlobal); - v8::Handle args[] = { object, valuemap }; - v8::Handle::Cast(function)->Call(v8engine->global(), 2, args); + QV4::Value f = v8engine->evaluateScript(QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal->v4Value().asObject()); + QV4::Value args[] = { object->v4Value(), valuemap->v4Value() }; + f.asFunctionObject()->call(v4engine->current, QV4::Value::fromObject(v4engine->globalObject), args, 2); } } @@ -1379,26 +1397,6 @@ QQmlComponentExtension::QQmlComponentExtension(QV8Engine *engine) QV8IncubatorResource::ForceCompletionGetter); incubationConstructor = qPersistentNew(ft->GetFunction()); } - - { -#define INITIALPROPERTIES_SOURCE \ - "(function(object, values) {"\ - "try {"\ - "for(var property in values) {" \ - "try {"\ - "var properties = property.split(\".\");"\ - "var o = object;"\ - "for (var ii = 0; ii < properties.length - 1; ++ii) {"\ - "o = o[properties[ii]];"\ - "}"\ - "o[properties[properties.length - 1]] = values[property];"\ - "} catch(e) {}"\ - "}"\ - "} catch(e) {}"\ - "})" - initialProperties = qPersistentNew(engine->qmlModeCompile(QLatin1String(INITIALPROPERTIES_SOURCE))); -#undef INITIALPROPERTIES_SOURCE - } } v8::Handle QV8IncubatorResource::ObjectGetter(v8::Local, @@ -1448,7 +1446,6 @@ void QV8IncubatorResource::StatusChangedSetter(v8::Local, v8::Local< QQmlComponentExtension::~QQmlComponentExtension() { qPersistentDispose(incubationConstructor); - qPersistentDispose(initialProperties); qPersistentDispose(forceCompletion); } @@ -1464,15 +1461,11 @@ void QV8IncubatorResource::setInitialState(QObject *o) if (!valuemap.IsEmpty()) { QQmlComponentExtension *e = componentExtension(engine); - v8::HandleScope handle_scope; - v8::Context::Scope scope(engine->context()); - - v8::Handle function = e->initialProperties->Run(qmlGlobal); - v8::Handle args[] = { engine->newQObject(o), valuemap }; - v8::Handle::Cast(function)->Call(engine->global(), 2, args); + QV4::ExecutionEngine *v4engine = QV8Engine::getV4(engine); - qPersistentDispose(valuemap); - qPersistentDispose(qmlGlobal); + QV4::Value f = engine->evaluateScript(QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal->v4Value().asObject()); + QV4::Value args[] = { engine->newQObject(o)->v4Value(), valuemap->v4Value() }; + f.asFunctionObject()->call(v4engine->current, QV4::Value::fromObject(v4engine->globalObject), args, 2); } } @@ -1517,4 +1510,6 @@ void QV8IncubatorResource::statusChanged(Status s) dispose(); } +#undef INITIALPROPERTIES_SOURCE + QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 67582e1..e470eaa 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -70,6 +70,7 @@ #include #include #include +#include Q_DECLARE_METATYPE(QList) @@ -1620,6 +1621,22 @@ QJSValue QV8Engine::evaluate(const QString& program, const QString& fileName, qu return evaluate(script, tryCatch); } +QV4::Value QV8Engine::evaluateScript(const QString &script, QV4::Object *scopeObject) +{ + QV4::ExecutionContext *ctx = m_v4Engine->current; + + QV4::Value result = QV4::Value::undefinedValue(); + + try { + QV4::EvalFunction *eval = new (m_v4Engine->memoryManager) QV4::EvalFunction(m_v4Engine->rootContext, scopeObject); + QV4::Value arg = QV4::Value::fromString(m_v4Engine->current, script); + result = eval->evalCall(m_v4Engine->current, QV4::Value::undefinedValue(), &arg, 1, /*directCall*/ false); + } catch (QV4::Exception &e) { + e.accept(ctx); + } + return result; +} + QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 187eea4..d5854d3 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -101,6 +101,7 @@ namespace QV4 { struct Value; } +#define V4FUNCTION(function, engine) new 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 @@ -383,6 +384,7 @@ public: QJSValue evaluate(const QString &program, const QString &fileName = QString(), quint16 lineNumber = 1); QJSValue evaluate(v8::Handle script, v8::TryCatch& tryCatch); + QV4::Value evaluateScript(const QString &script, QV4::Object *scopeObject = 0); QJSValue newArray(uint length); v8::Local newVariant(const QVariant &variant);