diff options
Diffstat (limited to 'src/qml/qml/qqmlvme.cpp')
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 193 |
1 files changed, 55 insertions, 138 deletions
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 736ed5f8bc..cde16e885d 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -58,14 +58,14 @@ #include "qqmlcomponent_p.h" #include "qqmlvmemetaobject_p.h" #include "qqmlcontext_p.h" -#include <private/qv4bindings_p.h> -#include <private/qv8bindings_p.h> #include "qqmlglobal_p.h" #include <private/qfinitestack_p.h> #include "qqmlscriptstring.h" #include "qqmlscriptstring_p.h" #include "qqmlpropertyvalueinterceptor_p.h" #include "qqmlvaluetypeproxybinding_p.h" +#include "qqmlexpression_p.h" +#include "qqmlcontextwrapper_p.h" #include <QStack> #include <QPointF> @@ -296,12 +296,12 @@ static QVariant variantFromString(const QString &string) #define QML_STORE_VAR(name, value) \ QML_BEGIN_INSTR(name) \ - v8::Handle<v8::Value> v8value = value; \ + QV4::Value v4value = value; \ QObject *target = objects.top(); \ CLEAN_PROPERTY(target, instr.propertyIndex); \ QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(target); \ Q_ASSERT(vmemo); \ - vmemo->setVMEProperty(instr.propertyIndex, v8value); \ + vmemo->setVMEProperty(instr.propertyIndex, v4value); \ QML_END_INSTR(name) #define QML_STORE_POINTER(name, value) \ @@ -340,10 +340,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QQmlEngine *engine = states.at(0).context->engine; QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - // Need a v8 handle scope and execution context for StoreVar instructions. - v8::HandleScope handleScope; - v8::Context::Scope contextScope(ep->v8engine()->context()); - int status = -1; // needed for dbus QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::RemoveBindingOnAliasWrite; @@ -376,7 +372,7 @@ QObject *QQmlVME::run(QList<QQmlError> *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); @@ -425,9 +421,9 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, // Store a literal value in a var property. // We deliberately do not use string converters here QML_STORE_VAR(StoreVar, ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value))); - QML_STORE_VAR(StoreVarInteger, v8::Integer::New(instr.value)); - QML_STORE_VAR(StoreVarDouble, v8::Number::New(instr.value)); - QML_STORE_VAR(StoreVarBool, v8::Boolean::New(instr.value)); + QML_STORE_VAR(StoreVarInteger, QV4::Value::fromInt32(instr.value)); + QML_STORE_VAR(StoreVarDouble, QV4::Value::fromDouble(instr.value)); + QML_STORE_VAR(StoreVarBool, QV4::Value::fromBoolean(instr.value)); // Store a literal value in a QJSValue property. QML_STORE_VALUE(StoreJSValueString, QJSValue, QJSValue(PRIMITIVES.at(instr.value))); @@ -449,10 +445,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, CTXT->setParent(parentCtxt); if (instr.contextCache != -1) CTXT->setIdPropertyData(COMP->contextCaches.at(instr.contextCache)); - if (instr.compiledBinding != -1) { - const char *v4data = DATAS.at(instr.compiledBinding).constData(); - CTXT->v4bindings = new QV4Bindings(v4data, CTXT); - } if (states.count() == 1) { rootContext = CTXT; rootContext->activeVMEData = data; @@ -476,8 +468,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, // double dispose. It is possible we could do this more efficiently using some form of // referencing instead. CTXT->importedScripts = creationContext->importedScripts; - for (int ii = 0; ii < CTXT->importedScripts.count(); ++ii) - CTXT->importedScripts[ii] = qPersistentNew<v8::Object>(CTXT->importedScripts[ii]); } QML_END_INSTR(Init) @@ -806,10 +796,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, status->classBegin(); QML_END_INSTR(BeginObject) - QML_BEGIN_INSTR(InitV8Bindings) - CTXT->v8bindings = new QV8Bindings(&PROGRAMS[instr.programIndex], instr.line, CTXT); - QML_END_INSTR(InitV8Bindings) - QML_BEGIN_INSTR(StoreBinding) QObject *target = objects.at(objects.count() - 1 - instr.owner); @@ -819,7 +805,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex)) QML_NEXT_INSTR(StoreBinding); - QQmlBinding *bind = new QQmlBinding(PRIMITIVES.at(instr.value), true, + QQmlBinding *bind = new QQmlBinding(PRIMITIVES.at(instr.value), context, CTXT, COMP->name, instr.line, instr.column); bindValues.push(bind); @@ -844,86 +830,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, } QML_END_INSTR(StoreBinding) - QML_BEGIN_INSTR(StoreV4Binding) - QObject *target = - objects.at(objects.count() - 1 - instr.owner); - QObject *scope = - objects.at(objects.count() - 1 - instr.context); - - int propertyIdx = (instr.property & 0x0000FFFF); - - if (instr.isRoot && BINDINGSKIPLIST.testBit(propertyIdx)) - QML_NEXT_INSTR(StoreV4Binding); - - QQmlAbstractBinding *binding = CTXT->v4bindings->configBinding(target, scope, &instr); - bindValues.push(binding); - binding->m_mePtr = &bindValues.top(); - - if (instr.isAlias) { - QQmlAbstractBinding *old = - QQmlPropertyPrivate::setBindingNoEnable(target, - propertyIdx, - instr.propType ? (instr.property >> 16) : -1, - binding); - if (old) { old->destroy(); } - } else { - Q_ASSERT(binding->propertyIndex() == instr.property); - Q_ASSERT(binding->object() == target); - - CLEAN_PROPERTY(target, instr.property); - - binding->addToObject(); - - if (instr.propType == 0) { - // All non-valuetype V4 bindings are safe bindings - QQmlData *data = QQmlData::get(target); - Q_ASSERT(data); - data->setPendingBindingBit(target, propertyIdx); - } - } - QML_END_INSTR(StoreV4Binding) - - QML_BEGIN_INSTR(StoreV8Binding) - QObject *target = - objects.at(objects.count() - 1 - instr.owner); - QObject *scope = - objects.at(objects.count() - 1 - instr.context); - - int coreIndex = instr.property.coreIndex; - - if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex)) - QML_NEXT_INSTR(StoreV8Binding); - - QQmlAbstractBinding *binding = CTXT->v8bindings->configBinding(target, scope, - &instr); - if (binding && !instr.isFallback) { - bindValues.push(binding); - binding->m_mePtr = &bindValues.top(); - - if (instr.isAlias) { - QQmlAbstractBinding *old = - QQmlPropertyPrivate::setBindingNoEnable(target, coreIndex, - instr.property.getValueTypeCoreIndex(), - binding); - if (old) { old->destroy(); } - } else { - typedef QQmlPropertyPrivate QDPP; - Q_ASSERT(binding->propertyIndex() == QDPP::bindingIndex(instr.property)); - Q_ASSERT(binding->object() == target); - - CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property)); - - binding->addToObject(); - - if (instr.isSafe && !instr.property.isValueTypeVirtual()) { - QQmlData *data = QQmlData::get(target); - Q_ASSERT(data); - data->setPendingBindingBit(target, coreIndex); - } - } - } - QML_END_INSTR(StoreV8Binding) - QML_BEGIN_INSTR(StoreValueSource) QObject *obj = objects.pop(); QQmlPropertyValueSource *vs = reinterpret_cast<QQmlPropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.castValue); @@ -1170,20 +1076,25 @@ void QQmlVME::reset() // Must be called with a handle scope and context void QQmlScriptData::initialize(QQmlEngine *engine) { - Q_ASSERT(m_program.IsEmpty()); + Q_ASSERT(!m_program); Q_ASSERT(engine); Q_ASSERT(!hasEngine()); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV8Engine *v8engine = ep->v8engine(); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine); + + // If compilation throws an error, a surrounding catch will record it. + // pass 0 as the QML object, we set it later before calling run() + QV4::Script *program = new QV4::Script(v4, 0, m_programSource, urlString, 1); + try { + program->parse(); + } catch (QV4::Exception &) { + delete program; + throw; + } - // If compilation throws an error, a surrounding v8::TryCatch will record it. - v8::Local<v8::Script> program = v8engine->qmlModeCompile(m_programSource.constData(), - m_programSource.length(), urlString, 1); - if (program.IsEmpty()) - return; - - m_program = qPersistentNew<v8::Script>(program); + m_program = program; m_programSource.clear(); // We don't need this anymore addToEngine(engine); @@ -1191,12 +1102,12 @@ void QQmlScriptData::initialize(QQmlEngine *engine) addref(); } -v8::Persistent<v8::Object> QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *script) +QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *script) { if (script->m_loaded) - return qPersistentNew<v8::Object>(script->m_value); + return script->m_value; - v8::Persistent<v8::Object> rv; + QV4::PersistentValue rv; Q_ASSERT(parentCtxt && parentCtxt->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine); @@ -1231,8 +1142,6 @@ v8::Persistent<v8::Object> QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptD } else if (effectiveCtxt) { ctxt->imports = effectiveCtxt->imports; ctxt->importedScripts = effectiveCtxt->importedScripts; - for (int ii = 0; ii < ctxt->importedScripts.count(); ++ii) - ctxt->importedScripts[ii] = qPersistentNew<v8::Object>(ctxt->importedScripts[ii]); } if (ctxt->imports) { @@ -1249,35 +1158,43 @@ v8::Persistent<v8::Object> QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptD ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData()); } - v8::HandleScope handle_scope; - v8::Context::Scope scope(v8engine->context()); - - v8::TryCatch try_catch; - if (!script->isInitialized()) - script->initialize(parentCtxt->engine); - - v8::Local<v8::Object> qmlglobal = v8engine->qmlScope(ctxt, 0); - v8engine->contextWrapper()->takeContextOwnership(qmlglobal); + if (!script->isInitialized()) { + QV4::ExecutionContext *ctx = QV8Engine::getV4(parentCtxt->engine)->current; + try { + script->initialize(parentCtxt->engine); + } catch (QV4::Exception &e) { + e.accept(ctx); + QQmlError error; + QQmlExpressionPrivate::exceptionToError(e, error); + if (error.isValid()) + ep->warning(error); + } + } - if (!script->m_program.IsEmpty()) { - script->m_program->Run(qmlglobal); - } else { - // Compilation failed. - Q_ASSERT(try_catch.HasCaught()); + if (!script->m_program) { + if (shared) + script->m_loaded = true; + return QV4::PersistentValue(); } - if (try_catch.HasCaught()) { - v8::Local<v8::Message> message = try_catch.Message(); - if (!message.IsEmpty()) { - QQmlError error; - QQmlExpressionPrivate::exceptionToError(message, error); + QV4::Value qmlglobal = QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0); + QV4::QmlContextWrapper::takeContextOwnership(qmlglobal); + + QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current; + try { + script->m_program->qml = qmlglobal; + script->m_program->run(); + } catch (QV4::Exception &e) { + e.accept(ctx); + QQmlError error; + QQmlExpressionPrivate::exceptionToError(e, error); + if (error.isValid()) ep->warning(error); - } } - rv = qPersistentNew<v8::Object>(qmlglobal); + rv = qmlglobal; if (shared) { - script->m_value = qPersistentNew<v8::Object>(qmlglobal); + script->m_value = rv; script->m_loaded = true; } |