Unzip initialization lists and constructors in JSCell hierarchy (5/7)
[WebKit-https.git] / Source / WebCore / bridge / qt / qt_runtime.h
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 "JSDOMBinding.h"
25 #include "JavaScript.h"
26 #include "Weak.h"
27 #include "qt_instance.h"
28 #include "runtime_method.h"
29
30 #include <QWeakPointer>
31
32 #include <qbytearray.h>
33 #include <qmetaobject.h>
34 #include <qvariant.h>
35
36 namespace JSC {
37 namespace Bindings {
38
39 class QtField : public Field {
40 public:
41
42     typedef enum {
43         MetaProperty,
44 #ifndef QT_NO_PROPERTIES
45         DynamicProperty,
46 #endif
47         ChildObject
48     } QtFieldType;
49
50     QtField(const QMetaProperty &p)
51         : m_type(MetaProperty), m_property(p)
52         {}
53
54 #ifndef QT_NO_PROPERTIES
55     QtField(const QByteArray &b)
56         : m_type(DynamicProperty), m_dynamicProperty(b)
57         {}
58 #endif
59
60     QtField(QObject *child)
61         : m_type(ChildObject), m_childObject(child)
62         {}
63
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;}
68 private:
69     QtFieldType m_type;
70     QByteArray m_dynamicProperty;
71     QMetaProperty m_property;
72     QWeakPointer<QObject> m_childObject;
73 };
74
75
76 template <typename T> class QtArray : public Array
77 {
78 public:
79     QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>);
80     virtual ~QtArray();
81
82     RootObject* rootObject() const;
83
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;}
87
88 private:
89     mutable QList<T> m_list; // setValueAt is const!
90     unsigned int m_length;
91     QMetaType::Type m_type;
92 };
93
94 // Based on RuntimeMethod
95
96 // Extra data classes (to avoid the CELL_SIZE limit on JS objects)
97 class QtRuntimeMethod;
98 class QtRuntimeMethodData : public WeakHandleOwner {
99     public:
100         virtual ~QtRuntimeMethodData();
101         RefPtr<QtInstance> m_instance;
102         Weak<QtRuntimeMethod> m_finalizer;
103
104     private:
105         void finalize(Handle<Unknown>, void*);
106 };
107
108 class QtRuntimeConnectionMethod;
109 class QtRuntimeMetaMethodData : public QtRuntimeMethodData {
110     public:
111         ~QtRuntimeMetaMethodData();
112         QByteArray m_signature;
113         bool m_allowPrivate;
114         int m_index;
115         WriteBarrier<QtRuntimeConnectionMethod> m_connect;
116         WriteBarrier<QtRuntimeConnectionMethod> m_disconnect;
117 };
118
119 class QtRuntimeConnectionMethodData : public QtRuntimeMethodData {
120     public:
121         ~QtRuntimeConnectionMethodData();
122         QByteArray m_signature;
123         int m_index;
124         bool m_isConnect;
125 };
126
127 // Common base class (doesn't really do anything interesting)
128 class QtRuntimeMethod : public InternalFunction {
129 public:
130     typedef InternalFunction Base;
131
132     virtual ~QtRuntimeMethod();
133
134     static const ClassInfo s_info;
135
136     static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject)
137     {
138         return globalObject->functionPrototype();
139     }
140
141     static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
142     {
143         return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType,  StructureFlags), AnonymousSlotCount, &s_info);
144     }
145
146 protected:
147     void finishCreation(ExecState*, const Identifier&, PassRefPtr<QtInstance>);
148     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesVisitChildren;
149
150     QtRuntimeMethodData *d_func() const {return d_ptr;}
151     QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *, Structure*, const Identifier &name, PassRefPtr<QtInstance>);
152     QtRuntimeMethodData *d_ptr;
153 };
154
155 class QtRuntimeMetaMethod : public QtRuntimeMethod {
156 public:
157     typedef QtRuntimeMethod Base;
158
159     static QtRuntimeMetaMethod* create(ExecState* exec, const Identifier& n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate)
160     {
161         Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
162         return new (allocateCell<QtRuntimeMetaMethod>(*exec->heap())) QtRuntimeMetaMethod(exec, domStructure, n, inst, index, signature, allowPrivate);
163     }
164
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);
168
169     virtual void visitChildren(SlotVisitor&);
170
171 protected:
172     QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}
173
174 private:
175     QtRuntimeMetaMethod(ExecState*, Structure*, const Identifier&, PassRefPtr<QtInstance>, int index, const QByteArray&, bool allowPrivate);
176
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&);
182 };
183
184 class QtConnectionObject;
185 class QtRuntimeConnectionMethod : public QtRuntimeMethod {
186 public:
187     typedef QtRuntimeMethod Base;
188
189     static QtRuntimeConnectionMethod* create(ExecState* exec, const Identifier& n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature)
190     {
191         Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
192         return new (allocateCell<QtRuntimeConnectionMethod>(*exec->heap())) QtRuntimeConnectionMethod(exec, domStructure, n, isConnect, inst, index, signature);
193     }
194
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);
198
199 protected:
200     QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
201
202 private:
203     QtRuntimeConnectionMethod(ExecState*, Structure*, const Identifier&, bool isConnect, PassRefPtr<QtInstance>, int index, const QByteArray&);
204
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 // 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
215 {
216 public:
217     QtConnectionObject(JSContextRef, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObjectRef receiver, JSObjectRef receiverFunction);
218     ~QtConnectionObject();
219
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);
225
226     void execute(void **argv);
227
228     bool match(JSContextRef, QObject* sender, int signalIndex, JSObjectRef thisObject, JSObjectRef funcObject);
229
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);
232
233 private:
234     JSContextRef m_context;
235     RefPtr<QtInstance> m_senderInstance;
236
237     // We use this as key in active connections multimap.
238     QObject* m_originalSender;
239
240     int m_signalIndex;
241     JSObjectRef m_receiver;
242     JSObjectRef m_receiverFunction;
243 };
244
245 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
246 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
247
248 } // namespace Bindings
249 } // namespace JSC
250
251 #endif