18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "qt_instance.h"
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "Error.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMBinding.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObject.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSLock.h"
275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "ObjectPrototype.h"
285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "PropertyNameArray.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "qt_class.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "qt_runtime.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "runtime_object.h"
3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "runtime/FunctionPrototype.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qdebug.h>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qhash.h>
365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include <qmetaobject.h>
375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include <qmetatype.h>
382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <qwebelement.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace Bindings {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Cache QtInstances
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef QMultiHash<void*, QtInstance*> QObjectInstanceMap;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic QObjectInstanceMap cachedInstances;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Derived RuntimeObject
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass QtRuntimeObject : public RuntimeObject {
49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectpublic:
50e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    QtRuntimeObject(ExecState*, JSGlobalObject*, PassRefPtr<Instance>);
51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static const ClassInfo s_info;
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    virtual void markChildren(MarkStack& markStack)
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        RuntimeObject::markChildren(markStack);
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        QtInstance* instance = static_cast<QtInstance*>(getInternalInstance());
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (instance)
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            instance->markAggregate(markStack);
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    {
642bde8e466a4451c7319e3a072d118917957d6554Steve Block        return Structure::create(globalData, prototype, TypeInfo(ObjectType,  StructureFlags), AnonymousSlotCount, &s_info);
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockprotected:
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static const unsigned StructureFlags = RuntimeObject::StructureFlags | OverridesMarkChildren;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockconst ClassInfo QtRuntimeObject::s_info = { "QtRuntimeObject", &RuntimeObject::s_info, 0, 0 };
72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
73e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockQtRuntimeObject::QtRuntimeObject(ExecState* exec, JSGlobalObject* globalObject, PassRefPtr<Instance> instance)
74e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    : RuntimeObject(exec, globalObject, WebCore::deprecatedGetDOMStructure<QtRuntimeObject>(exec), instance)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// QtInstance
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianQtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : Instance(rootObject)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_class(0)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_object(o)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hashkey(o)
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_ownership(ownership)
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // This is a good place to register Qt metatypes that are in the QtWebKit module, as this is class will initialize if we have a QObject bridge.
872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    qRegisterMetaType<QWebElement>();
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectQtInstance::~QtInstance()
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedInstances.remove(m_hashkey);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // clean up (unprotect from gc) the JSValues we've created
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_methods.clear();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    qDeleteAll(m_fields);
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_fields.clear();
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_object) {
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        switch (m_ownership) {
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case QScriptEngine::QtOwnership:
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case QScriptEngine::AutoOwnership:
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_object->parent())
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // fall through!
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case QScriptEngine::ScriptOwnership:
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            delete m_object;
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianPassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    foreach (QtInstance* instance, cachedInstances.values(o))
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (instance->rootObject() == rootObject) {
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // The garbage collector removes instances, but it may happen that the wrapped
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // QObject dies before the gc kicks in. To handle that case we have to do an additional
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // check if to see if the instance's wrapped object is still alive. If it isn't, then
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // we have to create a new wrapper.
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!instance->getObject())
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                cachedInstances.remove(instance->hashKey());
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            else
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return instance;
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedInstances.insert(o, ret.get());
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ret.release();
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool QtInstance::getOwnPropertySlot(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return object->JSObject::getOwnPropertySlot(exec, propertyName, slot);
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid QtInstance::put(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    object->JSObject::put(exec, propertyName, value, slot);
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid QtInstance::removeCachedMethod(JSObject* method)
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_defaultMethod.get() == method)
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_defaultMethod.clear();
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (QHash<QByteArray, WriteBarrier<JSObject> >::Iterator it = m_methods.begin(), end = m_methods.end(); it != end; ++it) {
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (it.value().get() == method) {
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_methods.erase(it);
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectQtInstance* QtInstance::getInstance(JSObject* object)
163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!object)
165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return 0;
166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!object->inherits(&QtRuntimeObject::s_info))
167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return 0;
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return static_cast<QtInstance*>(static_cast<RuntimeObject*>(object)->getInternalInstance());
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectClass* QtInstance::getClass() const
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17321939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (!m_class) {
17421939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (!m_object)
17521939df44de1705786c545cd1bf519d47250322dBen Murdoch            return 0;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_class = QtClass::classForObject(m_object);
17721939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_class;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockRuntimeObject* QtInstance::newRuntimeObject(ExecState* exec)
182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
184f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_methods.clear();
185e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return new (exec) QtRuntimeObject(exec, exec->lexicalGlobalObject(), this);
186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid QtInstance::markAggregate(MarkStack& markStack)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_defaultMethod)
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        markStack.append(&m_defaultMethod);
1922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (QHash<QByteArray, WriteBarrier<JSObject> >::Iterator it = m_methods.begin(), end = m_methods.end(); it != end; ++it)
1932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        markStack.append(&it.value());
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::begin()
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Do nothing.
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::end()
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Do nothing.
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::getPropertyNames(ExecState* exec, PropertyNameArray& array)
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This is the enumerable properties, so put:
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // properties
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // dynamic properties
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // slots
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QObject* obj = getObject();
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (obj) {
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const QMetaObject* meta = obj->metaObject();
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int i;
2175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        for (i = 0; i < meta->propertyCount(); i++) {
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            QMetaProperty prop = meta->property(i);
2195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            if (prop.isScriptable())
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                array.add(Identifier(exec, prop.name()));
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef QT_NO_PROPERTIES
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QList<QByteArray> dynProps = obj->dynamicPropertyNames();
2255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        foreach (const QByteArray& ba, dynProps)
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            array.add(Identifier(exec, ba.constData()));
227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        const int methodCount = meta->methodCount();
2306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        for (i = 0; i < methodCount; i++) {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            QMetaMethod method = meta->method(i);
2325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            if (method.access() != QMetaMethod::Private)
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                array.add(Identifier(exec, method.signature()));
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue QtInstance::getMethod(ExecState* exec, const Identifier& propertyName)
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!getClass())
241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return jsNull();
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    MethodList methodList = m_class->methodsNamed(propertyName, this);
24381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return new (exec) RuntimeMethod(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName, methodList);
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2465af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue QtInstance::invokeMethod(ExecState*, RuntimeMethod*)
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Implemented via fallbackMethod & QtRuntimeMetaMethod::callAsFunction
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsUndefined();
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2525f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hint == PreferString)
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return stringValue(exec);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hint == PreferNumber)
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return numberValue(exec);
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return valueOf(exec);
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2615f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::stringValue(ExecState* exec) const
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QObject* obj = getObject();
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!obj)
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return jsNull();
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Hmm.. see if there is a toString defined
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QByteArray buf;
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool useDefault = true;
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    getClass();
271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_class) {
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Cheat and don't use the full name resolution
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int index = obj->metaObject()->indexOfMethod("toString()");
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (index >= 0) {
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            QMetaMethod m = obj->metaObject()->method(index);
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Check to see how much we can call it
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m.access() != QMetaMethod::Private
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                && m.methodType() != QMetaMethod::Signal
2795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                && m.parameterTypes().isEmpty()) {
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                const char* retsig = m.typeName();
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (retsig && *retsig) {
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    QVariant ret(QMetaType::type(retsig), (void*)0);
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    void * qargs[1];
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    qargs[0] = ret.data();
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                    if (QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, qargs) < 0) {
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (ret.isValid() && ret.canConvert(QVariant::String)) {
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            buf = ret.toString().toLatin1().constData(); // ### Latin 1? Ascii?
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            useDefault = false;
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (useDefault) {
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const QMetaObject* meta = obj ? obj->metaObject() : &QObject::staticMetaObject;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed");
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QString str = QString::fromUtf8("%0(name = \"%1\")")
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                      .arg(QLatin1String(meta->className())).arg(name);
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        buf = str.toLatin1();
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsString(exec, buf.constData());
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue QtInstance::numberValue(ExecState*) const
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
310e14391e94c850b8bd03680c23b38978db68687a8John Reck    return jsNumber(0);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3135f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::booleanValue() const
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // ECMA 9.2
316dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return jsBoolean(getObject());
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3195f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::valueOf(ExecState* exec) const
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return stringValue(exec);
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// In qt_runtime.cpp
3255f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue convertQVariantToValue(ExecState*, PassRefPtr<RootObject> root, const QVariant& variant);
3265f1ab04193ad0130ca8204aadaceae083aca9881Feng QianQVariant convertValueToQVariant(ExecState*, JSValue, QMetaType::Type hint, int *distance);
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenQByteArray QtField::name() const
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_type == MetaProperty)
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_property.name();
3325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (m_type == ChildObject && m_childObject)
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_childObject->objectName().toLatin1();
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef QT_NO_PROPERTIES
3355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (m_type == DynamicProperty)
3366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return m_dynamicProperty;
337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
3386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return QByteArray(); // deleted child object
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3415f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtField::valueFromInstance(ExecState* exec, const Instance* inst) const
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const QtInstance* instance = static_cast<const QtInstance*>(inst);
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QObject* obj = instance->getObject();
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (obj) {
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QVariant val;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_type == MetaProperty) {
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_property.isReadable())
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                val = m_property.read(obj);
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return jsUndefined();
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (m_type == ChildObject)
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            val = QVariant::fromValue((QObject*) m_childObject);
355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef QT_NO_PROPERTIES
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (m_type == DynamicProperty)
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            val = obj->property(m_dynamicProperty);
358dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
3590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return convertQVariantToValue(exec, inst->rootObject(), val);
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name()));
362545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createError(exec, msg.toLatin1().constData()));
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid QtField::setValueToInstance(ExecState* exec, const Instance* inst, JSValue aValue) const
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_type == ChildObject) // QtScript doesn't allow setting to a named child
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const QtInstance* instance = static_cast<const QtInstance*>(inst);
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QObject* obj = instance->getObject();
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (obj) {
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QMetaType::Type argtype = QMetaType::Void;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_type == MetaProperty)
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            argtype = (QMetaType::Type) QMetaType::type(m_property.typeName());
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // dynamic properties just get any QVariant
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QVariant val = convertValueToQVariant(exec, aValue, argtype, 0);
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_type == MetaProperty) {
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_property.isWritable())
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_property.write(obj, val);
382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef QT_NO_PROPERTIES
384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (m_type == DynamicProperty)
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            obj->setProperty(m_dynamicProperty.constData(), val);
386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name()));
389545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        throwError(exec, createError(exec, msg.toLatin1().constData()));
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
396