, context(context->d())
, fullyCreated(false)
{
- Q_ASSERT(vtable == QV4::ArgumentsObject::staticVTable());
+ Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable());
ExecutionEngine *v4 = context->d()->engine;
Scope scope(v4);
Heap::MemberData *mappedArguments() { return d()->mappedArguments; }
static bool isNonStrictArgumentsObject(Managed *m) {
- return m->d()->vtable->type == Type_ArgumentsObject &&
+ return m->d()->vtable()->type == Type_ArgumentsObject &&
!static_cast<ArgumentsObject *>(m)->context()->strictMode;
}
bool isSparse() const { return type == Sparse; }
- const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable); }
+ const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable()); }
inline ReturnedValue get(uint i) const {
return vtable()->get(this, i);
template<>
inline const DateObject *Value::as() const {
- return isManaged() && m() && m()->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable()->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
}
struct DateCtor: FunctionObject
strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
*static_cast<Value *>(globalObject) = newObject();
- Q_ASSERT(globalObject->d()->vtable);
+ Q_ASSERT(globalObject->d()->vtable());
initRootContext();
jsObjects[StringProto] = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype());
//
rootContext()->d()->global = globalObject->d();
rootContext()->d()->callData->thisObject = globalObject;
- Q_ASSERT(globalObject->d()->vtable);
+ Q_ASSERT(globalObject->d()->vtable());
globalObject->defineDefaultProperty(QStringLiteral("Object"), *objectCtor());
globalObject->defineDefaultProperty(QStringLiteral("String"), *stringCtor());
Q_ASSERT(c->inUse());
if (!c->isMarked()) {
c->setMarkBit();
- c->gcGetVtable()->markObjects(c, this);
+ c->vtable()->markObjects(c, this);
}
c = c->parent;
}
void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject)
{
- Q_ASSERT(!baseObject.vtable->isObject || static_cast<const Heap::Object&>(baseObject).internalClass->engine == this);
+ Q_ASSERT(!baseObject.vtable()->isObject || static_cast<const Heap::Object&>(baseObject).internalClass->engine == this);
Q_UNUSED(baseObject);
}
template<>
inline const ErrorObject *Value::as() const {
- return isManaged() && m() && m()->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable()->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
}
struct EvalErrorObject: ErrorObject {
bool FunctionObject::isBinding() const
{
- return d()->vtable == QQmlBindingFunction::staticVTable();
+ return d()->vtable() == QQmlBindingFunction::staticVTable();
}
bool FunctionObject::isBoundFunction() const
{
- return d()->vtable == BoundFunction::staticVTable();
+ return d()->vtable() == BoundFunction::staticVTable();
}
QQmlSourceLocation FunctionObject::sourceLocation() const
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
- ctx.vtable = CallContext::staticVTable();
+#ifndef QT_NO_DEBUG
+ ctx.mm_data = 0; // make sure we don't run into the assertion in setVTable when allocating a context on the stack
+#endif
+ ctx.setVtable(CallContext::staticVTable());
ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f->d();
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
- ctx.vtable = CallContext::staticVTable();
+#ifndef QT_NO_DEBUG
+ ctx.mm_data = 0; // make sure we don't run into the assertion in setVTable when allocating a context on the stack
+#endif
+ ctx.setVtable(CallContext::staticVTable());
ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f->d();
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
- ctx.vtable = CallContext::staticVTable();
+#ifndef QT_NO_DEBUG
+ ctx.mm_data = 0; // make sure we don't run into the assertion in setVTable when allocating a context on the stack
+#endif
+ ctx.setVtable(CallContext::staticVTable());
ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
ctx.callData = callData;
Q_ASSERT(v4->currentContext() == &ctx);
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
- ctx.vtable = CallContext::staticVTable();
+#ifndef QT_NO_DEBUG
+ ctx.mm_data = 0; // make sure we don't run into the assertion in setVTable when allocating a context on the stack
+#endif
+ ctx.setVtable(CallContext::staticVTable());
ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
ctx.callData = callData;
Q_ASSERT(v4->currentContext() == &ctx);
template<>
inline const FunctionObject *Value::as() const {
- return isManaged() && m() && m()->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable()->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
}
if (!entry || entry->isMarked())
continue;
entry->setMarkBit();
- Q_ASSERT(entry->gcGetVtable()->markObjects);
- entry->gcGetVtable()->markObjects(entry, e);
+ Q_ASSERT(entry->vtable()->markObjects);
+ entry->vtable()->markObjects(entry, e);
}
}
};
QString Managed::className() const
{
const char *s = 0;
- switch (Type(d()->vtable->type)) {
+ switch (Type(d()->vtable()->type)) {
case Type_Invalid:
case Type_String:
return QString();
};
Q_MANAGED_TYPE(Invalid)
- bool isListType() const { return d()->vtable->type == Type_QmlSequence; }
+ bool isListType() const { return d()->vtable()->type == Type_QmlSequence; }
- bool isArrayObject() const { return d()->vtable->type == Type_ArrayObject; }
- bool isStringObject() const { return d()->vtable->type == Type_StringObject; }
+ bool isArrayObject() const { return d()->vtable()->type == Type_ArrayObject; }
+ bool isStringObject() const { return d()->vtable()->type == Type_StringObject; }
QString className() const;
bool isEqualTo(const Managed *other) const
- { return d()->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
+ { return d()->vtable()->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
static bool isEqualTo(Managed *m, Managed *other);
template<>
inline const Object *Value::as() const {
- return isManaged() && m() && m()->vtable->isObject ? objectValue() : 0;
+ return isManaged() && m() && m()->vtable()->isObject ? objectValue() : 0;
}
}
*attrs = o->arrayData->attributes(index);
return p;
}
- if (o->vtable->type == Type_StringObject) {
+ if (o->vtable()->type == Type_StringObject) {
if (index < static_cast<const Heap::StringObject *>(o)->length()) {
// this is an evil hack, but it works, as the method is only ever called from putIndexed,
// where we don't use the returned pointer there for non writable attributes
const Property *propertyAt(uint index) const { return d()->propertyAt(index); }
Property *propertyAt(uint index) { return d()->propertyAt(index); }
- const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable); }
+ const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable()); }
Heap::Object *prototype() const { return d()->prototype; }
bool setPrototype(Object *proto);
template<>
inline const ArrayObject *Value::as() const {
- return isManaged() && m() && m()->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable()->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
}
#ifndef V4_BOOTSTRAP
{
while (engine->jsStackTop > markBase) {
Heap::Base *h = engine->popForGC();
- Q_ASSERT (h->gcGetVtable()->markObjects);
- h->gcGetVtable()->markObjects(h, engine);
+ Q_ASSERT (h->vtable()->markObjects);
+ h->vtable()->markObjects(h, engine);
}
}
if (t == o)
return true;
- if (!o->d()->vtable->isString)
+ if (!o->d()->vtable()->isString)
return false;
return static_cast<String *>(t)->isEqualTo(static_cast<String *>(o));
template<>
inline const String *Value::as() const {
- return isManaged() && m() && m()->vtable->isString ? static_cast<const String *>(this) : 0;
+ return isManaged() && m() && m()->vtable()->isString ? static_cast<const String *>(this) : 0;
}
#ifndef V4_BOOTSTRAP
Heap::StringObject::StringObject(InternalClass *ic, QV4::Object *prototype)
: Heap::Object(ic, prototype)
{
- Q_ASSERT(vtable == QV4::StringObject::staticVTable());
+ Q_ASSERT(vtable() == QV4::StringObject::staticVTable());
string = ic->engine->newString();
Scope scope(ic->engine);
if (!m() || !isManaged())
return 0;
- Q_ASSERT(m()->vtable);
+ Q_ASSERT(m()->vtable());
#if !defined(QT_NO_QOBJECT_CHECK)
static_cast<const T *>(this)->qt_check_for_QMANAGED_macro(static_cast<const T *>(this));
#endif
- const VTable *vt = m()->vtable;
+ const VTable *vt = m()->vtable();
while (vt) {
if (vt == T::staticVTable())
return static_cast<const T *>(this);
{
if (!isManaged())
return false;
- return m() && m()->vtable->isString;
+ return m() && m()->vtable()->isString;
}
inline bool Value::isObject() const
{
if (!isManaged())
return false;
- return m() && m()->vtable->isObject;
+ return m() && m()->vtable()->isObject;
}
inline bool Value::isPrimitive() const
namespace Heap {
struct Q_QML_EXPORT Base {
- union {
- const VTable *vtable;
- quintptr mm_data;
- };
+ quintptr mm_data; // vtable and markbit
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
PointerMask = ~0x3
};
- VTable *gcGetVtable() const {
+ void setVtable(const VTable *v) {
+ Q_ASSERT(!(mm_data & MarkBit));
+ mm_data = reinterpret_cast<quintptr>(v);
+ }
+ VTable *vtable() const {
return reinterpret_cast<VTable *>(mm_data & PointerMask);
}
inline bool isMarked() const {
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
- if (m->gcGetVtable()->destroy)
- m->gcGetVtable()->destroy(m);
+ if (m->vtable()->destroy)
+ m->vtable()->destroy(m);
memset(m, 0, header->itemSize);
#ifdef V4_USE_VALGRIND
{
while (engine->jsStackTop > markBase) {
Heap::Base *h = engine->popForGC();
- Q_ASSERT (h->gcGetVtable()->markObjects);
- h->gcGetVtable()->markObjects(h, engine);
+ Q_ASSERT (h->vtable()->markObjects);
+ h->vtable()->markObjects(h, engine);
}
}
for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) {
if (!(*it).isManaged())
continue;
- if ((*it).managed()->d()->gcGetVtable() != QObjectWrapper::staticVTable())
+ if ((*it).managed()->d()->vtable() != QObjectWrapper::staticVTable())
continue;
QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper*>((*it).managed());
if (!qobjectWrapper)
i = i->next;
continue;
}
- if (m->gcGetVtable()->destroy)
- m->gcGetVtable()->destroy(m);
+ if (m->vtable()->destroy)
+ m->vtable()->destroy(m);
*last = i->next;
free(Q_V4_PROFILE_DEALLOC(m_d->engine, i, i->size + sizeof(Data::LargeItem),
{
size = align(size);
Heap::Base *o = allocData(size);
- o->vtable = ManagedType::staticVTable();
+ o->setVtable(ManagedType::staticVTable());
return static_cast<typename ManagedType::Data *>(o);
}