diff options
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 62 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 2 |
4 files changed, 48 insertions, 37 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 87987f7d50..8f0b1776d7 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -399,20 +399,26 @@ InternalClass *InternalClass::frozen() if (m_frozen) return m_frozen; - m_frozen = engine->emptyClass; + m_frozen = propertiesFrozen(); + m_frozen = m_frozen->nonExtensible(); + + m_frozen->m_frozen = m_frozen; + m_frozen->m_sealed = m_frozen; + return m_frozen; +} + +InternalClass *InternalClass::propertiesFrozen() const +{ + InternalClass *frozen = engine->emptyClass; for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); if (attrs.isEmpty()) continue; attrs.setWritable(false); attrs.setConfigurable(false); - m_frozen = m_frozen->addMember(nameMap.at(i), attrs); + frozen = frozen->addMember(nameMap.at(i), attrs); } - m_frozen = m_frozen->nonExtensible(); - - m_frozen->m_frozen = m_frozen; - m_frozen->m_sealed = m_frozen; - return m_frozen; + return frozen; } void InternalClass::destroy() diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 80590fe72e..342870fcd6 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -233,6 +233,7 @@ struct InternalClass : public QQmlJS::Managed { InternalClass *sealed(); InternalClass *frozen(); + InternalClass *propertiesFrozen() const; void destroy(); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 6cb316ce9f..effc37a0eb 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -191,41 +191,47 @@ void QV8Engine::initializeGlobal() m_illegalNames.insert(m_v4Engine->globalObject->internalClass()->nameMap.at(i)->string); } } +} - { -#define FREEZE_SOURCE "(function freeze_recur(obj) { "\ - " if (Qt.isQtObject(obj)) return;"\ - " if (obj != Function.connect && obj != Function.disconnect && "\ - " obj instanceof Object) {"\ - " var properties = Object.getOwnPropertyNames(obj);"\ - " for (var prop in properties) { "\ - " if (prop == \"connect\" || prop == \"disconnect\") {"\ - " Object.freeze(obj[prop]); "\ - " continue;"\ - " }"\ - " freeze_recur(obj[prop]);"\ - " }"\ - " }"\ - " if (obj instanceof Object) {"\ - " Object.freeze(obj);"\ - " }"\ - "})" - - QV4::ScopedFunctionObject result(scope, QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0)); - Q_ASSERT(!!result); - m_freezeObject.set(scope.engine, result); -#undef FREEZE_SOURCE +static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object) +{ + if (object->as<QV4::QObjectWrapper>()) + return; + + QV4::Scope scope(v4); + + bool instanceOfObject = false; + QV4::ScopedObject p(scope, object->prototype()); + while (p) { + if (p->d() == v4->objectPrototype()->d()) { + instanceOfObject = true; + break; + } + p = p->prototype(); + } + if (!instanceOfObject) + return; + + QV4::InternalClass *frozen = object->internalClass()->propertiesFrozen(); + if (object->internalClass() == frozen) + return; + object->setInternalClass(frozen); + + QV4::ScopedObject o(scope); + for (uint i = 0; i < frozen->size; ++i) { + if (!frozen->nameMap.at(i)) + continue; + o = *object->propertyData(i); + if (o) + freeze_recursive(v4, o); } } void QV8Engine::freezeObject(const QV4::Value &value) { QV4::Scope scope(m_v4Engine); - QV4::ScopedFunctionObject f(scope, m_freezeObject.value()); - QV4::ScopedCallData callData(scope, 1); - callData->args[0] = value; - callData->thisObject = m_v4Engine->globalObject; - f->call(callData); + QV4::ScopedObject o(scope, value); + freeze_recursive(m_v4Engine, o); } struct QV8EngineRegistrationData diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 238d12e0b2..552470c88c 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -217,8 +217,6 @@ protected: QV4::ExecutionEngine *m_v4Engine; - QV4::PersistentValue m_freezeObject; - void *m_xmlHttpRequestData; QVector<Deletable *> m_extensionData; |