1 /* 2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 */ 19 20 #ifndef BINDINGS_QT_RUNTIME_H_ 21 #define BINDINGS_QT_RUNTIME_H_ 22 23 #include "Bridge.h" 24 #include "Completion.h" 25 #include "Protect.h" 26 #include "runtime_method.h" 27 28 #include <qbytearray.h> 29 #include <qmetaobject.h> 30 #include <qpointer.h> 31 #include <qvariant.h> 32 33 namespace JSC { 34 namespace Bindings { 35 36 class QtInstance; 37 38 class QtField : public Field { 39 public: 40 41 typedef enum { 42 MetaProperty, 43 DynamicProperty, 44 ChildObject 45 } QtFieldType; 46 47 QtField(const QMetaProperty &p) 48 : m_type(MetaProperty), m_property(p) 49 {} 50 51 QtField(const QByteArray &b) 52 : m_type(DynamicProperty), m_dynamicProperty(b) 53 {} 54 55 QtField(QObject *child) 56 : m_type(ChildObject), m_childObject(child) 57 {} 58 59 virtual JSValue valueFromInstance(ExecState*, const Instance*) const; 60 virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const; 61 virtual const char* name() const; 62 QtFieldType fieldType() const {return m_type;} 63 private: 64 QtFieldType m_type; 65 QByteArray m_dynamicProperty; 66 QMetaProperty m_property; 67 QPointer<QObject> m_childObject; 68 }; 69 70 71 class QtMethod : public Method 72 { 73 public: 74 QtMethod(const QMetaObject *mo, int i, const QByteArray &ident, int numParameters) 75 : m_metaObject(mo), 76 m_index(i), 77 m_identifier(ident), 78 m_nParams(numParameters) 79 { } 80 81 virtual const char* name() const { return m_identifier.constData(); } 82 virtual int numParameters() const { return m_nParams; } 83 84 private: 85 friend class QtInstance; 86 const QMetaObject *m_metaObject; 87 int m_index; 88 QByteArray m_identifier; 89 int m_nParams; 90 }; 91 92 93 template <typename T> class QtArray : public Array 94 { 95 public: 96 QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>); 97 virtual ~QtArray(); 98 99 RootObject* rootObject() const; 100 101 virtual void setValueAt(ExecState*, unsigned index, JSValue) const; 102 virtual JSValue valueAt(ExecState*, unsigned index) const; 103 virtual unsigned int getLength() const {return m_length;} 104 105 private: 106 mutable QList<T> m_list; // setValueAt is const! 107 unsigned int m_length; 108 QMetaType::Type m_type; 109 }; 110 111 // Based on RuntimeMethod 112 113 // Extra data classes (to avoid the CELL_SIZE limit on JS objects) 114 115 class QtRuntimeMethodData { 116 public: 117 virtual ~QtRuntimeMethodData(); 118 RefPtr<QtInstance> m_instance; 119 }; 120 121 class QtRuntimeConnectionMethod; 122 class QtRuntimeMetaMethodData : public QtRuntimeMethodData { 123 public: 124 ~QtRuntimeMetaMethodData(); 125 QByteArray m_signature; 126 bool m_allowPrivate; 127 int m_index; 128 QtRuntimeConnectionMethod *m_connect; 129 QtRuntimeConnectionMethod *m_disconnect; 130 }; 131 132 class QtRuntimeConnectionMethodData : public QtRuntimeMethodData { 133 public: 134 ~QtRuntimeConnectionMethodData(); 135 QByteArray m_signature; 136 int m_index; 137 bool m_isConnect; 138 }; 139 140 // Common base class (doesn't really do anything interesting) 141 class QtRuntimeMethod : public InternalFunction { 142 public: 143 virtual ~QtRuntimeMethod(); 144 145 static const ClassInfo s_info; 146 147 static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject) 148 { 149 return globalObject->functionPrototype(); 150 } 151 152 static PassRefPtr<Structure> createStructure(JSValue prototype) 153 { 154 return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 155 } 156 157 protected: 158 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesMarkChildren; 159 160 QtRuntimeMethodData *d_func() const {return d_ptr;} 161 QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst); 162 QtRuntimeMethodData *d_ptr; 163 }; 164 165 class QtRuntimeMetaMethod : public QtRuntimeMethod 166 { 167 public: 168 QtRuntimeMetaMethod(ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate); 169 170 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 171 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 172 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); 173 174 virtual void markChildren(MarkStack& markStack); 175 176 protected: 177 QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);} 178 179 private: 180 virtual CallType getCallData(CallData&); 181 static JSValue JSC_HOST_CALL call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args); 182 static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&); 183 static JSValue connectGetter(ExecState*, const Identifier&, const PropertySlot&); 184 static JSValue disconnectGetter(ExecState*, const Identifier&, const PropertySlot&); 185 }; 186 187 class QtConnectionObject; 188 class QtRuntimeConnectionMethod : public QtRuntimeMethod 189 { 190 public: 191 QtRuntimeConnectionMethod(ExecState *exec, const Identifier &n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature ); 192 193 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 194 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 195 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); 196 197 protected: 198 QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);} 199 200 private: 201 virtual CallType getCallData(CallData&); 202 static JSValue JSC_HOST_CALL call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args); 203 static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&); 204 static QMultiMap<QObject *, QtConnectionObject *> connections; 205 friend class QtConnectionObject; 206 }; 207 208 class QtConnectionObject: public QObject 209 { 210 public: 211 QtConnectionObject(PassRefPtr<QtInstance> instance, int signalIndex, JSObject* thisObject, JSObject* funcObject); 212 ~QtConnectionObject(); 213 214 static const QMetaObject staticMetaObject; 215 virtual const QMetaObject *metaObject() const; 216 virtual void *qt_metacast(const char *); 217 virtual int qt_metacall(QMetaObject::Call, int, void **argv); 218 219 bool match(QObject *sender, int signalIndex, JSObject* thisObject, JSObject *funcObject); 220 221 // actual slot: 222 void execute(void **argv); 223 224 private: 225 RefPtr<QtInstance> m_instance; 226 int m_signalIndex; 227 QObject* m_originalObject; // only used as a key, not dereferenced 228 ProtectedPtr<JSObject> m_thisObject; 229 ProtectedPtr<JSObject> m_funcObject; 230 }; 231 232 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance); 233 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant); 234 235 } // namespace Bindings 236 } // namespace JSC 237 238 #endif 239