Remove V8 dependencies from the JSON wrapper
authorLars Knoll <lars.knoll@digia.com>
Fri, 19 Apr 2013 11:43:08 +0000 (13:43 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 19 Apr 2013 12:35:05 +0000 (14:35 +0200)
Change-Id: I0ac3cc83ba4482107402d7482a7777fd9c53b9da
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/v8/qv4jsonwrapper.cpp [moved from src/qml/qml/v8/qv8jsonwrapper.cpp with 51% similarity]
src/qml/qml/v8/qv4jsonwrapper_p.h [moved from src/qml/qml/v8/qv8jsonwrapper_p.h with 70% similarity]
src/qml/qml/v8/qv8engine.cpp
src/qml/qml/v8/qv8engine_p.h
src/qml/qml/v8/v8.pri

similarity index 51%
rename from src/qml/qml/v8/qv8jsonwrapper.cpp
rename to src/qml/qml/v8/qv4jsonwrapper.cpp
index 8f4e6f4..01cc194 100644 (file)
 **
 ****************************************************************************/
 
-#include "qv8jsonwrapper_p.h"
-#include "qv8engine_p.h"
+#include "qv4jsonwrapper_p.h"
+#include "private/qv4engine_p.h"
+#include "private/qv4object_p.h"
+#include "private/qv4objectiterator_p.h"
 #include "qjsconverter_p.h"
 
 QT_BEGIN_NAMESPACE
 
-QV8JsonWrapper::QV8JsonWrapper()
+using namespace QV4;
+
+QV4JsonWrapper::QV4JsonWrapper()
 : m_engine(0)
 {
 }
 
-QV8JsonWrapper::~QV8JsonWrapper()
+QV4JsonWrapper::~QV4JsonWrapper()
 {
 }
 
-void QV8JsonWrapper::init(QV8Engine *engine)
+void QV4JsonWrapper::init(QV4::ExecutionEngine *engine)
 {
     m_engine = engine;
 }
 
-void QV8JsonWrapper::destroy()
+void QV4JsonWrapper::destroy()
 {
 }
 
-v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value)
+QV4::Value QV4JsonWrapper::fromJsonValue(const QJsonValue &value)
 {
     if (value.isString())
-        return QJSConverter::toString(value.toString());
+        return Value::fromString(m_engine->current, value.toString());
     else if (value.isDouble())
-        return v8::Number::New(value.toDouble());
+        return Value::fromDouble(value.toDouble());
     else if (value.isBool())
-        return value.toBool() ? v8::True() : v8::False();
+        return Value::fromBoolean(value.toBool());
     else if (value.isArray())
         return fromJsonArray(value.toArray());
     else if (value.isObject())
         return fromJsonObject(value.toObject());
     else if (value.isNull())
-        return v8::Null();
+        return Value::nullValue();
     else
-        return v8::Undefined();
+        return Value::undefinedValue();
 }
 
-QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value,
-                                       V8ObjectSet &visitedObjects)
+QJsonValue QV4JsonWrapper::toJsonValue(const QV4::Value &value,
+                                       V4ObjectSet &visitedObjects)
 {
-    if (value->IsString())
-        return QJsonValue(QJSConverter::toString(value.As<v8::String>()));
-    else if (value->IsNumber())
-        return QJsonValue(value->NumberValue());
-    else if (value->IsBoolean())
-        return QJsonValue(value->BooleanValue());
-    else if (value->IsArray())
-        return toJsonArray(value.As<v8::Array>(), visitedObjects);
-    else if (value->IsObject())
-        return toJsonObject(value.As<v8::Object>(), visitedObjects);
-    else if (value->IsNull())
+    if (String *s = value.asString())
+        return QJsonValue(s->toQString());
+    else if (value.isNumber())
+        return QJsonValue(value.toNumber());
+    else if (value.isBoolean())
+        return QJsonValue((bool)value.booleanValue());
+    else if (ArrayObject *a = value.asArrayObject())
+        return toJsonArray(a, visitedObjects);
+    else if (Object *o = value.asObject())
+        return toJsonObject(o, visitedObjects);
+    else if (value.isNull())
         return QJsonValue(QJsonValue::Null);
     else
         return QJsonValue(QJsonValue::Undefined);
 }
 
