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 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ArgList.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" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "qt_class.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "qt_runtime.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PropertyNameArray.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "runtime_object.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ObjectPrototype.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Error.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qmetaobject.h> 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qdebug.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qmetatype.h> 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qhash.h> 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace Bindings { 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Cache QtInstances 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef QMultiHash<void*, QtInstance*> QObjectInstanceMap; 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic QObjectInstanceMap cachedInstances; 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Derived RuntimeObject 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass QtRuntimeObjectImp : public RuntimeObjectImp { 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectpublic: 49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project QtRuntimeObjectImp(ExecState*, PassRefPtr<Instance>); 50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static const ClassInfo s_info; 52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual void markChildren(MarkStack& markStack) 54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RuntimeObjectImp::markChildren(markStack); 56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project QtInstance* instance = static_cast<QtInstance*>(getInternalInstance()); 57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (instance) 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block instance->markAggregate(markStack); 59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static PassRefPtr<Structure> createStructure(JSValue prototype) 62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block { 63d0825bca7fe65beaee391d30da42e937db621564Steve Block return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 66643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockprotected: 67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static const unsigned StructureFlags = RuntimeObjectImp::StructureFlags | OverridesMarkChildren; 68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectprivate: 70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project virtual const ClassInfo* classInfo() const { return &s_info; } 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst ClassInfo QtRuntimeObjectImp::s_info = { "QtRuntimeObject", &RuntimeObjectImp::s_info, 0, 0 }; 74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectQtRuntimeObjectImp::QtRuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> instance) 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : RuntimeObjectImp(exec, WebCore::deprecatedGetDOMStructure<QtRuntimeObjectImp>(exec), instance) 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// QtInstance 818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianQtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership) 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : Instance(rootObject) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_class(0) 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_object(o) 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_hashkey(o) 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_defaultMethod(0) 878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_ownership(ownership) 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectQtInstance::~QtInstance() 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSLock lock(SilenceAssertionsOnly); 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cachedInstances.remove(m_hashkey); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // clean up (unprotect from gc) the JSValues we've created 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_methods.clear(); 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch qDeleteAll(m_fields); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fields.clear(); 1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_object) { 1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian switch (m_ownership) { 1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case QScriptEngine::QtOwnership: 1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case QScriptEngine::AutoOwnership: 1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_object->parent()) 1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // fall through! 1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case QScriptEngine::ScriptOwnership: 1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian delete m_object; 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianPassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership) 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSLock lock(SilenceAssertionsOnly); 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block foreach(QtInstance* instance, cachedInstances.values(o)) 123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (instance->rootObject() == rootObject) { 124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // The garbage collector removes instances, but it may happen that the wrapped 125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // QObject dies before the gc kicks in. To handle that case we have to do an additional 126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // check if to see if the instance's wrapped object is still alive. If it isn't, then 127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // we have to create a new wrapper. 128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!instance->getObject()) 129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cachedInstances.remove(instance->hashKey()); 130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return instance; 132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cachedInstances.insert(o, ret.get()); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ret.release(); 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool QtInstance::getOwnPropertySlot(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return object->JSObject::getOwnPropertySlot(exec, propertyName, slot); 143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid QtInstance::put(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project object->JSObject::put(exec, propertyName, value, slot); 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid QtInstance::removeCachedMethod(JSObject* method) 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (m_defaultMethod == method) 1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_defaultMethod = 0; 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for(QHash<QByteArray, JSObject*>::Iterator it = m_methods.begin(), 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch end = m_methods.end(); it != end; ++it) 1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (it.value() == method) { 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_methods.erase(it); 1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectQtInstance* QtInstance::getInstance(JSObject* object) 164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!object) 166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!object->inherits(&QtRuntimeObjectImp::s_info)) 168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return static_cast<QtInstance*>(static_cast<RuntimeObjectImp*>(object)->getInternalInstance()); 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectClass* QtInstance::getClass() const 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_class) 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_class = QtClass::classForObject(m_object); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_class; 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRuntimeObjectImp* QtInstance::newRuntimeObject(ExecState* exec) 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSLock lock(SilenceAssertionsOnly); 182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return new (exec) QtRuntimeObjectImp(exec, this); 183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid QtInstance::markAggregate(MarkStack& markStack) 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_defaultMethod) 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markStack.append(m_defaultMethod); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foreach(JSObject* val, m_methods.values()) { 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (val) 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markStack.append(val); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::begin() 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do nothing. 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::end() 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do nothing. 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid QtInstance::getPropertyNames(ExecState* exec, PropertyNameArray& array) 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This is the enumerable properties, so put: 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // properties 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // dynamic properties 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // slots 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QObject* obj = getObject(); 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (obj) { 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QMetaObject* meta = obj->metaObject(); 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int i; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (i=0; i < meta->propertyCount(); i++) { 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMetaProperty prop = meta->property(i); 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prop.isScriptable()) { 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project array.add(Identifier(exec, prop.name())); 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QList<QByteArray> dynProps = obj->dynamicPropertyNames(); 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foreach(QByteArray ba, dynProps) { 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project array.add(Identifier(exec, ba.constData())); 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (i=0; i < meta->methodCount(); i++) { 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMetaMethod method = meta->method(i); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (method.access() != QMetaMethod::Private) { 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project array.add(Identifier(exec, method.signature())); 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2375f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::invokeMethod(ExecState*, const MethodList&, const ArgList&) 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Implemented via fallbackMethod & QtRuntimeMetaMethod::callAsFunction 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2445f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hint == PreferString) 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return stringValue(exec); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hint == PreferNumber) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return numberValue(exec); 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return valueOf(exec); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2535f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::stringValue(ExecState* exec) const 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hmm.. see if there is a toString defined 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QByteArray buf; 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool useDefault = true; 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getClass(); 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QObject* obj = getObject(); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_class && obj) { 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cheat and don't use the full name resolution 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int index = obj->metaObject()->indexOfMethod("toString()"); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (index >= 0) { 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMetaMethod m = obj->metaObject()->method(index); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check to see how much we can call it 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m.access() != QMetaMethod::Private 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && m.methodType() != QMetaMethod::Signal 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && m.parameterTypes().count() == 0) { 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* retsig = m.typeName(); 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (retsig && *retsig) { 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QVariant ret(QMetaType::type(retsig), (void*)0); 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project void * qargs[1]; 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project qargs[0] = ret.data(); 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (obj->qt_metacall(QMetaObject::InvokeMetaMethod, index, qargs) < 0) { 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ret.isValid() && ret.canConvert(QVariant::String)) { 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project buf = ret.toString().toLatin1().constData(); // ### Latin 1? Ascii? 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project useDefault = false; 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (useDefault) { 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QMetaObject* meta = obj ? obj->metaObject() : &QObject::staticMetaObject; 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QString str = QString::fromUtf8("%0(name = \"%1\")") 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project .arg(QLatin1String(meta->className())).arg(name); 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project buf = str.toLatin1(); 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsString(exec, buf.constData()); 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2975f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::numberValue(ExecState* exec) const 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNumber(exec, 0); 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3025f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::booleanValue() const 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ECMA 9.2 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsBoolean(true); 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3085f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtInstance::valueOf(ExecState* exec) const 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return stringValue(exec); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// In qt_runtime.cpp 3145f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue convertQVariantToValue(ExecState*, PassRefPtr<RootObject> root, const QVariant& variant); 3155f1ab04193ad0130ca8204aadaceae083aca9881Feng QianQVariant convertValueToQVariant(ExecState*, JSValue, QMetaType::Type hint, int *distance); 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* QtField::name() const 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_type == MetaProperty) 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_property.name(); 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (m_type == ChildObject && m_childObject) 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_childObject->objectName().toLatin1(); 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (m_type == DynamicProperty) 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_dynamicProperty.constData(); 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ""; // deleted child object 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3285f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue QtField::valueFromInstance(ExecState* exec, const Instance* inst) const 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QtInstance* instance = static_cast<const QtInstance*>(inst); 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QObject* obj = instance->getObject(); 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (obj) { 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QVariant val; 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_type == MetaProperty) { 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_property.isReadable()) 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project val = m_property.read(obj); 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (m_type == ChildObject) 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project val = QVariant::fromValue((QObject*) m_childObject); 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (m_type == DynamicProperty) 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project val = obj->property(m_dynamicProperty); 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return convertQVariantToValue(exec, inst->rootObject(), val); 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name())); 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return throwError(exec, GeneralError, msg.toLatin1().constData()); 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid QtField::setValueToInstance(ExecState* exec, const Instance* inst, JSValue aValue) const 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_type == ChildObject) // QtScript doesn't allow setting to a named child 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QtInstance* instance = static_cast<const QtInstance*>(inst); 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QObject* obj = instance->getObject(); 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (obj) { 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMetaType::Type argtype = QMetaType::Void; 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_type == MetaProperty) 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project argtype = (QMetaType::Type) QMetaType::type(m_property.typeName()); 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // dynamic properties just get any QVariant 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QVariant val = convertValueToQVariant(exec, aValue, argtype, 0); 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_type == MetaProperty) { 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_property.isWritable()) 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_property.write(obj, val); 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (m_type == DynamicProperty) 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project obj->setProperty(m_dynamicProperty.constData(), val); 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name())); 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project throwError(exec, GeneralError, msg.toLatin1().constData()); 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 380