Home | History | Annotate | Download | only in qt
      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 
     49     QtField(const QMetaProperty &p)
     50         : m_type(MetaProperty), m_property(p)
     51         {}
     52 
     53 #ifndef QT_NO_PROPERTIES
     54     QtField(const QByteArray &b)
     55         : m_type(DynamicProperty), m_dynamicProperty(b)
     56         {}
     57 #endif
     58 
     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;
     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:
     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 
     85     virtual const char* name() const { return m_identifier.constData(); }
     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;
    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 
    151     static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject)
    152     {
    153         return globalObject->functionPrototype();
    154     }
    155 
    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 | OverridesMarkChildren;
    163 
    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 markChildren(MarkStack& markStack);
    179 
    180 protected:
    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:
    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