aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4managed_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4managed_p.h')
-rw-r--r--src/qml/jsruntime/qv4managed_p.h261
1 files changed, 181 insertions, 80 deletions
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index e10409f397..8c6f2daf9b 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -45,7 +45,7 @@
#include <QtCore/QVector>
#include <QtCore/QDebug>
#include "qv4global_p.h"
-#include "qv4value_def_p.h"
+#include "qv4value_p.h"
#include "qv4internalclass_p.h"
QT_BEGIN_NAMESPACE
@@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
#define Q_MANAGED_CHECK \
- template <typename T> inline void qt_check_for_QMANAGED_macro(const T &_q_argument) const \
- { int i = qYouForgotTheQ_MANAGED_Macro(this, &_q_argument); i = i + 1; }
+ template <typename T> inline void qt_check_for_QMANAGED_macro(const T *_q_argument) const \
+ { int i = qYouForgotTheQ_MANAGED_Macro(this, _q_argument); i = i + 1; }
template <typename T>
inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
@@ -62,13 +62,25 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
-#define Q_MANAGED \
+#define V4_MANAGED \
public: \
Q_MANAGED_CHECK \
static const QV4::ManagedVTable static_vtbl; \
+ static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+#define V4_OBJECT \
+ public: \
+ Q_MANAGED_CHECK \
+ static const QV4::ObjectVTable static_vtbl; \
+ static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ template <typename T> \
+ QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+
+#define Q_MANAGED_TYPE(type) \
+ public: \
+ enum { MyType = Type_##type };
struct GCDeletable
{
@@ -80,10 +92,25 @@ struct GCDeletable
struct ManagedVTable
{
+ uint isExecutionContext : 1;
+ uint isString : 1;
+ uint isObject : 1;
+ uint isFunctionObject : 1;
+ uint isErrorObject : 1;
+ uint isArrayData : 1;
+ uint unused : 18;
+ uint type : 8;
+ const char *className;
+ void (*destroy)(Managed *);
+ void (*markObjects)(Managed *, ExecutionEngine *e);
+ bool (*isEqualTo)(Managed *m, Managed *other);
+};
+
+struct ObjectVTable
+{
+ ManagedVTable managedVTable;
ReturnedValue (*call)(Managed *, CallData *data);
ReturnedValue (*construct)(Managed *, CallData *data);
- void (*markObjects)(Managed *, ExecutionEngine *e);
- void (*destroy)(Managed *);
void (*collectDeletables)(Managed *, GCDeletable **deletable);
ReturnedValue (*get)(Managed *, const StringRef name, bool *hasProperty);
ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
@@ -95,18 +122,58 @@ struct ManagedVTable
bool (*deleteIndexedProperty)(Managed *m, uint index);
ReturnedValue (*getLookup)(Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
- bool (*isEqualTo)(Managed *m, Managed *other);
- Property *(*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
- const char *className;
+ uint (*getLength)(const Managed *m);
+ void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
};
+#define DEFINE_MANAGED_VTABLE_INT(classname) \
+{ \
+ classname::IsExecutionContext, \
+ classname::IsString, \
+ classname::IsObject, \
+ classname::IsFunctionObject, \
+ classname::IsErrorObject, \
+ classname::IsArrayData, \
+ 0, \
+ classname::MyType, \
+ #classname, \
+ destroy, \
+ markObjects, \
+ isEqualTo \
+}
+
+
#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::ManagedVTable classname::static_vtbl = \
+const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
+
+
+#define DEFINE_OBJECT_VTABLE(classname) \
+const QV4::ObjectVTable classname::static_vtbl = \
+{ \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
+ call, \
+ construct, \
+ 0, \
+ get, \
+ getIndexed, \
+ put, \
+ putIndexed, \
+ query, \
+ queryIndexed, \
+ deleteProperty, \
+ deleteIndexedProperty, \
+ getLookup, \
+ setLookup, \
+ getLength, \
+ advanceIterator \
+}
+
+#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
+const QV4::ObjectVTable classname::static_vtbl = \
{ \
+ DEFINE_MANAGED_VTABLE_INT(name), \
call, \
construct, \
- markObjects, \
- destroy, \
0, \
get, \
getIndexed, \
@@ -118,18 +185,16 @@ const QV4::ManagedVTable classname::static_vtbl = \
deleteIndexedProperty, \
getLookup, \
setLookup, \
- isEqualTo, \
- advanceIterator, \
- #classname \
+ getLength, \
+ advanceIterator \
}
#define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
-const QV4::ManagedVTable classname::static_vtbl = \
+const QV4::ObjectVTable classname::static_vtbl = \
{ \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
call, \
construct, \
- markObjects, \
- destroy, \
collectDeletables, \
get, \
getIndexed, \
@@ -141,14 +206,21 @@ const QV4::ManagedVTable classname::static_vtbl = \
deleteIndexedProperty, \
getLookup, \
setLookup, \
- isEqualTo, \
- advanceIterator, \
- #classname \
+ getLength, \
+ advanceIterator \
}
struct Q_QML_EXPORT Managed
{
- Q_MANAGED
+ V4_MANAGED
+ enum {
+ IsExecutionContext = false,
+ IsString = false,
+ IsObject = false,
+ IsFunctionObject = false,
+ IsErrorObject = false,
+ IsArrayData = false
+ };
private:
void *operator new(size_t);
Managed(const Managed &other);
@@ -158,7 +230,7 @@ protected:
Managed(InternalClass *internal)
: internalClass(internal), _data(0)
{
- Q_ASSERT(!internalClass || internalClass->vtable);
+ Q_ASSERT(internalClass && internalClass->vtable);
inUse = 1; extensible = 1;
}
@@ -183,13 +255,16 @@ public:
Type_RegExpObject,
Type_ErrorObject,
Type_ArgumentsObject,
- Type_JSONObject,
+ Type_JsonObject,
Type_MathObject,
+
+ Type_ExecutionContext,
Type_ForeachIteratorObject,
Type_RegExp,
Type_QmlSequence
};
+ Q_MANAGED_TYPE(Invalid)
ExecutionEngine *engine() const;
@@ -199,9 +274,9 @@ public:
if (!this || !internalClass)
return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
- static_cast<T *>(this)->qt_check_for_QMANAGED_macro(*static_cast<T *>(this));
+ static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
#endif
- return internalClass->vtable == &T::static_vtbl ? static_cast<T *>(this) : 0;
+ return internalClass->vtable == T::staticVTable() ? static_cast<T *>(this) : 0;
}
template <typename T>
const T *as() const {
@@ -209,26 +284,26 @@ public:
if (!this)
return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T *>(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast<T *>(const_cast<Managed *>(this)));
+ static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
#endif
- return internalClass->vtable == &T::static_vtbl ? static_cast<const T *>(this) : 0;
+ return internalClass->vtable == T::staticVTable() ? static_cast<const T *>(this) : 0;
}
- String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
- Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
- ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
- FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
- BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
- NumberObject *asNumberObject() { return type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
- StringObject *asStringObject() { return type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
- DateObject *asDateObject() { return type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
- ErrorObject *asErrorObject() { return type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
- ArgumentsObject *asArgumentsObject() { return type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+ String *asString() { return internalClass->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
+ Object *asObject() { return internalClass->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
+ ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+ FunctionObject *asFunctionObject() { return internalClass->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+ BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+ NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+ StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+ DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+ ErrorObject *asErrorObject() { return internalClass->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+ ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
- bool isListType() const { return type == Type_QmlSequence; }
+ bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
- bool isArrayObject() const { return type == Type_ArrayObject; }
- bool isStringObject() const { return type == Type_StringObject; }
+ bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
+ bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
QString className() const;
@@ -244,61 +319,31 @@ public:
void setVTable(const ManagedVTable *vt);
- ReturnedValue construct(CallData *d);
- ReturnedValue call(CallData *d);
- ReturnedValue get(const StringRef name, bool *hasProperty = 0);
- ReturnedValue getIndexed(uint index, bool *hasProperty = 0);
- void put(const StringRef name, const ValueRef value);
- void putIndexed(uint index, const ValueRef value);
- PropertyAttributes query(StringRef name) const;
- PropertyAttributes queryIndexed(uint index) const
- { return internalClass->vtable->queryIndexed(this, index); }
-
- bool deleteProperty(const StringRef name);
- bool deleteIndexedProperty(uint index)
- { return internalClass->vtable->deleteIndexedProperty(this, index); }
- ReturnedValue getLookup(Lookup *l)
- { return internalClass->vtable->getLookup(this, l); }
- void setLookup(Lookup *l, const ValueRef v);
-
bool isEqualTo(Managed *other)
{ return internalClass->vtable->isEqualTo(this, other); }
- Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
static void destroy(Managed *that) { that->_data = 0; }
- static ReturnedValue construct(Managed *m, CallData *d);
- static ReturnedValue call(Managed *m, CallData *);
- static ReturnedValue getLookup(Managed *m, Lookup *);
- static void setLookup(Managed *m, Lookup *l, const ValueRef v);
static bool isEqualTo(Managed *m, Managed *other);
- uint internalType() const {
- return type;
- }
-
ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
InternalClass *internalClass;
- enum {
- SimpleArray = 1
- };
-
union {
uint _data;
struct {
uchar markBit : 1;
uchar inUse : 1;
uchar extensible : 1; // used by Object
- uchar isNonStrictArgumentsObject : 1;
+ uchar _unused : 1;
uchar needsActivation : 1; // used by FunctionObject
uchar strictMode : 1; // used by FunctionObject
uchar bindingKeyFlag : 1;
uchar hasAccessorProperty : 1;
- uchar type;
+ uchar _type;
mutable uchar subtype;
- uchar flags;
+ uchar _flags;
};
};
@@ -308,6 +353,7 @@ private:
friend struct ObjectIterator;
};
+
template<>
inline Managed *value_cast(const Value &v) {
return v.asManaged();
@@ -336,12 +382,67 @@ inline FunctionObject *managed_cast(Managed *m)
}
-inline ReturnedValue Managed::construct(CallData *d) {
- return internalClass->vtable->construct(this, d);
-}
-inline ReturnedValue Managed::call(CallData *d) {
- return internalClass->vtable->call(this, d);
-}
+Value *extractValuePointer(const ScopedValue &);
+template<typename T>
+Value *extractValuePointer(const Scoped<T> &);
+
+#define DEFINE_REF_METHODS(Class, Base) \
+ Class##Ref(const QV4::ScopedValue &v) \
+ { QV4::Value *val = extractValuePointer(v); ptr = QV4::value_cast<Class>(*val) ? val : 0; } \
+ Class##Ref(const QV4::Scoped<Class> &v) { ptr = extractValuePointer(v); } \
+ Class##Ref(QV4::TypedValue<Class> &v) { ptr = &v; } \
+ Class##Ref(QV4::Value &v) { ptr = QV4::value_cast<Class>(v) ? &v : 0; } \
+ Class##Ref &operator=(Class *t) { \
+ if (sizeof(void *) == 4) \
+ ptr->tag = QV4::Value::Managed_Type; \
+ ptr->m = t; \
+ return *this; \
+ } \
+ Class##Ref &operator=(QV4::Returned<Class> *t) { \
+ if (sizeof(void *) == 4) \
+ ptr->tag = QV4::Value::Managed_Type; \
+ ptr->m = t->getPointer(); \
+ return *this; \
+ } \
+ operator const Class *() const { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+ const Class *operator->() const { return static_cast<Class*>(ptr->managed()); } \
+ operator Class *() { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+ Class *operator->() { return static_cast<Class*>(ptr->managed()); } \
+ Class *getPointer() const { return static_cast<Class *>(ptr->managed()); } \
+ operator QV4::Returned<Class> *() const { return ptr ? QV4::Returned<Class>::create(getPointer()) : 0; } \
+ static Class##Ref null() { Class##Ref c; c.ptr = 0; return c; } \
+protected: \
+ Class##Ref() {} \
+public: \
+
+#define DEFINE_REF(Class, Base) \
+struct Class##Ref : public Base##Ref \
+{ DEFINE_REF_METHODS(Class, Base) } \
+
+
+struct ManagedRef {
+ // Important: Do NOT add a copy constructor to this class or any derived class
+ // adding a copy constructor actually changes the calling convention, ie.
+ // is not even binary compatible. Adding it would break assumptions made
+ // in the jit'ed code.
+ DEFINE_REF_METHODS(Managed, Managed);
+
+ bool operator==(const ManagedRef &other) {
+ if (ptr == other.ptr)
+ return true;
+ return ptr && other.ptr && ptr->m == other.ptr->m;
+ }
+ bool operator!=(const ManagedRef &other) {
+ return !operator==(other);
+ }
+ bool operator!() const { return !ptr || !ptr->managed(); }
+
+ bool isNull() const { return !ptr; }
+ ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
+
+public:
+ Value *ptr;
+};
}