2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
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.
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.
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
20 #ifndef BINDINGS_QT_RUNTIME_H_
21 #define BINDINGS_QT_RUNTIME_H_
23 #include "BridgeJSC.h"
24 #include "JSDOMBinding.h"
25 #include "JavaScript.h"
27 #include "qt_instance.h"
28 #include "runtime_method.h"
30 #include <QWeakPointer>
32 #include <qbytearray.h>
33 #include <qmetaobject.h>
39 class QtField : public Field {
44 #ifndef QT_NO_PROPERTIES
50 QtField(const QMetaProperty &p)
51 : m_type(MetaProperty), m_property(p)
54 #ifndef QT_NO_PROPERTIES
55 QtField(const QByteArray &b)
56 : m_type(DynamicProperty), m_dynamicProperty(b)
60 QtField(QObject *child)
61 : m_type(ChildObject), m_childObject(child)
64 virtual JSValue valueFromInstance(ExecState*, const Instance*) const;
65 virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const;
66 QByteArray name() const;
67 QtFieldType fieldType() const {return m_type;}
70 QByteArray m_dynamicProperty;
71 QMetaProperty m_property;
72 QWeakPointer<QObject> m_childObject;
76 template <typename T> class QtArray : public Array
79 QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>);
82 RootObject* rootObject() const;
84 virtual void setValueAt(ExecState*, unsigned index, JSValue) const;
85 virtual JSValue valueAt(ExecState*, unsigned index) const;
86 virtual unsigned int getLength() const {return m_length;}
89 mutable QList<T> m_list; // setValueAt is const!
90 unsigned int m_length;
91 QMetaType::Type m_type;
94 // Based on RuntimeMethod
96 // Extra data classes (to avoid the CELL_SIZE limit on JS objects)
97 class QtRuntimeMethod;
98 class QtRuntimeMethodData : public WeakHandleOwner {
100 virtual ~QtRuntimeMethodData();
101 RefPtr<QtInstance> m_instance;
102 Weak<QtRuntimeMethod> m_finalizer;
105 void finalize(Handle<Unknown>, void*);
108 class QtRuntimeConnectionMethod;
109 class QtRuntimeMetaMethodData : public QtRuntimeMethodData {
111 ~QtRuntimeMetaMethodData();
112 QByteArray m_signature;
115 WriteBarrier<QtRuntimeConnectionMethod> m_connect;
116 WriteBarrier<QtRuntimeConnectionMethod> m_disconnect;
119 class QtRuntimeConnectionMethodData : public QtRuntimeMethodData {
121 ~QtRuntimeConnectionMethodData();
122 QByteArray m_signature;
127 // Common base class (doesn't really do anything interesting)
128 class QtRuntimeMethod : public InternalFunction {
130 typedef InternalFunction Base;
132 virtual ~QtRuntimeMethod();
134 static const ClassInfo s_info;
136 static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject)
138 return globalObject->functionPrototype();
141 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
143 return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
147 void finishCreation(ExecState*, const Identifier&, PassRefPtr<QtInstance>);
148 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesVisitChildren;
150 QtRuntimeMethodData *d_func() const {return d_ptr;}
151 QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *, Structure*, const Identifier &name);
152 QtRuntimeMethodData *d_ptr;
155 class QtRuntimeMetaMethod : public QtRuntimeMethod {
157 typedef QtRuntimeMethod Base;
159 static QtRuntimeMetaMethod* create(ExecState* exec, const Identifier& n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate)
161 Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
162 QtRuntimeMetaMethod* method = new (allocateCell<QtRuntimeMetaMethod>(*exec->heap())) QtRuntimeMetaMethod(exec, domStructure, n, inst, index, signature, allowPrivate);
166 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
167 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
168 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
170 virtual void visitChildren(SlotVisitor&);
173 QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}
176 QtRuntimeMetaMethod(ExecState*, Structure*, const Identifier&, PassRefPtr<QtInstance>, int index, const QByteArray&, bool allowPrivate);
177 void finishCreation(ExecState*, const Identifier&, PassRefPtr<QtInstance>, int index, const QByteArray& signature, bool allowPrivate);
179 virtual CallType getCallData(CallData&);
180 static EncodedJSValue JSC_HOST_CALL call(ExecState* exec);
181 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
182 static JSValue connectGetter(ExecState*, JSValue, const Identifier&);
183 static JSValue disconnectGetter(ExecState*, JSValue, const Identifier&);
186 class QtConnectionObject;
187 class QtRuntimeConnectionMethod : public QtRuntimeMethod {
189 typedef QtRuntimeMethod Base;
191 static QtRuntimeConnectionMethod* create(ExecState* exec, const Identifier& n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature)
193 Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
194 return new (allocateCell<QtRuntimeConnectionMethod>(*exec->heap())) QtRuntimeConnectionMethod(exec, domStructure, n, isConnect, inst, index, signature);
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);
202 QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
205 QtRuntimeConnectionMethod(ExecState*, Structure*, const Identifier&, bool isConnect, PassRefPtr<QtInstance>, int index, const QByteArray&);
206 void finishCreation(ExecState*, const Identifier&, bool isConnect, PassRefPtr<QtInstance>, int index, const QByteArray& signature);
208 virtual CallType getCallData(CallData&);
209 static EncodedJSValue JSC_HOST_CALL call(ExecState* exec);
210 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
211 static QMultiMap<QObject *, QtConnectionObject *> connections;
212 friend class QtConnectionObject;
215 // A QtConnectionObject represents a connection created inside JS. It will connect its own execute() slot
216 // with the appropriate signal of 'sender'. When execute() is called, it will call JS 'receiverFunction'.
217 class QtConnectionObject : public QObject
220 QtConnectionObject(JSContextRef, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObjectRef receiver, JSObjectRef receiverFunction);
221 ~QtConnectionObject();
223 // Explicitly define these because want a custom qt_metacall(), so we can't use Q_OBJECT macro.
224 static const QMetaObject staticMetaObject;
225 virtual const QMetaObject *metaObject() const;
226 virtual void *qt_metacast(const char *);
227 virtual int qt_metacall(QMetaObject::Call, int, void **argv);
229 void execute(void **argv);
231 bool match(JSContextRef, QObject* sender, int signalIndex, JSObjectRef thisObject, JSObjectRef funcObject);
233 // Note: for callers using JSC internals, remove once we don't need anymore.
234 static QtConnectionObject* createWithInternalJSC(ExecState*, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObject* receiver, JSObject* receiverFunction);
237 JSContextRef m_context;
238 RefPtr<QtInstance> m_senderInstance;
240 // We use this as key in active connections multimap.
241 QObject* m_originalSender;
244 JSObjectRef m_receiver;
245 JSObjectRef m_receiverFunction;
248 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
249 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
251 } // namespace Bindings