55
55
#define Q_MANAGED_CHECK \
56
template <typename T> inline void qt_check_for_QMANAGED_macro(const T &_q_argument) const \
57
{ int i = qYouForgotTheQ_MANAGED_Macro(this, &_q_argument); i = i + 1; }
56
template <typename T> inline void qt_check_for_QMANAGED_macro(const T *_q_argument) const \
57
{ int i = qYouForgotTheQ_MANAGED_Macro(this, _q_argument); i = i + 1; }
59
59
template <typename T>
60
60
inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
62
62
template <typename T1, typename T2>
63
63
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
68
68
static const QV4::ManagedVTable static_vtbl; \
69
template <typename T> \
70
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
69
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
70
template <typename T> \
71
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
76
static const QV4::ObjectVTable static_vtbl; \
77
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
78
template <typename T> \
79
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
81
#define Q_MANAGED_TYPE(type) \
83
enum { MyType = Type_##type };
81
93
struct ManagedVTable
95
uint isExecutionContext : 1;
98
uint isFunctionObject : 1;
99
uint isErrorObject : 1;
100
uint isArrayData : 1;
103
const char *className;
104
void (*destroy)(Managed *);
105
void (*markObjects)(Managed *, ExecutionEngine *e);
106
bool (*isEqualTo)(Managed *m, Managed *other);
111
ManagedVTable managedVTable;
83
112
ReturnedValue (*call)(Managed *, CallData *data);
84
113
ReturnedValue (*construct)(Managed *, CallData *data);
85
void (*markObjects)(Managed *, ExecutionEngine *e);
86
void (*destroy)(Managed *);
87
void (*collectDeletables)(Managed *, GCDeletable **deletable);
88
114
ReturnedValue (*get)(Managed *, const StringRef name, bool *hasProperty);
89
115
ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
90
116
void (*put)(Managed *, const StringRef name, const ValueRef value);
95
121
bool (*deleteIndexedProperty)(Managed *m, uint index);
96
122
ReturnedValue (*getLookup)(Managed *m, Lookup *l);
97
123
void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
98
bool (*isEqualTo)(Managed *m, Managed *other);
99
Property *(*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
100
const char *className;
124
uint (*getLength)(const Managed *m);
125
void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
128
#define DEFINE_MANAGED_VTABLE_INT(classname) \
130
classname::IsExecutionContext, \
131
classname::IsString, \
132
classname::IsObject, \
133
classname::IsFunctionObject, \
134
classname::IsErrorObject, \
135
classname::IsArrayData, \
103
145
#define DEFINE_MANAGED_VTABLE(classname) \
104
const QV4::ManagedVTable classname::static_vtbl = \
118
deleteIndexedProperty, \
126
#define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
127
const QV4::ManagedVTable classname::static_vtbl = \
141
deleteIndexedProperty, \
149
struct Q_QML_EXPORT Managed
146
const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
149
#define DEFINE_OBJECT_VTABLE(classname) \
150
const QV4::ObjectVTable classname::static_vtbl = \
152
DEFINE_MANAGED_VTABLE_INT(classname), \
162
deleteIndexedProperty, \
169
#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
170
const QV4::ObjectVTable classname::static_vtbl = \
172
DEFINE_MANAGED_VTABLE_INT(name), \
182
deleteIndexedProperty, \
190
struct Q_QML_PRIVATE_EXPORT Managed
194
IsExecutionContext = false,
197
IsFunctionObject = false,
198
IsErrorObject = false,
153
202
void *operator new(size_t);
154
203
Managed(const Managed &other);
199
251
if (!this || !internalClass)
201
253
#if !defined(QT_NO_QOBJECT_CHECK)
202
static_cast<T *>(this)->qt_check_for_QMANAGED_macro(*static_cast<T *>(this));
254
static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
204
return internalClass->vtable == &T::static_vtbl ? static_cast<T *>(this) : 0;
256
return internalClass->vtable == T::staticVTable() ? static_cast<T *>(this) : 0;
206
258
template <typename T>
207
259
const T *as() const {
211
263
#if !defined(QT_NO_QOBJECT_CHECK)
212
reinterpret_cast<T *>(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast<T *>(const_cast<Managed *>(this)));
264
static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
214
return internalClass->vtable == &T::static_vtbl ? static_cast<const T *>(this) : 0;
266
return internalClass->vtable == T::staticVTable() ? static_cast<const T *>(this) : 0;
217
String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
218
Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
219
ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
220
FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
221
BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
222
NumberObject *asNumberObject() { return type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
223
StringObject *asStringObject() { return type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
224
DateObject *asDateObject() { return type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
225
ErrorObject *asErrorObject() { return type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
226
ArgumentsObject *asArgumentsObject() { return type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
228
bool isListType() const { return type == Type_QmlSequence; }
230
bool isArrayObject() const { return type == Type_ArrayObject; }
231
bool isStringObject() const { return type == Type_StringObject; }
269
String *asString() { return internalClass->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
270
Object *asObject() { return internalClass->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
271
ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
272
FunctionObject *asFunctionObject() { return internalClass->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
273
BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
274
NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
275
StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
276
DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
277
ErrorObject *asErrorObject() { return internalClass->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
278
ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
280
bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
282
bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
283
bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
233
285
QString className() const;
245
297
void setVTable(const ManagedVTable *vt);
247
ReturnedValue construct(CallData *d);
248
ReturnedValue call(CallData *d);
249
ReturnedValue get(const StringRef name, bool *hasProperty = 0);
250
ReturnedValue getIndexed(uint index, bool *hasProperty = 0);
251
void put(const StringRef name, const ValueRef value);
252
void putIndexed(uint index, const ValueRef value);
253
PropertyAttributes query(StringRef name) const;
254
PropertyAttributes queryIndexed(uint index) const
255
{ return internalClass->vtable->queryIndexed(this, index); }
257
bool deleteProperty(const StringRef name);
258
bool deleteIndexedProperty(uint index)
259
{ return internalClass->vtable->deleteIndexedProperty(this, index); }
260
ReturnedValue getLookup(Lookup *l)
261
{ return internalClass->vtable->getLookup(this, l); }
262
void setLookup(Lookup *l, const ValueRef v);
264
299
bool isEqualTo(Managed *other)
265
300
{ return internalClass->vtable->isEqualTo(this, other); }
266
Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
268
302
static void destroy(Managed *that) { that->_data = 0; }
269
static ReturnedValue construct(Managed *m, CallData *d);
270
static ReturnedValue call(Managed *m, CallData *);
271
static ReturnedValue getLookup(Managed *m, Lookup *);
272
static void setLookup(Managed *m, Lookup *l, const ValueRef v);
273
303
static bool isEqualTo(Managed *m, Managed *other);
275
uint internalType() const {
279
305
ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
282
308
InternalClass *internalClass;
291
313
uchar markBit : 1;
293
315
uchar extensible : 1; // used by Object
294
uchar isNonStrictArgumentsObject : 1;
295
317
uchar needsActivation : 1; // used by FunctionObject
296
318
uchar strictMode : 1; // used by FunctionObject
297
319
uchar bindingKeyFlag : 1;
298
320
uchar hasAccessorProperty : 1;
300
322
mutable uchar subtype;
339
inline ReturnedValue Managed::construct(CallData *d) {
340
return internalClass->vtable->construct(this, d);
342
inline ReturnedValue Managed::call(CallData *d) {
343
return internalClass->vtable->call(this, d);
362
Value *extractValuePointer(const ScopedValue &);
364
Value *extractValuePointer(const Scoped<T> &);
366
#define DEFINE_REF_METHODS(Class, Base) \
367
Class##Ref(const QV4::ScopedValue &v) \
368
{ QV4::Value *val = extractValuePointer(v); ptr = QV4::value_cast<Class>(*val) ? val : 0; } \
369
Class##Ref(const QV4::Scoped<Class> &v) { ptr = extractValuePointer(v); } \
370
Class##Ref(QV4::TypedValue<Class> &v) { ptr = &v; } \
371
Class##Ref(QV4::Value &v) { ptr = QV4::value_cast<Class>(v) ? &v : 0; } \
372
Class##Ref &operator=(Class *t) { \
373
if (sizeof(void *) == 4) \
374
ptr->tag = QV4::Value::Managed_Type; \
378
Class##Ref &operator=(QV4::Returned<Class> *t) { \
379
if (sizeof(void *) == 4) \
380
ptr->tag = QV4::Value::Managed_Type; \
381
ptr->m = t->getPointer(); \
384
operator const Class *() const { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
385
const Class *operator->() const { return static_cast<Class*>(ptr->managed()); } \
386
operator Class *() { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
387
Class *operator->() { return static_cast<Class*>(ptr->managed()); } \
388
Class *getPointer() const { return static_cast<Class *>(ptr->managed()); } \
389
operator QV4::Returned<Class> *() const { return ptr ? QV4::Returned<Class>::create(getPointer()) : 0; } \
390
static Class##Ref null() { Class##Ref c; c.ptr = 0; return c; } \
395
#define DEFINE_REF(Class, Base) \
396
struct Class##Ref : public Base##Ref \
397
{ DEFINE_REF_METHODS(Class, Base) } \
401
// Important: Do NOT add a copy constructor to this class or any derived class
402
// adding a copy constructor actually changes the calling convention, ie.
403
// is not even binary compatible. Adding it would break assumptions made
404
// in the jit'ed code.
405
DEFINE_REF_METHODS(Managed, Managed);
407
bool operator==(const ManagedRef &other) {
408
if (ptr == other.ptr)
410
return ptr && other.ptr && ptr->m == other.ptr->m;
412
bool operator!=(const ManagedRef &other) {
413
return !operator==(other);
415
bool operator!() const { return !ptr || !ptr->managed(); }
417
bool isNull() const { return !ptr; }
418
ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }