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 | OverridesVisitChildren;
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 visitChildren(SlotVisitor&);
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