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