initial import
[vuplus_webkit] / 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), &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);
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         QtRuntimeMetaMethod* method = new (allocateCell<QtRuntimeMetaMethod>(*exec->heap())) QtRuntimeMetaMethod(exec, domStructure, n, inst, index, signature, allowPrivate);
163         return method;
164     }
165
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);
169
170     virtual void visitChildren(SlotVisitor&);
171
172 protected:
173     QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}
174
175 private:
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);
178
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&);
184 };
185
186 class QtConnectionObject;
187 class QtRuntimeConnectionMethod : public QtRuntimeMethod {
188 public:
189     typedef QtRuntimeMethod Base;
190
191     static QtRuntimeConnectionMethod* create(ExecState* exec, const Identifier& n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature)
192     {
193         Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtRuntimeMethod>(exec);
194         return new (allocateCell<QtRuntimeConnectionMethod>(*exec->heap())) QtRuntimeConnectionMethod(exec, domStructure, n, isConnect, inst, index, signature);
195     }
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:
202     QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
203
204 private:
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);
207
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;
213 };
214
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
218 {
219 public:
220     QtConnectionObject(JSContextRef, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObjectRef receiver, JSObjectRef receiverFunction);
221     ~QtConnectionObject();
222
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);
228
229     void execute(void **argv);
230
231     bool match(JSContextRef, QObject* sender, int signalIndex, JSObjectRef thisObject, JSObjectRef funcObject);
232
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);
235
236 private:
237     JSContextRef m_context;
238     RefPtr<QtInstance> m_senderInstance;
239
240     // We use this as key in active connections multimap.
241     QObject* m_originalSender;
242
243     int m_signalIndex;
244     JSObjectRef m_receiver;
245     JSObjectRef m_receiverFunction;
246 };
247
248 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
249 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
250
251 } // namespace Bindings
252 } // namespace JSC
253
254 #endif