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 "Bridge.h"
     24 #include "Completion.h"
     25 #include "Protect.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         DynamicProperty,
     44         ChildObject
     45     } QtFieldType;
     46 
     47     QtField(const QMetaProperty &p)
     48         : m_type(MetaProperty), m_property(p)
     49         {}
     50 
     51     QtField(const QByteArray &b)
     52         : m_type(DynamicProperty), m_dynamicProperty(b)
     53         {}
     54 
     55     QtField(QObject *child)
     56         : m_type(ChildObject), m_childObject(child)
     57         {}
     58 
     59     virtual JSValue valueFromInstance(ExecState*, const Instance*) const;
     60     virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const;
     61     virtual const char* name() const;
     62     QtFieldType fieldType() const {return m_type;}
     63 private:
     64     QtFieldType m_type;
     65     QByteArray m_dynamicProperty;
     66     QMetaProperty m_property;
     67     QPointer<QObject> m_childObject;
     68 };
     69 
     70 
     71 class QtMethod : public Method
     72 {
     73 public:
     74     QtMethod(const QMetaObject *mo, int i, const QByteArray &ident, int numParameters)
     75         : m_metaObject(mo),
     76           m_index(i),
     77           m_identifier(ident),
     78           m_nParams(numParameters)
     79         { }
     80 
     81     virtual const char* name() const { return m_identifier.constData(); }
     82     virtual int numParameters() const { return m_nParams; }
     83 
     84 private:
     85     friend class QtInstance;
     86     const QMetaObject *m_metaObject;
     87     int m_index;
     88     QByteArray m_identifier;
     89     int m_nParams;
     90 };
     91 
     92 
     93 template <typename T> class QtArray : public Array
     94 {
     95 public:
     96     QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>);
     97     virtual ~QtArray();
     98 
     99     RootObject* rootObject() const;
    100 
    101     virtual void setValueAt(ExecState*, unsigned index, JSValue) const;
    102     virtual JSValue valueAt(ExecState*, unsigned index) const;
    103     virtual unsigned int getLength() const {return m_length;}
    104 
    105 private:
    106     mutable QList<T> m_list; // setValueAt is const!
    107     unsigned int m_length;
    108     QMetaType::Type m_type;
    109 };
    110 
    111 // Based on RuntimeMethod
    112 
    113 // Extra data classes (to avoid the CELL_SIZE limit on JS objects)
    114 
    115 class QtRuntimeMethodData {
    116     public:
    117         virtual ~QtRuntimeMethodData();
    118         RefPtr<QtInstance> m_instance;
    119 };
    120 
    121 class QtRuntimeConnectionMethod;
    122 class QtRuntimeMetaMethodData : public QtRuntimeMethodData {
    123     public:
    124         ~QtRuntimeMetaMethodData();
    125         QByteArray m_signature;
    126         bool m_allowPrivate;
    127         int m_index;
    128         QtRuntimeConnectionMethod *m_connect;
    129         QtRuntimeConnectionMethod *m_disconnect;
    130 };
    131 
    132 class QtRuntimeConnectionMethodData : public QtRuntimeMethodData {
    133     public:
    134         ~QtRuntimeConnectionMethodData();
    135         QByteArray m_signature;
    136         int m_index;
    137         bool m_isConnect;
    138 };
    139 
    140 // Common base class (doesn't really do anything interesting)
    141 class QtRuntimeMethod : public InternalFunction {
    142 public:
    143     virtual ~QtRuntimeMethod();
    144 
    145     static const ClassInfo s_info;
    146 
    147     static FunctionPrototype* createPrototype(ExecState*, JSGlobalObject* globalObject)
    148     {
    149         return globalObject->functionPrototype();
    150     }
    151 
    152     static PassRefPtr<Structure> createStructure(JSValue prototype)
    153     {
    154         return Structure::create(prototype, TypeInfo(ObjectType,  StructureFlags), AnonymousSlotCount);
    155     }
    156 
    157 protected:
    158     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InternalFunction::StructureFlags | OverridesMarkChildren;
    159 
    160     QtRuntimeMethodData *d_func() const {return d_ptr;}
    161     QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst);
    162     QtRuntimeMethodData *d_ptr;
    163 };
    164 
    165 class QtRuntimeMetaMethod : public QtRuntimeMethod
    166 {
    167 public:
    168     QtRuntimeMetaMethod(ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate);
    169 
    170     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    171     virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
    172     virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
    173 
    174     virtual void markChildren(MarkStack& markStack);
    175 
    176 protected:
    177     QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}
    178 
    179 private:
    180     virtual CallType getCallData(CallData&);
    181     static JSValue JSC_HOST_CALL call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args);
    182     static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    183     static JSValue connectGetter(ExecState*, const Identifier&, const PropertySlot&);
    184     static JSValue disconnectGetter(ExecState*, const Identifier&, const PropertySlot&);
    185 };
    186 
    187 class QtConnectionObject;
    188 class QtRuntimeConnectionMethod : public QtRuntimeMethod
    189 {
    190 public:
    191     QtRuntimeConnectionMethod(ExecState *exec, const Identifier &n, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature );
    192 
    193     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    194     virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
    195     virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
    196 
    197 protected:
    198     QtRuntimeConnectionMethodData* d_func() const {return reinterpret_cast<QtRuntimeConnectionMethodData*>(d_ptr);}
    199 
    200 private:
    201     virtual CallType getCallData(CallData&);
    202     static JSValue JSC_HOST_CALL call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args);
    203     static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    204     static QMultiMap<QObject *, QtConnectionObject *> connections;
    205     friend class QtConnectionObject;
    206 };
    207 
    208 class QtConnectionObject: public QObject
    209 {
    210 public:
    211     QtConnectionObject(PassRefPtr<QtInstance> instance, int signalIndex, JSObject* thisObject, JSObject* funcObject);
    212     ~QtConnectionObject();
    213 
    214     static const QMetaObject staticMetaObject;
    215     virtual const QMetaObject *metaObject() const;
    216     virtual void *qt_metacast(const char *);
    217     virtual int qt_metacall(QMetaObject::Call, int, void **argv);
    218 
    219     bool match(QObject *sender, int signalIndex, JSObject* thisObject, JSObject *funcObject);
    220 
    221     // actual slot:
    222     void execute(void **argv);
    223 
    224 private:
    225     RefPtr<QtInstance> m_instance;
    226     int m_signalIndex;
    227     QObject* m_originalObject; // only used as a key, not dereferenced
    228     ProtectedPtr<JSObject> m_thisObject;
    229     ProtectedPtr<JSObject> m_funcObject;
    230 };
    231 
    232 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
    233 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
    234 
    235 } // namespace Bindings
    236 } // namespace JSC
    237 
    238 #endif
    239