-v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object)
+QV4::Value QV4JsonWrapper::fromJsonObject(const QJsonObject &object)
 {
-    v8::Local<v8::Object> v8object = v8::Object::New();
+    Object *o = m_engine->newObject();
     for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
-        v8object->Set(QJSConverter::toString(it.key()), fromJsonValue(it.value()));
-    return v8object;
+        o->put(m_engine->current, m_engine->newString(it.key()), fromJsonValue(it.value()));
+    return Value::fromObject(o);
 }
 
-QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value,
-                                         V8ObjectSet &visitedObjects)
+QJsonObject QV4JsonWrapper::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects)
 {
     QJsonObject result;
-    if (!value->IsObject() || value->IsArray() || value->IsFunction())
+    if (!o || o->asFunctionObject())
         return result;
 
-    v8::Handle<v8::Object> v8object(value.As<v8::Object>());
-    if (visitedObjects.contains(v8object)) {
+    if (visitedObjects.contains(o)) {
         // Avoid recursion.
         // For compatibility with QVariant{List,Map} conversion, we return an
         // empty object (and no error is thrown).
         return result;
     }
 
-    visitedObjects.insert(v8object);
+    visitedObjects.insert(o);
+
+    ObjectIterator it(o, ObjectIterator::EnumberableOnly);
+    while (1) {
+        PropertyAttributes attributes;
+        String *name;
+        uint idx;
+        Property *p = it.next(&name, &idx, &attributes);
+        if (!p)
+            break;
 
-    v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object);
-    uint32_t length = propertyNames->Length();
-    for (uint32_t i = 0; i < length; ++i) {
-        v8::Local<v8::Value> name = propertyNames->Get(i);
-        v8::Local<v8::Value> propertyValue = v8object->Get(name);
-        if (!propertyValue->IsFunction())
-            result.insert(QJSConverter::toString(name->ToString()),
-                          toJsonValue(propertyValue, visitedObjects));
+        Value v = o->getValue(m_engine->current, p, attributes);
+        QString key = name ? name->toQString() : QString::number(idx);
+        result.insert(key, toJsonValue(v, visitedObjects));
     }
 
-    visitedObjects.remove(v8object);
+    visitedObjects.remove(o);
 
     return result;
 }
 
-v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array)
+QV4::Value QV4JsonWrapper::fromJsonArray(const QJsonArray &array)
 {
     int size = array.size();
-    v8::Local<v8::Array> v8array = v8::Array::New(size);
+    ArrayObject *a = m_engine->newArrayObject(m_engine->current);
+    a->arrayReserve(size);
     for (int i = 0; i < size; i++)
-        v8array->Set(i, fromJsonValue(array.at(i)));
-    return v8array;
+        a->arrayData[i].value = fromJsonValue(array.at(i));
+    a->setArrayLengthUnchecked(size);
+    return Value::fromObject(a);
 }
 
-QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value,
-                                       V8ObjectSet &visitedObjects)
+QJsonArray QV4JsonWrapper::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
 {
     QJsonArray result;
-    if (!value->IsArray())
+    if (!a)
         return result;
 
-    v8::Handle<v8::Array> v8array(value.As<v8::Array>());
-    if (visitedObjects.contains(v8array)) {
+    if (visitedObjects.contains(a)) {
         // Avoid recursion.
         // For compatibility with QVariant{List,Map} conversion, we return an
         // empty array (and no error is thrown).
         return result;
     }
 
-    visitedObjects.insert(v8array);
+    visitedObjects.insert(a);
 
-    uint32_t length = v8array->Length();
-    for (uint32_t i = 0; i < length; ++i) {
-        v8::Local<v8::Value> element = v8array->Get(i);
-        if (!element->IsFunction())
-            result.append(toJsonValue(element, visitedObjects));
+    quint32 length = a->arrayLength();
+    for (quint32 i = 0; i < length; ++i) {
+        Value v = a->getIndexed(m_engine->current, i);
+        result.append(toJsonValue(v, visitedObjects));
     }
 
-    visitedObjects.remove(v8array);
+    visitedObjects.remove(a);
 
     return result;
 }
similarity index 70%
rename from src/qml/qml/v8/qv8jsonwrapper_p.h
rename to src/qml/qml/v8/qv4jsonwrapper_p.h
index eb4a197..7fe24c0 100644 (file)
@@ -55,7 +55,6 @@
 
 #include <QtCore/qglobal.h>
 #include <QtCore/qset.h>
-#include <private/qv8_p.h>
 
 #include <QtCore/qjsonarray.h>
 #include <QtCore/qjsonobject.h>
 
 QT_BEGIN_NAMESPACE
 
-class QV8Engine;
-class QV8JsonWrapper
+namespace QV4 {
+struct Value;
+struct Object;
+struct ArrayObject;
+struct ExecutionEngine;
+}
+
+class QV4JsonWrapper
 {
-    typedef QSet<v8::Handle<v8::Object> > V8ObjectSet;
+    typedef QSet<QV4::Object *> V4ObjectSet;
 public:
-    QV8JsonWrapper();
-    ~QV8JsonWrapper();
+    QV4JsonWrapper();
+    ~QV4JsonWrapper();
 
-    void init(QV8Engine *);
+    void init(QV4::ExecutionEngine *);
     void destroy();
 
-    v8::Handle<v8::Value> fromJsonValue(const QJsonValue &value);
-    inline QJsonValue toJsonValue(v8::Handle<v8::Value> value)
-    { V8ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }
+    QV4::Value fromJsonValue(const QJsonValue &value);
+    inline QJsonValue toJsonValue(const QV4::Value &value)
+    { V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }
 
-    v8::Local<v8::Object> fromJsonObject(const QJsonObject &object);
-    inline QJsonObject toJsonObject(v8::Handle<v8::Value> value)
-    { V8ObjectSet visitedObjects; return toJsonObject(value, visitedObjects); }
+    QV4::Value fromJsonObject(const QJsonObject &object);
+    inline QJsonObject toJsonObject(QV4::Object *o)
+    { V4ObjectSet visitedObjects; return toJsonObject(o, visitedObjects); }
 
-    v8::Local<v8::Array> fromJsonArray(const QJsonArray &array);
-    inline QJsonArray toJsonArray(v8::Handle<v8::Value> value)
-    { V8ObjectSet visitedObjects; return toJsonArray(value, visitedObjects); }
+    QV4::Value fromJsonArray(const QJsonArray &array);
+    inline QJsonArray toJsonArray(QV4::ArrayObject *a)
+    { V4ObjectSet visitedObjects; return toJsonArray(a, visitedObjects); }
 
 private:
-    QJsonValue toJsonValue(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
-    QJsonObject toJsonObject(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
-    QJsonArray toJsonArray(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
+    QJsonValue toJsonValue(const QV4::Value &value, V4ObjectSet &visitedObjects);
+    QJsonObject toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects);
+    QJsonArray toJsonArray(QV4::ArrayObject *a, V4ObjectSet &visitedObjects);
 
-    QV8Engine *m_engine;
+    QV4::ExecutionEngine *m_engine;
 };
 
 QT_END_NAMESPACE
index 5e5b89d..200b6cf 100644 (file)
@@ -168,7 +168,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership)
     m_variantWrapper.init(this);
     m_valueTypeWrapper.init(this);
     m_sequenceWrapper.init(this);
-    m_jsonWrapper.init(this);
+    m_jsonWrapper.init(m_v4Engine);
 
     {
     v8::Handle<v8::Value> v = global()->Get(v8::String::New("Object"))->ToObject()->Get(v8::String::New("getOwnPropertyNames"));
@@ -1314,32 +1314,32 @@ QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value,
 
 v8::Handle<v8::Value> QV8Engine::jsonValueToJS(const QJsonValue &value)
 {
-    return m_jsonWrapper.fromJsonValue(value);
+    return v8::Value::fromV4Value(m_jsonWrapper.fromJsonValue(value));
 }
 
 QJsonValue QV8Engine::jsonValueFromJS(v8::Handle<v8::Value> value)
 {
-    return m_jsonWrapper.toJsonValue(value);
+    return m_jsonWrapper.toJsonValue(value.get()->v4Value());
 }
 
 v8::Local<v8::Object> QV8Engine::jsonObjectToJS(const QJsonObject &object)
 {
-    return m_jsonWrapper.fromJsonObject(object);
+    return v8::Local<v8::Object>::New(v8::Value::fromV4Value(m_jsonWrapper.fromJsonObject(object)));
 }
 
 QJsonObject QV8Engine::jsonObjectFromJS(v8::Handle<v8::Value> value)
 {
-    return m_jsonWrapper.toJsonObject(value);
+    return m_jsonWrapper.toJsonObject(value.get()->v4Value().asObject());
 }
 
 v8::Local<v8::Array> QV8Engine::jsonArrayToJS(const QJsonArray &array)
 {
-    return m_jsonWrapper.fromJsonArray(array);
+    return v8::Local<v8::Array>::New(v8::Value::fromV4Value(m_jsonWrapper.fromJsonArray(array)));
 }
 
 QJsonArray QV8Engine::jsonArrayFromJS(v8::Handle<v8::Value> value)
 {
-    return m_jsonWrapper.toJsonArray(value);
+    return m_jsonWrapper.toJsonArray(value.get()->v4Value().asArrayObject());
 }
 
 bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value,
index 509ebf4..247cc73 100644 (file)
@@ -78,7 +78,7 @@
 #include "qv8variantwrapper_p.h"
 #include "qv8valuetypewrapper_p.h"
 #include "qv8sequencewrapper_p.h"
-#include "qv8jsonwrapper_p.h"
+#include "qv4jsonwrapper_p.h"
 
 namespace v8 {
 
@@ -472,7 +472,7 @@ protected:
     QV8VariantWrapper m_variantWrapper;
     QV8ValueTypeWrapper m_valueTypeWrapper;
     QV8SequenceWrapper m_sequenceWrapper;
-    QV8JsonWrapper m_jsonWrapper;
+    QV4JsonWrapper m_jsonWrapper;
 
     v8::Persistent<v8::Function> m_getOwnPropertyNames;
     v8::Persistent<v8::Function> m_freezeObject;
index faad646..fc3f4d4 100644 (file)
@@ -14,7 +14,7 @@ HEADERS += \
     $$PWD/qv8variantwrapper_p.h \
     $$PWD/qv8variantresource_p.h \
     $$PWD/qv8valuetypewrapper_p.h \
-    $$PWD/qv8jsonwrapper_p.h \
+    $$PWD/qv4jsonwrapper_p.h \
     $$PWD/qv8include_p.h \
     $$PWD/qv8worker_p.h \
     $$PWD/qv8bindings_p.h \
@@ -33,7 +33,7 @@ SOURCES += \
     $$PWD/qv8listwrapper.cpp \
     $$PWD/qv8variantwrapper.cpp \
     $$PWD/qv8valuetypewrapper.cpp \
-    $$PWD/qv8jsonwrapper.cpp \
+    $$PWD/qv4jsonwrapper.cpp \
     $$PWD/qv8include.cpp \
     $$PWD/qv8worker.cpp \
     $$PWD/qv8bindings.cpp \