diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-07-16 14:50:50 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-07-16 14:50:50 (GMT) |
commit | 898437f97e3f3bbb96b501148d5f883d099133f7 (patch) | |
tree | dbe476f9d08df10fae21900739e6a44c433b9642 /src/script/bridge | |
parent | b6e5b8116ed297cdc127485c914e461d0cf7c56b (diff) | |
download | Qt-898437f97e3f3bbb96b501148d5f883d099133f7.zip Qt-898437f97e3f3bbb96b501148d5f883d099133f7.tar.gz Qt-898437f97e3f3bbb96b501148d5f883d099133f7.tar.bz2 |
start implementing constructors for QMetaObject wrappers
Diffstat (limited to 'src/script/bridge')
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 103 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject_p.h | 11 |
2 files changed, 110 insertions, 4 deletions
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 23d61e3..e289aad 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -1591,12 +1591,16 @@ bool QMetaObjectWrapperObject::getOwnPropertySlot( if (!meta) return false; - QByteArray name = qtStringFromJSCUString(propertyName.ustring()).toLatin1(); - if (name == "prototype") { - qWarning("getting of metaobject.prototype not implemented"); - return false; + if (propertyName == exec->propertyNames().prototype) { + if (data->ctor) + slot.setValue(data->ctor.get(exec, propertyName)); + else + slot.setValue(data->prototype); + return true; } + QByteArray name = qtStringFromJSCUString(propertyName.ustring()).toLatin1(); + for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); for (int j = 0; j < e.keyCount(); ++j) { @@ -1614,6 +1618,13 @@ bool QMetaObjectWrapperObject::getOwnPropertySlot( void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) { + if (propertyName == exec->propertyNames().prototype) { + if (data->ctor) + data->ctor.put(exec, propertyName, value, slot); + else + data->prototype = value; + return; + } const QMetaObject *meta = data->value; if (meta) { QByteArray name = qtStringFromJSCUString(propertyName.ustring()).toLatin1(); @@ -1631,6 +1642,8 @@ void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& bool QMetaObjectWrapperObject::deleteProperty( JSC::ExecState *exec, const JSC::Identifier& propertyName) { + if (propertyName == exec->propertyNames().prototype) + return false; const QMetaObject *meta = data->value; if (meta) { QByteArray name = qtStringFromJSCUString(propertyName.ustring()).toLatin1(); @@ -1649,6 +1662,10 @@ bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, unsigned &attributes) const { + if (propertyName == exec->propertyNames().prototype) { + attributes = JSC::DontDelete; + return true; + } const QMetaObject *meta = data->value; if (meta) { QByteArray name = qtStringFromJSCUString(propertyName.ustring()).toLatin1(); @@ -1678,6 +1695,84 @@ void QMetaObjectWrapperObject::getPropertyNames(JSC::ExecState *exec, JSC::Prope JSC::JSObject::getPropertyNames(exec, propertyNames); } +void QMetaObjectWrapperObject::mark() +{ + Q_ASSERT(!marked()); + if (data->ctor && !data->ctor.marked()) + data->ctor.mark(); + if (data->prototype && !data->prototype.marked()) + data->prototype.mark(); + JSC::JSObject::mark(); +} + +JSC::CallType QMetaObjectWrapperObject::getCallData(JSC::CallData& callData) +{ + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::ConstructType QMetaObjectWrapperObject::getConstructData(JSC::ConstructData& constructData) +{ + constructData.native.function = construct; + return JSC::ConstructTypeHost; +} + +JSC::JSValue JSC_HOST_CALL QMetaObjectWrapperObject::call( + JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->isObject(&QMetaObjectWrapperObject::info)) + return throwError(exec, JSC::TypeError, "callee is not a QMetaObject"); + QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee); + QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; + JSC::JSValue result = self->execute(exec, args); + eng_p->currentFrame = previousFrame; + return result; +} + +JSC::JSObject* QMetaObjectWrapperObject::construct(JSC::ExecState *exec, JSC::JSObject *callee, const JSC::ArgList &args) +{ + QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee); + QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; + JSC::JSValue result = self->execute(exec, args); + eng_p->currentFrame = previousFrame; + if (!result || !result.isObject()) + return 0; + return JSC::asObject(result); +} + +JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec, + const JSC::ArgList &args) +{ + if (data->ctor) { + JSC::CallData callData; + JSC::CallType callType = data->ctor.getCallData(callData); + return JSC::call(exec, data->ctor, callType, callData, /*thisValue=*/JSC::JSValue(), args); + } else { + if (data->value->constructorCount() > 0) { + Q_ASSERT_X(false, Q_FUNC_INFO, "implement me"); +#if 0 + callQtMethod(context, QMetaMethod::Constructor, /*thisQObject=*/0, + value, value->constructorCount()-1, /*maybeOverloaded=*/true); + if (context->state() == QScriptContext::NormalState) { + ExtQObject::Instance *inst = ExtQObject::Instance::get(context->m_result); + Q_ASSERT(inst != 0); + inst->ownership = QScriptEngine::AutoOwnership; + context->m_result.setPrototype(prototype); + } +#endif + } else { + QString message = QString::fromLatin1("no constructor for %0") + .arg(QLatin1String(data->value->className())); + return JSC::throwError(exec, JSC::TypeError, qtStringToJSCUString(message)); + } + } +} + struct StaticQtMetaObject : public QObject { static const QMetaObject *get() diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h index 766c3c7..8a4edf3 100644 --- a/src/script/bridge/qscriptqobject_p.h +++ b/src/script/bridge/qscriptqobject_p.h @@ -243,6 +243,7 @@ public: { const QMetaObject *value; JSC::JSValue ctor; + JSC::JSValue prototype; Data(const QMetaObject *mo, JSC::JSValue c) : value(mo), ctor(c) {} @@ -263,10 +264,20 @@ public: virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); + virtual void mark(); + + virtual JSC::CallType getCallData(JSC::CallData&); + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &info; } static const JSC::ClassInfo info; + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + static JSC::JSObject* construct(JSC::ExecState *, JSC::JSObject *, const JSC::ArgList &); + + JSC::JSValue execute(JSC::ExecState *exec, const JSC::ArgList &args); + inline const QMetaObject *value() const { return data->value; } inline void setValue(const QMetaObject* value) { data->value = value; } |