From 9e4b877430a6811079d209656587ea228334ed34 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 6 Oct 2009 15:30:59 +1000 Subject: Export the active QScriptContext during a callback Clearly the API needs work :) --- src/script/bridge/qscriptdeclarativeclass.cpp | 50 ++++++++++++++++++++++++-- src/script/bridge/qscriptdeclarativeclass_p.h | 4 +++ src/script/bridge/qscriptdeclarativeobject.cpp | 7 ++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index b990e33..a7667cb 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -78,14 +79,14 @@ QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentif class QScriptDeclarativeClassPrivate { public: - QScriptDeclarativeClassPrivate() {} + QScriptDeclarativeClassPrivate() : engine(0), q_ptr(0) {} QScriptEngine *engine; QScriptDeclarativeClass *q_ptr; }; QScriptDeclarativeClass::QScriptDeclarativeClass(QScriptEngine *engine) -: d_ptr(new QScriptDeclarativeClassPrivate) +: context(0), d_ptr(new QScriptDeclarativeClassPrivate) { Q_ASSERT(sizeof(void*) == sizeof(JSC::Identifier)); d_ptr->q_ptr = this; @@ -176,6 +177,51 @@ QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Iden return QScriptValue(); } +/* +Returns the scope chain entry \a index from the end. This is equivalent to: + context->scopeChain().at(context->scopeChain.length() - 1 - index) +*/ +QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index) +{ + context->activationObject(); //ensure the creation of the normal scope for native context + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + + JSC::ScopeChainNode *node = frame->scopeChain(); + JSC::ScopeChainIterator it(node); + + int count = 0; + for (it = node->begin(); it != node->end(); ++it) + ++count; + + if (count < index) + return QScriptValue(); + + count -= index; + + for (it = node->begin(); it != node->end(); ++it) { + + if (count == 0) { + + JSC::JSObject *object = *it; + if (!object) return QScriptValue(); + + if (object->inherits(&QScript::QScriptActivationObject::info) + && (static_cast(object)->delegate() != 0)) { + // Return the object that property access is being delegated to + object = static_cast(object)->delegate(); + } + return engine->scriptValueFromJSCValue(object); + + } else { + --count; + } + + } + + return QScriptValue(); +} + QScriptDeclarativeClass::~QScriptDeclarativeClass() { } diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index 07cfad1..0d05ec5 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QScriptDeclarativeClassPrivate; class PersistentIdentifierPrivate; +class QScriptContext; class Q_SCRIPT_EXPORT QScriptDeclarativeClass { public: @@ -75,6 +76,8 @@ public: static QScriptValue function(const QScriptValue &, const Identifier &); static QScriptValue property(const QScriptValue &, const Identifier &); + static QScriptValue scopeChainValue(QScriptContext *, int index); + class Q_SCRIPT_EXPORT PersistentIdentifier { public: @@ -113,6 +116,7 @@ public: virtual QObject *toQObject(Object *, bool *ok = 0); virtual QVariant toVariant(Object *, bool *ok = 0); + QScriptContext *context; protected: QScopedPointer d_ptr; }; diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index ef77de0..ffdebb0 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -87,13 +87,16 @@ bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object, QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); + m_class->context = reinterpret_cast(exec); QScriptClass::QueryFlags flags = m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess); if (flags & QScriptClass::HandlesReadAccess) { QScriptValue value = m_class->property(m_object, identifier); + m_class->context = 0; slot.setValue(engine->scriptValueToJSCValue(value)); return true; } + m_class->context = 0; return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot); } @@ -105,12 +108,16 @@ void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); + m_class->context = reinterpret_cast(exec); QScriptClass::QueryFlags flags = m_class->queryProperty(m_object, identifier, QScriptClass::HandlesWriteAccess); if (flags & QScriptClass::HandlesWriteAccess) { m_class->setProperty(m_object, identifier, engine->scriptValueFromJSCValue(value)); + m_class->context = 0; return; } + m_class->context = 0; + QScriptObjectDelegate::put(object, exec, propertyName, value, slot); } -- cgit v0.12