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), AnonymousSlotCount, &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, PassRefPtr<QtInstance>);
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 return new (allocateCell<QtRuntimeMetaMethod>(*exec->heap())) QtRuntimeMetaMethod(exec, domStructure, n, inst, index, signature, allowPrivate);
165 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
166 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
167 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
169 virtual void visitChildren(SlotVisitor&);
172 QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}
175 QtRuntimeMetaMethod(ExecState*, Structure*, const Identifier&, PassRefPtr<QtInstance>, int index, const QByteArray&, bool allowPrivate);
177 virtual CallType getCallData(CallData&);
178 static EncodedJSValue JSC_HOST_CALL call(ExecState* exec);
179 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
180 static JSValue connectGetter(ExecState*, JSValue, const Identifier&);
181 static JSValue disconnectGetter(ExecState*, JSValue, const Identifier&);
184 class QtConnectionObject;
185 class QtRuntimeConnectionMethod : public QtRuntimeMethod {
187 typedef QtRuntimeMethod Base;
189 static QtRuntimeConnectionMethod* create(ExecState* exec, const Identifier& n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature)
191 Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
192 return new (allocateCell<QtRuntimeConnectionMethod>(*exec->heap())) QtRuntimeConnectionMethod(exec, domStructure, n, isConnect, inst, index, signature);
195 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
196 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
197 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
200 QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
203 QtRuntimeConnectionMethod(ExecState*, Structure*, const Identifier&, bool isConnect, PassRefPtr<QtInstance>, int index, const QByteArray&);
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;
212 // A QtConnectionObject represents a connection created inside JS. It will connect its own execute() slot
213 // with the appropriate signal of 'sender'. When execute() is called, it will call JS 'receiverFunction'.
214 class QtConnectionObject : public QObject
217 QtConnectionObject(JSContextRef, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObjectRef receiver, JSObjectRef receiverFunction);
218 ~QtConnectionObject();
220 // Explicitly define these because want a custom qt_metacall(), so we can't use Q_OBJECT macro.
221 static const QMetaObject staticMetaObject;
222 virtual const QMetaObject *metaObject() const;
223 virtual void *qt_metacast(const char *);
224 virtual int qt_metacall(QMetaObject::Call, int, void **argv);
226 void execute(void **argv);
228 bool match(JSContextRef, QObject* sender, int signalIndex, JSObjectRef thisObject, JSObjectRef funcObject);
230 // Note: for callers using JSC internals, remove once we don't need anymore.
231 static QtConnectionObject* createWithInternalJSC(ExecState*, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObject* receiver, JSObject* receiverFunction);
234 JSContextRef m_context;
235 RefPtr<QtInstance> m_senderInstance;
237 // We use this as key in active connections multimap.
238 QObject* m_originalSender;
241 JSObjectRef m_receiver;
242 JSObjectRef m_receiverFunction;
245 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
246 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
248 } // namespace Bindings