diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-04-28 05:36:21 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-04-29 13:14:45 +0200 |
commit | 96d40fd09e4a59feb2cd8898267e6682fee2129d (patch) | |
tree | cde226e9f7699226536b3763f3628c9278a1c1cc /src/qml/qml | |
parent | 1a6dd638b830a5353fb2321b74a57d380539c92d (diff) |
Move more methods on QV8Engine over to use v4 based syntax
Change-Id: I7d3501a2c4cd0d749c7c30b5c60fee12cde58aa4
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlxmlhttprequest.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4bindings.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/v8/qjsengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qjsvalue_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8contextwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 143 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 83 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8include.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8qobjectwrapper.cpp | 39 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8sequencewrapper_p_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8typewrapper.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8valuetypewrapper.cpp | 2 |
16 files changed, 114 insertions, 190 deletions
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index a8b3a99e39..8bb5001226 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -172,7 +172,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, v8::Local<v8::Value> result; { v8::TryCatch try_catch; - v8::Handle<v8::Object> This = ep->v8engine()->global(); + v8::Handle<v8::Object> This = v8::Value::fromV4Value(ep->v8engine()->global()); if (scopeObject() && requiresThisObject()) { v8::Handle<v8::Value> value = ep->v8engine()->newQObject(scopeObject()); if (value->IsObject()) This = v8::Handle<v8::Object>::Cast(value); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index b29861c4dc..91effab027 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1551,7 +1551,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, return false; } else if (isVarProperty) { if (!result.IsEmpty() && result->IsFunction() - && !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) { + && !result->ToObject()->GetHiddenValue(v8::Value::fromV4Value(v8engine->bindingFlagKey())).IsEmpty()) { // we explicitly disallow this case to avoid confusion. Users can still store one // in an array in a var property if they need to, but the common case is user error. expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration.")); @@ -1568,11 +1568,11 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, writeValueProperty(object, core, QVariant(), context, flags); } else if (type == qMetaTypeId<QJSValue>()) { if (!result.IsEmpty() && result->IsFunction() - && !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) { + && !result->ToObject()->GetHiddenValue(v8::Value::fromV4Value(v8engine->bindingFlagKey())).IsEmpty()) { expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration.")); return false; } - writeValueProperty(object, core, QVariant::fromValue(v8engine->scriptValueFromInternal(result)), context, flags); + writeValueProperty(object, core, QVariant::fromValue(v8engine->scriptValueFromInternal(result->v4Value())), context, flags); } else if (isUndefined) { QString errorStr = QLatin1String("Unable to assign [undefined] to "); if (!QMetaType::typeName(type)) @@ -1582,7 +1582,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, expression->delayedError()->setErrorDescription(errorStr); return false; } else if (result->IsFunction()) { - if (!result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) + if (!result->ToObject()->GetHiddenValue(v8::Value::fromV4Value(v8engine->bindingFlagKey())).IsEmpty()) expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration.")); else expression->delayedError()->setErrorDescription(QLatin1String("Unable to assign a function to a property of any type other than var.")); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index a80cba2c5e..fbdd3893ca 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -944,7 +944,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) v8::TryCatch try_catch; - v8::Local<v8::Value> result = function->Call(ep->v8engine()->global(), data->parameterCount, args); + v8::Local<v8::Value> result = function->Call(v8::Value::fromV4Value(ep->v8engine()->global()), data->parameterCount, args); QVariant rv; if (try_catch.HasCaught()) { diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index ebdd9ea3d8..9f2af9b424 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1821,7 +1821,7 @@ void *qt_add_qmlxmlhttprequest(QV8Engine *engine) xmlhttprequest->Set(v8::String::New("HEADERS_RECEIVED"), v8::Integer::New(2), attributes); xmlhttprequest->Set(v8::String::New("LOADING"), v8::Integer::New(3), attributes); xmlhttprequest->Set(v8::String::New("DONE"), v8::Integer::New(4), attributes); - engine->global()->Set(v8::String::New("XMLHttpRequest"), xmlhttprequest->GetFunction()); + v8::Local<v8::Object>::New(v8::Value::fromV4Value(engine->global()))->Set(v8::String::New("XMLHttpRequest"), xmlhttprequest->GetFunction()); QQmlXMLHttpRequestData *data = new QQmlXMLHttpRequestData; return data; diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index a3b09b0ee8..bf7cc0b1bd 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -1644,7 +1644,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, v8::HandleScope handle_scope; v8::Context::Scope scope(v8engine->context()); new (output.getjsvalueptr()) QJSValue(v8engine->scriptValueFromInternal( - v8engine->valueTypeWrapper()->newValueType(tmp, vt))); + v8engine->valueTypeWrapper()->newValueType(tmp, vt)->v4Value())); JSVALUE_REGISTER(instr->unaryop.output); } } @@ -1775,7 +1775,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, MARK_CLEAN_REGISTER(instr->unaryop.output); } QV8Engine *v8engine = QQmlEnginePrivate::get(context->engine)->v8engine(); - new (output.getjsvalueptr()) QJSValue(v8engine->scriptValueFromInternal(tmp)); + new (output.getjsvalueptr()) QJSValue(v8engine->scriptValueFromInternal(tmp->v4Value())); JSVALUE_REGISTER(instr->unaryop.output); } } diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp index b842e058ff..63a176b283 100644 --- a/src/qml/qml/v8/qjsengine.cpp +++ b/src/qml/qml/v8/qjsengine.cpp @@ -322,7 +322,7 @@ QJSValue QJSEngine::newQObject(QObject *object) Q_D(QJSEngine); QScriptIsolate api(d, QScriptIsolate::NotNullEngine); v8::HandleScope handleScope; - return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership)); + return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership)->v4Value()); } /*! diff --git a/src/qml/qml/v8/qjsvalue_p.h b/src/qml/qml/v8/qjsvalue_p.h index 26dc7e6178..c085f39d50 100644 --- a/src/qml/qml/v8/qjsvalue_p.h +++ b/src/qml/qml/v8/qjsvalue_p.h @@ -70,7 +70,10 @@ public: QJSValuePrivate(QV4::ExecutionEngine *e, const QV4::Value &v) : PersistentValuePrivate(e, v) , string(QString()) - {} + { + if (value.isDeleted()) + value = QV4::Value::undefinedValue(); + } QJSValuePrivate(QV4::ExecutionEngine *e, QV4::Object *o) : PersistentValuePrivate(e, QV4::Value::fromObject(o)) , string(QString()) diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 11a8565604..c726f4c62d 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1650,7 +1650,7 @@ v8::Handle<v8::Value> binding(const v8::Arguments &args) V8THROW_TYPE("binding(): argument (binding expression) must be a function"); v8::Handle<v8::Object> rv = args[0]->ToObject()->Clone(); - rv->SetHiddenValue(V8ENGINE()->bindingFlagKey(), v8::Boolean::New(true)); + rv->SetHiddenValue(v8::Value::fromV4Value(V8ENGINE()->bindingFlagKey()), v8::Boolean::New(true)); return rv; } diff --git a/src/qml/qml/v8/qv8contextwrapper.cpp b/src/qml/qml/v8/qv8contextwrapper.cpp index b056cc111e..66ccb56269 100644 --- a/src/qml/qml/v8/qv8contextwrapper.cpp +++ b/src/qml/qml/v8/qv8contextwrapper.cpp @@ -270,7 +270,7 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, QHashedV8String propertystring(property); - if (context->imports && QV8Engine::startsWithUpper(property)) { + if (context->imports && QV8Engine::startsWithUpper(property->v4Value().asString())) { // Search for attached properties, enums and imported scripts QQmlTypeNameCache::Result r = context->imports->query(propertystring); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 1526e40d16..7aa7cefa28 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -161,7 +161,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership) QV8GCCallback::registerGcPrologueCallback(); m_strongReferencer = qPersistentNew(v8::Object::New()); - m_bindingFlagKey = qPersistentNew(v8::String::New("qml::binding")); + m_bindingFlagKey = QV4::PersistentValue(m_v4Engine, QV4::Value::fromString(m_v4Engine->current, QStringLiteral("qml::binding"))); m_contextWrapper.init(this); m_qobjectWrapper.init(this); @@ -197,8 +197,6 @@ QV8Engine::~QV8Engine() m_qobjectWrapper.destroy(); m_contextWrapper.destroy(); - qPersistentDispose(m_bindingFlagKey); - if (m_ownsV8Context) qPersistentDispose(m_context); } @@ -212,10 +210,10 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) return QVariant(value->BooleanValue()); if (typeHint == QMetaType::QJsonValue) - return QVariant::fromValue(jsonValueFromJS(value)); + return QVariant::fromValue(jsonValueFromJS(value->v4Value())); if (typeHint == qMetaTypeId<QJSValue>()) - return QVariant::fromValue(scriptValueFromInternal(value)); + return QVariant::fromValue(scriptValueFromInternal(value->v4Value())); if (value->IsObject()) { QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource(); @@ -251,7 +249,7 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) } } else if (typeHint == QMetaType::QJsonObject && !value->IsArray() && !value->IsFunction()) { - return QVariant::fromValue(jsonObjectFromJS(value)); + return QVariant::fromValue(jsonObjectFromJS(value->v4Value())); } } @@ -271,7 +269,7 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) return qVariantFromValue<QList<QObject*> >(list); } else if (typeHint == QMetaType::QJsonArray) { - return QVariant::fromValue(jsonArrayFromJS(value)); + return QVariant::fromValue(jsonArrayFromJS(value->v4Value())); } bool succeeded = false; @@ -371,11 +369,11 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant) case QMetaType::QVariantMap: return objectFromVariantMap(this, *reinterpret_cast<const QVariantMap *>(ptr)); case QMetaType::QJsonValue: - return jsonValueToJS(*reinterpret_cast<const QJsonValue *>(ptr)); + return v8::Value::fromV4Value(jsonValueToJS(*reinterpret_cast<const QJsonValue *>(ptr))); case QMetaType::QJsonObject: - return jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(ptr)); + return v8::Value::fromV4Value(jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(ptr))); case QMetaType::QJsonArray: - return jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(ptr)); + return v8::Value::fromV4Value(jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(ptr))); default: break; @@ -897,10 +895,9 @@ void QV8Engine::setEngine(QQmlEngine *engine) initQmlGlobalObject(); } -v8::Handle<v8::Value> QV8Engine::throwException(v8::Handle<v8::Value> value) +QV4::Value QV8Engine::global() { - __qmljs_throw(m_v4Engine->current, value->v4Value()); - return value; + return QV4::Value::fromObject(m_v4Engine->globalObject); } // Converts a QVariantList to JS. @@ -1086,7 +1083,7 @@ QV4::Value QV8Engine::metaTypeToJS(int type, const void *data) return QV4::Value::nullValue(); } else { // Fall back to wrapping in a QVariant. - result = newVariant(QVariant(type, data))->v4Value(); + result = variantWrapper()->newVariant(QVariant(type, data))->v4Value(); } } } @@ -1164,7 +1161,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { case QMetaType::QObjectStar: { v8::Handle<v8::Value> v = v8::Value::fromV4Value(value); if (isQObject(v) || value.isNull()) { - *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(v); + *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(v->v4Value()); return true; } break; } @@ -1187,13 +1184,13 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { *reinterpret_cast<QVariant*>(data) = variantFromJS(value); return true; case QMetaType::QJsonValue: - *reinterpret_cast<QJsonValue *>(data) = jsonValueFromJS(v8::Value::fromV4Value(value)); + *reinterpret_cast<QJsonValue *>(data) = jsonValueFromJS(value); return true; case QMetaType::QJsonObject: - *reinterpret_cast<QJsonObject *>(data) = jsonObjectFromJS(v8::Value::fromV4Value(value)); + *reinterpret_cast<QJsonObject *>(data) = jsonObjectFromJS(value); return true; case QMetaType::QJsonArray: - *reinterpret_cast<QJsonArray *>(data) = jsonArrayFromJS(v8::Value::fromV4Value(value)); + *reinterpret_cast<QJsonArray *>(data) = jsonArrayFromJS(value); return true; default: ; @@ -1221,11 +1218,11 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { // Try to use magic; for compatibility with qscriptvalue_cast. QByteArray name = QMetaType::typeName(type); - if (convertToNativeQObject(v8::Value::fromV4Value(value), name, reinterpret_cast<void* *>(data))) + if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(data))) return true; if (isVariant(v8::Value::fromV4Value(value)) && name.endsWith('*')) { int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = variantValue(v8::Value::fromV4Value(value)); + QVariant &var = variantWrapper()->variantValue(v8::Value::fromV4Value(value)); if (valueType == var.userType()) { // We have T t, T* is requested, so return &t. *reinterpret_cast<void* *>(data) = var.data(); @@ -1236,12 +1233,12 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { while (proto->IsObject()) { bool canCast = false; if (isVariant(proto)) { - canCast = (type == variantValue(proto).userType()) - || (valueType && (valueType == variantValue(proto).userType())); + canCast = (type == variantWrapper()->variantValue(proto).userType()) + || (valueType && (valueType == variantWrapper()->variantValue(proto).userType())); } else if (isQObject(proto)) { QByteArray className = name.left(name.size()-1); - if (QObject *qobject = qtObjectFromJS(proto)) + if (QObject *qobject = qtObjectFromJS(proto->v4Value())) canCast = qobject->qt_metacast(className) != 0; } if (canCast) { @@ -1306,47 +1303,45 @@ QVariant QV8Engine::variantFromJS(const QV4::Value &value, if (value.asRegExpObject()) return QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(v8::Value::fromV4Value(value))); if (isVariant(v8::Value::fromV4Value(value))) - return variantValue(v8::Value::fromV4Value(value)); + return variantWrapper()->variantValue(v8::Value::fromV4Value(value)); if (isQObject(v8::Value::fromV4Value(value))) - return qVariantFromValue(qtObjectFromJS(v8::Value::fromV4Value(value))); - if (isValueType(v8::Value::fromV4Value(value))) - return toValueType(v8::Value::fromV4Value(value)); + return qVariantFromValue(qtObjectFromJS(value)); + if (isValueType(value)) + return toValueType(value); return variantMapFromJS(value.asObject(), visitedObjects); } -v8::Handle<v8::Value> QV8Engine::jsonValueToJS(const QJsonValue &value) +QV4::Value QV8Engine::jsonValueToJS(const QJsonValue &value) { - return v8::Value::fromV4Value(m_jsonWrapper.fromJsonValue(value)); + return m_jsonWrapper.fromJsonValue(value); } -QJsonValue QV8Engine::jsonValueFromJS(v8::Handle<v8::Value> value) +QJsonValue QV8Engine::jsonValueFromJS(const QV4::Value &value) { - return m_jsonWrapper.toJsonValue(value.get()->v4Value()); + return m_jsonWrapper.toJsonValue(value); } -v8::Local<v8::Object> QV8Engine::jsonObjectToJS(const QJsonObject &object) +QV4::Value QV8Engine::jsonObjectToJS(const QJsonObject &object) { - return v8::Local<v8::Object>::New(v8::Value::fromV4Value(m_jsonWrapper.fromJsonObject(object))); + return m_jsonWrapper.fromJsonObject(object); } -QJsonObject QV8Engine::jsonObjectFromJS(v8::Handle<v8::Value> value) +QJsonObject QV8Engine::jsonObjectFromJS(const QV4::Value &value) { - return m_jsonWrapper.toJsonObject(value.get()->v4Value().asObject()); + return m_jsonWrapper.toJsonObject(value.asObject()); } -v8::Local<v8::Array> QV8Engine::jsonArrayToJS(const QJsonArray &array) +QV4::Value QV8Engine::jsonArrayToJS(const QJsonArray &array) { - return v8::Local<v8::Array>::New(v8::Value::fromV4Value(m_jsonWrapper.fromJsonArray(array))); + return m_jsonWrapper.fromJsonArray(array); } -QJsonArray QV8Engine::jsonArrayFromJS(v8::Handle<v8::Value> value) +QJsonArray QV8Engine::jsonArrayFromJS(const QV4::Value &value) { - return m_jsonWrapper.toJsonArray(value.get()->v4Value().asArrayObject()); + return m_jsonWrapper.toJsonArray(value.asArrayObject()); } -bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value, - const QByteArray &targetType, - void **result) +bool QV8Engine::convertToNativeQObject(const QV4::Value &value, const QByteArray &targetType, void **result) { if (!targetType.endsWith('*')) return false; @@ -1361,12 +1356,12 @@ bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value, return false; } -QObject *QV8Engine::qtObjectFromJS(v8::Handle<v8::Value> value) +QObject *QV8Engine::qtObjectFromJS(const QV4::Value &value) { - if (!value->IsObject()) + if (!value.isObject()) return 0; - QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource(); + QV8ObjectResource *r = (QV8ObjectResource *)v8::Value::fromV4Value(value)->ToObject()->GetExternalResource(); if (!r) return 0; QV8ObjectResource::ResourceType type = r->resourceType(); @@ -1381,48 +1376,9 @@ QObject *QV8Engine::qtObjectFromJS(v8::Handle<v8::Value> value) return 0; } - -QVariant &QV8Engine::variantValue(v8::Handle<v8::Value> value) -{ - return variantWrapper()->variantValue(value); -} - -// Creates a QVariant wrapper object. -v8::Local<v8::Object> QV8Engine::newVariant(const QVariant &value) -{ - return variantWrapper()->newVariant(value); -} - -QJSValue QV8Engine::evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch) -{ - v8::HandleScope handleScope; - - if (script.IsEmpty()) { - v8::Handle<v8::Value> exception = tryCatch.Exception(); - if (exception.IsEmpty()) { - // This is possible on syntax errors like { a:12, b:21 } <- missing "(", ")" around expression. - return QJSValue(); - } - return new QJSValuePrivate(m_v4Engine, exception.get()->v4Value()); - } - v8::Handle<v8::Value> result; - result = script->Run(); - if (result.IsEmpty()) { - v8::Handle<v8::Value> exception = tryCatch.Exception(); - // TODO: figure out why v8 doesn't always produce an exception value - //Q_ASSERT(!exception.IsEmpty()); - if (exception.IsEmpty()) - exception = v8::Exception::Error(v8::String::New("missing exception value")); - return new QJSValuePrivate(m_v4Engine, exception.get()->v4Value()); - } - return new QJSValuePrivate(m_v4Engine, result.get()->v4Value()); -} - -QJSValue QV8Engine::scriptValueFromInternal(v8::Handle<v8::Value> value) const +QJSValue QV8Engine::scriptValueFromInternal(const QV4::Value &value) const { - if (value.IsEmpty()) - return QJSValue(); - return new QJSValuePrivate(m_v4Engine, value.get()->v4Value()); + return new QJSValuePrivate(m_v4Engine, value); } QJSValue QV8Engine::newArray(uint length) @@ -1580,21 +1536,6 @@ QQmlV4Handle QQmlV4Handle::fromValue(const QV4::Value &v) return handle; } -QJSValue QV8Engine::evaluate(const QString& program, const QString& fileName, quint16 lineNumber) -{ - v8::TryCatch tryCatch; - v8::ScriptOrigin scriptOrigin(QJSConverter::toString(fileName), v8::Integer::New(lineNumber - 1)); - v8::Handle<v8::Script> script; - script = v8::Script::Compile(QJSConverter::toString(program), &scriptOrigin); - if (script.IsEmpty()) { - // TODO: Why don't we get the exception, as with Script::Compile()? - // Q_ASSERT(tryCatch.HasCaught()); - QV4::Object *error = m_v4Engine->newSyntaxErrorObject(m_v4Engine->current, 0); - return new QJSValuePrivate(m_v4Engine, QV4::Value::fromObject(error)); - } - return evaluate(script, tryCatch); -} - QV4::Value QV8Engine::evaluateScript(const QString &script, QV4::Object *scopeObject) { QV4::ExecutionContext *ctx = m_v4Engine->current; diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index fe22b991e4..cc535acc87 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -283,17 +283,9 @@ public: void initQmlGlobalObject(); void setEngine(QQmlEngine *engine); QQmlEngine *engine() { return m_engine; } - v8::Local<v8::Object> global() { return m_context->Global(); } + QV4::Value global(); v8::Handle<v8::Context> context() const { return m_context; } -// inline void registerValue(QJSValuePrivate *data); -// inline void unregisterValue(QJSValuePrivate *data); -// inline void invalidateAllValues(); - -// inline void registerValueIterator(QJSValueIteratorPrivate *data); -// inline void unregisterValueIterator(QJSValueIteratorPrivate *data); -// inline void invalidateAllIterators(); - QV8ContextWrapper *contextWrapper() { return &m_contextWrapper; } QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; } QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; } @@ -312,7 +304,7 @@ public: QV4::Value getOwnPropertyNames(const QV4::Value &o); void freezeObject(const QV4::Value &value); - static inline bool startsWithUpper(v8::Handle<v8::String>); + static inline bool startsWithUpper(QV4::String *); QVariant toVariant(v8::Handle<v8::Value>, int typeHint); v8::Handle<v8::Value> fromVariant(const QVariant &); @@ -339,20 +331,16 @@ public: v8::Local<v8::String> toString(const QString &string); // Create a new value type object - inline v8::Handle<v8::Value> newValueType(QObject *, int coreIndex, QQmlValueType *); - inline v8::Handle<v8::Value> newValueType(const QVariant &, QQmlValueType *); - inline bool isValueType(v8::Handle<v8::Value>) const; - inline QVariant toValueType(v8::Handle<v8::Value> obj); + inline QV4::Value newValueType(QObject *, int coreIndex, QQmlValueType *); + inline QV4::Value newValueType(const QVariant &, QQmlValueType *); + inline bool isValueType(const QV4::Value &value) const; + inline QVariant toValueType(const QV4::Value &obj); // Create a new sequence type object - inline v8::Handle<v8::Value> newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded); - - // Create a new QVariant object. This doesn't examine the type of the variant, but always returns - // a QVariant wrapper - inline v8::Handle<v8::Value> newQVariant(const QVariant &); + inline QV4::Value newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded); // Return the JS string key for the "function is a binding" flag - inline v8::Handle<v8::String> bindingFlagKey() const; + inline QV4::Value bindingFlagKey() const; // Return the network access manager for this engine. By default this returns the network // access manager of the QQmlEngine. It is overridden in the case of a threaded v8 @@ -365,8 +353,6 @@ public: inline void collectGarbage() { gc(); } void gc(); - v8::Handle<v8::Value> throwException(v8::Handle<v8::Value> value); - #ifdef QML_GLOBAL_HANDLE_DEBUGGING // Used for handle debugging static void registerHandle(void *); @@ -379,12 +365,9 @@ public: inline Deletable *extensionData(int) const; void setExtensionData(int, Deletable *); - QJSValue evaluate(const QString &program, const QString &fileName = QString(), quint16 lineNumber = 1); - QJSValue evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch); QV4::Value evaluateScript(const QString &script, QV4::Object *scopeObject = 0); QJSValue newArray(uint length); - v8::Local<v8::Object> newVariant(const QVariant &variant); QV4::Value variantListToJS(const QVariantList &lst); inline QVariantList variantListFromJS(QV4::ArrayObject *array) @@ -398,23 +381,21 @@ public: inline QVariant variantFromJS(const QV4::Value &value) { V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); } - v8::Handle<v8::Value> jsonValueToJS(const QJsonValue &value); - QJsonValue jsonValueFromJS(v8::Handle<v8::Value> value); - v8::Local<v8::Object> jsonObjectToJS(const QJsonObject &object); - QJsonObject jsonObjectFromJS(v8::Handle<v8::Value> value); - v8::Local<v8::Array> jsonArrayToJS(const QJsonArray &array); - QJsonArray jsonArrayFromJS(v8::Handle<v8::Value> value); + QV4::Value jsonValueToJS(const QJsonValue &value); + QJsonValue jsonValueFromJS(const QV4::Value &value); + QV4::Value jsonObjectToJS(const QJsonObject &object); + QJsonObject jsonObjectFromJS(const QV4::Value &value); + QV4::Value jsonArrayToJS(const QJsonArray &array); + QJsonArray jsonArrayFromJS(const QV4::Value &value); QV4::Value metaTypeToJS(int type, const void *data); bool metaTypeFromJS(const QV4::Value &value, int type, void *data); - bool convertToNativeQObject(v8::Handle<v8::Value> value, + bool convertToNativeQObject(const QV4::Value &value, const QByteArray &targetType, void **result); - QVariant &variantValue(v8::Handle<v8::Value> value); - - QJSValue scriptValueFromInternal(v8::Handle<v8::Value>) const; + QJSValue scriptValueFromInternal(const QV4::Value &) const; // used for console.time(), console.timeEnd() void startTimer(const QString &timerName); @@ -423,7 +404,7 @@ public: // used for console.count() int consoleCountHelper(const QString &file, quint16 line, quint16 column); - QObject *qtObjectFromJS(v8::Handle<v8::Value> value); + QObject *qtObjectFromJS(const QV4::Value &value); static QDateTime qtDateTimeFromJsDate(double jsDate); @@ -459,7 +440,7 @@ protected: bool m_ownsV8Context; v8::Persistent<v8::Context> m_context; - v8::Persistent<v8::String> m_bindingFlagKey; + QV4::PersistentValue m_bindingFlagKey; QV8ContextWrapper m_contextWrapper; QV8QObjectWrapper m_qobjectWrapper; @@ -583,43 +564,41 @@ v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object, const ObjectOwnersh return result; } -v8::Handle<v8::Value> QV8Engine::newValueType(QObject *object, int property, QQmlValueType *type) +QV4::Value QV8Engine::newValueType(QObject *object, int property, QQmlValueType *type) { - return m_valueTypeWrapper.newValueType(object, property, type); + return m_valueTypeWrapper.newValueType(object, property, type)->v4Value(); } -v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QQmlValueType *type) +QV4::Value QV8Engine::newValueType(const QVariant &value, QQmlValueType *type) { - return m_valueTypeWrapper.newValueType(value, type); + return m_valueTypeWrapper.newValueType(value, type)->v4Value(); } -bool QV8Engine::isValueType(v8::Handle<v8::Value> obj) const +bool QV8Engine::isValueType(const QV4::Value &value) const { - return obj->IsObject()?m_valueTypeWrapper.isValueType(v8::Handle<v8::Object>::Cast(obj)):false; + return value.isObject() ? m_valueTypeWrapper.isValueType(v8::Handle<v8::Object>::Cast(v8::Value::fromV4Value(value))) : false; } -QVariant QV8Engine::toValueType(v8::Handle<v8::Value> obj) +QVariant QV8Engine::toValueType(const QV4::Value &obj) { - return obj->IsObject()?m_valueTypeWrapper.toVariant(v8::Handle<v8::Object>::Cast(obj)):QVariant(); + return obj.isObject() ? m_valueTypeWrapper.toVariant(v8::Handle<v8::Object>::Cast(v8::Value::fromV4Value(obj))) : QVariant(); } -v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded) +QV4::Value QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded) { - return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded); + return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded)->v4Value(); } -v8::Handle<v8::String> QV8Engine::bindingFlagKey() const +QV4::Value QV8Engine::bindingFlagKey() const { return m_bindingFlagKey; } // XXX Can this be made more optimal? It is called prior to resolving each and every // unqualified name in QV8ContextWrapper. -bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) +bool QV8Engine::startsWithUpper(QV4::String *string) { - v8::String::Value value(string); - Q_ASSERT(*value != NULL); - uint16_t c = **value; + uint16_t c = string->toQString().at(0).unicode(); return (c >= 'A' && c <= 'Z') || (c > 127 && QChar::category(c) == QChar::Letter_Uppercase); } diff --git a/src/qml/qml/v8/qv8include.cpp b/src/qml/qml/v8/qv8include.cpp index b5ba87b718..eb897fa42f 100644 --- a/src/qml/qml/v8/qv8include.cpp +++ b/src/qml/qml/v8/qv8include.cpp @@ -96,7 +96,7 @@ void QV8Include::callback(QV8Engine *engine, v8::Handle<v8::Function> callback, if (!callback.IsEmpty()) { v8::Handle<v8::Value> args[] = { status }; v8::TryCatch tc; - callback->Call(engine->global(), 1, args); + callback->Call(v8::Value::fromV4Value(engine->global()), 1, args); } } diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index db9ac6959b..444c2638cb 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -343,7 +343,7 @@ void QV8QObjectWrapper::init(QV8Engine *engine) v8::Local<v8::Function> fn = v8::Local<v8::Function>::Cast(script->Run()); v8::Handle<v8::Value> invokeFn = v8::FunctionTemplate::New(Invoke)->GetFunction(); v8::Handle<v8::Value> args[] = { invokeFn }; - v8::Local<v8::Function> createFn = v8::Local<v8::Function>::Cast(fn->Call(engine->global(), 1, args)); + v8::Local<v8::Function> createFn = v8::Local<v8::Function>::Cast(fn->Call(v8::Value::fromV4Value(engine->global()), 1, args)); m_methodConstructor = qPersistentNew<v8::Function>(createFn); } @@ -359,7 +359,8 @@ void QV8QObjectWrapper::init(QV8Engine *engine) } { - v8::Local<v8::Object> prototype = engine->global()->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject(); + v8::Local<v8::Object> prototype = v8::Local<v8::Object>::New(v8::Value::fromV4Value(engine->global())) + ->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject(); prototype->Set(v8::String::New("connect"), connect, v8::DontEnum); prototype->Set(v8::String::New("disconnect"), disconnect, v8::DontEnum); } @@ -440,7 +441,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, if (QQmlValueTypeFactory::isValueType(v.userType())) { if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(v.userType())) - return engine->newValueType(object, property.coreIndex, valueType); // VariantReference value-type. + return v8::Value::fromV4Value(engine->newValueType(object, property.coreIndex, valueType)); // VariantReference value-type. } return engine->fromVariant(v); @@ -448,14 +449,14 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, Q_ASSERT(notifier == 0); if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property.propType)) - return engine->newValueType(object, property.coreIndex, valueType); + return v8::Value::fromV4Value(engine->newValueType(object, property.coreIndex, valueType)); } else { Q_ASSERT(notifier == 0); // see if it's a sequence type bool succeeded = false; - v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex, - &succeeded); + v8::Handle<v8::Value> retn = v8::Value::fromV4Value(engine->newSequence(property.propType, object, property.coreIndex, + &succeeded)); if (succeeded) return retn; } @@ -489,7 +490,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject v8::Integer::New(index) }; Q_ASSERT(argv[0]->IsObject()); - return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 2, argv); + return engine->qobjectWrapper()->m_methodConstructor->Call(v8::Value::fromV4Value(engine->global()), 2, argv); } static v8::Handle<v8::Value> createWithGlobal(QV8Engine *engine, QObject *object, v8::Handle<v8::Value> *objectHandle, @@ -500,7 +501,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject v8::Context::GetCallingQmlGlobal() }; Q_ASSERT(argv[0]->IsObject()); - return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 3, argv); + return engine->qobjectWrapper()->m_methodConstructor->Call(v8::Value::fromV4Value(engine->global()), 3, argv); } }; @@ -596,7 +597,7 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert { QQmlBinding *newBinding = 0; if (value->IsFunction()) { - if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) { + if (value->ToObject()->GetHiddenValue(v8::Value::fromV4Value(engine->bindingFlagKey())).IsEmpty()) { if (!property->isVarProperty() && property->propType != qMetaTypeId<QJSValue>()) { // assigning a JS function to a non var or QJSValue property or is not allowed. QString error = QLatin1String("Cannot assign JavaScript function to "); @@ -657,7 +658,7 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert } else if (value->IsUndefined() && property->propType == QMetaType::QJsonValue) { PROPERTY_STORE(QJsonValue, QJsonValue(QJsonValue::Undefined)); } else if (!newBinding && property->propType == qMetaTypeId<QJSValue>()) { - PROPERTY_STORE(QJSValue, engine->scriptValueFromInternal(value)); + PROPERTY_STORE(QJSValue, engine->scriptValueFromInternal(value->v4Value())); } else if (value->IsUndefined()) { QString error = QLatin1String("Cannot assign [undefined] to "); if (!QMetaType::typeName(property->propType)) @@ -763,7 +764,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Getter(v8::Local<v8::String> property, if (!result.IsEmpty()) return result; - if (QV8Engine::startsWithUpper(property)) { + if (QV8Engine::startsWithUpper(property->v4Value().asString())) { // Check for attached properties if (context && context->imports) { QQmlTypeNameCache::Result r = context->imports->query(propertystring); @@ -1203,7 +1204,7 @@ QPair<QObject *, int> QV8QObjectWrapper::ExtractQtMethod(QV8Engine *engine, v8:: // This is one of our special QObject method wrappers v8::Handle<v8::Value> args[] = { engine->qobjectWrapper()->m_hiddenObject }; - v8::Local<v8::Value> data = function->Call(engine->global(), 1, args); + v8::Local<v8::Value> data = function->Call(v8::Value::fromV4Value(engine->global()), 1, args); if (data->IsArray()) { v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(data); @@ -1330,7 +1331,7 @@ int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, v v8::TryCatch try_catch; if (connection.thisObject.IsEmpty()) { - connection.function->Call(engine->global(), argCount, args.data()); + connection.function->Call(v8::Value::fromV4Value(engine->global()), argCount, args.data()); } else { connection.function->Call(connection.thisObject, argCount, args.data()); } @@ -2187,13 +2188,13 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val handlePtr = new (&allocData) QQmlV4Handle(QQmlV4Handle::fromV8Handle(value)); type = callType; } else if (callType == QMetaType::QJsonArray) { - jsonArrayPtr = new (&allocData) QJsonArray(engine->jsonArrayFromJS(value)); + jsonArrayPtr = new (&allocData) QJsonArray(engine->jsonArrayFromJS(value->v4Value())); type = callType; } else if (callType == QMetaType::QJsonObject) { - jsonObjectPtr = new (&allocData) QJsonObject(engine->jsonObjectFromJS(value)); + jsonObjectPtr = new (&allocData) QJsonObject(engine->jsonObjectFromJS(value->v4Value())); type = callType; } else if (callType == QMetaType::QJsonValue) { - jsonValuePtr = new (&allocData) QJsonValue(engine->jsonValueFromJS(value)); + jsonValuePtr = new (&allocData) QJsonValue(engine->jsonValueFromJS(value->v4Value())); type = callType; } else if (callType == QMetaType::Void) { *qvariantPtr = QVariant(); @@ -2261,11 +2262,11 @@ v8::Handle<v8::Value> CallArgument::toValue(QV8Engine *engine) } else if (type == qMetaTypeId<QQmlV4Handle>()) { return handlePtr->toV8Handle(); } else if (type == QMetaType::QJsonArray) { - return engine->jsonArrayToJS(*jsonArrayPtr); + return v8::Value::fromV4Value(engine->jsonArrayToJS(*jsonArrayPtr)); } else if (type == QMetaType::QJsonObject) { - return engine->jsonObjectToJS(*jsonObjectPtr); + return v8::Value::fromV4Value(engine->jsonObjectToJS(*jsonObjectPtr)); } else if (type == QMetaType::QJsonValue) { - return engine->jsonValueToJS(*jsonValuePtr); + return v8::Value::fromV4Value(engine->jsonValueToJS(*jsonValuePtr)); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { QVariant value = *qvariantPtr; v8::Handle<v8::Value> rv = engine->fromVariant(value); diff --git a/src/qml/qml/v8/qv8sequencewrapper_p_p.h b/src/qml/qml/v8/qv8sequencewrapper_p_p.h index 0c486b8321..80f68c4674 100644 --- a/src/qml/qml/v8/qv8sequencewrapper_p_p.h +++ b/src/qml/qml/v8/qv8sequencewrapper_p_p.h @@ -482,7 +482,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) bool operator()(SequenceElementType e0, SequenceElementType e1) \ { \ v8::Handle<v8::Value> argv[2] = { eng->fromVariant(e0), eng->fromVariant(e1) }; \ - v8::Handle<v8::Value> compareValue = jsFn->Call(eng->global(), 2, argv); \ + v8::Handle<v8::Value> compareValue = jsFn->Call(v8::Value::fromV4Value(eng->global()), 2, argv); \ return compareValue->NumberValue() < 0; \ } \ private: \ diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp index 6ebee592c0..61ac4f9007 100644 --- a/src/qml/qml/v8/qv8typewrapper.cpp +++ b/src/qml/qml/v8/qv8typewrapper.cpp @@ -174,7 +174,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, QObject *qobjectSingleton = siinfo->qobjectApi(e); if (qobjectSingleton) { // check for enum value - if (QV8Engine::startsWithUpper(property)) { + if (QV8Engine::startsWithUpper(property->v4Value().asString())) { if (resource->mode == IncludeEnums) { QString name = property->v4Value().toQString(); @@ -207,7 +207,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, } else { - if (QV8Engine::startsWithUpper(property)) { + if (QV8Engine::startsWithUpper(property->v4Value().asString())) { bool ok = false; int value = type->enumValue(propertystring, &ok); if (ok) diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp index 0e9984316c..30fe193137 100644 --- a/src/qml/qml/v8/qv8valuetypewrapper.cpp +++ b/src/qml/qml/v8/qv8valuetypewrapper.cpp @@ -373,7 +373,7 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property QQmlBinding *newBinding = 0; if (value->IsFunction()) { - if (value->ToObject()->GetHiddenValue(r->engine->bindingFlagKey()).IsEmpty()) { + if (value->ToObject()->GetHiddenValue(v8::Value::fromV4Value(r->engine->bindingFlagKey())).IsEmpty()) { // assigning a JS function to a non-var-property is not allowed. QString error = QLatin1String("Cannot assign JavaScript function to value-type property"); v8::ThrowException(v8::Exception::Error(r->engine->toString(error))); |