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 "BridgeJSC.h" 24 #include "Completion.h" 25 #include "Strong.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 #ifndef QT_NO_PROPERTIES 44 DynamicProperty, 45 #endif 46 ChildObject 47 } QtFieldType; 48 QtField(const QMetaProperty & p)49 QtField(const QMetaProperty &p) 50 : m_type(MetaProperty), m_property(p) 51 {} 52 53 #ifndef QT_NO_PROPERTIES QtField(const QByteArray & b)54 QtField(const QByteArray &b) 55 : m_type(DynamicProperty), m_dynamicProperty(b) 56 {} 57 #endif 58 QtField(QObject * child)59 QtField(QObject *child) 60 : m_type(ChildObject), m_childObject(child) 61 {} 62 63 virtual JSValue valueFromInstance(ExecState*, const Instance*) const; 64 virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const; 65 QByteArray name() const; fieldType()66 QtFieldType fieldType() const {return m_type;} 67 private: 68 QtFieldType m_type; 69 QByteArray m_dynamicProperty; 70 QMetaProperty m_property; 71 QPointer<QObject> m_childObject; 72 }; 73 74 75 class QtMethod : public Method 76 { 77 public: QtMethod(const QMetaObject * mo,int i,const QByteArray & ident,int numParameters)78 QtMethod(const QMetaObject *mo, int i, const QByteArray &ident, int numParameters) 79 : m_metaObject(mo), 80 m_index(i), 81 m_identifier(ident), 82 m_nParams(numParameters) 83 { } 84 name()85 virtual const char* name() const { return m_identifier.constData(); } numParameters()86 virtual int numParameters() const { return m_nParams; } 87 88 private: 89 friend class QtInstance; 90 const QMetaObject *m_metaObject; 91 int m_index; 92 QByteArray m_identifier; 93 int m_nParams; 94 }; 95 96 97 template <typename T> class QtArray : public Array 98 { 99 public: 100 QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>); 101 virtual ~QtArray(); 102 103 RootObject* rootObject() const; 104 105 virtual void setValueAt(ExecState*, unsigned index, JSValue) const; 106 virtual JSValue valueAt(ExecState*, unsigned index) const; getLength()107 virtual unsigned int getLength() const {return m_length;} 108 109 private: 110 mutable QList<T> m_list; // setValueAt is const! 111 unsigned int m_length; 112 QMetaType::Type m_type; 113 }; 114 115 // Based on RuntimeMethod 116 117 // Extra data classes (to avoid the CELL_SIZE limit on JS objects) 118 119 class QtRuntimeMethodData { 120 public: 121 virtual ~QtRuntimeMethodData(); 122 RefPtr<QtInstance> m_instance; 123 }; 124 125 class QtRuntimeConnectionMethod; 126 class QtRuntimeMetaMethodData : public QtRuntimeMethodData { 127 public: 128 ~QtRuntimeMetaMethodData(); 129 QByteArray m_signature; 130 bool m_allowPrivate; 131 int m_index; 132 WriteBarrier<QtRuntimeConnectionMethod> m_connect; 133 WriteBarrier<QtRuntimeConnectionMethod> m_disconnect; 134 }; 135 136 class QtRuntimeConnectionMethodData : public QtRuntimeMethodData { 137 public: 138 ~QtRuntimeConnectionMethodData(); 139 QByteArray m_signature; 140 int m_index; 141 bool m_isConnect; 142 }; 143 144 // Common base class (doesn't really do anything interesting) 145 class QtRuntimeMethod : public InternalFunction { 146 public: 147 virtual ~QtRuntimeMethod(); 148 149 static const ClassInfo s_info; 150 createPrototype(ExecState *,JSGlobalObject * globalObject)151 static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject) 152 { 153 return globalObject->functionPrototype(); 154 } 155 createStructure(JSGlobalData & globalData,JSValue prototype)156 static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) 157 { 158 return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); 159 } 160 161 protected: 162 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesMarkChildren; 163 d_func()164 QtRuntimeMethodData *d_func() const {return d_ptr;} 165 QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst); 166 QtRuntimeMethodData *d_ptr; 167 }; 168 169 class QtRuntimeMetaMethod : public QtRuntimeMethod 170 { 171 public: 172 QtRuntimeMetaMethod(ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate); 173 174 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 175 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 176 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); 177 178 virtual void markChildren(MarkStack& markStack); 179 180 protected: d_func()181 QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);} 182 183 private: 184 virtual CallType getCallData(CallData&); 185 static EncodedJSValue JSC_HOST_CALL call(ExecState* exec); 186 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&); 187 static JSValue connectGetter(ExecState*, JSValue, const Identifier&); 188 static JSValue disconnectGetter(ExecState*, JSValue, const Identifier&); 189 }; 190 191 class QtConnectionObject; 192 class QtRuntimeConnectionMethod : public QtRuntimeMethod 193 { 194 public: 195 QtRuntimeConnectionMethod(ExecState *exec, const Identifier &n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature ); 196 197 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 198 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 199 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); 200 201 protected: d_func()202 QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);} 203 204 private: 205 virtual CallType getCallData(CallData&); 206 static EncodedJSValue JSC_HOST_CALL call(ExecState* exec); 207 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&); 208 static QMultiMap<QObject *, QtConnectionObject *> connections; 209 friend class QtConnectionObject; 210 }; 211 212 class QtConnectionObject: public QObject 213 { 214 public: 215 QtConnectionObject(JSGlobalData&, PassRefPtr<QtInstance> instance, int signalIndex, JSObject* thisObject, JSObject* funcObject); 216 ~QtConnectionObject(); 217 218 static const QMetaObject staticMetaObject; 219 virtual const QMetaObject *metaObject() const; 220 virtual void *qt_metacast(const char *); 221 virtual int qt_metacall(QMetaObject::Call, int, void **argv); 222 223 bool match(QObject *sender, int signalIndex, JSObject* thisObject, JSObject *funcObject); 224 225 // actual slot: 226 void execute(void **argv); 227 228 private: 229 RefPtr<QtInstance> m_instance; 230 int m_signalIndex; 231 QObject* m_originalObject; // only used as a key, not dereferenced 232 Strong<JSObject> m_thisObject; 233 Strong<JSObject> m_funcObject; 234 }; 235 236 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance); 237 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant); 238 239 } // namespace Bindings 240 } // namespace JSC 241 242 #endif 243