diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-01-11 04:21:18 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-01-11 04:21:18 (GMT) |
commit | ece224f79dfe3b859910cb24d64e96277b3c737f (patch) | |
tree | 9dd6f037ac81bd492cc553870d1e390520e58200 /src/script | |
parent | e1dfba9da8e093255c6020cb61b1b0ea68d2c012 (diff) | |
download | Qt-ece224f79dfe3b859910cb24d64e96277b3c737f.zip Qt-ece224f79dfe3b859910cb24d64e96277b3c737f.tar.gz Qt-ece224f79dfe3b859910cb24d64e96277b3c737f.tar.bz2 |
Optimization: Add QScriptDeclarativeClass::Value
This class is essentially the same as QScriptValue, but it is faster
as it doesn't reference objects. Thus, they might be collected
if the gc runs. For return values from QScriptDeclarativeClass this
isn't a problem, of course.
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass.cpp | 169 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass_p.h | 31 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeobject.cpp | 4 |
3 files changed, 199 insertions, 5 deletions
diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index 2c13066..d67804a 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -35,6 +35,107 @@ QT_BEGIN_NAMESPACE +/*! +\class QScriptDeclarativeClass::Value +\internal +\brief The QScriptDeclarativeClass::Value class acts as a container for JavaScript data types. + +QScriptDeclarativeClass::Value class is similar to QScriptValue, but it is slightly faster. +Unlike QScriptValue, however, Value instances cannot be stored as they may not survive garbage +collection. If you need to store a Value, convert it to a QScriptValue and store that. +*/ + +QScriptDeclarativeClass::Value::Value() +{ + new (this) JSC::JSValue(); +} + +QScriptDeclarativeClass::Value::Value(const Value &other) +{ + new (this) JSC::JSValue((JSC::JSValue &)other); +} + +static QScriptDeclarativeClass::Value jscToValue(const JSC::JSValue &val) +{ + return QScriptDeclarativeClass::Value((QScriptDeclarativeClass::Value &)val); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, int value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, uint value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, bool value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, double value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, float value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); +} + +QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, const QString &value) +{ + new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::frameForContext(ctxt), value)); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, int value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, uint value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, bool value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, double value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, float value) +{ + new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); +} + +QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, const QString &value) +{ + new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::get(eng)->currentFrame, value)); +} + +QScriptDeclarativeClass::Value::Value(const QScriptValue &value) +{ + new (this) JSC::JSValue(QScriptValuePrivate::get(&value)->engine->scriptValueToJSCValue(value)); +} + + +QScriptDeclarativeClass::Value::~Value() +{ + ((JSC::JSValue *)(this))->~JSValue(); +} + +QScriptValue QScriptDeclarativeClass::Value::toScriptValue(QScriptEngine *engine) const +{ + return QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue((JSC::JSValue &)*this); +} + QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier() : identifier(0) { @@ -83,6 +184,22 @@ QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, return p->scriptValueFromJSCValue(result); } +QScriptDeclarativeClass::Value +QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine, + QScriptDeclarativeClass *scriptClass, + Object *object) +{ + Q_ASSERT(engine); + Q_ASSERT(scriptClass); + + QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine)); + + JSC::ExecState* exec = p->currentFrame; + QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); + result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object)); + return jscToValue(JSC::JSValue(result)); +} + QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v) { QScriptValuePrivate *d = QScriptValuePrivate::get(v); @@ -152,6 +269,53 @@ QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Iden return QScriptValue(); } +QScriptDeclarativeClass::Value +QScriptDeclarativeClass::functionValue(const QScriptValue &v, const Identifier &name) +{ + QScriptValuePrivate *d = QScriptValuePrivate::get(v); + + if (!d->isObject()) + return Value(); + + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSObject *object = d->jscValue.getObject(); + JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object)); + JSC::JSValue result; + + JSC::Identifier id(exec, (JSC::UString::Rep *)name); + + if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) { + result = slot.getValue(exec, id); + if (QScript::isFunction(result)) + return jscToValue(result); + } + + return Value(); +} + +QScriptDeclarativeClass::Value +QScriptDeclarativeClass::propertyValue(const QScriptValue &v, const Identifier &name) +{ + QScriptValuePrivate *d = QScriptValuePrivate::get(v); + + if (!d->isObject()) + return Value(); + + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSObject *object = d->jscValue.getObject(); + JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object)); + JSC::JSValue result; + + JSC::Identifier id(exec, (JSC::UString::Rep *)name); + + if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) { + result = slot.getValue(exec, id); + return jscToValue(result); + } + + return Value(); +} + /* Returns the scope chain entry at \a index. If index is less than 0, returns entries starting at the end. For example, scopeChainValue(context, -1) will return @@ -291,11 +455,12 @@ QScriptDeclarativeClass::queryProperty(Object *object, const Identifier &name, return 0; } -QScriptValue QScriptDeclarativeClass::property(Object *object, const Identifier &name) +QScriptDeclarativeClass::Value +QScriptDeclarativeClass::property(Object *object, const Identifier &name) { Q_UNUSED(object); Q_UNUSED(name); - return QScriptValue(); + return Value(); } void QScriptDeclarativeClass::setProperty(Object *object, const Identifier &name, diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index f2557bd..87ab964 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -47,16 +47,45 @@ class QScriptContext; class Q_SCRIPT_EXPORT QScriptDeclarativeClass { public: + class Value + { + public: + Value(); + Value(const Value &); + Value(const QScriptValue &); + + Value(QScriptContext *, int); + Value(QScriptContext *, uint); + Value(QScriptContext *, bool); + Value(QScriptContext *, double); + Value(QScriptContext *, float); + Value(QScriptContext *, const QString &); + Value(QScriptEngine *, int); + Value(QScriptEngine *, uint); + Value(QScriptEngine *, bool); + Value(QScriptEngine *, double); + Value(QScriptEngine *, float); + Value(QScriptEngine *, const QString &); + ~Value(); + + QScriptValue toScriptValue(QScriptEngine *) const; + private: + char dummy[8]; + }; + typedef void* Identifier; struct Object { virtual ~Object() {} }; static QScriptValue newObject(QScriptEngine *, QScriptDeclarativeClass *, Object *); + static Value newObjectValue(QScriptEngine *, QScriptDeclarativeClass *, Object *); static QScriptDeclarativeClass *scriptClass(const QScriptValue &); static Object *object(const QScriptValue &); static QScriptValue function(const QScriptValue &, const Identifier &); static QScriptValue property(const QScriptValue &, const Identifier &); + static Value functionValue(const QScriptValue &, const Identifier &); + static Value propertyValue(const QScriptValue &, const Identifier &); static QScriptValue scopeChainValue(QScriptContext *, int index); static QScriptContext *pushCleanContext(QScriptEngine *); @@ -91,7 +120,7 @@ public: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags); - virtual QScriptValue property(Object *, const Identifier &); + virtual Value property(Object *, const Identifier &); virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &); diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index 6b4f5cb..72e31a9 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -74,9 +74,9 @@ bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object, QScriptClass::QueryFlags flags = m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess); if (flags & QScriptClass::HandlesReadAccess) { - QScriptValue value = m_class->property(m_object, identifier); + QScriptDeclarativeClass::Value val = m_class->property(m_object, identifier); p->context = 0; - slot.setValue(engine->scriptValueToJSCValue(value)); + slot.setValue((const JSC::JSValue &)val); return true; } p->context = 0; |