diff options
author | Jedrzej Nowacki <jedrzej.nowacki@nokia.com> | 2009-07-13 08:11:58 (GMT) |
---|---|---|
committer | Jedrzej Nowacki <jedrzej.nowacki@nokia.com> | 2009-07-13 08:11:58 (GMT) |
commit | 777762fa72de048b8ace97e21192bb659accb9f9 (patch) | |
tree | ef516cb06c1078d7945fe0d9aabf51395390eab7 /src/script/api | |
parent | f6304c909b074a951dc33c39bc2b9d75536b1c22 (diff) | |
parent | 7f2fadda40fa79a35e9c77ef4f9613940c23f382 (diff) | |
download | Qt-777762fa72de048b8ace97e21192bb659accb9f9.zip Qt-777762fa72de048b8ace97e21192bb659accb9f9.tar.gz Qt-777762fa72de048b8ace97e21192bb659accb9f9.tar.bz2 |
Merge branch 'qtscript-jsc-backend' of git@scm.dev.nokia.troll.no:qt/qt-webkit into qtscript-jsc-backend
Diffstat (limited to 'src/script/api')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 222 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 62 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 77 |
3 files changed, 93 insertions, 268 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 97a1c61..bf76cd4 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -17,7 +17,6 @@ #include "qscriptengine_p.h" #include "qscriptcontext_p.h" -#include "../bridge/qscriptqobject_p.h" #include "qscriptstring_p.h" #include "qscriptvalue_p.h" #include "qscriptvalueiterator.h" @@ -42,6 +41,8 @@ #include "utils/qscriptdate_p.h" #include "bridge/qscriptfunction_p.h" +#include "bridge/qscriptobject_p.h" +#include "bridge/qscriptclassobject_p.h" #include "bridge/qscriptvariant_p.h" #include "bridge/qscriptqobject_p.h" @@ -62,10 +63,6 @@ Q_DECLARE_METATYPE(QObjectList) #endif Q_DECLARE_METATYPE(QList<int>) -// ### move -Q_DECLARE_METATYPE(QScriptContext*) -Q_DECLARE_METATYPE(QScriptValueList) - QT_BEGIN_NAMESPACE /*! @@ -389,157 +386,6 @@ QString qtStringFromJSCUString(const JSC::UString &str) return QString(reinterpret_cast<const QChar*>(str.data()), str.size()); } -// ### move -const JSC::ClassInfo ClassObject::info = { "QScript::ClassObject", 0, 0, 0 }; - -ClassObject::ClassObject(QScriptClass *scriptClass, WTF::PassRefPtr<JSC::Structure> sid) - : JSC::JSObject(sid), data(new Data(scriptClass)) -{ -} - -ClassObject::~ClassObject() -{ - delete data; -} - -bool ClassObject::getOwnPropertySlot(JSC::ExecState *exec, - const JSC::Identifier &propertyName, - JSC::PropertySlot &slot) -{ - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; - QScriptValue scriptObject = engine->scriptValueFromJSCValue(this); - QString name = qtStringFromJSCUString(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); - uint id = 0; - QScriptClass::QueryFlags flags = data->scriptClass->queryProperty( - scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); - if (flags & QScriptClass::HandlesReadAccess) { - QScriptValue value = data->scriptClass->property(scriptObject, scriptName, id); - slot.setValue(engine->scriptValueToJSCValue(value)); - return true; - } - return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -void ClassObject::put(JSC::ExecState *exec, const JSC::Identifier &propertyName, - JSC::JSValue value, JSC::PutPropertySlot &slot) -{ - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; - QScriptValue scriptObject = engine->scriptValueFromJSCValue(this); - QString name = qtStringFromJSCUString(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); - uint id = 0; - QScriptClass::QueryFlags flags = data->scriptClass->queryProperty( - scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); - if (flags & QScriptClass::HandlesWriteAccess) { - data->scriptClass->setProperty(scriptObject, scriptName, id, engine->scriptValueFromJSCValue(value)); - return; - } - JSC::JSObject::put(exec, propertyName, value, slot); -} - -bool ClassObject::deleteProperty(JSC::ExecState *exec, - const JSC::Identifier &propertyName) -{ - Q_ASSERT_X(false, Q_FUNC_INFO, "implement me"); - return JSC::JSObject::deleteProperty(exec, propertyName); -} - -bool ClassObject::getPropertyAttributes(JSC::ExecState *exec, - const JSC::Identifier &propertyName, - unsigned &attribs) const -{ - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; - QScriptValue scriptObject = engine->scriptValueFromJSCValue(this); - QString name = qtStringFromJSCUString(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); - uint id = 0; - QScriptClass::QueryFlags flags = data->scriptClass->queryProperty( - scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); - if (flags & QScriptClass::HandlesReadAccess) { - QScriptValue::PropertyFlags flags = data->scriptClass->propertyFlags(scriptObject, scriptName, id); - attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - if (flags & QScriptValue::PropertyGetter) - attribs |= JSC::Getter; - if (flags & QScriptValue::PropertySetter) - attribs |= JSC::Setter; - attribs |= flags & QScriptValue::UserRange; - return true; - } - return JSC::JSObject::getPropertyAttributes(exec, propertyName, attribs); -} - -void ClassObject::getPropertyNames(JSC::ExecState *exec, - JSC::PropertyNameArray &propertyNames) -{ - qWarning("Enumeration of custom script objects not implemented"); - JSC::JSObject::getPropertyNames(exec, propertyNames); -} - -JSC::CallType ClassObject::getCallData(JSC::CallData &callData) -{ - if (!data->scriptClass->supportsExtension(QScriptClass::Callable)) - return JSC::CallTypeNone; - callData.native.function = call; - return JSC::CallTypeHost; -} - -JSC::JSValue JSC_HOST_CALL ClassObject::call(JSC::ExecState *exec, JSC::JSObject *callee, - JSC::JSValue thisValue, const JSC::ArgList &args) -{ - if (!callee->isObject(&ClassObject::info)) - return throwError(exec, JSC::TypeError, "callee is not a ClassObject object"); - ClassObject *obj = static_cast<ClassObject*>(callee); - QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; - JSC::ExecState *previousFrame = eng_p->currentFrame; - QScriptContext *ctx = eng_p->contextForFrame(exec); - eng_p->currentFrame = exec; - QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj); - QVariant result = obj->scriptClass()->extension(QScriptClass::Callable, qVariantFromValue(ctx)); - eng_p->currentFrame = previousFrame; - eng_p->releaseContextForFrame(exec); - return eng_p->jscValueFromVariant(result); -} - -bool ClassObject::hasInstance(JSC::ExecState *exec, JSC::JSValue value, JSC::JSValue proto) -{ - if (!scriptClass()->supportsExtension(QScriptClass::HasInstance)) - return JSC::JSObject::hasInstance(exec, value, proto); - QScriptValueList args; - QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; - args << eng_p->scriptValueFromJSCValue(this) << eng_p->scriptValueFromJSCValue(value); - QVariant result = scriptClass()->extension(QScriptClass::HasInstance, qVariantFromValue(args)); - return result.toBool(); -} - -const JSC::ClassInfo* ClassObject::classInfo() const -{ - // ### respect QScriptClass::name() - return &info; -} - -QScriptClass *ClassObject::scriptClass() const -{ - return data->scriptClass; -} - -void ClassObject::setScriptClass(QScriptClass *scriptClass) -{ - data->scriptClass = scriptClass; -} - -ClassObjectPrototype::ClassObjectPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure, - JSC::Structure* prototypeFunctionStructure) - : ClassObject(/*scriptClass=*/0, structure) -{ -} - bool isFunction(JSC::JSValue value) { @@ -723,8 +569,6 @@ void GlobalObject::mark() engine->qmetaobjectPrototype->mark(); if (engine->variantPrototype) engine->variantPrototype->mark(); - if (engine->classObjectPrototype) - engine->classObjectPrototype->mark(); { QHash<JSC::JSCell*,QBasicAtomicInt>::const_iterator it; @@ -745,8 +589,10 @@ void GlobalObject::mark() { QHash<int, QScriptTypeInfo*>::const_iterator it; - for (it = engine->m_typeInfos.constBegin(); it != engine->m_typeInfos.constEnd(); ++it) - (*it)->prototype.mark(); + for (it = engine->m_typeInfos.constBegin(); it != engine->m_typeInfos.constEnd(); ++it) { + if ((*it)->prototype) + (*it)->prototype.mark(); + } } } @@ -921,17 +767,16 @@ QScriptEnginePrivate::QScriptEnginePrivate() : idGenerator(1) JSC::ExecState* exec = globalObject->globalExec(); + scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype()); + qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); - qobjectWrapperObjectStructure = QScript::QObjectWrapperObject::createStructure(qobjectPrototype); + qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype); qmetaobjectPrototype = new (exec) QScript::QMetaObjectPrototype(exec, QScript::QMetaObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); qmetaobjectWrapperObjectStructure = QScript::QMetaObjectWrapperObject::createStructure(qmetaobjectPrototype); variantPrototype = new (exec) QScript::QVariantPrototype(exec, QScript::QVariantPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); - variantWrapperObjectStructure = QScript::QVariantWrapperObject::createStructure(variantPrototype); - - classObjectPrototype = new (exec) QScript::ClassObjectPrototype(exec, QScript::ClassObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); - classObjectStructure = QScript::ClassObject::createStructure(classObjectPrototype); + variantWrapperObjectStructure = QScriptObject::createStructure(variantPrototype); globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "print"), QScript::functionPrint)); globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 0, JSC::Identifier(exec, "gc"), QScript::functionGC)); @@ -1152,8 +997,9 @@ JSC::JSValue QScriptEnginePrivate::newQObject( if (!object) return JSC::jsNull(); JSC::ExecState* exec = currentFrame; - QScript::QObjectWrapperObject *result = new (exec) QScript::QObjectWrapperObject(object, ownership, options, qobjectWrapperObjectStructure); - + QScriptObject *result = new (exec) QScriptObject(qobjectWrapperObjectStructure); + result->setDelegate(new QScript::QObjectDelegate(object, ownership, options)); + // ### TODO /*if (setDefaultPrototype)*/ { const QMetaObject *meta = object->metaObject(); while (meta) { @@ -1170,7 +1016,6 @@ JSC::JSValue QScriptEnginePrivate::newQObject( meta = meta->superClass(); } } - return result; } @@ -1529,8 +1374,8 @@ QScriptValue QScriptEngine::newVariant(const QVariant &value) { Q_D(QScriptEngine); JSC::ExecState* exec = d->currentFrame; - QScript::QVariantWrapperObject *obj = new (exec) QScript::QVariantWrapperObject(d->variantWrapperObjectStructure); - obj->setValue(value); + QScriptObject *obj = new (exec) QScriptObject(d->variantWrapperObjectStructure); + obj->setDelegate(new QScript::QVariantDelegate(value)); QScriptValue result = d->scriptValueFromJSCValue(obj); QScriptValue proto = defaultPrototype(value.userType()); if (proto.isValid()) @@ -1567,8 +1412,13 @@ QScriptValue QScriptEngine::newVariant(const QScriptValue &object, { if (!object.isObject()) return newVariant(value); - else if (!object.isVariant()) { - qWarning("QScriptEngine::newVariant(): Object-->QVariant promotion not implemented"); + JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue); + if (!jscObject->isObject(&QScriptObject::info)) + return QScriptValue(); + QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); + if (!object.isVariant()) { + delete jscScriptObject->delegate(); + jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); } else { QScriptValuePrivate::get(object)->setVariantValue(value); } @@ -1638,14 +1488,18 @@ QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, { if (!scriptObject.isObject()) return newQObject(qtObject, ownership, options); - else if (!scriptObject.isQObject()) { - qWarning("QScriptEngine::newQObject(): Object-->QObject promotion not implemented"); + JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue); + if (!jscObject->isObject(&QScriptObject::info)) + return QScriptValue(); + QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); + if (!scriptObject.isQObject()) { + delete jscScriptObject->delegate(); + jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options)); } else { - JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue); - QScript::QObjectWrapperObject *wrapper = static_cast<QScript::QObjectWrapperObject*>(jscObject); - wrapper->setValue(qtObject); - wrapper->setOwnership(ownership); - wrapper->setOptions(options); + QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate()); + delegate->setValue(qtObject); + delegate->setOwnership(ownership); + delegate->setOptions(options); } return scriptObject; } @@ -1664,7 +1518,7 @@ QScriptValue QScriptEngine::newObject() { Q_D(QScriptEngine); JSC::ExecState* exec = d->currentFrame; - JSC::JSObject *result = JSC::constructEmptyObject(exec); + JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure); return d->scriptValueFromJSCValue(result); } @@ -1687,7 +1541,8 @@ QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass, { Q_D(QScriptEngine); JSC::ExecState* exec = d->currentFrame; - QScript::ClassObject *result = new (exec) QScript::ClassObject(scriptClass, d->classObjectStructure); + QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure); + result->setDelegate(new QScript::ClassObjectDelegate(scriptClass)); QScriptValue scriptObject = d->scriptValueFromJSCValue(result); scriptObject.setData(data); QScriptValue proto = scriptClass->prototype(); @@ -2095,7 +1950,7 @@ QScriptContext *QScriptEngine::pushContext() { Q_D(QScriptEngine); qWarning("QScriptEngine::pushContext() not implemented"); - return 0; + return d->contextForFrame(d->currentFrame); #ifndef Q_SCRIPT_NO_EVENT_NOTIFY // notifyContextPush(); TODO #endif @@ -2836,7 +2691,8 @@ QScriptValue QScriptEngine::importExtension(const QString &extension) } // if the __postInit__ function has been set, we call it - QScriptValue postInit = ctx->activationObject().property(QLatin1String("__postInit__")); + // ### enable once activationObject() works + QScriptValue postInit; // = ctx->activationObject().property(QLatin1String("__postInit__")); if (postInit.isFunction()) { postInit.call(globalObject()); if (hasUncaughtException()) { diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 545a8c8..64f2145 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -50,7 +50,6 @@ namespace QScript class QObjectPrototype; class QMetaObjectPrototype; class QVariantPrototype; - class ClassObjectPrototype; #ifndef QT_NO_QOBJECT class QObjectData; #endif @@ -160,6 +159,8 @@ public: QHash<JSC::ExecState*, QScriptContext*> contextForFrameHash; JSC::JSValue uncaughtException; + WTF::RefPtr<JSC::Structure> scriptObjectStructure; + QScript::QObjectPrototype *qobjectPrototype; WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure; @@ -169,9 +170,6 @@ public: QScript::QVariantPrototype *variantPrototype; WTF::RefPtr<JSC::Structure> variantWrapperObjectStructure; - QScript::ClassObjectPrototype *classObjectPrototype; - WTF::RefPtr<JSC::Structure> classObjectStructure; - QScriptEngineAgent *agent; QHash<JSC::JSCell*, QBasicAtomicInt> keepAliveValues; QHash<int, QScriptTypeInfo*> m_typeInfos; @@ -208,62 +206,6 @@ public: QScriptEnginePrivate *engine; }; -// ### move -class ClassObject : public JSC::JSObject -{ -public: - // work around CELL_SIZE limitation - struct Data - { - QScriptClass *scriptClass; - - Data(QScriptClass *sc) - : scriptClass(sc) {} - }; - - explicit ClassObject(QScriptClass *scriptClass, - WTF::PassRefPtr<JSC::Structure> sid); - ~ClassObject(); - - virtual bool getOwnPropertySlot(JSC::ExecState*, - const JSC::Identifier& propertyName, - JSC::PropertySlot&); - virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, - JSC::JSValue, JSC::PutPropertySlot&); - virtual bool deleteProperty(JSC::ExecState*, - const JSC::Identifier& propertyName); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, - unsigned&) const; - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - - virtual JSC::CallType getCallData(JSC::CallData&); - static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, - JSC::JSValue, const JSC::ArgList&); - - virtual bool hasInstance(JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); - - virtual const JSC::ClassInfo* classInfo() const; - static const JSC::ClassInfo info; - - static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) - { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance)); - } - - QScriptClass *scriptClass() const; - void setScriptClass(QScriptClass *scriptClass); - -private: - Data *data; -}; - -class ClassObjectPrototype : public ClassObject -{ -public: - ClassObjectPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure>, - JSC::Structure* prototypeFunctionStructure); -}; - } // namespace QScript QT_END_NAMESPACE diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index e523c93..0232dab 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -36,6 +36,8 @@ #include <QtCore/qnumeric.h> #include "utils/qscriptdate_p.h" +#include "bridge/qscriptobject_p.h" +#include "bridge/qscriptclassobject_p.h" #include "bridge/qscriptvariant_p.h" #include "bridge/qscriptqobject_p.h" @@ -368,12 +370,18 @@ QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const QVariant &QScriptValuePrivate::variantValue() const { - return static_cast<QScript::QVariantWrapperObject*>(JSC::asObject(jscValue))->value(); + Q_ASSERT(jscValue.isObject(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return static_cast<QScript::QVariantDelegate*>(delegate)->value(); } void QScriptValuePrivate::setVariantValue(const QVariant &value) { - static_cast<QScript::QVariantWrapperObject*>(JSC::asObject(jscValue))->setValue(value); + Q_ASSERT(jscValue.isObject(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); } /*! @@ -1554,7 +1562,8 @@ QObject *QScriptValue::toQObject() const { Q_D(const QScriptValue); if (isQObject()) { - return static_cast<QScript::QObjectWrapperObject*>(JSC::asObject(d->jscValue))->value(); + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + return static_cast<QScript::QObjectDelegate*>(object->delegate())->value(); } else if (isVariant()) { QVariant var = toVariant(); int type = var.userType(); @@ -2281,9 +2290,11 @@ bool QScriptValue::isObject() const bool QScriptValue::isVariant() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.isObject()) + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) return false; - return JSC::asObject(d->jscValue)->isObject(&QScript::QVariantWrapperObject::info); + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); } /*! @@ -2298,9 +2309,11 @@ bool QScriptValue::isVariant() const bool QScriptValue::isQObject() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.isObject()) + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) return false; - return JSC::asObject(d->jscValue)->isObject(&QScript::QObjectWrapperObject::info); + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); } /*! @@ -2344,8 +2357,14 @@ QScriptValue QScriptValue::data() const Q_D(const QScriptValue); if (!d || !d->isJSC() || !d->jscValue.isObject()) return QScriptValue(); - // ### make hidden property - return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + if (d->jscValue.isObject(&QScriptObject::info)) { + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine); + return eng_p->scriptValueFromJSCValue(scriptObject->data()); + } else { + // ### make hidden property + return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + } } /*! @@ -2363,13 +2382,18 @@ void QScriptValue::setData(const QScriptValue &data) return; QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine); JSC::JSValue other = eng_p->scriptValueToJSCValue(data); - JSC::ExecState *exec = eng_p->currentFrame; - JSC::Identifier id = JSC::Identifier(exec, "__qt_data__"); - if (!data.isValid()) { - JSC::asObject(d->jscValue)->removeDirect(id); + if (d->jscValue.isObject(&QScriptObject::info)) { + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + scriptObject->setData(other); } else { - // ### make hidden property - JSC::asObject(d->jscValue)->putDirect(id, other); + JSC::ExecState *exec = eng_p->currentFrame; + JSC::Identifier id = JSC::Identifier(exec, "__qt_data__"); + if (!data.isValid()) { + JSC::asObject(d->jscValue)->removeDirect(id); + } else { + // ### make hidden property + JSC::asObject(d->jscValue)->putDirect(id, other); + } } } @@ -2384,12 +2408,13 @@ void QScriptValue::setData(const QScriptValue &data) QScriptClass *QScriptValue::scriptClass() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.isObject()) + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) return 0; - if (!d->jscValue.isObject(&QScript::ClassObject::info)) + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) return 0; - QScript::ClassObject *instance = static_cast<QScript::ClassObject*>(JSC::asObject(d->jscValue)); - return instance->scriptClass(); + return static_cast<QScript::ClassObjectDelegate*>(delegate)->scriptClass(); } /*! @@ -2408,14 +2433,16 @@ QScriptClass *QScriptValue::scriptClass() const void QScriptValue::setScriptClass(QScriptClass *scriptClass) { Q_D(QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.isObject()) - return; - if (!d->jscValue.isObject(&QScript::ClassObject::info)) { - qWarning("QScriptValue::setScriptClass() not implemented"); + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) return; + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) { + delete delegate; + delegate = new QScript::ClassObjectDelegate(scriptClass); + scriptObject->setDelegate(delegate); } - QScript::ClassObject *instance = static_cast<QScript::ClassObject*>(JSC::asObject(d->jscValue)); - instance->setScriptClass(scriptClass); + static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass); } /*! |