diff options
Diffstat (limited to 'src/qml/jsruntime')
74 files changed, 663 insertions, 1634 deletions
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index ef44ca6f4d..5c63ac1728 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -10,7 +10,6 @@ SOURCES += \ $$PWD/qv4lookup.cpp \ $$PWD/qv4identifier.cpp \ $$PWD/qv4identifiertable.cpp \ - $$PWD/qv4mm.cpp \ $$PWD/qv4managed.cpp \ $$PWD/qv4internalclass.cpp \ $$PWD/qv4sparsearray.cpp \ @@ -57,7 +56,6 @@ HEADERS += \ $$PWD/qv4lookup_p.h \ $$PWD/qv4identifier_p.h \ $$PWD/qv4identifiertable_p.h \ - $$PWD/qv4mm_p.h \ $$PWD/qv4managed_p.h \ $$PWD/qv4internalclass_p.h \ $$PWD/qv4sparsearray_p.h \ diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 92c77570af..d0c18cf9fd 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -40,7 +40,7 @@ DEFINE_OBJECT_VTABLE(ArgumentsObject); Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context) : Heap::Object(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass, - context->d()->engine->objectPrototype.asObject()) + context->d()->engine->objectPrototype.objectValue()) , context(context->d()) , fullyCreated(false) { @@ -144,9 +144,9 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con return result; } -ReturnedValue ArgumentsObject::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue ArgumentsObject::getIndexed(const Managed *m, uint index, bool *hasProperty) { - ArgumentsObject *args = static_cast<ArgumentsObject *>(m); + const ArgumentsObject *args = static_cast<const ArgumentsObject *>(m); if (args->fullyCreated()) return Object::getIndexed(m, index, hasProperty); @@ -199,11 +199,11 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index) DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction); -ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData) +ReturnedValue ArgumentsGetterFunction::call(const Managed *getter, CallData *callData) { - ExecutionEngine *v4 = static_cast<ArgumentsGetterFunction *>(getter)->engine(); + ExecutionEngine *v4 = static_cast<const ArgumentsGetterFunction *>(getter)->engine(); Scope scope(v4); - Scoped<ArgumentsGetterFunction> g(scope, static_cast<ArgumentsGetterFunction *>(getter)); + Scoped<ArgumentsGetterFunction> g(scope, static_cast<const ArgumentsGetterFunction *>(getter)); Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>()); if (!o) return v4->throwTypeError(); @@ -214,11 +214,11 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData) DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction); -ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData) +ReturnedValue ArgumentsSetterFunction::call(const Managed *setter, CallData *callData) { - ExecutionEngine *v4 = static_cast<ArgumentsSetterFunction *>(setter)->engine(); + ExecutionEngine *v4 = static_cast<const ArgumentsSetterFunction *>(setter)->engine(); Scope scope(v4); - Scoped<ArgumentsSetterFunction> s(scope, static_cast<ArgumentsSetterFunction *>(setter)); + Scoped<ArgumentsSetterFunction> s(scope, static_cast<const ArgumentsSetterFunction *>(setter)); Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>()); if (!o) return v4->throwTypeError(); diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 43cd6d1dee..b49962db07 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -71,7 +71,7 @@ struct ArgumentsGetterFunction: FunctionObject V4_OBJECT2(ArgumentsGetterFunction, FunctionObject) uint index() const { return d()->index; } - static ReturnedValue call(Managed *that, CallData *d); + static ReturnedValue call(const Managed *that, CallData *d); }; inline @@ -86,7 +86,7 @@ struct ArgumentsSetterFunction: FunctionObject V4_OBJECT2(ArgumentsSetterFunction, FunctionObject) uint index() const { return d()->index; } - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; inline @@ -111,7 +111,7 @@ struct ArgumentsObject: Object { } bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs); - static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static void putIndexed(Managed *m, uint index, const Value &value); static bool deleteIndexedProperty(Managed *m, uint index); static PropertyAttributes queryIndexed(const Managed *m, uint index); diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index 11664f1194..145e400c20 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -44,9 +44,9 @@ Heap::ArrayBufferCtor::ArrayBufferCtor(QV4::ExecutionContext *scope) { } -ReturnedValue ArrayBufferCtor::construct(Managed *m, CallData *callData) +ReturnedValue ArrayBufferCtor::construct(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(m)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); Scope scope(v4); ScopedValue l(scope, callData->argument(0)); @@ -64,7 +64,7 @@ ReturnedValue ArrayBufferCtor::construct(Managed *m, CallData *callData) } -ReturnedValue ArrayBufferCtor::call(Managed *that, CallData *callData) +ReturnedValue ArrayBufferCtor::call(const Managed *that, CallData *callData) { return construct(that, callData); } @@ -83,7 +83,7 @@ ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx) Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, size_t length) - : Heap::Object(e->emptyClass, e->arrayBufferPrototype.asObject()) + : Heap::Object(e->emptyClass, e->arrayBufferPrototype.objectValue()) { data = QTypedArrayData<char>::allocate(length + 1); if (!data) { @@ -96,7 +96,7 @@ Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, size_t length) } Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, const QByteArray& array) - : Heap::Object(e->emptyClass, e->arrayBufferPrototype.asObject()) + : Heap::Object(e->emptyClass, e->arrayBufferPrototype.as<QV4::Object>()) , data(const_cast<QByteArray&>(array).data_ptr()) { data->ref.ref(); diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index fe3150618d..a7f9e92c80 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -61,8 +61,8 @@ struct ArrayBufferCtor: FunctionObject { V4_OBJECT2(ArrayBufferCtor, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); static ReturnedValue method_isView(CallContext *ctx); diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 737c891f9b..d653b5c886 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -33,13 +33,13 @@ #include "qv4arraydata_p.h" #include "qv4object_p.h" #include "qv4functionobject_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4runtime_p.h" #include "qv4argumentsobject_p.h" using namespace QV4; -const QV4::ManagedVTable QV4::ArrayData::static_vtbl = { +const QV4::VTable QV4::ArrayData::static_vtbl = { 0, QV4::ArrayData::IsExecutionContext, QV4::ArrayData::IsString, @@ -231,7 +231,7 @@ ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index) bool SimpleArrayData::put(Object *o, uint index, const Value &value) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor()); // ### honour attributes dd->data(index) = value; @@ -245,7 +245,7 @@ bool SimpleArrayData::put(Object *o, uint index, const Value &value) bool SimpleArrayData::del(Object *o, uint index) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (index >= dd->len) return true; @@ -267,12 +267,12 @@ void SimpleArrayData::setAttribute(Object *o, uint index, PropertyAttributes att void SimpleArrayData::push_front(Object *o, const Value *values, uint n) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); Q_ASSERT(!dd->attrs); if (dd->len + n > dd->alloc) { realloc(o, Heap::ArrayData::Simple, dd->len + n, false); Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Simple); - dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); } dd->offset = (dd->offset - n) % dd->alloc; dd->len += n; @@ -282,7 +282,7 @@ void SimpleArrayData::push_front(Object *o, const Value *values, uint n) ReturnedValue SimpleArrayData::pop_front(Object *o) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); Q_ASSERT(!dd->attrs); if (!dd->len) return Encode::undefined(); @@ -295,7 +295,7 @@ ReturnedValue SimpleArrayData::pop_front(Object *o) uint SimpleArrayData::truncate(Object *o, uint newLen) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (dd->len < newLen) return newLen; @@ -319,10 +319,10 @@ uint SimpleArrayData::length(const Heap::ArrayData *d) bool SimpleArrayData::putArray(Object *o, uint index, const Value *values, uint n) { - Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (index + n > dd->alloc) { reallocate(o, index + n + 1, false); - dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); } for (uint i = dd->len; i < index; ++i) dd->data(i) = Primitive::emptyValue(); @@ -370,13 +370,13 @@ Heap::ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttr uint SparseArrayData::allocate(Object *o, bool doubleSlot) { Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse); - Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (doubleSlot) { uint *last = &dd->freeList; while (1) { if (*last == UINT_MAX) { reallocate(o, dd->alloc + 2, true); - dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); last = &dd->freeList; Q_ASSERT(*last != UINT_MAX); } @@ -394,7 +394,7 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot) } else { if (dd->freeList == UINT_MAX) { reallocate(o, dd->alloc + 1, false); - dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + dd = o->d()->arrayData.cast<Heap::SimpleArrayData>(); } uint idx = dd->freeList; Q_ASSERT(idx != UINT_MAX); @@ -419,12 +419,12 @@ bool SparseArrayData::put(Object *o, uint index, const Value &value) if (value.isEmpty()) return true; - Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *s = o->d()->arrayData.cast<Heap::SparseArrayData>(); SparseArrayNode *n = s->sparse->insert(index); Q_ASSERT(n->value == UINT_MAX || !s->attrs || !s->attrs[n->value].isAccessor()); if (n->value == UINT_MAX) n->value = allocate(o); - s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + s = o->d()->arrayData.cast<Heap::SparseArrayData>(); s->arrayData[n->value] = value; if (s->attrs) s->attrs[n->value] = Attr_Data; @@ -433,7 +433,7 @@ bool SparseArrayData::put(Object *o, uint index, const Value &value) bool SparseArrayData::del(Object *o, uint index) { - Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *dd = o->d()->arrayData.cast<Heap::SparseArrayData>(); SparseArrayNode *n = dd->sparse->findNode(index); if (!n) @@ -469,28 +469,28 @@ bool SparseArrayData::del(Object *o, uint index) void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs) { - Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>(); SparseArrayNode *n = d->sparse->insert(index); if (n->value == UINT_MAX) { n->value = allocate(o, attrs.isAccessor()); - d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + d = o->d()->arrayData.cast<Heap::SparseArrayData>(); } else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) { // need to convert the slot free(o->arrayData(), n->value); n->value = allocate(o, attrs.isAccessor()); - d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + d = o->d()->arrayData.cast<Heap::SparseArrayData>(); } d->attrs[n->value] = attrs; } void SparseArrayData::push_front(Object *o, const Value *values, uint n) { - Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>(); Q_ASSERT(!d->attrs); for (int i = n - 1; i >= 0; --i) { uint idx = allocate(o); - d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + d = o->d()->arrayData.cast<Heap::SparseArrayData>(); d->arrayData[idx] = values[i]; d->sparse->push_front(idx); } @@ -498,7 +498,7 @@ void SparseArrayData::push_front(Object *o, const Value *values, uint n) ReturnedValue SparseArrayData::pop_front(Object *o) { - Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>(); Q_ASSERT(!d->attrs); uint idx = d->sparse->pop_front(); ReturnedValue v; @@ -513,7 +513,7 @@ ReturnedValue SparseArrayData::pop_front(Object *o) uint SparseArrayData::truncate(Object *o, uint newLen) { - Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>(); SparseArrayNode *begin = d->sparse->lowerBound(newLen); if (begin != d->sparse->end()) { SparseArrayNode *it = d->sparse->end()->previousNode(); @@ -607,11 +607,11 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n) Property *ArrayData::insert(Object *o, uint index, bool isAccessor) { if (!isAccessor && o->d()->arrayData->type != Heap::ArrayData::Sparse) { - Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *d = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (index < 0x1000 || index < d->len + (d->len >> 2)) { if (index >= d->alloc) { o->arrayReserve(index + 1); - d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + d = o->d()->arrayData.cast<Heap::SimpleArrayData>(); } if (index >= d->len) { // mark possible hole in the array @@ -624,11 +624,11 @@ Property *ArrayData::insert(Object *o, uint index, bool isAccessor) } o->initSparseArray(); - Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *s = o->d()->arrayData.cast<Heap::SparseArrayData>(); SparseArrayNode *n = s->sparse->insert(index); if (n->value == UINT_MAX) n->value = SparseArrayData::allocate(o, isAccessor); - s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + s = o->d()->arrayData.cast<Heap::SparseArrayData>(); return reinterpret_cast<Property *>(s->arrayData + n->value); } @@ -738,7 +738,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c if (!arrayData || !arrayData->length()) return; - if (!(comparefn.isUndefined() || comparefn.asObject())) { + if (!(comparefn.isUndefined() || comparefn.as<Object>())) { engine->throwTypeError(); return; } @@ -756,7 +756,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c thisObject->setArrayData(0); ArrayData::realloc(thisObject, Heap::ArrayData::Simple, sparse->sparse()->nEntries(), sparse->attrs() ? true : false); - Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData); + Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>(); SparseArrayNode *n = sparse->sparse()->begin(); uint i = 0; @@ -796,7 +796,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c } } else { - Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData); + Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>(); if (len > d->len) len = d->len; diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index 915e862bbb..667827d1e9 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -47,7 +47,7 @@ namespace QV4 { Q_MANAGED_CHECK \ typedef QV4::Heap::DataClass Data; \ static const QV4::ArrayVTable static_vtbl; \ - static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \ + static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ V4_MANAGED_SIZE_TEST \ const Data *d() const { return static_cast<const Data *>(m); } \ Data *d() { return static_cast<Data *>(m); } @@ -57,7 +57,7 @@ struct ArrayData; struct ArrayVTable { - ManagedVTable managedVTable; + VTable vTable; uint type; Heap::ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes); ReturnedValue (*get)(const Heap::ArrayData *d, uint index); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 231eb93dd5..707d4640a7 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -47,9 +47,9 @@ Heap::ArrayCtor::ArrayCtor(QV4::ExecutionContext *scope) { } -ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData) +ReturnedValue ArrayCtor::construct(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = static_cast<ArrayCtor *>(m)->engine(); + ExecutionEngine *v4 = static_cast<const ArrayCtor *>(m)->engine(); Scope scope(v4); ScopedArrayObject a(scope, v4->newArrayObject()); uint len; @@ -72,7 +72,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData) return a.asReturnedValue(); } -ReturnedValue ArrayCtor::call(Managed *that, CallData *callData) +ReturnedValue ArrayCtor::call(const Managed *that, CallData *callData) { return construct(that, callData); } @@ -110,7 +110,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx) { - bool isArray = ctx->argc() && ctx->args()[0].asArrayObject(); + bool isArray = ctx->argc() && ctx->args()[0].as<ArrayObject>(); return Encode(isArray); } @@ -194,7 +194,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx) QString R; // ### FIXME - if (ArrayObject *a = self->asArrayObject()) { + if (ArrayObject *a = self->as<ArrayObject>()) { ScopedValue e(scope); for (uint i = 0; i < a->getLength(); ++i) { if (i) @@ -619,7 +619,7 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx) return Encode(-1); } else { Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex); - Heap::SimpleArrayData *sa = static_cast<Heap::SimpleArrayData *>(instance->d()->arrayData); + Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>(); if (len > sa->len) len = sa->len; uint idx = fromIndex; diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index 4e67eb2e31..422a0de675 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -53,8 +53,8 @@ struct ArrayCtor: FunctionObject { V4_OBJECT2(ArrayCtor, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct ArrayPrototype: ArrayObject diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index 9c293e783b..a70e45068a 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qv4booleanobject_p.h" +#include "qv4string_p.h" using namespace QV4; @@ -43,14 +44,14 @@ Heap::BooleanCtor::BooleanCtor(QV4::ExecutionContext *scope) { } -ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData) +ReturnedValue BooleanCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<BooleanCtor *>(m)->engine()); + Scope scope(static_cast<const BooleanCtor *>(m)->engine()); bool n = callData->argc ? callData->args[0].toBoolean() : false; return Encode(scope.engine->newBooleanObject(n)); } -ReturnedValue BooleanCtor::call(Managed *, CallData *callData) +ReturnedValue BooleanCtor::call(const Managed *, CallData *callData) { bool value = callData->argc ? callData->args[0].toBoolean() : 0; return Encode(value); @@ -73,7 +74,7 @@ ReturnedValue BooleanPrototype::method_toString(CallContext *ctx) if (ctx->thisObject().isBoolean()) { result = ctx->thisObject().booleanValue(); } else { - BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>(); + const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>(); if (!thisObject) return ctx->engine()->throwTypeError(); result = thisObject->value(); @@ -87,7 +88,7 @@ ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx) if (ctx->thisObject().isBoolean()) return ctx->thisObject().asReturnedValue(); - BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>(); + const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>(); if (!thisObject) return ctx->engine()->throwTypeError(); diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h index 903261bdce..77b5a74fde 100644 --- a/src/qml/jsruntime/qv4booleanobject_p.h +++ b/src/qml/jsruntime/qv4booleanobject_p.h @@ -53,8 +53,8 @@ struct BooleanCtor: FunctionObject { V4_OBJECT2(BooleanCtor, FunctionObject) - static ReturnedValue construct(Managed *, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct BooleanPrototype: BooleanObject diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 9330f10780..0ef7d56c4d 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -36,10 +36,11 @@ #include <qv4context_p.h> #include <qv4object_p.h> #include <qv4objectproto_p.h> -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include <qv4argumentsobject_p.h> #include "qv4function_p.h" #include "qv4errorobject_p.h" +#include "qv4string_p.h" using namespace QV4; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 8392dd836d..cf229d4221 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -45,6 +45,7 @@ struct CompilationUnit; struct Function; } +struct Identifier; struct CallContext; struct CatchContext; struct WithContext; @@ -160,7 +161,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed static void markObjects(Heap::Base *m, ExecutionEngine *e); - const Value &thisObject() const { + Value &thisObject() const { return d()->callData->thisObject; } int argc() const { diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 8a66c2cbfc..9f87f4270b 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -46,9 +46,9 @@ Heap::DataViewCtor::DataViewCtor(QV4::ExecutionContext *scope) { } -ReturnedValue DataViewCtor::construct(Managed *m, CallData *callData) +ReturnedValue DataViewCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<Object *>(m)->engine()); + Scope scope(static_cast<const Object *>(m)->engine()); Scoped<ArrayBuffer> buffer(scope, callData->argument(0)); if (!buffer) return scope.engine->throwTypeError(); @@ -69,14 +69,14 @@ ReturnedValue DataViewCtor::construct(Managed *m, CallData *callData) } -ReturnedValue DataViewCtor::call(Managed *that, CallData *callData) +ReturnedValue DataViewCtor::call(const Managed *that, CallData *callData) { return construct(that, callData); } Heap::DataView::DataView(ExecutionEngine *e) - : Heap::Object(e->emptyClass, e->dataViewPrototype.asObject()), + : Heap::Object(e->emptyClass, e->dataViewPrototype.objectValue()), buffer(0), byteLength(0), byteOffset(0) diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index 3f0c1e9e23..3f352883b8 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -59,8 +59,8 @@ struct DataViewCtor: FunctionObject { V4_OBJECT2(DataViewCtor, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct DataView : Object diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 451ef2486d..cb48f0871e 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -628,7 +628,7 @@ static double getLocalTZA() DEFINE_OBJECT_VTABLE(DateObject); Heap::DateObject::DateObject(QV4::ExecutionEngine *engine, const QDateTime &date) - : Heap::Object(engine->emptyClass, engine->datePrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->datePrototype.objectValue()) { value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN()); } @@ -645,9 +645,9 @@ Heap::DateCtor::DateCtor(QV4::ExecutionContext *scope) { } -ReturnedValue DateCtor::construct(Managed *m, CallData *callData) +ReturnedValue DateCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<DateCtor *>(m)->engine()); + Scope scope(static_cast<const DateCtor *>(m)->engine()); double t = 0; if (callData->argc == 0) @@ -655,7 +655,7 @@ ReturnedValue DateCtor::construct(Managed *m, CallData *callData) else if (callData->argc == 1) { ScopedValue arg(scope, callData->args[0]); - if (DateObject *d = arg->asDateObject()) + if (DateObject *d = arg->as<DateObject>()) arg = d->date(); else arg = RuntimeHelpers::toPrimitive(arg, PREFERREDTYPE_HINT); @@ -683,10 +683,10 @@ ReturnedValue DateCtor::construct(Managed *m, CallData *callData) return Encode(scope.engine->newDateObject(Primitive::fromDouble(t))); } -ReturnedValue DateCtor::call(Managed *m, CallData *) +ReturnedValue DateCtor::call(const Managed *m, CallData *) { double t = currentTime(); - return static_cast<DateCtor *>(m)->engine()->newString(ToString(t))->asReturnedValue(); + return static_cast<const DateCtor *>(m)->engine()->newString(ToString(t))->asReturnedValue(); } void DatePrototype::init(ExecutionEngine *engine, Object *ctor) @@ -752,7 +752,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor) double DatePrototype::getThisDate(ExecutionContext *ctx) { - if (DateObject *thisObject = ctx->thisObject().asDateObject()) + if (DateObject *thisObject = ctx->thisObject().as<DateObject>()) return thisObject->date().asDouble(); else { ctx->engine()->throwTypeError(); @@ -1013,7 +1013,7 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1025,7 +1025,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx) ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1039,7 +1039,7 @@ ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1053,7 +1053,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx) ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1068,7 +1068,7 @@ ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1083,7 +1083,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx) ReturnedValue DatePrototype::method_setHours(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1099,7 +1099,7 @@ ReturnedValue DatePrototype::method_setHours(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1115,7 +1115,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx) ReturnedValue DatePrototype::method_setDate(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1128,7 +1128,7 @@ ReturnedValue DatePrototype::method_setDate(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1141,7 +1141,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx) ReturnedValue DatePrototype::method_setMonth(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1155,7 +1155,7 @@ ReturnedValue DatePrototype::method_setMonth(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1169,7 +1169,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx) ReturnedValue DatePrototype::method_setYear(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1195,7 +1195,7 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx) ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1210,7 +1210,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx) ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1227,7 +1227,7 @@ ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx) ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1250,7 +1250,7 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits) ReturnedValue DatePrototype::method_toISOString(CallContext *ctx) { - DateObject *self = ctx->thisObject().asDateObject(); + DateObject *self = ctx->thisObject().as<DateObject>(); if (!self) return ctx->engine()->throwTypeError(); @@ -1297,7 +1297,7 @@ ReturnedValue DatePrototype::method_toJSON(CallContext *ctx) ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString"))); ScopedValue v(scope, O->objectValue()->get(s)); - FunctionObject *toIso = v->asFunctionObject(); + FunctionObject *toIso = v->as<FunctionObject>(); if (!toIso) return ctx->engine()->throwTypeError(); diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index dad3689054..a4c508a628 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -53,7 +53,7 @@ struct DateObject : Object { } DateObject(QV4::ExecutionEngine *engine, const Value &date) - : Object(engine->emptyClass, engine->datePrototype.asObject()) + : Object(engine->emptyClass, engine->datePrototype.objectValue()) { value = date; } @@ -61,6 +61,7 @@ struct DateObject : Object { Value value; }; + struct DateCtor : FunctionObject { DateCtor(QV4::ExecutionContext *scope); }; @@ -79,12 +80,17 @@ struct DateObject: Object { QDateTime toQDateTime() const; }; +template<> +inline const DateObject *Value::as() const { + return isManaged() && m && m->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0; +} + struct DateCtor: FunctionObject { V4_OBJECT2(DateCtor, FunctionObject) - static ReturnedValue construct(Managed *, CallData *callData); - static ReturnedValue call(Managed *that, CallData *); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *); }; struct DatePrototype: DateObject diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 36e7a3558c..5f1194c39f 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -793,7 +793,7 @@ void Debugger::Collector::collect(const QString &name, const ScopedValue &value) addBoolean(name, value->booleanValue()); break; case Value::Managed_Type: - if (String *s = value->asString()) + if (const String *s = value->as<String>()) addString(name, s->toQString()); else addObject(name, value); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index cbfac86e9f..8859f73bd7 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -48,7 +48,7 @@ #include <qv4regexp_p.h> #include <qv4variantobject_p.h> #include <qv4runtime_p.h> -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include <qv4argumentsobject_p.h> #include <qv4dateobject_p.h> #include <qv4jsonobject_p.h> @@ -286,7 +286,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) objectPrototype = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0); arrayClass = emptyClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable); - arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.asObject()); + arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.as<Object>()); InternalClass *argsClass = emptyClass->addMember(id_length, Attr_NotEnumerable); argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable); @@ -297,15 +297,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) Q_ASSERT(globalObject()->d()->vtable); initRootContext(); - stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype.asObject()); - numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype.asObject()); - booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype.asObject()); - datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype.asObject()); + stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype.as<Object>()); + numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype.as<Object>()); + booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype.as<Object>()); + datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype.as<Object>()); uint index; InternalClass *functionProtoClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); - functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.asObject()); + functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.as<Object>()); functionClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); simpleScriptFunctionClass = functionClass->addMember(id_name, Attr_ReadOnly, &index); @@ -321,18 +321,18 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayInput); - errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype.asObject()); - evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype.asObject()); - rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype.asObject()); - referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype.asObject()); - syntaxErrorPrototype = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype.asObject()); - typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype.asObject()); - uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype.asObject()); + errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype.as<Object>()); + evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype.as<Object>()); + rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype.as<Object>()); + referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype.as<Object>()); + syntaxErrorPrototype = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype.as<Object>()); + typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype.as<Object>()); + uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype.as<Object>()); - variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype.asObject()); - Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject()->d()); + variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype.as<Object>()); + Q_ASSERT(variantPrototype.as<Object>()->prototype() == objectPrototype.as<Object>()->d()); - sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject())); + sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.as<Object>())); ScopedContext global(scope, rootContext()); objectCtor = memoryManager->alloc<ObjectCtor>(global); @@ -351,40 +351,40 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(global); uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(global); - static_cast<ObjectPrototype *>(objectPrototype.asObject())->init(this, objectCtor.asObject()); - static_cast<StringPrototype *>(stringPrototype.asObject())->init(this, stringCtor.asObject()); - static_cast<NumberPrototype *>(numberPrototype.asObject())->init(this, numberCtor.asObject()); - static_cast<BooleanPrototype *>(booleanPrototype.asObject())->init(this, booleanCtor.asObject()); - static_cast<ArrayPrototype *>(arrayPrototype.asObject())->init(this, arrayCtor.asObject()); - static_cast<DatePrototype *>(datePrototype.asObject())->init(this, dateCtor.asObject()); - static_cast<FunctionPrototype *>(functionPrototype.asObject())->init(this, functionCtor.asObject()); - static_cast<RegExpPrototype *>(regExpPrototype.asObject())->init(this, regExpCtor.asObject()); - static_cast<ErrorPrototype *>(errorPrototype.asObject())->init(this, errorCtor.asObject()); - static_cast<EvalErrorPrototype *>(evalErrorPrototype.asObject())->init(this, evalErrorCtor.asObject()); - static_cast<RangeErrorPrototype *>(rangeErrorPrototype.asObject())->init(this, rangeErrorCtor.asObject()); - static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.asObject())->init(this, referenceErrorCtor.asObject()); - static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.asObject())->init(this, syntaxErrorCtor.asObject()); - static_cast<TypeErrorPrototype *>(typeErrorPrototype.asObject())->init(this, typeErrorCtor.asObject()); - static_cast<URIErrorPrototype *>(uRIErrorPrototype.asObject())->init(this, uRIErrorCtor.asObject()); - - static_cast<VariantPrototype *>(variantPrototype.asObject())->init(); + static_cast<ObjectPrototype *>(objectPrototype.as<Object>())->init(this, objectCtor.as<Object>()); + static_cast<StringPrototype *>(stringPrototype.as<Object>())->init(this, stringCtor.as<Object>()); + static_cast<NumberPrototype *>(numberPrototype.as<Object>())->init(this, numberCtor.as<Object>()); + static_cast<BooleanPrototype *>(booleanPrototype.as<Object>())->init(this, booleanCtor.as<Object>()); + static_cast<ArrayPrototype *>(arrayPrototype.as<Object>())->init(this, arrayCtor.as<Object>()); + static_cast<DatePrototype *>(datePrototype.as<Object>())->init(this, dateCtor.as<Object>()); + static_cast<FunctionPrototype *>(functionPrototype.as<Object>())->init(this, functionCtor.as<Object>()); + static_cast<RegExpPrototype *>(regExpPrototype.as<Object>())->init(this, regExpCtor.as<Object>()); + static_cast<ErrorPrototype *>(errorPrototype.as<Object>())->init(this, errorCtor.as<Object>()); + static_cast<EvalErrorPrototype *>(evalErrorPrototype.as<Object>())->init(this, evalErrorCtor.as<Object>()); + static_cast<RangeErrorPrototype *>(rangeErrorPrototype.as<Object>())->init(this, rangeErrorCtor.as<Object>()); + static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.as<Object>())->init(this, referenceErrorCtor.as<Object>()); + static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.as<Object>())->init(this, syntaxErrorCtor.as<Object>()); + static_cast<TypeErrorPrototype *>(typeErrorPrototype.as<Object>())->init(this, typeErrorCtor.as<Object>()); + static_cast<URIErrorPrototype *>(uRIErrorPrototype.as<Object>())->init(this, uRIErrorCtor.as<Object>()); + + static_cast<VariantPrototype *>(variantPrototype.as<Object>())->init(); sequencePrototype.cast<SequencePrototype>()->init(); // typed arrays arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(global); - arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype.asObject()); - static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.asObject())->init(this, arrayBufferCtor.asObject()); + arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype.as<Object>()); + static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.as<Object>())->init(this, arrayBufferCtor.as<Object>()); dataViewCtor = memoryManager->alloc<DataViewCtor>(global); - dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype.asObject()); - static_cast<DataViewPrototype *>(dataViewPrototype.asObject())->init(this, dataViewCtor.asObject()); + dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype.as<Object>()); + static_cast<DataViewPrototype *>(dataViewPrototype.as<Object>())->init(this, dataViewCtor.as<Object>()); for (int i = 0; i < Heap::TypedArray::NTypes; ++i) { typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i)); typedArrayPrototype[i] = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i)); - typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject())); + typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>())); } // @@ -414,7 +414,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) globalObject()->defineDefaultProperty(QStringLiteral("DataView"), dataViewCtor); ScopedString str(scope); for (int i = 0; i < Heap::TypedArray::NTypes; ++i) - globalObject()->defineDefaultProperty((str = typedArrayCtors[i].asFunctionObject()->name())->toQString(), typedArrayCtors[i]); + globalObject()->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]); ScopedObject o(scope); globalObject()->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this))); globalObject()->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this))); @@ -640,7 +640,7 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re) Heap::Object *ExecutionEngine::newErrorObject(const Value &value) { Scope scope(this); - ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype.asObject(), value)); + ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype.as<Object>(), value)); return object->d(); } @@ -1185,7 +1185,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int Q_ASSERT (!value.isEmpty()); QV4::Scope scope(e); - if (QV4::VariantObject *v = value.as<QV4::VariantObject>()) + if (const QV4::VariantObject *v = value.as<QV4::VariantObject>()) return v->d()->data; if (typeHint == QVariant::Bool) @@ -1197,10 +1197,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int if (typeHint == qMetaTypeId<QJSValue>()) return QVariant::fromValue(QJSValue(e, value.asReturnedValue())); - if (value.asObject()) { + if (value.as<Object>()) { QV4::ScopedObject object(scope, value); if (typeHint == QMetaType::QJsonObject - && !value.asArrayObject() && !value.asFunctionObject()) { + && !value.as<ArrayObject>() && !value.as<FunctionObject>()) { return QVariant::fromValue(QV4::JsonObject::toJsonObject(object)); } else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) { return qVariantFromValue<QObject *>(wrapper->object()); @@ -1216,7 +1216,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return QV4::SequencePrototype::toVariant(object); } - if (value.asArrayObject()) { + if (value.as<ArrayObject>()) { QV4::ScopedArrayObject a(scope, value); if (typeHint == qMetaTypeId<QList<QObject *> >()) { QList<QObject *> list; @@ -1254,9 +1254,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return value.asDouble(); if (value.isString()) return value.stringValue()->toQString(); - if (QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) + if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) return ld->d()->locale; - if (QV4::DateObject *d = value.asDateObject()) + if (const QV4::DateObject *d = value.as<DateObject>()) return d->toQDateTime(); // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! @@ -1283,7 +1283,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an // empty object (and no error is thrown). - if (o->asArrayObject()) + if (o->as<ArrayObject>()) return QVariantList(); return QVariantMap(); } @@ -1291,7 +1291,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec QVariant result; - if (o->asArrayObject()) { + if (o->as<ArrayObject>()) { QV4::Scope scope(e); QV4::ScopedArrayObject a(scope, o->asReturnedValue()); QV4::ScopedValue v(scope); @@ -1304,7 +1304,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec } result = list; - } else if (!o->asFunctionObject()) { + } else if (!o->as<FunctionObject>()) { QVariantMap map; QV4::Scope scope(e); QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); @@ -1672,22 +1672,22 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da } return true; case QMetaType::QDateTime: - if (QV4::DateObject *d = value.asDateObject()) { + if (const QV4::DateObject *d = value.as<DateObject>()) { *reinterpret_cast<QDateTime *>(data) = d->toQDateTime(); return true; } break; case QMetaType::QDate: - if (QV4::DateObject *d = value.asDateObject()) { + if (const QV4::DateObject *d = value.as<DateObject>()) { *reinterpret_cast<QDate *>(data) = d->toQDateTime().date(); return true; } break; case QMetaType::QRegExp: - if (QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) { + if (const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) { *reinterpret_cast<QRegExp *>(data) = r->toQRegExp(); return true; } break; case QMetaType::QObjectStar: { - QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>(); + const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>(); if (qobjectWrapper || value.isNull()) { *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(scope.engine, value); return true; @@ -1766,7 +1766,7 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da } #endif - // Try to use magic; for compatibility with qscriptvalue_cast. + // Try to use magic; for compatibility with qjsvalue_cast. QByteArray name = QMetaType::typeName(type); if (convertToNativeQObject(this, value, name, reinterpret_cast<void* *>(data))) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index f01579be71..33dce48737 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -37,6 +37,8 @@ #include "private/qv4isel_p.h" #include "qv4managed_p.h" #include "qv4context_p.h" +#include "qv4string_p.h" +#include "qv4internalclass_p.h" #include <private/qintrusivelist_p.h> namespace WTF { diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 9034dee6a0..2c5795e8b3 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -33,11 +33,13 @@ #include "qv4errorobject_p.h" -#include "qv4mm_p.h" +#include <QtCore/qnumeric.h> +#include <QtCore/qmath.h> #include <QtCore/QDateTime> #include <QtCore/QStringList> #include <QtCore/QDebug> +#include <private/qv4mm_p.h> #include <private/qqmljsengine_p.h> #include <private/qqmljslexer_p.h> #include <private/qqmljsparser_p.h> @@ -179,57 +181,57 @@ DEFINE_OBJECT_VTABLE(ErrorObject); DEFINE_OBJECT_VTABLE(SyntaxErrorObject); Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const Value &msg) - : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.asObject(), msg, SyntaxError) + : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.objectValue(), msg, SyntaxError) { } Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber) - : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, SyntaxError) + : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.objectValue(), msg, fileName, lineNumber, columnNumber, SyntaxError) { } Heap::EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const Value &message) - : Heap::ErrorObject(engine->emptyClass, engine->evalErrorPrototype.asObject(), message, EvalError) + : Heap::ErrorObject(engine->emptyClass, engine->evalErrorPrototype.objectValue(), message, EvalError) { } Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const Value &message) - : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.asObject(), message, RangeError) + : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.objectValue(), message, RangeError) { } Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const QString &message) - : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.asObject(), message, RangeError) + : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.objectValue(), message, RangeError) { } Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const Value &message) - : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError) + : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.objectValue(), message, ReferenceError) { } Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &message) - : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError) + : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.objectValue(), message, ReferenceError) { } Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber) - : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, ReferenceError) + : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.objectValue(), msg, fileName, lineNumber, columnNumber, ReferenceError) { } Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const Value &message) - : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.asObject(), message, TypeError) + : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.objectValue(), message, TypeError) { } Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const QString &message) - : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.asObject(), message, TypeError) + : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.objectValue(), message, TypeError) { } Heap::URIErrorObject::URIErrorObject(ExecutionEngine *engine, const Value &message) - : Heap::ErrorObject(engine->emptyClass, engine->uRIErrorPrototype.asObject(), message, URIError) + : Heap::ErrorObject(engine->emptyClass, engine->uRIErrorPrototype.objectValue(), message, URIError) { } @@ -251,16 +253,16 @@ Heap::ErrorCtor::ErrorCtor(QV4::ExecutionContext *scope, const QString &name) { } -ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue ErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<ErrorCtor *>(m)->engine()); + Scope scope(static_cast<const ErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return Encode(scope.engine->newErrorObject(v)); } -ReturnedValue ErrorCtor::call(Managed *that, CallData *callData) +ReturnedValue ErrorCtor::call(const Managed *that, CallData *callData) { - return static_cast<Object *>(that)->construct(callData); + return static_cast<const Object *>(that)->construct(callData); } Heap::EvalErrorCtor::EvalErrorCtor(QV4::ExecutionContext *scope) @@ -268,9 +270,9 @@ Heap::EvalErrorCtor::EvalErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue EvalErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<EvalErrorCtor *>(m)->engine()); + Scope scope(static_cast<const EvalErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<EvalErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -280,9 +282,9 @@ Heap::RangeErrorCtor::RangeErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue RangeErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<RangeErrorCtor *>(m)->engine()); + Scope scope(static_cast<const RangeErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<RangeErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -292,9 +294,9 @@ Heap::ReferenceErrorCtor::ReferenceErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue ReferenceErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<ReferenceErrorCtor *>(m)->engine()); + Scope scope(static_cast<const ReferenceErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<ReferenceErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -304,9 +306,9 @@ Heap::SyntaxErrorCtor::SyntaxErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue SyntaxErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<SyntaxErrorCtor *>(m)->engine()); + Scope scope(static_cast<const SyntaxErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<SyntaxErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -316,9 +318,9 @@ Heap::TypeErrorCtor::TypeErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue TypeErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<TypeErrorCtor *>(m)->engine()); + Scope scope(static_cast<const TypeErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<TypeErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -328,9 +330,9 @@ Heap::URIErrorCtor::URIErrorCtor(QV4::ExecutionContext *scope) { } -ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData) +ReturnedValue URIErrorCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<URIErrorCtor *>(m)->engine()); + Scope scope(static_cast<const URIErrorCtor *>(m)->engine()); ScopedValue v(scope, callData->argument(0)); return (scope.engine->memoryManager->alloc<URIErrorObject>(scope.engine, v))->asReturnedValue(); } @@ -351,7 +353,7 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx) { Scope scope(ctx); - Object *o = ctx->thisObject().asObject(); + Object *o = ctx->thisObject().as<Object>(); if (!o) return ctx->engine()->throwTypeError(); diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 071f5b8c9a..e26654e931 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -141,8 +141,8 @@ struct ErrorObject: Object { }; template<> -inline ErrorObject *value_cast(const Value &v) { - return v.asErrorObject(); +inline const ErrorObject *Value::as() const { + return isManaged() && m && m->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0; } struct EvalErrorObject: ErrorObject { @@ -183,50 +183,50 @@ struct ErrorCtor: FunctionObject { V4_OBJECT2(ErrorCtor, FunctionObject) - static ReturnedValue construct(Managed *, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct EvalErrorCtor: ErrorCtor { V4_OBJECT2(EvalErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct RangeErrorCtor: ErrorCtor { V4_OBJECT2(RangeErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct ReferenceErrorCtor: ErrorCtor { V4_OBJECT2(ReferenceErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct SyntaxErrorCtor: ErrorCtor { V4_OBJECT2(SyntaxErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct TypeErrorCtor: ErrorCtor { V4_OBJECT2(TypeErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct URIErrorCtor: ErrorCtor { V4_OBJECT2(URIErrorCtor, ErrorCtor) - static ReturnedValue construct(Managed *m, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index efe6c7c226..8f737c995b 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -37,7 +37,7 @@ #include "qv4value_inl_p.h" #include "qv4engine_p.h" #include "qv4lookup_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 0a12d013ac..5a68cf6b79 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -37,7 +37,7 @@ #include "qv4objectproto_p.h" #include "qv4stringobject_p.h" #include "qv4function_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4arrayobject_p.h" #include "qv4scopedvalue_p.h" @@ -63,7 +63,7 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(FunctionObject); Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto) - : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject()) + : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.objectValue()) , scope(scope->d()) , function(Q_NULLPTR) { @@ -73,7 +73,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String * } Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *function, bool createProto) - : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject()) + : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.objectValue()) , scope(scope->d()) , function(Q_NULLPTR) { @@ -84,7 +84,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *fun } Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto) - : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject()) + : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.objectValue()) , scope(scope->d()) , function(Q_NULLPTR) { @@ -95,7 +95,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString } Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto) - : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject()) + : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.objectValue()) , scope(scope) , function(Q_NULLPTR) { @@ -106,7 +106,7 @@ Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &nam } Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name) - : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject()) + : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.objectValue()) , scope(scope->d()) , function(Q_NULLPTR) { @@ -117,7 +117,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const Returne } Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name) - : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject()) + : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.objectValue()) , scope(scope) , function(Q_NULLPTR) { @@ -152,7 +152,7 @@ void FunctionObject::init(String *n, bool createProto) ensureMemberIndex(s.engine, Heap::FunctionObject::Index_Prototype); if (createProto) { - ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype.asObject())); + ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype.as<Object>())); proto->ensureMemberIndex(s.engine, Heap::FunctionObject::Index_ProtoConstructor); proto->memberData()->data[Heap::FunctionObject::Index_ProtoConstructor] = this->asReturnedValue(); memberData()->data[Heap::FunctionObject::Index_Prototype] = proto.asReturnedValue(); @@ -164,7 +164,7 @@ void FunctionObject::init(String *n, bool createProto) defineReadonlyProperty(s.engine->id_name, v); } -ReturnedValue FunctionObject::name() +ReturnedValue FunctionObject::name() const { return get(scope()->engine->id_name); } @@ -177,13 +177,12 @@ ReturnedValue FunctionObject::newInstance() return construct(callData); } -ReturnedValue FunctionObject::construct(Managed *that, CallData *) +ReturnedValue FunctionObject::construct(const Managed *that, CallData *) { - static_cast<FunctionObject *>(that)->internalClass()->engine->throwTypeError(); - return Encode::undefined(); + return static_cast<const FunctionObject *>(that)->engine()->throwTypeError(); } -ReturnedValue FunctionObject::call(Managed *, CallData *) +ReturnedValue FunctionObject::call(const Managed *, CallData *) { return Encode::undefined(); } @@ -237,10 +236,10 @@ Heap::FunctionCtor::FunctionCtor(QV4::ExecutionContext *scope) } // 15.3.2 -ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData) +ReturnedValue FunctionCtor::construct(const Managed *that, CallData *callData) { - Scope scope(static_cast<Object *>(that)->engine()); - Scoped<FunctionCtor> f(scope, static_cast<FunctionCtor *>(that)); + Scope scope(static_cast<const Object *>(that)->engine()); + Scoped<FunctionCtor> f(scope, static_cast<const FunctionCtor *>(that)); ScopedContext ctx(scope, scope.engine->currentContext()); QString arguments; QString body; @@ -287,7 +286,7 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData) } // 15.3.1: This is equivalent to new Function(...) -ReturnedValue FunctionCtor::call(Managed *that, CallData *callData) +ReturnedValue FunctionCtor::call(const Managed *that, CallData *callData) { return construct(that, callData); } @@ -318,7 +317,7 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) ReturnedValue FunctionPrototype::method_toString(CallContext *ctx) { - FunctionObject *fun = ctx->thisObject().asFunctionObject(); + FunctionObject *fun = ctx->thisObject().as<FunctionObject>(); if (!fun) return ctx->engine()->throwTypeError(); @@ -328,7 +327,7 @@ ReturnedValue FunctionPrototype::method_toString(CallContext *ctx) ReturnedValue FunctionPrototype::method_apply(CallContext *ctx) { Scope scope(ctx); - ScopedFunctionObject o(scope, ctx->thisObject().asFunctionObject()); + ScopedFunctionObject o(scope, ctx->thisObject().as<FunctionObject>()); if (!o) return ctx->engine()->throwTypeError(); @@ -370,7 +369,7 @@ ReturnedValue FunctionPrototype::method_call(CallContext *ctx) { Scope scope(ctx); - ScopedFunctionObject o(scope, ctx->thisObject().asFunctionObject()); + ScopedFunctionObject o(scope, ctx->thisObject().as<FunctionObject>()); if (!o) return ctx->engine()->throwTypeError(); @@ -409,15 +408,15 @@ Heap::ScriptFunction::ScriptFunction(QV4::ExecutionContext *scope, Function *fun { } -ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData) +ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(that)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(that)->engine(); if (v4->hasException) return Encode::undefined(); CHECK_STACK_LIMITS(v4); Scope scope(v4); - Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that)); + Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that)); InternalClass *ic = scope.engine->emptyClass; ScopedObject proto(scope, f->protoForConstructor()); @@ -441,15 +440,15 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData) return obj.asReturnedValue(); } -ReturnedValue ScriptFunction::call(Managed *that, CallData *callData) +ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(that)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(that)->engine(); if (v4->hasException) return Encode::undefined(); CHECK_STACK_LIMITS(v4); Scope scope(v4); - Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that)); + Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that)); ScopedContext context(scope, v4->currentContext()); Scoped<CallContext> ctx(scope, context->newCallContext(f, callData)); @@ -466,7 +465,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData) DEFINE_OBJECT_VTABLE(SimpleScriptFunction); Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto) - : Heap::FunctionObject(function->compilationUnit->engine->simpleScriptFunctionClass, function->compilationUnit->engine->functionPrototype.asObject()) + : Heap::FunctionObject(function->compilationUnit->engine->simpleScriptFunctionClass, function->compilationUnit->engine->functionPrototype.as<QV4::Object>()) { this->scope = scope->d(); @@ -497,15 +496,15 @@ Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, F } } -ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) +ReturnedValue SimpleScriptFunction::construct(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(that)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(that)->engine(); if (v4->hasException) return Encode::undefined(); CHECK_STACK_LIMITS(v4); Scope scope(v4); - Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that)); + Scoped<SimpleScriptFunction> f(scope, static_cast<const SimpleScriptFunction *>(that)); InternalClass *ic = scope.engine->emptyClass; ScopedObject proto(scope, f->protoForConstructor()); @@ -536,15 +535,15 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) return result.asReturnedValue(); } -ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) +ReturnedValue SimpleScriptFunction::call(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = static_cast<SimpleScriptFunction *>(that)->internalClass()->engine; + ExecutionEngine *v4 = static_cast<const SimpleScriptFunction *>(that)->internalClass()->engine; if (v4->hasException) return Encode::undefined(); CHECK_STACK_LIMITS(v4); Scope scope(v4); - Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that)); + Scoped<SimpleScriptFunction> f(scope, static_cast<const SimpleScriptFunction *>(that)); ExecutionContextSaver ctxSaver(scope, v4->currentContext()); @@ -575,7 +574,7 @@ Heap::Object *SimpleScriptFunction::protoForConstructor() ScopedObject p(scope, protoProperty()); if (p) return p->d(); - return scope.engine->objectPrototype.asObject()->d(); + return scope.engine->objectPrototype.as<Object>()->d(); } @@ -588,14 +587,14 @@ Heap::BuiltinFunction::BuiltinFunction(QV4::ExecutionContext *scope, QV4::String { } -ReturnedValue BuiltinFunction::construct(Managed *f, CallData *) +ReturnedValue BuiltinFunction::construct(const Managed *f, CallData *) { - return static_cast<BuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); + return static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); } -ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData) +ReturnedValue BuiltinFunction::call(const Managed *that, CallData *callData) { - BuiltinFunction *f = static_cast<BuiltinFunction *>(that); + const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that); ExecutionEngine *v4 = f->internalClass()->engine; if (v4->hasException) return Encode::undefined(); @@ -614,9 +613,9 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData) return f->d()->code(sctx); } -ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) +ReturnedValue IndexedBuiltinFunction::call(const Managed *that, CallData *callData) { - IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that); + const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that); ExecutionEngine *v4 = f->internalClass()->engine; if (v4->hasException) return Encode::undefined(); @@ -665,9 +664,9 @@ Heap::BoundFunction::BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionOb f->insertMember(s.engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); } -ReturnedValue BoundFunction::call(Managed *that, CallData *dd) +ReturnedValue BoundFunction::call(const Managed *that, CallData *dd) { - BoundFunction *f = static_cast<BoundFunction *>(that); + const BoundFunction *f = static_cast<const BoundFunction *>(that); Scope scope(f->engine()); if (scope.hasException()) return Encode::undefined(); @@ -685,9 +684,9 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd) return t->call(callData); } -ReturnedValue BoundFunction::construct(Managed *that, CallData *dd) +ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd) { - BoundFunction *f = static_cast<BoundFunction *>(that); + const BoundFunction *f = static_cast<const BoundFunction *>(that); Scope scope(f->engine()); if (scope.hasException()) return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 252ff40a1a..2aa5d95831 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -36,7 +36,7 @@ #include "qv4object_p.h" #include "qv4function_p.h" #include "qv4context_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> QT_BEGIN_NAMESPACE @@ -117,10 +117,10 @@ struct Q_QML_EXPORT FunctionObject: Object { Q_MANAGED_TYPE(FunctionObject) V4_NEEDS_DESTROY - Heap::ExecutionContext *scope() { return d()->scope; } - Function *function() { return d()->function; } + Heap::ExecutionContext *scope() const { return d()->scope; } + Function *function() const { return d()->function; } - ReturnedValue name(); + ReturnedValue name() const; unsigned int formalParameterCount() { return d()->formalParameterCount(); } unsigned int varCount() { return d()->varCount(); } @@ -130,12 +130,8 @@ struct Q_QML_EXPORT FunctionObject: Object { using Object::construct; using Object::call; - static ReturnedValue construct(Managed *that, CallData *); - static ReturnedValue call(Managed *that, CallData *d); - - static FunctionObject *cast(const Value &v) { - return v.asFunctionObject(); - } + static ReturnedValue construct(const Managed *that, CallData *); + static ReturnedValue call(const Managed *that, CallData *d); static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true); @@ -152,16 +148,17 @@ struct Q_QML_EXPORT FunctionObject: Object { }; template<> -inline FunctionObject *value_cast(const Value &v) { - return v.asFunctionObject(); +inline const FunctionObject *Value::as() const { + return isManaged() && m && m->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0; } + struct FunctionCtor: FunctionObject { V4_OBJECT2(FunctionCtor, FunctionObject) - static ReturnedValue construct(Managed *that, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct FunctionPrototype: FunctionObject @@ -184,20 +181,20 @@ struct Q_QML_EXPORT BuiltinFunction: FunctionObject { return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code); } - static ReturnedValue construct(Managed *, CallData *); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct IndexedBuiltinFunction: FunctionObject { V4_OBJECT2(IndexedBuiltinFunction, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *) + static ReturnedValue construct(const Managed *m, CallData *) { - return static_cast<IndexedBuiltinFunction *>(m)->engine()->throwTypeError(); + return static_cast<const IndexedBuiltinFunction *>(m)->engine()->throwTypeError(); } - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; Heap::IndexedBuiltinFunction::IndexedBuiltinFunction(QV4::ExecutionContext *scope, uint index, @@ -212,8 +209,8 @@ Heap::IndexedBuiltinFunction::IndexedBuiltinFunction(QV4::ExecutionContext *scop struct SimpleScriptFunction: FunctionObject { V4_OBJECT2(SimpleScriptFunction, FunctionObject) - static ReturnedValue construct(Managed *, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); Heap::Object *protoForConstructor(); }; @@ -221,8 +218,8 @@ struct SimpleScriptFunction: FunctionObject { struct ScriptFunction: SimpleScriptFunction { V4_OBJECT2(ScriptFunction, FunctionObject) - static ReturnedValue construct(Managed *, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; @@ -234,12 +231,12 @@ struct BoundFunction: FunctionObject { return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs); } - Heap::FunctionObject *target() { return d()->target; } + Heap::FunctionObject *target() const { return d()->target; } Value boundThis() const { return d()->boundThis; } Heap::MemberData *boundArgs() const { return d()->boundArgs; } - static ReturnedValue construct(Managed *, CallData *d); - static ReturnedValue call(Managed *that, CallData *dd); + static ReturnedValue construct(const Managed *, CallData *d); + static ReturnedValue call(const Managed *that, CallData *dd); static void markObjects(Heap::Base *that, ExecutionEngine *e); }; diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 4b08194b60..3385547710 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -168,7 +168,7 @@ struct Property; struct Value; struct Lookup; struct ArrayData; -struct ManagedVTable; +struct VTable; struct BooleanObject; struct NumberObject; diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 8e33cec57f..b4ab122b98 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qv4globalobject_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4value_inl_p.h" #include "qv4context_p.h" #include "qv4function_p.h" @@ -346,7 +346,7 @@ Heap::EvalFunction::EvalFunction(QV4::ExecutionContext *scope) f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(1)); } -ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) +ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const { if (callData->argc < 1) return Encode::undefined(); @@ -399,10 +399,10 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) } -ReturnedValue EvalFunction::call(Managed *that, CallData *callData) +ReturnedValue EvalFunction::call(const Managed *that, CallData *callData) { // indirect call - return static_cast<EvalFunction *>(that)->evalCall(callData, false); + return static_cast<const EvalFunction *>(that)->evalCall(callData, false); } diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h index 74de233b47..ba1d5d2e0b 100644 --- a/src/qml/jsruntime/qv4globalobject_p.h +++ b/src/qml/jsruntime/qv4globalobject_p.h @@ -52,10 +52,10 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject { V4_OBJECT2(EvalFunction, FunctionObject) - ReturnedValue evalCall(CallData *callData, bool directCall); + ReturnedValue evalCall(CallData *callData, bool directCall) const; using Object::construct; - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct GlobalFunctions diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index e4bd460966..ed7ace9ed1 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -54,7 +54,7 @@ QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine, QQmlContex : v4(engine), m_network(0), m_reply(0), m_url(url), m_redirectCount(0), m_context(context) { m_qmlglobal.set(engine, qmlglobal); - if (callback.asFunctionObject()) + if (callback.as<QV4::FunctionObject>()) m_callbackFunction.set(engine, callback); m_resultObject.set(v4, resultValue(v4)); @@ -94,7 +94,7 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) { if (!callback.isObject()) return; - QV4::ExecutionEngine *v4 = callback.asObject()->engine(); + QV4::ExecutionEngine *v4 = callback.as<QV4::Object>()->engine(); QV4::Scope scope(v4); QV4::ScopedFunctionObject f(scope, callback); if (!f) @@ -184,7 +184,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx) QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow())); QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue()); - if (ctx->argc() >= 2 && ctx->args()[1].asFunctionObject()) + if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>()) callbackFunction = ctx->args()[1]; QString localFile = QQmlFile::urlToLocalFileOrQrc(url); @@ -224,7 +224,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx) QV4::ScopedValue ex(scope, scope.engine->catchException()); result = resultValue(scope.engine, Exception); QV4::ScopedString exception(scope, scope.engine->newString(QStringLiteral("exception"))); - result->asObject()->put(exception, ex); + result->as<QV4::Object>()->put(exception, ex); } else { result = resultValue(scope.engine, Ok); } diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 3289058cb7..80590fe72e 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -46,7 +46,7 @@ struct String; struct ExecutionEngine; struct Object; struct Identifier; -struct ManagedVTable; +struct VTable; struct PropertyHashData; struct PropertyHash diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index e7905974df..f6e9f5a3d1 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -39,7 +39,6 @@ #include <qv4scopedvalue_p.h> #include <qv4runtime_p.h> -#include <qjsondocument.h> #include <qstack.h> #include <qstringlist.h> @@ -62,33 +61,6 @@ static int indent = 0; DEFINE_OBJECT_VTABLE(JsonObject); -class JsonParser -{ -public: - JsonParser(ExecutionEngine *engine, const QChar *json, int length); - - ReturnedValue parse(QJsonParseError *error); - -private: - inline bool eatSpace(); - inline QChar nextToken(); - - ReturnedValue parseObject(); - ReturnedValue parseArray(); - bool parseMember(Object *o); - bool parseString(QString *string); - bool parseValue(Value *val); - bool parseNumber(Value *val); - - ExecutionEngine *engine; - const QChar *head; - const QChar *json; - const QChar *end; - - int nestingLevel; - QJsonParseError::ParseError lastError; -}; - static const int nestingLimit = 1024; @@ -728,11 +700,11 @@ QString Stringify::Str(const QString &key, const Value &v) o = value->asReturnedValue(); if (o) { - if (NumberObject *n = o->asNumberObject()) + if (NumberObject *n = o->as<NumberObject>()) value = Encode(n->value()); - else if (StringObject *so = o->asStringObject()) + else if (StringObject *so = o->as<StringObject>()) value = so->d()->value; - else if (BooleanObject *b =o->asBooleanObject()) + else if (BooleanObject *b = o->as<BooleanObject>()) value = Encode(b->value()); } @@ -750,8 +722,8 @@ QString Stringify::Str(const QString &key, const Value &v) o = value->asReturnedValue(); if (o) { - if (!o->asFunctionObject()) { - if (o->asArrayObject()) { + if (!o->as<FunctionObject>()) { + if (o->as<ArrayObject>()) { return JA(static_cast<ArrayObject *>(o.getPointer())); } else { return JO(o); @@ -879,7 +851,7 @@ QString Stringify::JA(ArrayObject *a) Heap::JsonObject::JsonObject(ExecutionEngine *e) - : Heap::Object(e->emptyClass, e->objectPrototype.asObject()) + : Heap::Object(e->emptyClass, e->objectPrototype.objectValue()) { Scope scope(e); ScopedObject o(scope, this); @@ -915,13 +887,13 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx) ScopedObject o(scope, ctx->argument(1)); if (o) { - stringify.replacerFunction = o->asFunctionObject(); + stringify.replacerFunction = o->as<FunctionObject>(); if (o->isArrayObject()) { uint arrayLen = o->getLength(); ScopedValue v(scope); for (uint i = 0; i < arrayLen; ++i) { v = o->getIndexed(i); - if (v->asNumberObject() || v->asStringObject() || v->isNumber()) + if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber()) v = RuntimeHelpers::toString(scope.engine, v); if (v->isString()) { String *s = v->stringValue(); @@ -933,9 +905,9 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx) } ScopedValue s(scope, ctx->argument(2)); - if (NumberObject *n = s->asNumberObject()) + if (NumberObject *n = s->as<NumberObject>()) s = Encode(n->value()); - else if (StringObject *so = s->asStringObject()) + else if (StringObject *so = s->as<StringObject>()) s = so->d()->value; if (s->isNumber()) { @@ -986,7 +958,7 @@ QJsonValue JsonObject::toJsonValue(const Value &value, V4ObjectSet &visitedObjec return QJsonValue(value.toQString()); Q_ASSERT(value.isObject()); - Scope scope(value.asObject()->engine()); + Scope scope(value.as<Object>()->engine()); ScopedArrayObject a(scope, value); if (a) return toJsonArray(a, visitedObjects); @@ -1012,7 +984,7 @@ QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJs QJsonObject JsonObject::toJsonObject(Object *o, V4ObjectSet &visitedObjects) { QJsonObject result; - if (!o || o->asFunctionObject()) + if (!o || o->as<FunctionObject>()) return result; Scope scope(o->engine()); @@ -1035,7 +1007,7 @@ QJsonObject JsonObject::toJsonObject(Object *o, V4ObjectSet &visitedObjects) break; QString key = name->toQStringNoThrow(); - if (!val->asFunctionObject()) + if (!val->as<FunctionObject>()) result.insert(key, toJsonValue(val, visitedObjects)); } @@ -1078,7 +1050,7 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) quint32 length = a->getLength(); for (quint32 i = 0; i < length; ++i) { v = a->getIndexed(i); - if (v->asFunctionObject()) + if (v->as<FunctionObject>()) v = Encode::null(); result.append(toJsonValue(v, visitedObjects)); } diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h index 81a783ee92..b8b9cf3093 100644 --- a/src/qml/jsruntime/qv4jsonobject_p.h +++ b/src/qml/jsruntime/qv4jsonobject_p.h @@ -37,6 +37,7 @@ #include <qjsonarray.h> #include <qjsonobject.h> #include <qjsonvalue.h> +#include <qjsondocument.h> QT_BEGIN_NAMESPACE @@ -79,6 +80,33 @@ private: }; +class JsonParser +{ +public: + JsonParser(ExecutionEngine *engine, const QChar *json, int length); + + ReturnedValue parse(QJsonParseError *error); + +private: + inline bool eatSpace(); + inline QChar nextToken(); + + ReturnedValue parseObject(); + ReturnedValue parseArray(); + bool parseMember(Object *o); + bool parseString(QString *string); + bool parseValue(Value *val); + bool parseNumber(Value *val); + + ExecutionEngine *engine; + const QChar *head; + const QChar *json; + const QChar *end; + + int nestingLevel; + QJsonParseError::ParseError lastError; +}; + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 82b20337cb..d65d5c69da 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -72,7 +72,7 @@ ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttribu return Primitive::emptyValue().asReturnedValue(); } -ReturnedValue Lookup::lookup(Object *thisObject, PropertyAttributes *attrs) +ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs) { Heap::Object *obj = thisObject->d(); ExecutionEngine *engine = thisObject->engine(); @@ -123,7 +123,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons ScopedObject o(scope, object); if (!o) { if (idx < UINT_MAX) { - if (String *str = object.asString()) { + if (const String *str = object.as<String>()) { if (idx >= (uint)str->toQString().length()) { return Encode::undefined(); } @@ -168,7 +168,7 @@ ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, con Object *o = object.objectValue(); if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) { - Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (idx < s->len) if (!s->data(idx).isEmpty()) return s->data(idx).asReturnedValue(); @@ -200,7 +200,7 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value & uint idx = index.asArrayIndex(); if (idx < UINT_MAX) { if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) { - Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (idx < s->len) { s->data(idx) = value; return; @@ -224,7 +224,7 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value Object *o = object.objectValue(); if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) { - Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>(); if (idx < s->len) { s->data(idx) = v; return; @@ -235,7 +235,7 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object) { - if (Object *o = object.asObject()) + if (const Object *o = object.as<Object>()) return o->getLookup(l); Object *proto; @@ -244,11 +244,11 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va case Value::Null_Type: return engine->throwTypeError(); case Value::Boolean_Type: - proto = engine->booleanPrototype.asObject(); + proto = engine->booleanPrototype.as<Object>(); break; case Value::Managed_Type: { Q_ASSERT(object.isString()); - proto = engine->stringPrototype.asObject(); + proto = engine->stringPrototype.as<Object>(); Scope scope(engine); ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]); if (name->equals(engine->id_length)) { @@ -260,7 +260,7 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va } case Value::Integer_Type: default: // Number - proto = engine->numberPrototype.asObject(); + proto = engine->numberPrototype.as<Object>(); } PropertyAttributes attrs; @@ -291,7 +291,7 @@ ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Lookup l1 = *l; if (l1.getter == Lookup::getter0 || l1.getter == Lookup::getter1) { - if (Object *o = object.asObject()) { + if (const Object *o = object.as<Object>()) { ReturnedValue v = o->getLookup(l); Lookup l2 = *l; @@ -560,7 +560,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engin ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object) { - if (String *s = object.asString()) + if (const String *s = object.as<String>()) return Encode(s->d()->length()); l->getter = getterGeneric; @@ -569,7 +569,7 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, con ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object) { - if (ArrayObject *a = object.asArrayObject()) + if (const ArrayObject *a = object.as<ArrayObject>()) return a->memberData()->data[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue(); l->getter = getterGeneric; @@ -701,7 +701,7 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine) return globalGetterGeneric(l, engine); } -void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { Scope scope(engine); ScopedObject o(scope, object); @@ -716,11 +716,11 @@ void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &obje o->setLookup(l, value); } -void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { Lookup l1 = *l; - if (Object *o = object.asObject()) { + if (Object *o = object.as<Object>()) { o->setLookup(l, value); if (l->setter == Lookup::setter0) { @@ -735,7 +735,7 @@ void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &o setterFallback(l, engine, object, value); } -void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { QV4::Scope scope(engine); QV4::ScopedObject o(scope, object.toObject(scope.engine)); @@ -745,9 +745,9 @@ void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const Value &obj } } -void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Object *o = static_cast<Object *>(object.asManaged()); + Object *o = object.as<Object>(); if (o && o->internalClass() == l->classList[0]) { o->memberData()->data[l->index] = value; return; @@ -756,9 +756,9 @@ void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const Value &object, co setterTwoClasses(l, engine, object, value); } -void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Object *o = static_cast<Object *>(object.asManaged()); + Object *o = object.as<Object>(); if (o && o->internalClass() == l->classList[0]) { if (!o->prototype()) { if (!o->memberData() || l->index >= o->memberData()->size) @@ -773,9 +773,9 @@ void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &obje setterFallback(l, engine, object, value); } -void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Object *o = static_cast<Object *>(object.asManaged()); + Object *o = object.as<Object>(); if (o && o->internalClass() == l->classList[0]) { Heap::Object *p = o->prototype(); if (p && p->internalClass == l->classList[1]) { @@ -791,9 +791,9 @@ void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &obje setterFallback(l, engine, object, value); } -void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Object *o = static_cast<Object *>(object.asManaged()); + Object *o = object.as<Object>(); if (o && o->internalClass() == l->classList[0]) { Heap::Object *p = o->prototype(); if (p && p->internalClass == l->classList[1]) { @@ -812,9 +812,9 @@ void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &obje setterFallback(l, engine, object, value); } -void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value) +void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Object *o = static_cast<Object *>(object.asManaged()); + Object *o = object.as<Object>(); if (o) { if (o->internalClass() == l->classList[0]) { o->memberData()->data[l->index] = value; diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 88397dc36c..232e909c48 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -51,7 +51,7 @@ struct Lookup { void (*indexedSetter)(Lookup *l, const Value &object, const Value &index, const Value &v); ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object); ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine); - void (*setter)(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &v); + void (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v); }; union { ExecutionEngine *engine; @@ -107,17 +107,17 @@ struct Lookup { static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine); static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine); - static void setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setterFallback(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); - static void setter0setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value); + static void setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static void setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); ReturnedValue lookup(const Value &thisObject, Object *obj, PropertyAttributes *attrs); - ReturnedValue lookup(Object *obj, PropertyAttributes *attrs); + ReturnedValue lookup(const Object *obj, PropertyAttributes *attrs); }; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index c4b9fc597e..546190086e 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -32,13 +32,13 @@ ****************************************************************************/ #include "qv4managed_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4errorobject_p.h" using namespace QV4; -const ManagedVTable Managed::static_vtbl = +const VTable Managed::static_vtbl = { 0, Managed::IsExecutionContext, diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 0fe5c7ee49..a5d941e864 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -35,7 +35,7 @@ #include "qv4global_p.h" #include "qv4value_p.h" -#include "qv4internalclass_p.h" +#include <private/qv4heap_p.h> QT_BEGIN_NAMESPACE @@ -65,8 +65,8 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {} Q_MANAGED_CHECK \ typedef QV4::Heap::DataClass Data; \ typedef superClass SuperClass; \ - static const QV4::ManagedVTable static_vtbl; \ - static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \ + static const QV4::VTable static_vtbl; \ + static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \ V4_MANAGED_SIZE_TEST \ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); } @@ -86,23 +86,6 @@ struct GCDeletable bool lastCall; }; -struct ManagedVTable -{ - const ManagedVTable * const parent; - 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)(Heap::Base *); - void (*markObjects)(Heap::Base *, ExecutionEngine *e); - bool (*isEqualTo)(Managed *m, Managed *other); -}; - #define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \ { \ parentVTable, \ @@ -121,7 +104,7 @@ struct ManagedVTable } #define DEFINE_MANAGED_VTABLE(classname) \ -const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0) +const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0) struct Q_QML_PRIVATE_EXPORT Managed : Value { @@ -167,46 +150,6 @@ public: }; Q_MANAGED_TYPE(Invalid) - template <typename T> - T *as() { - Q_ASSERT(d()->vtable); -#if !defined(QT_NO_QOBJECT_CHECK) - static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this)); -#endif - const ManagedVTable *vt = d()->vtable; - while (vt) { - if (vt == T::staticVTable()) - return static_cast<T *>(this); - vt = vt->parent; - } - return 0; - } - template <typename T> - const T *as() const { - Q_ASSERT(d()->vtable); -#if !defined(QT_NO_QOBJECT_CHECK) - static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this))); -#endif - const ManagedVTable *vt = d()->vtable; - while (vt) { - if (vt == T::staticVTable()) - return static_cast<T *>(this); - vt = vt->parent; - } - return 0; - } - - String *asString() { return d()->vtable->isString ? reinterpret_cast<String *>(this) : 0; } - Object *asObject() { return d()->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; } - ArrayObject *asArrayObject() { return d()->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; } - FunctionObject *asFunctionObject() { return d()->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; } - BooleanObject *asBooleanObject() { return d()->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; } - NumberObject *asNumberObject() { return d()->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; } - StringObject *asStringObject() { return d()->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; } - DateObject *asDateObject() { return d()->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; } - ErrorObject *asErrorObject() { return d()->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; } - ArgumentsObject *asArgumentsObject() { return d()->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; } - bool isListType() const { return d()->vtable->type == Type_QmlSequence; } bool isArrayObject() const { return d()->vtable->type == Type_ArrayObject; } @@ -231,37 +174,15 @@ private: template<> -inline Managed *value_cast(const Value &v) { - return v.asManaged(); -} - -template<typename T> -inline T *managed_cast(Managed *m) -{ - return m ? m->as<T>() : 0; +inline const Managed *Value::as() const { + if (isManaged()) + return managed(); + return 0; } template<> -inline String *managed_cast(Managed *m) -{ - return m ? m->asString() : 0; -} -template<> -inline Object *managed_cast(Managed *m) -{ - return m ? m->asObject() : 0; -} -template<> -inline FunctionObject *managed_cast(Managed *m) -{ - return m ? m->asFunctionObject() : 0; -} - -inline Value Value::fromManaged(Managed *m) -{ - if (!m) - return QV4::Primitive::undefinedValue(); - return *m; +inline const Object *Value::as() const { + return isManaged() && m && m->vtable->isObject ? objectValue() : 0; } } diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 473e05bf88..4e51de9291 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -48,7 +48,7 @@ DEFINE_OBJECT_VTABLE(MathObject); static const double qt_PI = 2.0 * ::asin(1.0); Heap::MathObject::MathObject(ExecutionEngine *e) - : Heap::Object(e->emptyClass, e->objectPrototype.asObject()) + : Heap::Object(e->emptyClass, e->objectPrototype.objectValue()) { Scope scope(e); ScopedObject m(scope, this); diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 03dfee3dcf..9d85545c6a 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -32,7 +32,8 @@ ****************************************************************************/ #include "qv4memberdata_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> +#include "qv4value_inl_p.h" using namespace QV4; diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp deleted file mode 100644 index 07408a343c..0000000000 --- a/src/qml/jsruntime/qv4mm.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv4engine_p.h" -#include "qv4object_p.h" -#include "qv4objectproto_p.h" -#include "qv4mm_p.h" -#include "qv4qobjectwrapper_p.h" -#include <qqmlengine.h> -#include "PageAllocation.h" -#include "StdLibExtras.h" - -#include <QTime> -#include <QVector> -#include <QVector> -#include <QMap> - -#include <iostream> -#include <cstdlib> -#include <algorithm> -#include "qv4alloca_p.h" -#include "qv4profiling_p.h" - -#ifdef V4_USE_VALGRIND -#include <valgrind/valgrind.h> -#include <valgrind/memcheck.h> -#endif - -#if OS(QNX) -#include <sys/storage.h> // __tls() -#endif - -#if USE(PTHREADS) && HAVE(PTHREAD_NP_H) -#include <pthread_np.h> -#endif - -using namespace WTF; - -QT_BEGIN_NAMESPACE - -using namespace QV4; - -struct MemoryManager::Data -{ - struct ChunkHeader { - Heap::Base freeItems; - ChunkHeader *nextNonFull; - char *itemStart; - char *itemEnd; - int itemSize; - }; - - bool gcBlocked; - bool aggressiveGC; - bool gcStats; - ExecutionEngine *engine; - - enum { MaxItemSize = 512 }; - ChunkHeader *nonFullChunks[MaxItemSize/16]; - uint nChunks[MaxItemSize/16]; - uint availableItems[MaxItemSize/16]; - uint allocCount[MaxItemSize/16]; - int totalItems; - int totalAlloc; - uint maxShift; - std::size_t maxChunkSize; - QVector<PageAllocation> heapChunks; - - struct LargeItem { - LargeItem *next; - size_t size; - void *data; - - Heap::Base *heapObject() { - return reinterpret_cast<Heap::Base *>(&data); - } - }; - - LargeItem *largeItems; - std::size_t totalLargeItemsAllocated; - - GCDeletable *deletable; - - // statistics: -#ifdef DETAILED_MM_STATS - QVector<unsigned> allocSizeCounters; -#endif // DETAILED_MM_STATS - - Data() - : gcBlocked(false) - , engine(0) - , totalItems(0) - , totalAlloc(0) - , maxShift(6) - , maxChunkSize(32*1024) - , largeItems(0) - , totalLargeItemsAllocated(0) - , deletable(0) - { - memset(nonFullChunks, 0, sizeof(nonFullChunks)); - memset(nChunks, 0, sizeof(nChunks)); - memset(availableItems, 0, sizeof(availableItems)); - memset(allocCount, 0, sizeof(allocCount)); - aggressiveGC = !qgetenv("QV4_MM_AGGRESSIVE_GC").isEmpty(); - gcStats = !qgetenv("QV4_MM_STATS").isEmpty(); - - QByteArray overrideMaxShift = qgetenv("QV4_MM_MAXBLOCK_SHIFT"); - bool ok; - uint override = overrideMaxShift.toUInt(&ok); - if (ok && override <= 11 && override > 0) - maxShift = override; - - QByteArray maxChunkString = qgetenv("QV4_MM_MAX_CHUNK_SIZE"); - std::size_t tmpMaxChunkSize = maxChunkString.toUInt(&ok); - if (ok) - maxChunkSize = tmpMaxChunkSize; - } - - ~Data() - { - for (QVector<PageAllocation>::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) { - Q_V4_PROFILE_DEALLOC(engine, 0, i->size(), Profiling::HeapPage); - i->deallocate(); - } - } -}; - -namespace { - -bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine) -{ - bool isEmpty = true; - Heap::Base *tail = &header->freeItems; -// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4); -#ifdef V4_USE_VALGRIND - VALGRIND_DISABLE_ERROR_REPORTING; -#endif - for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) { - Heap::Base *m = reinterpret_cast<Heap::Base *>(item); -// qDebug("chunk @ %p, size = %lu, in use: %s, mark bit: %s", -// item, m->size, (m->inUse ? "yes" : "no"), (m->markBit ? "true" : "false")); - - Q_ASSERT((qintptr) item % 16 == 0); - - if (m->isMarked()) { - Q_ASSERT(m->inUse()); - m->clearMarkBit(); - isEmpty = false; - ++(*itemsInUse); - } else { - if (m->inUse()) { -// qDebug() << "-- collecting it." << m << tail << m->nextFree(); -#ifdef V4_USE_VALGRIND - VALGRIND_ENABLE_ERROR_REPORTING; -#endif - if (m->gcGetVtable()->destroy) - m->gcGetVtable()->destroy(m); - - memset(m, 0, header->itemSize); -#ifdef V4_USE_VALGRIND - VALGRIND_DISABLE_ERROR_REPORTING; - VALGRIND_MEMPOOL_FREE(engine->memoryManager, m); -#endif - Q_V4_PROFILE_DEALLOC(engine, m, header->itemSize, Profiling::SmallItem); - ++(*itemsInUse); - } - // Relink all free blocks to rewrite references to any released chunk. - tail->setNextFree(m); - tail = m; - } - } - tail->setNextFree(0); -#ifdef V4_USE_VALGRIND - VALGRIND_ENABLE_ERROR_REPORTING; -#endif - return isEmpty; -} - -} // namespace - -MemoryManager::MemoryManager(ExecutionEngine *engine) - : m_d(new Data) - , m_persistentValues(new PersistentValueStorage(engine)) - , m_weakValues(new PersistentValueStorage(engine)) -{ -#ifdef V4_USE_VALGRIND - VALGRIND_CREATE_MEMPOOL(this, 0, true); -#endif - m_d->engine = engine; -} - -Heap::Base *MemoryManager::allocData(std::size_t size) -{ - if (m_d->aggressiveGC) - runGC(); -#ifdef DETAILED_MM_STATS - willAllocate(size); -#endif // DETAILED_MM_STATS - - Q_ASSERT(size >= 16); - Q_ASSERT(size % 16 == 0); - - size_t pos = size >> 4; - - // doesn't fit into a small bucket - if (size >= MemoryManager::Data::MaxItemSize) { - if (m_d->totalLargeItemsAllocated > 8 * 1024 * 1024) - runGC(); - - // we use malloc for this - MemoryManager::Data::LargeItem *item = static_cast<MemoryManager::Data::LargeItem *>( - malloc(Q_V4_PROFILE_ALLOC(m_d->engine, size + sizeof(MemoryManager::Data::LargeItem), - Profiling::LargeItem))); - memset(item, 0, size + sizeof(MemoryManager::Data::LargeItem)); - item->next = m_d->largeItems; - item->size = size; - m_d->largeItems = item; - m_d->totalLargeItemsAllocated += size; - return item->heapObject(); - } - - Heap::Base *m = 0; - Data::ChunkHeader *header = m_d->nonFullChunks[pos]; - if (header) { - m = header->freeItems.nextFree(); - goto found; - } - - // try to free up space, otherwise allocate - if (m_d->allocCount[pos] > (m_d->availableItems[pos] >> 1) && m_d->totalAlloc > (m_d->totalItems >> 1) && !m_d->aggressiveGC) { - runGC(); - header = m_d->nonFullChunks[pos]; - if (header) { - m = header->freeItems.nextFree(); - goto found; - } - } - - // no free item available, allocate a new chunk - { - // allocate larger chunks at a time to avoid excessive GC, but cap at maximum chunk size (2MB by default) - uint shift = ++m_d->nChunks[pos]; - if (shift > m_d->maxShift) - shift = m_d->maxShift; - std::size_t allocSize = m_d->maxChunkSize*(size_t(1) << shift); - allocSize = roundUpToMultipleOf(WTF::pageSize(), allocSize); - PageAllocation allocation = PageAllocation::allocate( - Q_V4_PROFILE_ALLOC(m_d->engine, allocSize, Profiling::HeapPage), - OSAllocator::JSGCHeapPages); - m_d->heapChunks.append(allocation); - std::sort(m_d->heapChunks.begin(), m_d->heapChunks.end()); - - header = reinterpret_cast<Data::ChunkHeader *>(allocation.base()); - header->itemSize = int(size); - header->itemStart = reinterpret_cast<char *>(allocation.base()) + roundUpToMultipleOf(16, sizeof(Data::ChunkHeader)); - header->itemEnd = reinterpret_cast<char *>(allocation.base()) + allocation.size() - header->itemSize; - - header->nextNonFull = m_d->nonFullChunks[pos]; - m_d->nonFullChunks[pos] = header; - - Heap::Base *last = &header->freeItems; - for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) { - Heap::Base *o = reinterpret_cast<Heap::Base *>(item); - last->setNextFree(o); - last = o; - - } - last->setNextFree(0); - m = header->freeItems.nextFree(); - const size_t increase = (header->itemEnd - header->itemStart) / header->itemSize; - m_d->availableItems[pos] += uint(increase); - m_d->totalItems += int(increase); -#ifdef V4_USE_VALGRIND - VALGRIND_MAKE_MEM_NOACCESS(allocation.base(), allocSize); - VALGRIND_MEMPOOL_ALLOC(this, header, sizeof(Data::ChunkHeader)); -#endif - } - - found: -#ifdef V4_USE_VALGRIND - VALGRIND_MEMPOOL_ALLOC(this, m, size); -#endif - Q_V4_PROFILE_ALLOC(m_d->engine, size, Profiling::SmallItem); - - ++m_d->allocCount[pos]; - ++m_d->totalAlloc; - header->freeItems.setNextFree(m->nextFree()); - if (!header->freeItems.nextFree()) - m_d->nonFullChunks[pos] = header->nextNonFull; - return m; -} - -static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase) -{ - while (engine->jsStackTop > markBase) { - Heap::Base *h = engine->popForGC(); - Q_ASSERT (h->gcGetVtable()->markObjects); - h->gcGetVtable()->markObjects(h, engine); - } -} - -void MemoryManager::mark() -{ - Value *markBase = m_d->engine->jsStackTop; - - m_d->engine->markObjects(); - - m_persistentValues->mark(m_d->engine); - - collectFromJSStack(); - - // Preserve QObject ownership rules within JavaScript: A parent with c++ ownership - // keeps all of its children alive in JavaScript. - - // Do this _after_ collectFromStack to ensure that processing the weak - // managed objects in the loop down there doesn't make then end up as leftovers - // on the stack and thus always get collected. - for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { - if (!(*it).isManaged()) - continue; - if ((*it).managed()->d()->gcGetVtable() != QObjectWrapper::staticVTable()) - continue; - QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper*>((*it).managed()); - if (!qobjectWrapper) - continue; - QObject *qobject = qobjectWrapper->object(); - if (!qobject) - continue; - bool keepAlive = QQmlData::keepAliveDuringGarbageCollection(qobject); - - if (!keepAlive) { - if (QObject *parent = qobject->parent()) { - while (parent->parent()) - parent = parent->parent(); - - keepAlive = QQmlData::keepAliveDuringGarbageCollection(parent); - } - } - - if (keepAlive) - qobjectWrapper->mark(m_d->engine); - - if (m_d->engine->jsStackTop >= m_d->engine->jsStackLimit) - drainMarkStack(m_d->engine, markBase); - } - - drainMarkStack(m_d->engine, markBase); -} - -void MemoryManager::sweep(bool lastSweep) -{ - if (m_weakValues) { - for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { - if (Managed *m = (*it).asManaged()) { - if (!m->markBit()) - (*it) = Primitive::undefinedValue(); - } - } - } - - if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = m_d->engine->m_multiplyWrappedQObjects) { - for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) { - if (!it.value()->markBit()) - it = multiplyWrappedQObjects->erase(it); - else - ++it; - } - } - - bool *chunkIsEmpty = (bool *)alloca(m_d->heapChunks.size() * sizeof(bool)); - uint itemsInUse[MemoryManager::Data::MaxItemSize/16]; - memset(itemsInUse, 0, sizeof(itemsInUse)); - memset(m_d->nonFullChunks, 0, sizeof(m_d->nonFullChunks)); - - for (int i = 0; i < m_d->heapChunks.size(); ++i) { - Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base()); - chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], m_d->engine); - } - - QVector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin(); - for (int i = 0; i < m_d->heapChunks.size(); ++i) { - Q_ASSERT(chunkIter != m_d->heapChunks.end()); - Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(chunkIter->base()); - const size_t pos = header->itemSize >> 4; - const size_t decrease = (header->itemEnd - header->itemStart) / header->itemSize; - - // Release that chunk if it could have been spared since the last GC run without any difference. - if (chunkIsEmpty[i] && m_d->availableItems[pos] - decrease >= itemsInUse[pos]) { - Q_V4_PROFILE_DEALLOC(m_d->engine, 0, chunkIter->size(), Profiling::HeapPage); -#ifdef V4_USE_VALGRIND - VALGRIND_MEMPOOL_FREE(this, header); -#endif - --m_d->nChunks[pos]; - m_d->availableItems[pos] -= uint(decrease); - m_d->totalItems -= int(decrease); - chunkIter->deallocate(); - chunkIter = m_d->heapChunks.erase(chunkIter); - continue; - } else if (header->freeItems.nextFree()) { - header->nextNonFull = m_d->nonFullChunks[pos]; - m_d->nonFullChunks[pos] = header; - } - ++chunkIter; - } - - Data::LargeItem *i = m_d->largeItems; - Data::LargeItem **last = &m_d->largeItems; - while (i) { - Heap::Base *m = i->heapObject(); - Q_ASSERT(m->inUse()); - if (m->isMarked()) { - m->clearMarkBit(); - last = &i->next; - i = i->next; - continue; - } - if (m->gcGetVtable()->destroy) - m->gcGetVtable()->destroy(m); - - *last = i->next; - free(Q_V4_PROFILE_DEALLOC(m_d->engine, i, i->size + sizeof(Data::LargeItem), - Profiling::LargeItem)); - i = *last; - } - - GCDeletable *deletable = m_d->deletable; - m_d->deletable = 0; - while (deletable) { - GCDeletable *next = deletable->next; - deletable->lastCall = lastSweep; - delete deletable; - deletable = next; - } - - // some execution contexts are allocated on the stack, make sure we clear their markBit as well - if (!lastSweep) { - Heap::ExecutionContext *ctx = engine()->current; - while (ctx) { - ctx->clearMarkBit(); - ctx = ctx->parent; - } - } -} - -bool MemoryManager::isGCBlocked() const -{ - return m_d->gcBlocked; -} - -void MemoryManager::setGCBlocked(bool blockGC) -{ - m_d->gcBlocked = blockGC; -} - -void MemoryManager::runGC() -{ - if (m_d->gcBlocked) { -// qDebug() << "Not running GC."; - return; - } - - if (!m_d->gcStats) { - mark(); - sweep(); - } else { - const size_t totalMem = getAllocatedMem(); - - QTime t; - t.start(); - mark(); - int markTime = t.elapsed(); - t.restart(); - const size_t usedBefore = getUsedMem(); - int chunksBefore = m_d->heapChunks.size(); - sweep(); - const size_t usedAfter = getUsedMem(); - int sweepTime = t.elapsed(); - - qDebug() << "========== GC =========="; - qDebug() << "Marked object in" << markTime << "ms."; - qDebug() << "Sweeped object in" << sweepTime << "ms."; - qDebug() << "Allocated" << totalMem << "bytes in" << m_d->heapChunks.size() << "chunks."; - qDebug() << "Used memory before GC:" << usedBefore; - qDebug() << "Used memory after GC:" << usedAfter; - qDebug() << "Freed up bytes:" << (usedBefore - usedAfter); - qDebug() << "Released chunks:" << (chunksBefore - m_d->heapChunks.size()); - qDebug() << "======== End GC ========"; - } - - memset(m_d->allocCount, 0, sizeof(m_d->allocCount)); - m_d->totalAlloc = 0; - m_d->totalLargeItemsAllocated = 0; -} - -size_t MemoryManager::getUsedMem() const -{ - size_t usedMem = 0; - for (QVector<PageAllocation>::const_iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) { - Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(i->base()); - for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) { - Heap::Base *m = reinterpret_cast<Heap::Base *>(item); - Q_ASSERT((qintptr) item % 16 == 0); - if (m->inUse()) - usedMem += header->itemSize; - } - } - return usedMem; -} - -size_t MemoryManager::getAllocatedMem() const -{ - size_t total = 0; - for (int i = 0; i < m_d->heapChunks.size(); ++i) - total += m_d->heapChunks.at(i).size(); - return total; -} - -size_t MemoryManager::getLargeItemsMem() const -{ - size_t total = 0; - for (const Data::LargeItem *i = m_d->largeItems; i != 0; i = i->next) - total += i->size; - return total; -} - -MemoryManager::~MemoryManager() -{ - delete m_persistentValues; - delete m_weakValues; - m_weakValues = 0; - - sweep(/*lastSweep*/true); -#ifdef V4_USE_VALGRIND - VALGRIND_DESTROY_MEMPOOL(this); -#endif -} - -ExecutionEngine *MemoryManager::engine() const -{ - return m_d->engine; -} - -void MemoryManager::dumpStats() const -{ -#ifdef DETAILED_MM_STATS - std::cerr << "=================" << std::endl; - std::cerr << "Allocation stats:" << std::endl; - std::cerr << "Requests for each chunk size:" << std::endl; - for (int i = 0; i < m_d->allocSizeCounters.size(); ++i) { - if (unsigned count = m_d->allocSizeCounters[i]) { - std::cerr << "\t" << (i << 4) << " bytes chunks: " << count << std::endl; - } - } -#endif // DETAILED_MM_STATS -} - -void MemoryManager::registerDeletable(GCDeletable *d) -{ - d->next = m_d->deletable; - m_d->deletable = d; -} - -#ifdef DETAILED_MM_STATS -void MemoryManager::willAllocate(std::size_t size) -{ - unsigned alignedSize = (size + 15) >> 4; - QVector<unsigned> &counters = m_d->allocSizeCounters; - if ((unsigned) counters.size() < alignedSize + 1) - counters.resize(alignedSize + 1); - counters[alignedSize]++; -} - -#endif // DETAILED_MM_STATS - -void MemoryManager::collectFromJSStack() const -{ - Value *v = m_d->engine->jsStackBase; - Value *top = m_d->engine->jsStackTop; - while (v < top) { - Managed *m = v->asManaged(); - if (m && m->inUse()) - // Skip pointers to already freed objects, they are bogus as well - m->mark(m_d->engine); - ++v; - } -} -QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h deleted file mode 100644 index 00b41b796a..0000000000 --- a/src/qml/jsruntime/qv4mm_p.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV4GC_H -#define QV4GC_H - -#include "qv4global_p.h" -#include "qv4value_inl_p.h" -#include "qv4scopedvalue_p.h" - -//#define DETAILED_MM_STATS - -QT_BEGIN_NAMESPACE - -namespace QV4 { - -struct GCDeletable; - -class Q_QML_EXPORT MemoryManager -{ - Q_DISABLE_COPY(MemoryManager); - -public: - struct Data; - - class GCBlocker - { - public: - GCBlocker(MemoryManager *mm) - : mm(mm) - , wasBlocked(mm->isGCBlocked()) - { - mm->setGCBlocked(true); - } - - ~GCBlocker() - { - mm->setGCBlocked(wasBlocked); - } - - private: - MemoryManager *mm; - bool wasBlocked; - }; - -public: - MemoryManager(ExecutionEngine *engine); - ~MemoryManager(); - - // TODO: this is only for 64bit (and x86 with SSE/AVX), so exend it for other architectures to be slightly more efficient (meaning, align on 8-byte boundaries). - // Note: all occurrences of "16" in alloc/dealloc are also due to the alignment. - static inline std::size_t align(std::size_t size) - { return (size + 15) & ~0xf; } - - template<typename ManagedType> - inline typename ManagedType::Data *allocManaged(std::size_t size) - { - size = align(size); - Heap::Base *o = allocData(size); - o->vtable = ManagedType::staticVTable(); - return static_cast<typename ManagedType::Data *>(o); - } - - template <typename ManagedType> - typename ManagedType::Data *alloc() - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(); - return t->d(); - } - - template <typename ManagedType, typename Arg1> - typename ManagedType::Data *alloc(Arg1 arg1) - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1); - return t->d(); - } - - template <typename ManagedType, typename Arg1, typename Arg2> - typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2) - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2); - return t->d(); - } - - template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3> - typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3) - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3); - return t->d(); - } - - template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4> - typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4); - return t->d(); - } - - template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> - typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) - { - Scope scope(engine()); - Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5); - return t->d(); - } - - bool isGCBlocked() const; - void setGCBlocked(bool blockGC); - void runGC(); - - ExecutionEngine *engine() const; - - void dumpStats() const; - - void registerDeletable(GCDeletable *d); - - size_t getUsedMem() const; - size_t getAllocatedMem() const; - size_t getLargeItemsMem() const; - -protected: - /// expects size to be aligned - // TODO: try to inline - Heap::Base *allocData(std::size_t size); - -#ifdef DETAILED_MM_STATS - void willAllocate(std::size_t size); -#endif // DETAILED_MM_STATS - -private: - void collectFromJSStack() const; - void mark(); - void sweep(bool lastSweep = false); - -protected: - QScopedPointer<Data> m_d; -public: - PersistentValueStorage *m_persistentValues; - PersistentValueStorage *m_weakValues; -}; - -} - -QT_END_NAMESPACE - -#endif // QV4GC_H diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 89ff110b20..3f7806682e 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -50,14 +50,14 @@ Heap::NumberCtor::NumberCtor(QV4::ExecutionContext *scope) { } -ReturnedValue NumberCtor::construct(Managed *m, CallData *callData) +ReturnedValue NumberCtor::construct(const Managed *m, CallData *callData) { Scope scope(m->cast<NumberCtor>()->engine()); double dbl = callData->argc ? callData->args[0].toNumber() : 0.; return Encode(scope.engine->newNumberObject(dbl)); } -ReturnedValue NumberCtor::call(Managed *, CallData *callData) +ReturnedValue NumberCtor::call(const Managed *, CallData *callData) { double dbl = callData->argc ? callData->args[0].toNumber() : 0.; return Encode(dbl); @@ -97,7 +97,7 @@ inline ReturnedValue thisNumberValue(ExecutionContext *ctx) { if (ctx->thisObject().isNumber()) return ctx->thisObject().asReturnedValue(); - NumberObject *n = ctx->thisObject().asNumberObject(); + NumberObject *n = ctx->thisObject().as<NumberObject>(); if (!n) return ctx->engine()->throwTypeError(); return Encode(n->value()); @@ -107,7 +107,7 @@ inline double thisNumber(ExecutionContext *ctx) { if (ctx->thisObject().isNumber()) return ctx->thisObject().asDouble(); - NumberObject *n = ctx->thisObject().asNumberObject(); + NumberObject *n = ctx->thisObject().as<NumberObject>(); if (!n) return ctx->engine()->throwTypeError(); return n->value(); diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index 205995701b..04798d31fc 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -53,8 +53,8 @@ struct NumberCtor: FunctionObject { V4_OBJECT2(NumberCtor, FunctionObject) - static ReturnedValue construct(Managed *that, CallData *callData); - static ReturnedValue call(Managed *, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *, CallData *callData); }; struct NumberPrototype: NumberObject diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 211fd1812e..736598a213 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -37,7 +37,7 @@ #include "qv4objectproto_p.h" #include "qv4stringobject_p.h" #include "qv4argumentsobject_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4lookup_p.h" #include "qv4scopedvalue_p.h" #include "qv4memberdata_p.h" @@ -356,7 +356,7 @@ bool Object::hasOwnProperty(uint index) const return true; if (isStringObject()) { - String *s = static_cast<const StringObject *>(this)->d()->value.asString(); + String *s = static_cast<const StringObject *>(this)->d()->value.as<String>(); if (index < (uint)s->d()->length()) return true; } @@ -365,24 +365,24 @@ bool Object::hasOwnProperty(uint index) const return false; } -ReturnedValue Object::construct(Managed *m, CallData *) +ReturnedValue Object::construct(const Managed *m, CallData *) { - return static_cast<Object *>(m)->engine()->throwTypeError(); + return static_cast<const Object *>(m)->engine()->throwTypeError(); } -ReturnedValue Object::call(Managed *m, CallData *) +ReturnedValue Object::call(const Managed *m, CallData *) { - return static_cast<Object *>(m)->engine()->throwTypeError(); + return static_cast<const Object *>(m)->engine()->throwTypeError(); } -ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue Object::get(const Managed *m, String *name, bool *hasProperty) { - return static_cast<Object *>(m)->internalGet(name, hasProperty); + return static_cast<const Object *>(m)->internalGet(name, hasProperty); } -ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty) { - return static_cast<Object *>(m)->internalGetIndexed(index, hasProperty); + return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty); } void Object::put(Managed *m, String *name, const Value &value) @@ -416,7 +416,7 @@ PropertyAttributes Object::queryIndexed(const Managed *m, uint index) return o->arrayData()->attributes(index); if (o->isStringObject()) { - String *s = static_cast<const StringObject *>(o)->d()->value.asString(); + String *s = static_cast<const StringObject *>(o)->d()->value.as<String>(); if (index < (uint)s->d()->length()) return (Attr_NotWritable|Attr_NotConfigurable); } @@ -433,9 +433,9 @@ bool Object::deleteIndexedProperty(Managed *m, uint index) return static_cast<Object *>(m)->internalDeleteIndexedProperty(index); } -ReturnedValue Object::getLookup(Managed *m, Lookup *l) +ReturnedValue Object::getLookup(const Managed *m, Lookup *l) { - Object *o = static_cast<Object *>(m); + const Object *o = static_cast<const Object *>(m); PropertyAttributes attrs; ReturnedValue v = l->lookup(o, &attrs); if (v != Primitive::emptyValue().asReturnedValue()) { @@ -531,7 +531,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name while (it->arrayNode != o->sparseEnd()) { int k = it->arrayNode->key(); uint pidx = it->arrayNode->value; - Heap::SparseArrayData *sa = static_cast<Heap::SparseArrayData *>(o->d()->arrayData); + Heap::SparseArrayData *sa = o->d()->arrayData.cast<Heap::SparseArrayData>(); Property *p = reinterpret_cast<Property *>(sa->arrayData + pidx); it->arrayNode = it->arrayNode->nextNode(); PropertyAttributes a = sa->attrs ? sa->attrs[pidx] : Attr_Data; @@ -548,7 +548,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name } // dense arrays while (it->arrayIndex < o->d()->arrayData->len) { - Heap::SimpleArrayData *sa = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData); + Heap::SimpleArrayData *sa = o->d()->arrayData.cast<Heap::SimpleArrayData>(); Value &val = sa->data(it->arrayIndex); PropertyAttributes a = o->arrayData()->attributes(it->arrayIndex); ++it->arrayIndex; @@ -585,7 +585,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name } // Section 8.12.3 -ReturnedValue Object::internalGet(String *name, bool *hasProperty) +ReturnedValue Object::internalGet(String *name, bool *hasProperty) const { uint idx = name->asArrayIndex(); if (idx != UINT_MAX) @@ -611,7 +611,7 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty) return Encode::undefined(); } -ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) +ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const { Property *pd = 0; PropertyAttributes attrs; @@ -710,7 +710,7 @@ void Object::internalPut(String *name, const Value &value) // Clause 5 if (pd && attrs.isAccessor()) { - assert(pd->setter() != 0); + Q_ASSERT(pd->setter() != 0); Scope scope(engine()); ScopedFunctionObject setter(scope, pd->setter()); @@ -784,7 +784,7 @@ void Object::internalPutIndexed(uint index, const Value &value) // Clause 5 if (pd && attrs.isAccessor()) { - assert(pd->setter() != 0); + Q_ASSERT(pd->setter() != 0); Scope scope(engine()); ScopedFunctionObject setter(scope, pd->setter()); @@ -1137,7 +1137,7 @@ void Object::initSparseArray() DEFINE_OBJECT_VTABLE(ArrayObject); Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list) - : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject()) + : Heap::Object(engine->arrayClass, engine->arrayPrototype.objectValue()) { init(); Scope scope(engine); @@ -1155,14 +1155,14 @@ Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list) a->setArrayLengthUnchecked(len); } -ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l) +ReturnedValue ArrayObject::getLookup(const Managed *m, Lookup *l) { - Scope scope(static_cast<Object *>(m)->engine()); + Scope scope(static_cast<const Object *>(m)->engine()); ScopedString name(scope, scope.engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]); if (name->equals(scope.engine->id_length)) { // special case, as the property is on the object itself l->getter = Lookup::arrayLengthGetter; - ArrayObject *a = static_cast<ArrayObject *>(m); + const ArrayObject *a = static_cast<const ArrayObject *>(m); return a->memberData()->data[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue(); } return Object::getLookup(m, l); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 71a997e133..94709c2941 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -36,6 +36,9 @@ #include "qv4managed_p.h" #include "qv4memberdata_p.h" #include "qv4arraydata_p.h" +#include "qv4engine_p.h" +#include "qv4scopedvalue_p.h" +#include "qv4value_inl_p.h" QT_BEGIN_NAMESPACE @@ -55,9 +58,9 @@ struct Object : Base { Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData->data + index); } InternalClass *internalClass; - Heap::Object *prototype; - MemberData *memberData; - ArrayData *arrayData; + Pointer<Object> prototype; + Pointer<MemberData> memberData; + Pointer<ArrayData> arrayData; }; } @@ -67,7 +70,7 @@ struct Object : Base { Q_MANAGED_CHECK \ typedef superClass SuperClass; \ static const QV4::ObjectVTable static_vtbl; \ - static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \ + static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ V4_MANAGED_SIZE_TEST \ Data *d() const { return static_cast<Data *>(m); } @@ -77,24 +80,24 @@ struct Object : Base { typedef QV4::Heap::DataClass Data; \ typedef superClass SuperClass; \ static const QV4::ObjectVTable static_vtbl; \ - static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \ + static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ V4_MANAGED_SIZE_TEST \ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); } struct ObjectVTable { - ManagedVTable managedVTable; - ReturnedValue (*call)(Managed *, CallData *data); - ReturnedValue (*construct)(Managed *, CallData *data); - ReturnedValue (*get)(Managed *, String *name, bool *hasProperty); - ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty); + VTable vTable; + ReturnedValue (*call)(const Managed *, CallData *data); + ReturnedValue (*construct)(const Managed *, CallData *data); + ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty); + ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty); void (*put)(Managed *, String *name, const Value &value); void (*putIndexed)(Managed *, uint index, const Value &value); PropertyAttributes (*query)(const Managed *, String *name); PropertyAttributes (*queryIndexed)(const Managed *, uint index); bool (*deleteProperty)(Managed *m, String *name); bool (*deleteIndexedProperty)(Managed *m, uint index); - ReturnedValue (*getLookup)(Managed *m, Lookup *l); + ReturnedValue (*getLookup)(const Managed *m, Lookup *l); void (*setLookup)(Managed *m, Lookup *l, const Value &v); uint (*getLength)(const Managed *m); void (*advanceIterator)(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes); @@ -103,7 +106,7 @@ struct ObjectVTable #define DEFINE_OBJECT_VTABLE(classname) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.managedVTable), \ + DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.vTable), \ call, \ construct, \ get, \ @@ -272,9 +275,9 @@ public: } void ensureMemberIndex(uint idx); - inline ReturnedValue get(String *name, bool *hasProperty = 0) + inline ReturnedValue get(String *name, bool *hasProperty = 0) const { return vtable()->get(this, name, hasProperty); } - inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) + inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const { return vtable()->getIndexed(this, idx, hasProperty); } inline void put(String *name, const Value &v) { vtable()->put(this, name, v); } @@ -288,7 +291,7 @@ public: { return vtable()->deleteProperty(this, name); } bool deleteIndexedProperty(uint index) { return vtable()->deleteIndexedProperty(this, index); } - ReturnedValue getLookup(Lookup *l) + ReturnedValue getLookup(Lookup *l) const { return vtable()->getLookup(this, l); } void setLookup(Lookup *l, const Value &v) { vtable()->setLookup(this, l, v); } @@ -296,30 +299,30 @@ public: { vtable()->advanceIterator(this, it, name, index, p, attributes); } uint getLength() const { return vtable()->getLength(this); } - inline ReturnedValue construct(CallData *d) + inline ReturnedValue construct(CallData *d) const { return vtable()->construct(this, d); } - inline ReturnedValue call(CallData *d) + inline ReturnedValue call(CallData *d) const { return vtable()->call(this, d); } protected: static void markObjects(Heap::Base *that, ExecutionEngine *e); - static ReturnedValue construct(Managed *m, CallData *); - static ReturnedValue call(Managed *m, CallData *); - static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue construct(const Managed *m, CallData *); + static ReturnedValue call(const Managed *m, CallData *); + static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); + static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void putIndexed(Managed *m, uint index, const Value &value); static PropertyAttributes query(const Managed *m, String *name); static PropertyAttributes queryIndexed(const Managed *m, uint index); static bool deleteProperty(Managed *m, String *name); static bool deleteIndexedProperty(Managed *m, uint index); - static ReturnedValue getLookup(Managed *m, Lookup *l); + static ReturnedValue getLookup(const Managed *m, Lookup *l); static void setLookup(Managed *m, Lookup *l, const Value &v); static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes); static uint getLength(const Managed *m); private: - ReturnedValue internalGet(String *name, bool *hasProperty); - ReturnedValue internalGetIndexed(uint index, bool *hasProperty); + ReturnedValue internalGet(String *name, bool *hasProperty) const; + ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const; void internalPut(String *name, const Value &value); void internalPutIndexed(uint index, const Value &value); bool internalDeleteProperty(String *name); @@ -339,7 +342,7 @@ struct BooleanObject : Object { } BooleanObject(ExecutionEngine *engine, bool b) - : Object(engine->emptyClass, engine->booleanPrototype.asObject()), + : Object(engine->emptyClass, engine->booleanPrototype.objectValue()), b(b) { } @@ -354,7 +357,7 @@ struct NumberObject : Object { } NumberObject(ExecutionEngine *engine, double val) - : Object(engine->emptyClass, engine->numberPrototype.asObject()), + : Object(engine->emptyClass, engine->numberPrototype.objectValue()), value(val) { } @@ -367,7 +370,7 @@ struct ArrayObject : Object { }; ArrayObject(ExecutionEngine *engine) - : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject()) + : Heap::Object(engine->arrayClass, engine->arrayPrototype.objectValue()) { init(); } ArrayObject(ExecutionEngine *engine, const QStringList &list); ArrayObject(InternalClass *ic, QV4::Object *prototype) @@ -400,7 +403,7 @@ struct ArrayObject: Object { void init(ExecutionEngine *engine); - static ReturnedValue getLookup(Managed *m, Lookup *l); + static ReturnedValue getLookup(const Managed *m, Lookup *l); using Object::getLength; static uint getLength(const Managed *m); @@ -454,14 +457,10 @@ inline void Object::arraySet(uint index, const Value &value) setArrayLengthUnchecked(index + 1); } -template<> -inline Object *value_cast(const Value &v) { - return v.asObject(); -} template<> -inline ArrayObject *value_cast(const Value &v) { - return v.asArrayObject(); +inline const ArrayObject *Value::as() const { + return isManaged() && m && m->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0; } #ifndef V4_BOOTSTRAP diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index f36ee554a7..77920e2716 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -83,7 +83,7 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper *name = 0; *index = UINT_MAX; - if (!object->asObject()) { + if (!object->as<Object>()) { *attrs = PropertyAttributes(); return; } @@ -92,19 +92,19 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper ScopedString n(scope); while (1) { - if (!current->asObject()) + if (!current->as<Object>()) break; while (1) { - current->asObject()->advanceIterator(this, name, index, pd, attrs); + current->as<Object>()->advanceIterator(this, name, index, pd, attrs); if (attrs->isEmpty()) break; // check the property is not already defined earlier in the proto chain if (current->heapObject() != object->heapObject()) { - o = object->asObject(); + o = object->as<Object>(); n = *name; bool shadowed = false; - while (o->asObject()->d() != current->heapObject()) { + while (o->d() != current->heapObject()) { if ((!!n && o->hasOwnProperty(n)) || (*index != UINT_MAX && o->hasOwnProperty(*index))) { shadowed = true; @@ -131,7 +131,7 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper ReturnedValue ObjectIterator::nextPropertyName(Value *value) { - if (!object->asObject()) + if (!object->as<Object>()) return Encode::null(); PropertyAttributes attrs; @@ -147,13 +147,13 @@ ReturnedValue ObjectIterator::nextPropertyName(Value *value) if (!!name) return name->asReturnedValue(); - assert(index < UINT_MAX); + Q_ASSERT(index < UINT_MAX); return Encode(index); } ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value) { - if (!object->asObject()) + if (!object->as<Object>()) return Encode::null(); PropertyAttributes attrs; @@ -169,13 +169,13 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value) if (!!name) return name->asReturnedValue(); - assert(index < UINT_MAX); + Q_ASSERT(index < UINT_MAX); return Encode(engine->newString(QString::number(index))); } ReturnedValue ObjectIterator::nextPropertyNameAsString() { - if (!object->asObject()) + if (!object->as<Object>()) return Encode::null(); PropertyAttributes attrs; diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 9356ea434e..8324a1aee2 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -34,7 +34,7 @@ #include "qv4objectproto_p.h" #include "qv4argumentsobject_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4scopedvalue_p.h" #include "qv4runtime_p.h" #include "qv4objectiterator_p.h" @@ -52,9 +52,9 @@ Heap::ObjectCtor::ObjectCtor(QV4::ExecutionContext *scope) { } -ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData) +ReturnedValue ObjectCtor::construct(const Managed *that, CallData *callData) { - ObjectCtor *ctor = static_cast<ObjectCtor *>(that); + const ObjectCtor *ctor = static_cast<const ObjectCtor *>(that); ExecutionEngine *v4 = ctor->engine(); Scope scope(v4); if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) { @@ -67,9 +67,9 @@ ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData) return RuntimeHelpers::toObject(scope.engine, callData->args[0]); } -ReturnedValue ObjectCtor::call(Managed *m, CallData *callData) +ReturnedValue ObjectCtor::call(const Managed *m, CallData *callData) { - ObjectCtor *ctor = static_cast<ObjectCtor *>(m); + const ObjectCtor *ctor = static_cast<const ObjectCtor *>(m); ExecutionEngine *v4 = ctor->engine(); if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) return v4->newObject()->asReturnedValue(); @@ -163,7 +163,7 @@ ReturnedValue ObjectPrototype::method_create(CallContext *ctx) return ctx->engine()->throwTypeError(); ScopedObject newObject(scope, ctx->d()->engine->newObject()); - newObject->setPrototype(O->asObject()); + newObject->setPrototype(O->as<Object>()); if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) { ctx->d()->callData->args[0] = newObject.asReturnedValue(); @@ -525,7 +525,7 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx) ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx) { Scope scope(ctx); - ScopedObject o(scope, ctx->thisObject().asObject()); + ScopedObject o(scope, ctx->thisObject().as<Object>()); if (!o) return ctx->engine()->throwTypeError(); @@ -580,7 +580,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value if (o->hasProperty(engine->id_get)) { ScopedValue get(scope, o->get(engine->id_get)); - FunctionObject *f = get->asFunctionObject(); + FunctionObject *f = get->as<FunctionObject>(); if (f || get->isUndefined()) { desc->value = get; } else { @@ -592,7 +592,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value if (o->hasProperty(engine->id_set)) { ScopedValue set(scope, o->get(engine->id_set)); - FunctionObject *f = set->asFunctionObject(); + FunctionObject *f = set->as<FunctionObject>(); if (f || set->isUndefined()) { desc->set = set; } else { diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h index 4e96681017..d571e50cd4 100644 --- a/src/qml/jsruntime/qv4objectproto_p.h +++ b/src/qml/jsruntime/qv4objectproto_p.h @@ -53,8 +53,8 @@ struct ObjectCtor: FunctionObject { V4_OBJECT2(ObjectCtor, FunctionObject) - static ReturnedValue construct(Managed *that, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct ObjectPrototype: Object diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp index 88dc1946b8..f7e88dddd6 100644 --- a/src/qml/jsruntime/qv4persistent.cpp +++ b/src/qml/jsruntime/qv4persistent.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qv4persistent_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4object_p.h" #include "PageAllocation.h" @@ -190,7 +190,7 @@ void PersistentValueStorage::mark(ExecutionEngine *e) Page *p = static_cast<Page *>(firstPage); while (p) { for (int i = 0; i < kEntriesPerPage; ++i) { - if (Managed *m = p->values[i].asManaged()) + if (Managed *m = p->values[i].as<Managed>()) m->mark(e); } drainMarkStack(e, markBase); diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h index 7cac2ed95f..2d2f856424 100644 --- a/src/qml/jsruntime/qv4persistent_p.h +++ b/src/qml/jsruntime/qv4persistent_p.h @@ -33,7 +33,7 @@ #ifndef QV4PERSISTENT_H #define QV4PERSISTENT_H -#include "qv4value_inl_p.h" +#include "qv4value_p.h" QT_BEGIN_NAMESPACE @@ -96,7 +96,7 @@ public: Managed *asManaged() const { if (!val) return 0; - return val->asManaged(); + return val->as<Managed>(); } ExecutionEngine *engine() const { @@ -138,7 +138,7 @@ public: Managed *asManaged() const { if (!val) return 0; - return val->asManaged(); + return val->as<Managed>(); } ExecutionEngine *engine() const { diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index a7019d0558..a67d377063 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qv4profiling_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h index 1b55abd1f7..34d9cdadeb 100644 --- a/src/qml/jsruntime/qv4property_p.h +++ b/src/qml/jsruntime/qv4property_p.h @@ -35,7 +35,6 @@ #include "qv4global_p.h" #include "qv4value_p.h" -#include "qv4internalclass_p.h" QT_BEGIN_NAMESPACE @@ -73,8 +72,8 @@ struct Property { inline Heap::FunctionObject *getter() const { return value.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(value.heapObject()) : 0; } inline Heap::FunctionObject *setter() const { return set.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(set.heapObject()) : 0; } - inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); } - inline void setSetter(FunctionObject *s) { set = s ? Primitive::fromManaged(reinterpret_cast<Managed *>(s)) : Value::fromHeapObject(0); } + inline void setGetter(FunctionObject *g) { value = reinterpret_cast<Managed *>(g); } + inline void setSetter(FunctionObject *s) { set = (s ? reinterpret_cast<Managed *>(s) : 0); } void copy(const Property *other, PropertyAttributes attrs) { value = other->value; @@ -85,8 +84,8 @@ struct Property { explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(0); } explicit Property(Value v) : value(v) { set = Value::fromHeapObject(0); } Property(FunctionObject *getter, FunctionObject *setter) { - value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter)); - set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter)); + value = reinterpret_cast<Managed *>(getter); + set = reinterpret_cast<Managed *>(setter); } Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) { value.m = reinterpret_cast<Heap::Base *>(getter); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 50efff001d..a7810563c9 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -55,6 +55,7 @@ #include <private/qv4objectproto_p.h> #include <private/qv4jsonobject_p.h> #include <private/qv4regexpobject_p.h> +#include <private/qv4dateobject_p.h> #include <private/qv4scopedvalue_p.h> #include <private/qv4mm_p.h> #include <private/qqmlscriptstring_p.h> @@ -97,7 +98,7 @@ static QPair<QObject *, int> extractQtMethod(QV4::FunctionObject *function) static QPair<QObject *, int> extractQtSignal(const Value &value) { if (value.isObject()) { - QV4::ExecutionEngine *v4 = value.asObject()->engine(); + QV4::ExecutionEngine *v4 = value.as<Object>()->engine(); QV4::Scope scope(v4); QV4::ScopedFunctionObject function(scope, value); if (function) @@ -240,8 +241,8 @@ Heap::QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object) void QObjectWrapper::initializeBindings(ExecutionEngine *engine) { - engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("connect"), method_connect); - engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect); + engine->functionPrototype.as<Object>()->defineDefaultProperty(QStringLiteral("connect"), method_connect); + engine->functionPrototype.as<Object>()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect); } QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const @@ -260,7 +261,7 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont } ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String *n, QObjectWrapper::RevisionMode revisionMode, - bool *hasProperty, bool includeImports) + bool *hasProperty, bool includeImports) const { if (QQmlData::wasDeleted(d()->object)) { if (hasProperty) @@ -346,8 +347,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx QV4::ScopedString connect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("connect"))); QV4::ScopedString disconnect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("disconnect"))); - handler->put(connect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(connect))); - handler->put(disconnect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(disconnect))); + handler->put(connect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.as<Object>()->get(connect))); + handler->put(disconnect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.as<Object>()->get(disconnect))); return handler.asReturnedValue(); } else { @@ -519,7 +520,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro error += QLatin1String(QMetaType::typeName(property->propType)); ctx->engine()->throwError(error); return; - } else if (value.asFunctionObject()) { + } else if (value.as<FunctionObject>()) { // this is handled by the binding creation above } else if (property->propType == QMetaType::Int && value.isNumber()) { PROPERTY_STORE(int, value.asDouble()); @@ -658,7 +659,7 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b) { Q_ASSERT(a->as<QV4::QObjectWrapper>()); QV4::QObjectWrapper *qobjectWrapper = static_cast<QV4::QObjectWrapper *>(a); - QV4::Object *o = b->asObject(); + QV4::Object *o = b->as<Object>(); if (o) { if (QV4::QmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QmlTypeWrapper>()) return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object(); @@ -674,9 +675,9 @@ ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object) return (engine->memoryManager->alloc<QV4::QObjectWrapper>(engine, object))->asReturnedValue(); } -QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty) +QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *hasProperty) { - QObjectWrapper *that = static_cast<QObjectWrapper*>(m); + const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m); QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(that->engine()); return that->getQmlProperty(qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true); } @@ -1221,7 +1222,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) default: return 10; } - } else if (actual.asDateObject()) { + } else if (actual.as<DateObject>()) { switch (conversionType) { case QMetaType::QDateTime: return 0; @@ -1239,7 +1240,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) default: return 10; } - } else if (actual.asArrayObject()) { + } else if (actual.as<ArrayObject>()) { switch (conversionType) { case QMetaType::QJsonArray: return 3; @@ -1268,7 +1269,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) return 10; } } - } else if (QV4::Object *obj = actual.asObject()) { + } else if (const Object *obj = actual.as<Object>()) { if (obj->as<QV4::VariantObject>()) { if (conversionType == qMetaTypeId<QVariant>()) return 0; @@ -1598,9 +1599,9 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q type = callType; } else if (callType == QMetaType::QObjectStar) { qobjectPtr = 0; - if (QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) + if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) qobjectPtr = qobjectWrapper->object(); - else if (QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>()) + else if (const QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>()) queryEngine = qmlTypeWrapper->isSingleton(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { @@ -1622,7 +1623,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q } } else { QObject *o = 0; - if (QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) + if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) o = qobjectWrapper->object(); qlistPtr->append(o); } @@ -1746,14 +1747,14 @@ ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, in return method.asReturnedValue(); } -ReturnedValue QObjectMethod::create(ExecutionContext *scope, QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal) +ReturnedValue QObjectMethod::create(ExecutionContext *scope, const QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal) { Scope valueScope(scope); Scoped<QObjectMethod> method(valueScope, scope->d()->engine->memoryManager->alloc<QObjectMethod>(scope)); method->d()->propertyCache = valueType->d()->propertyCache; method->d()->index = index; method->d()->qmlGlobal = qmlGlobal; - method->d()->valueTypeWrapper = valueType; + method->d()->valueTypeWrapper = *valueType; return method.asReturnedValue(); } @@ -1769,7 +1770,7 @@ const QMetaObject *Heap::QObjectMethod::metaObject() return object->metaObject(); } -QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) +QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) const { QString result; if (const QMetaObject *metaObject = d()->metaObject()) { @@ -1795,7 +1796,7 @@ QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) return ctx->d()->engine->newString(result)->asReturnedValue(); } -QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) +QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const { if (!d()->object) return Encode::undefined(); @@ -1814,13 +1815,13 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con return Encode::undefined(); } -ReturnedValue QObjectMethod::call(Managed *m, CallData *callData) +ReturnedValue QObjectMethod::call(const Managed *m, CallData *callData) { - QObjectMethod *This = static_cast<QObjectMethod*>(m); + const QObjectMethod *This = static_cast<const QObjectMethod*>(m); return This->callInternal(callData); } -ReturnedValue QObjectMethod::callInternal(CallData *callData) +ReturnedValue QObjectMethod::callInternal(CallData *callData) const { Scope scope(engine()); ScopedContext context(scope, scope.engine->currentContext()); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 1b41ca65c1..8421c67f26 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -104,7 +104,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object QObject *object() const { return d()->object.data(); } - ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false); + ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false) const; static ReturnedValue getQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0); static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value); @@ -127,7 +127,7 @@ private: QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const; - static ReturnedValue get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static PropertyAttributes query(const Managed *, String *name); static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes); @@ -148,17 +148,17 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject enum { DestroyMethod = -1, ToStringMethod = -2 }; static ReturnedValue create(QV4::ExecutionContext *scope, QObject *object, int index, const Value &qmlGlobal = Primitive::undefinedValue()); - static ReturnedValue create(QV4::ExecutionContext *scope, QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal = Primitive::undefinedValue()); + static ReturnedValue create(QV4::ExecutionContext *scope, const QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal = Primitive::undefinedValue()); int methodIndex() const { return d()->index; } QObject *object() const { return d()->object.data(); } - QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx); - QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc); + QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx) const; + QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const; - static ReturnedValue call(Managed *, CallData *callData); + static ReturnedValue call(const Managed *, CallData *callData); - ReturnedValue callInternal(CallData *callData); + ReturnedValue callInternal(CallData *callData) const; static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e); }; diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 8e18a5fbdd..715df2d666 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -34,7 +34,7 @@ #include "qv4regexp_p.h" #include "qv4engine_p.h" #include "qv4scopedvalue_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> using namespace QV4; diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index f6e88e62b7..1948d047fb 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -37,7 +37,7 @@ #include "qv4objectproto_p.h" #include "qv4regexp_p.h" #include "qv4stringobject_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4scopedvalue_p.h" #include <private/qqmljsengine_p.h> @@ -75,7 +75,7 @@ Heap::RegExpObject::RegExpObject(InternalClass *ic, QV4::Object *prototype) } Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global) - : Heap::Object(engine->emptyClass, engine->regExpPrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->regExpPrototype.objectValue()) , value(value->d()) , global(global) { @@ -88,7 +88,7 @@ Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *valu // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re) - : Heap::Object(engine->emptyClass, engine->regExpPrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->regExpPrototype.objectValue()) { value = 0; global = false; @@ -236,9 +236,9 @@ void Heap::RegExpCtor::clearLastMatch() lastMatchEnd = 0; } -ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) +ReturnedValue RegExpCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<Object *>(m)->engine()); + Scope scope(static_cast<const Object *>(m)->engine()); ScopedContext ctx(scope, scope.engine->currentContext()); ScopedValue r(scope, callData->argument(0)); @@ -286,7 +286,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) return Encode(ctx->d()->engine->newRegExpObject(regexp, global)); } -ReturnedValue RegExpCtor::call(Managed *that, CallData *callData) +ReturnedValue RegExpCtor::call(const Managed *that, CallData *callData) { if (callData->argc > 0 && callData->args[0].as<RegExpObject>()) { if (callData->argc == 1 || callData->args[1].isUndefined()) @@ -372,7 +372,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx) } // fill in result data - ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->regExpExecArrayClass, scope.engine->arrayPrototype.asObject())); + ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->regExpExecArrayClass, scope.engine->arrayPrototype.as<Object>())); int len = r->value()->captureCount(); array->arrayReserve(len); ScopedValue v(scope); @@ -425,7 +425,7 @@ ReturnedValue RegExpPrototype::method_compile(CallContext *ctx) ScopedCallData callData(scope, ctx->argc()); memcpy(callData->args, ctx->args(), ctx->argc()*sizeof(Value)); - Scoped<RegExpObject> re(scope, ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData)); + Scoped<RegExpObject> re(scope, ctx->d()->engine->regExpCtor.as<FunctionObject>()->construct(callData)); r->d()->value = re->value(); r->d()->global = re->global(); diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index f5f255faf5..34acea6df1 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -121,8 +121,8 @@ struct RegExpCtor: FunctionObject int lastMatchStart() { return d()->lastMatchStart; } int lastMatchEnd() { return d()->lastMatchEnd; } - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); static void markObjects(Heap::Base *that, ExecutionEngine *e); }; @@ -146,7 +146,7 @@ struct RegExpPrototype: RegExpObject }; inline Heap::RegExpPrototype::RegExpPrototype(ExecutionEngine *e) - : RegExpObject(e->emptyClass, e->objectPrototype.asObject()) + : RegExpObject(e->emptyClass, e->objectPrototype.objectValue()) { } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index c31de6a9f0..ae618ceb6e 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -40,6 +40,7 @@ #include "qv4stringobject_p.h" #include "qv4argumentsobject_p.h" #include "qv4objectiterator_p.h" +#include "qv4dateobject_p.h" #include "qv4lookup_p.h" #include "qv4function_p.h" #include "private/qlocale_tools_p.h" @@ -313,14 +314,14 @@ ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex) QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const Value &left, const Value &right) { Scope scope(engine); - ScopedFunctionObject f(scope, right.asFunctionObject()); + ScopedFunctionObject f(scope, right.as<FunctionObject>()); if (!f) return engine->throwTypeError(); if (f->isBoundFunction()) f = static_cast<BoundFunction *>(f.getPointer())->target(); - ScopedObject v(scope, left.asObject()); + ScopedObject v(scope, left.as<Object>()); if (!v) return Encode(false); @@ -380,10 +381,10 @@ Heap::String *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double n return engine->newString(qstr); } -ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint) +ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeHint) { if (typeHint == PREFERREDTYPE_HINT) { - if (object->asDateObject()) + if (object->as<DateObject>()) typeHint = STRING_HINT; else typeHint = NUMBER_HINT; @@ -401,10 +402,10 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint) Scope scope(engine); ScopedCallData callData(scope, 0); - callData->thisObject = object; + callData->thisObject = *object; ScopedValue conv(scope, object->get(*meth1)); - if (FunctionObject *o = conv->asFunctionObject()) { + if (FunctionObject *o = conv->as<FunctionObject>()) { ScopedValue r(scope, o->call(callData)); if (r->isPrimitive()) return r->asReturnedValue(); @@ -414,7 +415,7 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint) return Encode::undefined(); conv = object->get(*meth2); - if (FunctionObject *o = conv->asFunctionObject()) { + if (FunctionObject *o = conv->as<FunctionObject>()) { ScopedValue r(scope, o->call(callData)); if (r->isPrimitive()) return r->asReturnedValue(); @@ -575,7 +576,7 @@ ReturnedValue Runtime::getElement(ExecutionEngine *engine, const Value &object, ScopedObject o(scope, object); if (!o) { if (idx < UINT_MAX) { - if (String *str = object.asString()) { + if (const String *str = object.as<String>()) { if (idx >= (uint)str->toQString().length()) { return Encode::undefined(); } @@ -931,7 +932,7 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameI if (base) callData->thisObject = base; - FunctionObject *o = func->asFunctionObject(); + FunctionObject *o = func->as<FunctionObject>(); if (!o) { QString objectAsString = QStringLiteral("[null]"); if (base) @@ -1034,7 +1035,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int if (scope.engine->hasException) return Encode::undefined(); - Object *f = func->asObject(); + Object *f = func->as<Object>(); if (!f) return engine->throwTypeError(); @@ -1043,7 +1044,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int ReturnedValue Runtime::constructValue(ExecutionEngine *engine, const Value &func, CallData *callData) { - Object *f = func.asObject(); + const Object *f = func.as<Object>(); if (!f) return engine->throwTypeError(); @@ -1100,7 +1101,7 @@ ReturnedValue Runtime::typeofValue(ExecutionEngine *engine, const Value &value) case Value::Managed_Type: if (value.isString()) res = engine->id_string; - else if (value.objectValue()->asFunctionObject()) + else if (value.objectValue()->as<FunctionObject>()) res = engine->id_function; else res = engine->id_object; // ### implementation-defined @@ -1199,7 +1200,7 @@ ReturnedValue Runtime::objectLiteral(ExecutionEngine *engine, const QV4::Value * { Scope scope(engine); QV4::InternalClass *klass = engine->currentContext()->compilationUnit->runtimeClasses[classId]; - ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype.asObject())); + ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype.as<Object>())); { bool needSparseArray = arrayGetterSetterCountAndFlags >> 30; diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index f2f90bbc15..44c7fbcb9c 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -218,7 +218,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime { }; struct Q_QML_PRIVATE_EXPORT RuntimeHelpers { - static ReturnedValue objectDefaultValue(Object *object, int typeHint); + static ReturnedValue objectDefaultValue(const Object *object, int typeHint); static ReturnedValue toPrimitive(const Value &value, int typeHint); static double stringToNumber(const QString &s); @@ -243,7 +243,7 @@ struct Q_QML_PRIVATE_EXPORT RuntimeHelpers { #ifndef V4_BOOTSTRAP inline ReturnedValue RuntimeHelpers::toPrimitive(const Value &value, int typeHint) { - Object *o = value.asObject(); + const Object *o = value.as<Object>(); if (!o) return value.asReturnedValue(); return RuntimeHelpers::objectDefaultValue(o, typeHint); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 908248f0f0..b469567866 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -202,7 +202,7 @@ struct Scoped { enum _Convert { Convert }; - inline void setPointer(Managed *p) { + inline void setPointer(const Managed *p) { ptr->m = p ? p->m : 0; #if QT_POINTER_SIZE == 4 ptr->tag = QV4::Value::Managed_Type; @@ -225,7 +225,7 @@ struct Scoped Scoped(const Scope &scope, const Value &v) { ptr = scope.engine->jsStackTop++; - setPointer(value_cast<T>(v)); + setPointer(v.as<T>()); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -235,7 +235,7 @@ struct Scoped Value v; v = o; ptr = scope.engine->jsStackTop++; - setPointer(value_cast<T>(v)); + setPointer(v.as<T>()); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -243,7 +243,7 @@ struct Scoped Scoped(const Scope &scope, const ScopedValue &v) { ptr = scope.engine->jsStackTop++; - setPointer(value_cast<T>(*v.ptr)); + setPointer(v.ptr->as<T>()); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -261,7 +261,7 @@ struct Scoped Scoped(const Scope &scope, const Value *v) { ptr = scope.engine->jsStackTop++; - setPointer(v ? value_cast<T>(*v) : 0); + setPointer(v ? v->as<T>() : 0); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -287,7 +287,7 @@ struct Scoped Scoped(const Scope &scope, const ReturnedValue &v) { ptr = scope.engine->jsStackTop++; - setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v))); + setPointer(QV4::Value::fromReturnedValue(v).as<T>()); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -302,9 +302,7 @@ struct Scoped } Scoped<T> &operator=(Heap::Base *o) { - Value v; - v = o; - setPointer(value_cast<T>(v)); + setPointer(Value::fromHeapObject(o).as<T>()); return *this; } Scoped<T> &operator=(typename T::Data *t) { @@ -312,16 +310,16 @@ struct Scoped return *this; } Scoped<T> &operator=(const Value &v) { - setPointer(value_cast<T>(v)); + setPointer(v.as<T>()); return *this; } Scoped<T> &operator=(Value *v) { - setPointer(v ? value_cast<T>(*v) : 0); + setPointer(v ? v->as<T>() : 0); return *this; } Scoped<T> &operator=(const ReturnedValue &v) { - setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v))); + setPointer(QV4::Value::fromReturnedValue(v).as<T>()); return *this; } diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 4fde0e2445..05653c1177 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qv4script_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4functionobject_p.h" #include "qv4function_p.h" #include "qv4context_p.h" @@ -122,13 +122,13 @@ Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::Ob s.engine->popContext(); } -ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *) +ReturnedValue QmlBindingWrapper::call(const Managed *that, CallData *) { - ExecutionEngine *engine = static_cast<Object *>(that)->engine(); + ExecutionEngine *engine = static_cast<const Object *>(that)->engine(); CHECK_STACK_LIMITS(engine); Scope scope(engine); - QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that); + const QmlBindingWrapper *This = static_cast<const QmlBindingWrapper *>(that); if (!This->function()) return QV4::Encode::undefined(); diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index 05a9e45f45..fcc24b6cb7 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -99,7 +99,7 @@ struct QmlBindingWrapper : Heap::FunctionObject { struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject { V4_OBJECT2(QmlBindingWrapper, FunctionObject) - static ReturnedValue call(Managed *that, CallData *); + static ReturnedValue call(const Managed *that, CallData *); static void markObjects(Heap::Base *m, ExecutionEngine *e); Heap::CallContext *context() const { return d()->qmlContext; } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index f1f546bece..79bd1db6c0 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -175,7 +175,7 @@ template <> QUrl convertValueToElement(const Value &value) template <> QModelIndex convertValueToElement(const Value &value) { - const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value); + const QQmlValueTypeWrapper *v = value.as<QQmlValueTypeWrapper>(); if (v) return v->toVariant().toModelIndex(); return QModelIndex(); @@ -183,7 +183,7 @@ template <> QModelIndex convertValueToElement(const Value &value) template <> QItemSelectionRange convertValueToElement(const Value &value) { - const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value); + const QQmlValueTypeWrapper *v = value.as<QQmlValueTypeWrapper>(); if (v) return v->toVariant().value<QItemSelectionRange>(); return QItemSelectionRange(); @@ -231,7 +231,7 @@ public: defineAccessorProperty(QStringLiteral("length"), method_get_length, method_set_length); } - QV4::ReturnedValue containerGetIndexed(uint index, bool *hasProperty) + QV4::ReturnedValue containerGetIndexed(uint index, bool *hasProperty) const { /* Qt containers have int (rather than uint) allowable indexes. */ if (index > INT_MAX) { @@ -419,7 +419,7 @@ public: } QV4::Scope scope(ctx); - if (ctx->argc() == 1 && ctx->args()[0].asFunctionObject()) { + if (ctx->argc() == 1 && ctx->args()[0].as<FunctionObject>()) { CompareFunctor cf(ctx, ctx->args()[0]); std::sort(d()->container.begin(), d()->container.end(), cf); } else { @@ -526,8 +526,8 @@ public: QMetaObject::metacall(d()->object, QMetaObject::WriteProperty, d()->propertyIndex, a); } - static QV4::ReturnedValue getIndexed(QV4::Managed *that, uint index, bool *hasProperty) - { return static_cast<QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); } + static QV4::ReturnedValue getIndexed(const QV4::Managed *that, uint index, bool *hasProperty) + { return static_cast<const QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); } static void putIndexed(Managed *that, uint index, const QV4::Value &value) { static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); } static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index) @@ -544,7 +544,7 @@ public: template <typename Container> Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const Container &container) - : Heap::Object(engine->emptyClass, engine->sequencePrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->sequencePrototype.objectValue()) , container(container) , propertyIndex(-1) , isReference(false) @@ -557,7 +557,7 @@ Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const template <typename Container> Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex) - : Heap::Object(engine->emptyClass, engine->sequencePrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->sequencePrototype.objectValue()) , object(object) , propertyIndex(propertyIndex) , isReference(true) @@ -700,11 +700,11 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo { *succeeded = true; - if (!array.asArrayObject()) { + if (!array.as<ArrayObject>()) { *succeeded = false; return QVariant(); } - QV4::Scope scope(array.asObject()->engine()); + QV4::Scope scope(array.as<Object>()->engine()); QV4::ScopedArrayObject a(scope, array); FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ *succeeded = false; return QVariant(); } @@ -717,7 +717,7 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo return qMetaTypeId<SequenceType>(); \ } else -int SequencePrototype::metaTypeForSequence(QV4::Object *object) +int SequencePrototype::metaTypeForSequence(const QV4::Object *object) { FOREACH_QML_SEQUENCE_TYPE(MAP_META_TYPE) /*else*/ { diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 9949278a89..61ff6e18de 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -70,7 +70,7 @@ struct SequencePrototype : public QV4::Object static bool isSequenceType(int sequenceTypeId); static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded); - static int metaTypeForSequence(Object *object); + static int metaTypeForSequence(const Object *object); static QVariant toVariant(Object *object); static QVariant toVariant(const Value &array, int typeHint, bool *succeeded); }; diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index e669924d4a..ddd7555dde 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -168,11 +168,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine char *buffer = data.data() + offset; memcpy(buffer, qstr.constData(), length*sizeof(QChar)); - } else if (v.asFunctionObject()) { + } else if (v.as<FunctionObject>()) { // XXX TODO: Implement passing function objects between the main and // worker scripts push(data, valueheader(WorkerUndefined)); - } else if (QV4::ArrayObject *array = v.asArrayObject()) { + } else if (const QV4::ArrayObject *array = v.as<ArrayObject>()) { uint length = array->getLength(); if (length > 0xFFFFFF) { push(data, valueheader(WorkerUndefined)); @@ -195,11 +195,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine reserve(data, sizeof(quint32) + sizeof(double)); push(data, valueheader(WorkerNumber)); push(data, v.asDouble()); - } else if (QV4::DateObject *d = v.asDateObject()) { + } else if (const QV4::DateObject *d = v.as<DateObject>()) { reserve(data, sizeof(quint32) + sizeof(double)); push(data, valueheader(WorkerDate)); push(data, d->date().asDouble()); - } else if (RegExpObject *re = v.as<RegExpObject>()) { + } else if (const RegExpObject *re = v.as<RegExpObject>()) { quint32 flags = re->flags(); QString pattern = re->source(); int length = pattern.length() + 1; @@ -218,7 +218,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine char *buffer = data.data() + offset; memcpy(buffer, pattern.constData(), length*sizeof(QChar)); - } else if (QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) { + } else if (const QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) { // XXX TODO: Generalize passing objects between the main thread and worker scripts so // that others can trivially plug in their elements. QQmlListModel *lm = qobject_cast<QQmlListModel *>(qobjectWrapper->object()); @@ -231,7 +231,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine } // No other QObject's are allowed to be sent push(data, valueheader(WorkerUndefined)); - } else if (Object *o = v.asObject()) { + } else if (const Object *o = v.as<Object>()) { if (o->isListType()) { // valid sequence. we generate a length (sequence length + 1 for the sequence type) uint seqLength = ScopedValue(scope, o->get(engine->id_length))->toUInt32(); @@ -265,7 +265,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine s = properties->getIndexed(ii); serialize(data, s, engine); - QV4::String *str = s->asString(); + QV4::String *str = s->as<String>(); val = o->get(str); if (scope.hasException()) scope.engine->catchException(); @@ -356,7 +356,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine) QVariant var = qVariantFromValue(ref); QV4::ScopedValue v(scope, scope.engine->fromVariant(var)); QV4::ScopedString s(scope, engine->newString(QStringLiteral("__qml:hidden:ref"))); - rv->asObject()->defineReadonlyProperty(s, v); + rv->as<Object>()->defineReadonlyProperty(s, v); agent->release(); agent->setEngine(engine); diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h index 861c7dd28d..8496fc32e7 100644 --- a/src/qml/jsruntime/qv4sparsearray_p.h +++ b/src/qml/jsruntime/qv4sparsearray_p.h @@ -35,11 +35,7 @@ #define QV4SPARSEARRAY_H #include "qv4global_p.h" -#include <QtCore/qmap.h> -#include "qv4value_inl_p.h" -#include "qv4scopedvalue_p.h" -#include "qv4property_p.h" -#include <assert.h> +#include <QtCore/qlist.h> //#define Q_MAP_DEBUG #ifdef Q_MAP_DEBUG @@ -188,7 +184,7 @@ public: typedef qptrdiff difference_type; typedef int size_type; -#ifndef QT_NO_DEBUG +#ifdef Q_MAP_DEBUG void dump() const; #endif }; @@ -261,7 +257,7 @@ inline void SparseArray::push_back(uint index, uint len) n->value = index; } -#ifndef QT_NO_DEBUG +#ifdef Q_MAP_DEBUG inline void SparseArray::dump() const { const SparseArrayNode *it = begin(); @@ -344,4 +340,4 @@ inline SparseArrayNode *SparseArray::upperBound(uint akey) QT_END_NAMESPACE -#endif // QMAP_H +#endif diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 5a0c83b4b9..a225825031 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -184,6 +184,11 @@ public: static uint toArrayIndex(const QString &str); }; +template<> +inline const String *Value::as() const { + return isManaged() && m && m->vtable->isString ? static_cast<const String *>(this) : 0; +} + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index e0b84f6da3..f4a6e455cd 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -36,7 +36,7 @@ #include "qv4regexp_p.h" #include "qv4regexpobject_p.h" #include "qv4objectproto_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4scopedvalue_p.h" #include "qv4alloca_p.h" #include <QtCore/QDateTime> @@ -80,7 +80,7 @@ Heap::StringObject::StringObject(InternalClass *ic, QV4::Object *prototype) } Heap::StringObject::StringObject(ExecutionEngine *engine, const Value &val) - : Heap::Object(engine->emptyClass, engine->stringPrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->stringPrototype.objectValue()) { value = val; Q_ASSERT(value.isString()); @@ -104,7 +104,7 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index) { ExecutionEngine *v4 = static_cast<StringObject *>(m)->engine(); Scope scope(v4); - Scoped<StringObject> o(scope, m->asStringObject()); + Scoped<StringObject> o(scope, m->as<StringObject>()); Q_ASSERT(!!o); if (index < static_cast<uint>(o->d()->value.stringValue()->toQString().length())) { @@ -158,9 +158,9 @@ Heap::StringCtor::StringCtor(QV4::ExecutionContext *scope) { } -ReturnedValue StringCtor::construct(Managed *m, CallData *callData) +ReturnedValue StringCtor::construct(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(m)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); Scope scope(v4); ScopedValue value(scope); if (callData->argc) @@ -170,9 +170,9 @@ ReturnedValue StringCtor::construct(Managed *m, CallData *callData) return Encode(v4->newStringObject(value)); } -ReturnedValue StringCtor::call(Managed *m, CallData *callData) +ReturnedValue StringCtor::call(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = static_cast<Object *>(m)->engine(); + ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); Scope scope(v4); ScopedValue value(scope); if (callData->argc) @@ -220,7 +220,7 @@ static QString getThisString(ExecutionContext *ctx) ScopedValue t(scope, ctx->thisObject()); if (t->isString()) return t->stringValue()->toQString(); - if (StringObject *thisString = t->asStringObject()) + if (StringObject *thisString = t->as<StringObject>()) return thisString->d()->value.stringValue()->toQString(); if (t->isUndefined() || t->isNull()) { scope.engine->throwTypeError(); @@ -234,7 +234,7 @@ ReturnedValue StringPrototype::method_toString(CallContext *context) if (context->thisObject().isString()) return context->thisObject().asReturnedValue(); - StringObject *o = context->thisObject().asStringObject(); + StringObject *o = context->thisObject().as<StringObject>(); if (!o) return context->engine()->throwTypeError(); return o->d()->value.asReturnedValue(); @@ -368,7 +368,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context) if (!rx) { ScopedCallData callData(scope, 1); callData->args[0] = regexp; - rx = context->d()->engine->regExpCtor.asFunctionObject()->construct(callData); + rx = context->d()->engine->regExpCtor.as<FunctionObject>()->construct(callData); } if (!rx) @@ -379,7 +379,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context) // ### use the standard builtin function, not the one that might be redefined in the proto ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec"))); - ScopedFunctionObject exec(scope, scope.engine->regExpPrototype.asObject()->get(execString)); + ScopedFunctionObject exec(scope, scope.engine->regExpPrototype.as<Object>()->get(execString)); ScopedCallData callData(scope, 1); callData->thisObject = rx; @@ -470,7 +470,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx) { Scope scope(ctx); QString string; - if (StringObject *thisString = ctx->thisObject().asStringObject()) + if (StringObject *thisString = ctx->thisObject().as<StringObject>()) string = thisString->d()->value.stringValue()->toQString(); else string = ctx->thisObject().toQString(); @@ -593,7 +593,7 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx) if (!regExp) { ScopedCallData callData(scope, 1); callData->args[0] = regExpValue; - regExpValue = ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData); + regExpValue = ctx->d()->engine->regExpCtor.as<FunctionObject>()->construct(callData); if (scope.engine->hasException) return Encode::undefined(); regExp = regExpValue->as<RegExpObject>(); diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index 459dc1322e..b0f2dd3e97 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -78,8 +78,8 @@ struct StringCtor: FunctionObject { V4_OBJECT2(StringCtor, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct StringPrototype: StringObject diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 429ec96f0b..94a9d90a5b 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -201,10 +201,10 @@ Heap::TypedArrayCtor::TypedArrayCtor(QV4::ExecutionContext *scope, TypedArray::T { } -ReturnedValue TypedArrayCtor::construct(Managed *m, CallData *callData) +ReturnedValue TypedArrayCtor::construct(const Managed *m, CallData *callData) { - Scope scope(static_cast<Object *>(m)->engine()); - Scoped<TypedArrayCtor> that(scope, static_cast<TypedArrayCtor *>(m)); + Scope scope(static_cast<const Object *>(m)->engine()); + Scoped<TypedArrayCtor> that(scope, static_cast<const TypedArrayCtor *>(m)); if (!callData->argc || !callData->args[0].isObject()) { // ECMA 6 22.2.1.1 @@ -329,13 +329,13 @@ ReturnedValue TypedArrayCtor::construct(Managed *m, CallData *callData) return array.asReturnedValue(); } -ReturnedValue TypedArrayCtor::call(Managed *that, CallData *callData) +ReturnedValue TypedArrayCtor::call(const Managed *that, CallData *callData) { return construct(that, callData); } Heap::TypedArray::TypedArray(ExecutionEngine *e, Type t) - : Heap::Object(e->emptyClass, e->typedArrayPrototype[t].asObject()), + : Heap::Object(e->emptyClass, e->typedArrayPrototype[t].objectValue()), type(operations + t), arrayType(t) { @@ -347,10 +347,10 @@ void TypedArray::markObjects(Heap::Base *that, ExecutionEngine *e) Object::markObjects(that, e); } -ReturnedValue TypedArray::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProperty) { - Scope scope(static_cast<Object *>(m)->engine()); - Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m)); + Scope scope(static_cast<const Object *>(m)->engine()); + Scoped<TypedArray> a(scope, static_cast<const TypedArray *>(m)); uint bytesPerElement = a->d()->type->bytesPerElement; uint byteOffset = a->d()->byteOffset + index * bytesPerElement; diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index afd1bb97e7..d2f5eeaf44 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -113,7 +113,7 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object } static void markObjects(Heap::Base *that, ExecutionEngine *e); - static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static void putIndexed(Managed *m, uint index, const Value &value); }; @@ -121,8 +121,8 @@ struct TypedArrayCtor: FunctionObject { V4_OBJECT2(TypedArrayCtor, FunctionObject) - static ReturnedValue construct(Managed *m, CallData *callData); - static ReturnedValue call(Managed *that, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index 68228f06bb..0ea4676f47 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -35,7 +35,7 @@ #ifndef V4_BOOTSTRAP #include <qv4object_p.h> #include <qv4objectproto_p.h> -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #endif #include <wtf/MathExtras.h> diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h index 3a4c5c4822..9297f2ceda 100644 --- a/src/qml/jsruntime/qv4value_inl_p.h +++ b/src/qml/jsruntime/qv4value_inl_p.h @@ -36,7 +36,7 @@ #include <cmath> // this HAS to come #include "qv4value_p.h" - +#include <private/qv4heap_p.h> #include "qv4string_p.h" #include "qv4managed_p.h" #include "qv4engine_p.h" @@ -45,36 +45,11 @@ QT_BEGIN_NAMESPACE namespace QV4 { -inline bool Value::isString() const -{ - if (!isManaged()) - return false; - return m && m->vtable->isString; -} -inline bool Value::isObject() const -{ - if (!isManaged()) - return false; - return m && m->vtable->isObject; -} - -inline bool Value::isPrimitive() const -{ - return !isObject(); -} - -inline String *Value::asString() const -{ - if (isString()) - return stringValue(); - return 0; -} - -inline void Value::mark(ExecutionEngine *e) const +inline void Value::mark(ExecutionEngine *e) { if (!val) return; - Managed *m = asManaged(); + Managed *m = as<Managed>(); if (m) m->mark(e); } @@ -178,6 +153,13 @@ inline bool Value::toBoolean() const } } +inline +ReturnedValue Heap::Base::asReturnedValue() const +{ + return Value::fromHeapObject(const_cast<Heap::Base *>(this)).asReturnedValue(); +} + + #ifndef V4_BOOTSTRAP inline uint Value::asArrayIndex() const { @@ -231,51 +213,6 @@ inline uint Value::asArrayLength(bool *ok) const return idx; } -inline Object *Value::asObject() const -{ - return isObject() ? objectValue() : 0; -} - -inline FunctionObject *Value::asFunctionObject() const -{ - return isObject() ? managed()->asFunctionObject() : 0; -} - -inline NumberObject *Value::asNumberObject() const -{ - return isObject() ? managed()->asNumberObject() : 0; -} - -inline StringObject *Value::asStringObject() const -{ - return isObject() ? managed()->asStringObject() : 0; -} - -inline DateObject *Value::asDateObject() const -{ - return isObject() ? managed()->asDateObject() : 0; -} - -inline ArrayObject *Value::asArrayObject() const -{ - return isObject() ? managed()->asArrayObject() : 0; -} - -inline ErrorObject *Value::asErrorObject() const -{ - return isObject() ? managed()->asErrorObject() : 0; -} - -template<typename T> -inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; } - -#ifndef V4_BOOTSTRAP - -template<> -inline String *value_cast(const Value &v) { - return v.asString(); -} - template<> inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v) { @@ -284,8 +221,6 @@ inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v) #endif -#endif - } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index cd1aef86d7..7deb2098ac 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -37,61 +37,18 @@ #include <QtCore/QString> #include "qv4global_p.h" +#include <private/qv4heap_p.h> QT_BEGIN_NAMESPACE namespace QV4 { -typedef uint Bool; - namespace Heap { - -struct Q_QML_EXPORT Base { - union { - const ManagedVTable *vtable; - quintptr mm_data; - }; - - inline ReturnedValue asReturnedValue() const; - inline void mark(QV4::ExecutionEngine *engine); - - enum { - MarkBit = 0x1, - NotInUse = 0x2, - PointerMask = ~0x3 - }; - - ManagedVTable *gcGetVtable() const { - return reinterpret_cast<ManagedVTable *>(mm_data & PointerMask); - } - inline bool isMarked() const { - return mm_data & MarkBit; - } - inline void setMarkBit() { - mm_data |= MarkBit; - } - inline void clearMarkBit() { - mm_data &= ~MarkBit; - } - - inline bool inUse() const { - return !(mm_data & NotInUse); - } - - Base *nextFree() { - return reinterpret_cast<Base *>(mm_data & PointerMask); - } - void setNextFree(Base *m) { - mm_data = (reinterpret_cast<quintptr>(m) | NotInUse); - } - - void *operator new(size_t, Managed *m) { return m; } - void *operator new(size_t, Heap::Base *m) { return m; } - void operator delete(void *, Heap::Base *) {} -}; - + struct Base; } +typedef uint Bool; + struct Q_QML_PRIVATE_EXPORT Value { /* @@ -326,8 +283,6 @@ struct Q_QML_PRIVATE_EXPORT Value return v; } - static inline Value fromManaged(Managed *m); - int toUInt16() const; inline int toInt32() const; inline unsigned int toUInt32() const; @@ -349,17 +304,28 @@ struct Q_QML_PRIVATE_EXPORT Value return b; } - inline String *asString() const; - inline Managed *asManaged() const; - inline Object *asObject() const; - inline FunctionObject *asFunctionObject() const; - inline NumberObject *asNumberObject() const; - inline StringObject *asStringObject() const; - inline DateObject *asDateObject() const; - inline ArrayObject *asArrayObject() const; - inline ErrorObject *asErrorObject() const; + template <typename T> + const T *as() const { + if (!m || !isManaged()) + return 0; + + 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; + while (vt) { + if (vt == T::staticVTable()) + return static_cast<const T *>(this); + vt = vt->parent; + } + return 0; + } + template <typename T> + T *as() { + return const_cast<T *>(const_cast<const Value *>(this)->as<T>()); + } - template<typename T> inline T *as() const; template<typename T> inline T *cast() { return static_cast<T *>(managed()); } @@ -376,12 +342,17 @@ struct Q_QML_PRIVATE_EXPORT Value // Section 9.12 bool sameValue(Value other) const; - inline void mark(ExecutionEngine *e) const; + inline void mark(ExecutionEngine *e); Value &operator =(const ScopedValue &v); Value &operator=(ReturnedValue v) { val = v; return *this; } Value &operator=(Managed *m) { - val = Value::fromManaged(m).val; + if (!m) { + tag = Undefined_Type; + uint_32 = 0; + } else { + val = reinterpret_cast<Value *>(m)->val; + } return *this; } Value &operator=(Heap::Base *o) { @@ -400,13 +371,25 @@ struct Q_QML_PRIVATE_EXPORT Value } }; -inline Managed *Value::asManaged() const +inline bool Value::isString() const +{ + if (!isManaged()) + return false; + return m && m->vtable->isString; +} +inline bool Value::isObject() const +{ + if (!isManaged()) + return false; + return m && m->vtable->isObject; +} + +inline bool Value::isPrimitive() const { - if (isManaged()) - return managed(); - return 0; + return !isObject(); } + struct Q_QML_PRIVATE_EXPORT Primitive : public Value { inline static Primitive emptyValue(); @@ -519,19 +502,6 @@ private: Encode(void *); }; -inline -ReturnedValue Heap::Base::asReturnedValue() const -{ - return Value::fromHeapObject(const_cast<Heap::Base *>(this)).asReturnedValue(); -} - - -template<typename T> -T *value_cast(const Value &v) -{ - return v.as<T>(); -} - template<typename T> ReturnedValue value_convert(ExecutionEngine *e, const Value &v); diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 966f83acef..d862c12ba8 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -44,7 +44,7 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(VariantObject); Heap::VariantObject::VariantObject(QV4::ExecutionEngine *engine, const QVariant &value) - : Heap::Object(engine->emptyClass, engine->variantPrototype.asObject()) + : Heap::Object(engine->emptyClass, engine->variantPrototype.objectValue()) { data = value; if (isScarce()) |