, context(context)
, fullyCreated(false)
{
- setArrayType(ArrayData::Complex);
-
ExecutionEngine *v4 = context->engine;
Scope scope(v4);
ScopedObject protectThis(scope, this);
+ setArrayType(ArrayData::Complex);
+
if (context->strictMode) {
Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
const ArrayVTable SimpleArrayData::static_vtbl =
{
+ DEFINE_MANAGED_VTABLE_INT(SimpleArrayData),
SimpleArrayData::Simple,
- SimpleArrayData::destroy,
- SimpleArrayData::markObjects,
SimpleArrayData::reserve,
SimpleArrayData::get,
SimpleArrayData::put,
const ArrayVTable SparseArrayData::static_vtbl =
{
+ DEFINE_MANAGED_VTABLE_INT(SparseArrayData),
ArrayData::Sparse,
- SparseArrayData::destroy,
- SparseArrayData::markObjects,
SparseArrayData::reserve,
SparseArrayData::get,
SparseArrayData::put,
}
-void SimpleArrayData::destroy(ArrayData *d)
+void SimpleArrayData::destroy(Managed *d)
{
SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
delete [] (dd->data - dd->offset);
if (dd->attrs)
delete [] (dd->attrs - dd->offset);
- delete dd;
}
-void SimpleArrayData::markObjects(ArrayData *d, ExecutionEngine *e)
+void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e)
{
- uint l = static_cast<SimpleArrayData *>(d)->len;
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+ uint l = dd->len;
for (uint i = 0; i < l; ++i)
- d->data[i].mark(e);
+ dd->data[i].mark(e);
}
ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index)
}
-void SparseArrayData::destroy(ArrayData *d)
+void SparseArrayData::destroy(Managed *d)
{
- delete static_cast<SparseArrayData *>(d)->sparse;
- delete [] d->data;
- if (d->attrs)
- delete [] d->attrs;
- delete d;
+ SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ delete dd->sparse;
+ delete [] dd->data;
+ if (dd->attrs)
+ delete [] dd->attrs;
}
-void SparseArrayData::markObjects(ArrayData *d, ExecutionEngine *e)
+void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
{
- uint l = d->alloc;
+ SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ uint l = dd->alloc;
for (uint i = 0; i < l; ++i)
- d->data[i].mark(e);
+ dd->data[i].mark(e);
}
void SparseArrayData::reserve(ArrayData *d, uint n)
if (!sparse->sparse->nEntries())
return;
- SimpleArrayData *d = new SimpleArrayData;
+ SimpleArrayData *d = new (context->engine->memoryManager) SimpleArrayData(context->engine);
thisObject->arrayData = d;
- d->vtable->reserve(d, sparse->sparse->nEntries());
+ d->vtable()->reserve(d, sparse->sparse->nEntries());
SparseArrayNode *n = sparse->sparse->begin();
uint i = 0;
}
}
-
- sparse->ArrayData::destroy();
+ // ### explicitly delete sparse
} else {
SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
if (len > d->len)
namespace QV4 {
+#define V4_ARRAYDATA \
+ public: \
+ Q_MANAGED_CHECK \
+ static const QV4::ArrayVTable 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); } \
+
struct ArrayData;
struct ArrayVTable
{
+ ManagedVTable managedVTable;
uint type;
- void (*destroy)(ArrayData *d);
- void (*markObjects)(ArrayData *, ExecutionEngine *e);
void (*reserve)(ArrayData *d, uint n);
ReturnedValue (*get)(const ArrayData *d, uint index);
bool (*put)(ArrayData *d, uint index, ValueRef value);
};
-struct Q_QML_EXPORT ArrayData
+struct Q_QML_EXPORT ArrayData : public Managed
{
- ArrayData()
- : vtable(0)
+ ArrayData(InternalClass *ic)
+ : Managed(ic)
, alloc(0)
, type(0)
, attrs(0)
Custom = 3
};
- const ArrayVTable *vtable;
uint alloc;
uint type;
PropertyAttributes *attrs;
SafeValue *data;
+ const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
bool isSparse() const { return this && type == Sparse; }
uint length() const {
if (!this)
return 0;
- return vtable->length(this);
+ return vtable()->length(this);
}
bool hasAttributes() const {
void ensureAttributes();
PropertyAttributes attributes(int i) const {
Q_ASSERT(this);
- return attrs ? vtable->attribute(this, i) : Attr_Data;
+ return attrs ? vtable()->attribute(this, i) : Attr_Data;
}
void setAttributes(uint i, PropertyAttributes a) {
Q_ASSERT(this);
if (attrs || a != Attr_Data) {
ensureAttributes();
a.resolve();
- vtable->setAttribute(this, i, a);
+ vtable()->setAttribute(this, i, a);
}
}
bool isEmpty(uint i) const {
if (!this)
return true;
- return (vtable->get(this, i) == Primitive::emptyValue().asReturnedValue());
+ return (vtable()->get(this, i) == Primitive::emptyValue().asReturnedValue());
}
- inline void destroy() {
- vtable->destroy(this);
- }
-
- inline void markObjects(ExecutionEngine *e) {
- vtable->markObjects(this, e);
- }
-
inline void push_front(SafeValue *values, uint nValues) {
- vtable->push_front(this, values, nValues);
+ vtable()->push_front(this, values, nValues);
}
inline ReturnedValue pop_front() {
- return vtable->pop_front(this);
+ return vtable()->pop_front(this);
}
inline uint push_back(uint l, uint n, SafeValue *values) {
- vtable->putArray(this, l, values, n);
+ vtable()->putArray(this, l, values, n);
return length();
}
inline bool deleteIndex(uint index) {
- return vtable->del(this, index);
+ return vtable()->del(this, index);
}
inline uint truncate(uint newLen) {
if (!this)
return newLen;
- return vtable->truncate(this, newLen);
+ return vtable()->truncate(this, newLen);
}
bool put(uint index, ValueRef value) {
- return vtable->put(this, index, value);
+ return vtable()->put(this, index, value);
}
bool put(uint index, SafeValue *values, uint n) {
- return vtable->putArray(this, index, values, n);
+ return vtable()->putArray(this, index, values, n);
}
ReturnedValue get(uint i) const {
if (!this)
return Primitive::emptyValue().asReturnedValue();
- return vtable->get(this, i);
+ return vtable()->get(this, i);
}
inline Property *getProperty(uint index) const;
struct Q_QML_EXPORT SimpleArrayData : public ArrayData
{
- SimpleArrayData()
- : ArrayData()
+ V4_ARRAYDATA
+
+ SimpleArrayData(ExecutionEngine *engine)
+ : ArrayData(engine->emptyClass)
, len(0)
, offset(0)
- { vtable = &static_vtbl; }
+ { setVTable(staticVTable()); }
uint len;
uint offset;
static void getHeadRoom(ArrayData *d);
static void reserve(ArrayData *d, uint n);
- static void destroy(ArrayData *d);
- static void markObjects(ArrayData *d, ExecutionEngine *e);
+ static void destroy(Managed *d);
+ static void markObjects(Managed *d, ExecutionEngine *e);
static ReturnedValue get(const ArrayData *d, uint index);
static bool put(ArrayData *d, uint index, ValueRef value);
static ReturnedValue pop_front(ArrayData *d);
static uint truncate(ArrayData *d, uint newLen);
static uint length(const ArrayData *d);
-
- static const ArrayVTable static_vtbl;
-
};
struct Q_QML_EXPORT SparseArrayData : public ArrayData
{
- SparseArrayData()
- : freeList(0)
+ V4_ARRAYDATA
+
+ SparseArrayData(ExecutionEngine *engine)
+ : ArrayData(engine->emptyClass)
+ , freeList(0)
, sparse(0)
- { vtable = &static_vtbl; }
+ { setVTable(staticVTable()); }
uint freeList;
SparseArray *sparse;
static uint allocate(ArrayData *d, bool doubleSlot = false);
static void free(ArrayData *d, uint idx);
- static void destroy(ArrayData *d);
- static void markObjects(ArrayData *d, ExecutionEngine *e);
+ static void destroy(Managed *d);
+ static void markObjects(Managed *d, ExecutionEngine *e);
static void reserve(ArrayData *d, uint n);
static ReturnedValue get(const ArrayData *d, uint index);
static ReturnedValue pop_front(ArrayData *d);
static uint truncate(ArrayData *d, uint newLen);
static uint length(const ArrayData *d);
-
- static const ArrayVTable static_vtbl;
};
using namespace QV4;
-const ManagedVTable ExecutionContext::static_vtbl =
-{
- ExecutionContext::IsExecutionContext,
- ExecutionContext::IsString,
- ExecutionContext::IsObject,
- ExecutionContext::IsFunctionObject,
- ExecutionContext::IsErrorObject,
- 0,
- ExecutionContext::MyType,
- "ExecutionContext",
- destroy,
- markObjects,
- isEqualTo
-};
+DEFINE_MANAGED_VTABLE(ExecutionContext);
CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
{
Managed::IsObject,
Managed::IsFunctionObject,
Managed::IsErrorObject,
+ Managed::IsArrayData,
0,
Managed::MyType,
"Managed",
uint isObject : 1;
uint isFunctionObject : 1;
uint isErrorObject : 1;
- uint unused : 19;
+ uint isArrayData : 1;
+ uint unused : 18;
uint type : 8;
const char *className;
void (*destroy)(Managed *);
void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
};
-#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::ManagedVTable classname::static_vtbl = \
+#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, \
+ isEqualTo \
}
+#define DEFINE_MANAGED_VTABLE(classname) \
+const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
+
+
#define DEFINE_OBJECT_VTABLE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- { \
- classname::IsExecutionContext, \
- classname::IsString, \
- classname::IsObject, \
- classname::IsFunctionObject, \
- classname::IsErrorObject, \
- 0, \
- classname::MyType, \
- #classname, \
- destroy, \
- markObjects, \
- isEqualTo, \
- }, \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
call, \
construct, \
0, \
#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- { \
- classname::IsExecutionContext, \
- classname::IsString, \
- classname::IsObject, \
- classname::IsFunctionObject, \
- classname::IsErrorObject, \
- 0, \
- classname::MyType, \
- #name, \
- destroy, \
- markObjects, \
- isEqualTo, \
- }, \
+ DEFINE_MANAGED_VTABLE_INT(name), \
call, \
construct, \
0, \
#define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- { \
- classname::IsExecutionContext, \
- classname::IsString, \
- classname::IsObject, \
- classname::IsFunctionObject, \
- classname::IsErrorObject, \
- 0, \
- classname::MyType, \
- #classname, \
- destroy, \
- markObjects, \
- isEqualTo, \
- }, \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
call, \
construct, \
collectDeletables, \
IsString = false,
IsObject = false,
IsFunctionObject = false,
- IsErrorObject = false
+ IsErrorObject = false,
+ IsArrayData = false
};
private:
void *operator new(size_t);
{
if (memberData != inlineProperties)
delete [] memberData;
- if (arrayData)
- arrayData->destroy();
_data = 0;
}
}
}
if (o->arrayData)
- o->arrayData->markObjects(e);
+ o->arrayData->mark(e);
}
void Object::ensureMemberIndex(uint idx)
Q_ASSERT(!arrayData && other->arrayData);
if (other->arrayType() == ArrayData::Sparse) {
SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData);
- SparseArrayData *dd = new SparseArrayData;
+ SparseArrayData *dd = new (engine()->memoryManager) SparseArrayData(engine());
dd->type = ArrayData::Sparse;
dd->sparse = new SparseArray(*od->sparse);
dd->freeList = od->freeList;
if (arrayType() == ArrayData::Sparse)
return;
- SparseArrayData *data = new SparseArrayData;
+ SparseArrayData *data = new (engine()->memoryManager) SparseArrayData(engine());
data->type = ArrayData::Sparse;
data->sparse = new SparseArray;
if (!arrayData) {
data->alloc = simple->alloc;
simple->data = 0;
simple->attrs = 0;
- delete simple;
+ // ### explicitly free old data? delete simple;
arrayData = data;
uint *lastFree = &data->freeList;
inline void arrayReserve(uint n) {
arrayCreate();
- arrayData->vtable->reserve(arrayData, n);
+ arrayData->vtable()->reserve(arrayData, n);
}
void arrayCreate() {
if (!arrayData)
- arrayData = new SimpleArrayData;
+ arrayData = new (engine()->memoryManager) SimpleArrayData(engine());
#ifdef CHECK_SPARSE_ARRAYS
initSparseArray();
#endif
} else if (index > 0x1000 && index > 2*arrayData->alloc) {
initSparseArray();
} else {
- arrayData->vtable->reserve(arrayData, index + 1);
+ arrayData->vtable()->reserve(arrayData, index + 1);
}
arrayData->setAttributes(index, attributes);
Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
const ObjectVTable String::static_vtbl =
{
- {
- String::IsExecutionContext,
- String::IsString,
- String::IsObject,
- String::IsFunctionObject,
- String::IsErrorObject,
- 0,
- String::MyType,
- "String",
- destroy,
- markObjects,
- isEqualTo
- },
+ DEFINE_MANAGED_VTABLE_INT(String),
0,
0,
0 /*collectDeletables*/,