X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/b5422865f473faf3977f31b96a635c4c8c4ede09..9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73:/bindings/qt/qt_instance.cpp diff --git a/bindings/qt/qt_instance.cpp b/bindings/qt/qt_instance.cpp deleted file mode 100644 index 0197b84..0000000 --- a/bindings/qt/qt_instance.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) 2006 Trolltech ASA - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "qt_instance.h" - -#include "JSGlobalObject.h" -#include "list.h" -#include "qt_class.h" -#include "qt_runtime.h" -#include "PropertyNameArray.h" -#include "runtime_object.h" -#include "object_object.h" - -#include -#include -#include -#include - -namespace KJS { -namespace Bindings { - -// Cache QtInstances -typedef QMultiHash QObjectInstanceMap; -static QObjectInstanceMap cachedInstances; - -// Cache JSObjects -typedef QHash InstanceJSObjectMap; -static InstanceJSObjectMap cachedObjects; - -// Derived RuntimeObject -class QtRuntimeObjectImp : public RuntimeObjectImp { - public: - QtRuntimeObjectImp(Instance*); - ~QtRuntimeObjectImp(); - virtual void invalidate(); - - // Additions - virtual bool implementsConstruct() const {return implementsCall();} - virtual JSObject* construct(ExecState* exec, const List& args); - protected: - void removeFromCache(); -}; - -QtRuntimeObjectImp::QtRuntimeObjectImp(Instance* instance) - : RuntimeObjectImp(instance) -{ -} - -QtRuntimeObjectImp::~QtRuntimeObjectImp() -{ - removeFromCache(); -} - -void QtRuntimeObjectImp::invalidate() -{ - removeFromCache(); - RuntimeObjectImp::invalidate(); -} - -void QtRuntimeObjectImp::removeFromCache() -{ - JSLock lock; - QtInstance* key = cachedObjects.key(this); - if (key) - cachedObjects.remove(key); -} - -JSObject* QtRuntimeObjectImp::construct(ExecState* exec, const List& args) -{ - // ECMA 15.2.2.1 (?) - JSValue *val = callAsFunction(exec, this, args); - - if (!val || val->type() == NullType || val->type() == UndefinedType) - return new JSObject(exec->lexicalGlobalObject()->objectPrototype()); - else - return val->toObject(exec); -} - -// QtInstance -QtInstance::QtInstance(QObject* o, PassRefPtr rootObject) - : Instance(rootObject) - , m_class(0) - , m_object(o) - , m_hashkey(o) - , m_defaultMethod(0) - , m_defaultMethodIndex(-2) -{ -} - -QtInstance::~QtInstance() -{ - JSLock lock; - - cachedObjects.remove(this); - cachedInstances.remove(m_hashkey); - - // clean up (unprotect from gc) the JSValues we've created - foreach(JSValue* val, m_methods.values()) { - gcUnprotect(val); - } - m_methods.clear(); - - foreach(QtField* f, m_fields.values()) { - delete f; - } - m_fields.clear(); - - if (m_defaultMethod) - gcUnprotect(m_defaultMethod); -} - -QtInstance* QtInstance::getQtInstance(QObject* o, PassRefPtr rootObject) -{ - JSLock lock; - - foreach(QtInstance* instance, cachedInstances.values(o)) { - if (instance->rootObject() == rootObject) - return instance; - } - - QtInstance* ret = new QtInstance(o, rootObject); - cachedInstances.insert(o, ret); - - return ret; -} - -JSObject* QtInstance::getRuntimeObject(QtInstance* instance) -{ - JSLock lock; - JSObject* ret = cachedObjects.value(instance); - if (!ret) { - ret = new QtRuntimeObjectImp(instance); - cachedObjects.insert(instance, ret); - } - return ret; -} - -Class* QtInstance::getClass() const -{ - if (!m_class) - m_class = QtClass::classForObject(m_object); - return m_class; -} - -void QtInstance::begin() -{ - // Do nothing. -} - -void QtInstance::end() -{ - // Do nothing. -} - -void QtInstance::getPropertyNames(ExecState* , PropertyNameArray& array) -{ - // This is the enumerable properties, so put: - // properties - // dynamic properties - // slots - QObject* obj = getObject(); - if (obj) { - const QMetaObject* meta = obj->metaObject(); - - int i; - for (i=0; i < meta->propertyCount(); i++) { - QMetaProperty prop = meta->property(i); - if (prop.isScriptable()) { - array.add(Identifier(prop.name())); - } - } - - QList dynProps = obj->dynamicPropertyNames(); - foreach(QByteArray ba, dynProps) { - array.add(Identifier(ba.constData())); - } - - for (i=0; i < meta->methodCount(); i++) { - QMetaMethod method = meta->method(i); - if (method.access() != QMetaMethod::Private) { - array.add(Identifier(method.signature())); - } - } - } -} - -JSValue* QtInstance::invokeMethod(ExecState*, const MethodList&, const List&) -{ - // Implemented via fallbackMethod & QtRuntimeMetaMethod::callAsFunction - return jsUndefined(); -} - -bool QtInstance::implementsCall() const -{ - // See if we have qscript_call - if (m_defaultMethodIndex == -2) { - if (m_object) { - const QMetaObject* meta = m_object->metaObject(); - int count = meta->methodCount(); - const QByteArray defsig("qscript_call"); - for (int index = count - 1; index >= 0; --index) { - const QMetaMethod m = meta->method(index); - - QByteArray signature = m.signature(); - signature.truncate(signature.indexOf('(')); - - if (defsig == signature) { - m_defaultMethodIndex = index; - break; - } - } - } - - if (m_defaultMethodIndex == -2) // Not checked - m_defaultMethodIndex = -1; // No qscript_call - } - - // typeof object that implements call == function - return (m_defaultMethodIndex >= 0); -} - -JSValue* QtInstance::invokeDefaultMethod(ExecState* exec, const List& args) -{ - // QtScript tries to invoke a meta method qscript_call - if (!getObject()) - return throwError(exec, GeneralError, "cannot call function of deleted QObject"); - - // implementsCall will update our default method cache, if possible - if (implementsCall()) { - if (!m_defaultMethod) { - m_defaultMethod = new QtRuntimeMetaMethod(exec, Identifier("[[Call]]"),this, m_defaultMethodIndex, QByteArray("qscript_call"), true); - gcProtect(m_defaultMethod); - } - - return m_defaultMethod->callAsFunction(exec, 0, args); // Luckily QtRuntimeMetaMethod ignores the obj parameter - } else - return throwError(exec, TypeError, "not a function"); -} - -JSValue* QtInstance::defaultValue(JSType hint) const -{ - if (hint == StringType) - return stringValue(); - if (hint == NumberType) - return numberValue(); - if (hint == BooleanType) - return booleanValue(); - return valueOf(); -} - -JSValue* QtInstance::stringValue() const -{ - // Hmm.. see if there is a toString defined - QByteArray buf; - bool useDefault = true; - getClass(); - QObject* obj = getObject(); - if (m_class && obj) { - // Cheat and don't use the full name resolution - int index = obj->metaObject()->indexOfMethod("toString()"); - if (index >= 0) { - QMetaMethod m = obj->metaObject()->method(index); - // Check to see how much we can call it - if (m.access() != QMetaMethod::Private - && m.methodType() != QMetaMethod::Signal - && m.parameterTypes().count() == 0) { - const char* retsig = m.typeName(); - if (retsig && *retsig) { - QVariant ret(QMetaType::type(retsig), (void*)0); - void * qargs[1]; - qargs[0] = ret.data(); - - if (obj->qt_metacall(QMetaObject::InvokeMetaMethod, index, qargs) < 0) { - if (ret.isValid() && ret.canConvert(QVariant::String)) { - buf = ret.toString().toLatin1().constData(); // ### Latin 1? Ascii? - useDefault = false; - } - } - } - } - } - } - - if (useDefault) { - const QMetaObject* meta = obj ? obj->metaObject() : &QObject::staticMetaObject; - QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); - QString str = QString::fromUtf8("%0(name = \"%1\")") - .arg(QLatin1String(meta->className())).arg(name); - - buf = str.toLatin1(); - } - return jsString(buf.constData()); -} - -JSValue* QtInstance::numberValue() const -{ - return jsNumber(0); -} - -JSValue* QtInstance::booleanValue() const -{ - // ECMA 9.2 - return jsBoolean(true); -} - -JSValue* QtInstance::valueOf() const -{ - return stringValue(); -} - -// In qt_runtime.cpp -JSValue* convertQVariantToValue(ExecState* exec, PassRefPtr root, const QVariant& variant); -QVariant convertValueToQVariant(ExecState* exec, JSValue* value, QMetaType::Type hint, int *distance); - -const char* QtField::name() const -{ - if (m_type == MetaProperty) - return m_property.name(); - else if (m_type == ChildObject && m_childObject) - return m_childObject->objectName().toLatin1(); - else if (m_type == DynamicProperty) - return m_dynamicProperty.constData(); - return ""; // deleted child object -} - -JSValue* QtField::valueFromInstance(ExecState* exec, const Instance* inst) const -{ - const QtInstance* instance = static_cast(inst); - QObject* obj = instance->getObject(); - - if (obj) { - QVariant val; - if (m_type == MetaProperty) { - if (m_property.isReadable()) - val = m_property.read(obj); - else - return jsUndefined(); - } else if (m_type == ChildObject) - val = QVariant::fromValue((QObject*) m_childObject); - else if (m_type == DynamicProperty) - val = obj->property(m_dynamicProperty); - - return convertQVariantToValue(exec, inst->rootObject(), val); - } else { - QString msg = QString("cannot access member `%1' of deleted QObject").arg(name()); - return throwError(exec, GeneralError, msg.toLatin1().constData()); - } -} - -void QtField::setValueToInstance(ExecState* exec, const Instance* inst, JSValue* aValue) const -{ - if (m_type == ChildObject) // QtScript doesn't allow setting to a named child - return; - - const QtInstance* instance = static_cast(inst); - QObject* obj = instance->getObject(); - if (obj) { - QMetaType::Type argtype = QMetaType::Void; - if (m_type == MetaProperty) - argtype = (QMetaType::Type) QMetaType::type(m_property.typeName()); - - // dynamic properties just get any QVariant - QVariant val = convertValueToQVariant(exec, aValue, argtype, 0); - if (m_type == MetaProperty) { - if (m_property.isWritable()) - m_property.write(obj, val); - } else if (m_type == DynamicProperty) - obj->setProperty(m_dynamicProperty.constData(), val); - } else { - QString msg = QString("cannot access member `%1' of deleted QObject").arg(name()); - throwError(exec, GeneralError, msg.toLatin1().constData()); - } -} - - -} -}