aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/jsruntime.pri7
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp123
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h56
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp486
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h93
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp191
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h11
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp24
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h10
-rw-r--r--src/qml/jsruntime/qv4context.cpp341
-rw-r--r--src/qml/jsruntime/qv4context_p.h169
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp268
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h42
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp34
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp294
-rw-r--r--src/qml/jsruntime/qv4engine_p.h19
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp204
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h141
-rw-r--r--src/qml/jsruntime/qv4function.cpp5
-rw-r--r--src/qml/jsruntime/qv4function_p.h4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp319
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h130
-rw-r--r--src/qml/jsruntime/qv4global_p.h14
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp102
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h7
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp4
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp36
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h12
-rw-r--r--src/qml/jsruntime/qv4include.cpp51
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp63
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h3
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp72
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h14
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp236
-rw-r--r--src/qml/jsruntime/qv4managed.cpp35
-rw-r--r--src/qml/jsruntime/qv4managed_p.h242
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp110
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h7
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp30
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h20
-rw-r--r--src/qml/jsruntime/qv4mm.cpp90
-rw-r--r--src/qml/jsruntime/qv4mm_p.h59
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp66
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4object.cpp359
-rw-r--r--src/qml/jsruntime/qv4object_p.h213
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp80
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h31
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp195
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h10
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h2
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp23
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h43
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp212
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h59
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp43
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h95
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp179
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h59
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp239
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h44
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h113
-rw-r--r--src/qml/jsruntime/qv4script.cpp126
-rw-r--r--src/qml/jsruntime/qv4script_p.h30
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp219
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp8
-rw-r--r--src/qml/jsruntime/qv4string.cpp120
-rw-r--r--src/qml/jsruntime/qv4string_p.h107
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp234
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h24
-rw-r--r--src/qml/jsruntime/qv4value.cpp6
-rw-r--r--src/qml/jsruntime/qv4value_inl_p.h4
-rw-r--r--src/qml/jsruntime/qv4value_p.h12
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp68
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h24
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp50
78 files changed, 3748 insertions, 3546 deletions
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 72010d3fa8..c27aaa90d8 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -105,13 +105,6 @@ SOURCES += \
$$PWD/qv4string.cpp \
$$PWD/qv4value.cpp
-# Use SSE2 floating point math on 32 bit instead of the default
-# 387 to make test results pass on 32 and on 64 bit builds.
-linux-g++*:isEqual(QT_ARCH,i386) {
- QMAKE_CFLAGS += -march=pentium4 -msse2 -mfpmath=sse
- QMAKE_CXXFLAGS += -march=pentium4 -msse2 -mfpmath=sse
-}
-
valgrind {
DEFINES += V4_USE_VALGRIND
}
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 987b228209..71563b7b0d 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -46,63 +46,58 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(ArgumentsObject);
-ArgumentsObject::ArgumentsObject(CallContext *context)
- : Object(context->strictMode ? context->engine->strictArgumentsObjectClass : context->engine->argumentsObjectClass)
+ArgumentsObject::Data::Data(CallContext *context)
+ : Object::Data(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass)
, context(context)
, fullyCreated(false)
{
- ExecutionEngine *v4 = context->engine;
+ Q_ASSERT(internalClass->vtable == staticVTable());
+
+ ExecutionEngine *v4 = context->d()->engine;
Scope scope(v4);
- ScopedObject protectThis(scope, this);
+ Scoped<ArgumentsObject> args(scope, this);
- setArrayType(ArrayData::Complex);
+ args->setArrayType(ArrayData::Complex);
- if (context->strictMode) {
- Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
- Q_ASSERT(CallerPropertyIndex == internalClass->find(context->engine->id_caller));
- propertyAt(CalleePropertyIndex)->value = v4->thrower;
- propertyAt(CalleePropertyIndex)->set = v4->thrower;
- propertyAt(CallerPropertyIndex)->value = v4->thrower;
- propertyAt(CallerPropertyIndex)->set = v4->thrower;
+ if (context->d()->strictMode) {
+ Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee));
+ Q_ASSERT(CallerPropertyIndex == args->internalClass()->find(context->d()->engine->id_caller));
+ args->propertyAt(CalleePropertyIndex)->value = v4->thrower;
+ args->propertyAt(CalleePropertyIndex)->set = v4->thrower;
+ args->propertyAt(CallerPropertyIndex)->value = v4->thrower;
+ args->propertyAt(CallerPropertyIndex)->set = v4->thrower;
- arrayReserve(context->callData->argc);
- arrayPut(0, context->callData->args, context->callData->argc);
- fullyCreated = true;
+ args->arrayReserve(context->d()->callData->argc);
+ args->arrayPut(0, context->d()->callData->args, context->d()->callData->argc);
+ args->d()->fullyCreated = true;
} else {
- hasAccessorProperty = 1;
- Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
- memberData[CalleePropertyIndex] = context->function->asReturnedValue();
+ args->setHasAccessorProperty();
+ Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee));
+ args->memberData()[CalleePropertyIndex] = context->d()->function->asReturnedValue();
}
- Q_ASSERT(LengthPropertyIndex == internalClass->find(context->engine->id_length));
- memberData[LengthPropertyIndex] = Primitive::fromInt32(context->realArgumentCount);
-
- Q_ASSERT(internalClass->vtable == staticVTable());
-}
-
-void ArgumentsObject::destroy(Managed *that)
-{
- static_cast<ArgumentsObject *>(that)->~ArgumentsObject();
+ Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(context->d()->engine->id_length));
+ args->memberData()[LengthPropertyIndex] = Primitive::fromInt32(context->d()->realArgumentCount);
}
void ArgumentsObject::fullyCreate()
{
- if (fullyCreated)
+ if (fullyCreated())
return;
- uint numAccessors = qMin((int)context->function->formalParameterCount(), context->realArgumentCount);
- uint argCount = qMin(context->realArgumentCount, context->callData->argc);
+ uint numAccessors = qMin((int)context()->d()->function->formalParameterCount(), context()->d()->realArgumentCount);
+ uint argCount = qMin(context()->d()->realArgumentCount, context()->d()->callData->argc);
ArrayData::realloc(this, ArrayData::Sparse, 0, argCount, true);
- context->engine->requireArgumentsAccessors(numAccessors);
- mappedArguments.ensureIndex(engine(), numAccessors);
+ context()->d()->engine->requireArgumentsAccessors(numAccessors);
+ mappedArguments().ensureIndex(engine(), numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
- mappedArguments[i] = context->callData->args[i];
- arraySet(i, context->engine->argumentsAccessors[i], Attr_Accessor);
+ mappedArguments()[i] = context()->d()->callData->args[i];
+ arraySet(i, context()->d()->engine->argumentsAccessors[i], Attr_Accessor);
}
- arrayPut(numAccessors, context->callData->args + numAccessors, argCount - numAccessors);
+ arrayPut(numAccessors, context()->d()->callData->args + numAccessors, argCount - numAccessors);
for (uint i = numAccessors; i < argCount; ++i)
setArrayAttributes(i, Attr_Data);
- fullyCreated = true;
+ d()->fullyCreated = true;
}
bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const Property &desc, PropertyAttributes attrs)
@@ -110,26 +105,26 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
fullyCreate();
Scope scope(ctx);
- Property *pd = arrayData->getProperty(index);
+ Property *pd = arrayData()->getProperty(index);
Property map;
PropertyAttributes mapAttrs;
bool isMapped = false;
- uint numAccessors = qMin((int)context->function->formalParameterCount(), context->realArgumentCount);
+ uint numAccessors = qMin((int)context()->d()->function->formalParameterCount(), context()->d()->realArgumentCount);
if (pd && index < (uint)numAccessors)
- isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors[index].getter();
+ isMapped = arrayData()->attributes(index).isAccessor() && pd->getter() == context()->d()->engine->argumentsAccessors[index].getter();
if (isMapped) {
- mapAttrs = arrayData->attributes(index);
+ mapAttrs = arrayData()->attributes(index);
map.copy(*pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
- pd = arrayData->getProperty(index);
- pd->value = mappedArguments[index];
+ pd = arrayData()->getProperty(index);
+ pd->value = mappedArguments()[index];
}
- bool strict = ctx->strictMode;
- ctx->strictMode = false;
+ bool strict = ctx->d()->strictMode;
+ ctx->d()->strictMode = false;
bool result = Object::defineOwnProperty2(ctx, index, desc, attrs);
- ctx->strictMode = strict;
+ ctx->d()->strictMode = strict;
if (isMapped && attrs.isData()) {
ScopedCallData callData(scope, 1);
@@ -139,12 +134,12 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
if (attrs.isWritable()) {
setArrayAttributes(index, mapAttrs);
- pd = arrayData->getProperty(index);
+ pd = arrayData()->getProperty(index);
pd->copy(map, mapAttrs);
}
}
- if (ctx->strictMode && !result)
+ if (ctx->d()->strictMode && !result)
return ctx->throwTypeError();
return result;
}
@@ -152,13 +147,13 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
ReturnedValue ArgumentsObject::getIndexed(Managed *m, uint index, bool *hasProperty)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
- if (args->fullyCreated)
+ if (args->fullyCreated())
return Object::getIndexed(m, index, hasProperty);
- if (index < static_cast<uint>(args->context->callData->argc)) {
+ if (index < static_cast<uint>(args->context()->d()->callData->argc)) {
if (hasProperty)
*hasProperty = true;
- return args->context->callData->args[index].asReturnedValue();
+ return args->context()->d()->callData->args[index].asReturnedValue();
}
if (hasProperty)
*hasProperty = false;
@@ -168,21 +163,21 @@ ReturnedValue ArgumentsObject::getIndexed(Managed *m, uint index, bool *hasPrope
void ArgumentsObject::putIndexed(Managed *m, uint index, const ValueRef value)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
- if (!args->fullyCreated && index >= static_cast<uint>(args->context->callData->argc))
+ if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->d()->callData->argc))
args->fullyCreate();
- if (args->fullyCreated) {
+ if (args->fullyCreated()) {
Object::putIndexed(m, index, value);
return;
}
- args->context->callData->args[index] = value;
+ args->context()->d()->callData->args[index] = value;
}
bool ArgumentsObject::deleteIndexedProperty(Managed *m, uint index)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
- if (!args->fullyCreated)
+ if (!args->fullyCreated())
args->fullyCreate();
return Object::deleteIndexedProperty(m, index);
}
@@ -190,11 +185,11 @@ bool ArgumentsObject::deleteIndexedProperty(Managed *m, uint index)
PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
{
const ArgumentsObject *args = static_cast<const ArgumentsObject *>(m);
- if (args->fullyCreated)
+ if (args->fullyCreated())
return Object::queryIndexed(m, index);
- uint numAccessors = qMin((int)args->context->function->formalParameterCount(), args->context->realArgumentCount);
- uint argCount = qMin(args->context->realArgumentCount, args->context->callData->argc);
+ uint numAccessors = qMin((int)args->context()->d()->function->formalParameterCount(), args->context()->d()->realArgumentCount);
+ uint argCount = qMin(args->context()->d()->realArgumentCount, args->context()->d()->callData->argc);
if (index >= argCount)
return PropertyAttributes();
if (index >= numAccessors)
@@ -213,8 +208,8 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
if (!o)
return v4->currentContext()->throwTypeError();
- Q_ASSERT(g->index < static_cast<unsigned>(o->context->callData->argc));
- return o->context->argument(g->index);
+ Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->d()->callData->argc));
+ return o->context()->argument(g->index());
}
DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction);
@@ -228,17 +223,17 @@ ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
if (!o)
return v4->currentContext()->throwTypeError();
- Q_ASSERT(s->index < static_cast<unsigned>(o->context->callData->argc));
- o->context->callData->args[s->index] = callData->argc ? callData->args[0].asReturnedValue() : Encode::undefined();
+ Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->d()->callData->argc));
+ o->context()->d()->callData->args[s->index()] = callData->argc ? callData->args[0].asReturnedValue() : Encode::undefined();
return Encode::undefined();
}
void ArgumentsObject::markObjects(Managed *that, ExecutionEngine *e)
{
ArgumentsObject *o = static_cast<ArgumentsObject *>(that);
- if (o->context)
- o->context->mark(e);
- o->mappedArguments.mark(e);
+ if (o->context())
+ o->context()->mark(e);
+ o->mappedArguments().mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 80c2a70501..59ab9f020e 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -50,43 +50,58 @@ namespace QV4 {
struct ArgumentsGetterFunction: FunctionObject
{
- V4_OBJECT
- uint index;
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, uint index)
+ : FunctionObject::Data(scope)
+ , index(index)
+ {
+ setVTable(staticVTable());
+ }
+ uint index;
+ };
+ V4_OBJECT(FunctionObject)
- ArgumentsGetterFunction(ExecutionContext *scope, uint index)
- : FunctionObject(scope), index(index) {
- setVTable(staticVTable());
- }
+ uint index() const { return d()->index; }
static ReturnedValue call(Managed *that, CallData *d);
};
struct ArgumentsSetterFunction: FunctionObject
{
- V4_OBJECT
- uint index;
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, uint index)
+ : FunctionObject::Data(scope)
+ , index(index)
+ {
+ setVTable(staticVTable());
+ }
+ uint index;
+ };
+ V4_OBJECT(FunctionObject)
- ArgumentsSetterFunction(ExecutionContext *scope, uint index)
- : FunctionObject(scope), index(index) {
- setVTable(staticVTable());
- }
+ uint index() const { return d()->index; }
static ReturnedValue call(Managed *that, CallData *callData);
};
struct ArgumentsObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(CallContext *context);
+ CallContext *context;
+ bool fullyCreated;
+ Members mappedArguments;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(ArgumentsObject)
- CallContext *context;
- bool fullyCreated;
- Members mappedArguments;
- ArgumentsObject(CallContext *context);
- ~ArgumentsObject() {}
+
+ CallContext *context() const { return d()->context; }
+ bool fullyCreated() const { return d()->fullyCreated; }
+ Members &mappedArguments() { return d()->mappedArguments; }
static bool isNonStrictArgumentsObject(Managed *m) {
- return m->internalClass->vtable->type == Type_ArgumentsObject &&
- !static_cast<ArgumentsObject *>(m)->context->strictMode;
+ return m->internalClass()->vtable->type == Type_ArgumentsObject &&
+ !static_cast<ArgumentsObject *>(m)->context()->d()->strictMode;
}
enum {
@@ -100,7 +115,6 @@ struct ArgumentsObject: Object {
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static void markObjects(Managed *that, ExecutionEngine *e);
- static void destroy(Managed *);
void fullyCreate();
};
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index ed2122fb89..f56c31b177 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -45,9 +45,25 @@
using namespace QV4;
+const QV4::ManagedVTable QV4::ArrayData::static_vtbl = {
+ 0,
+ QV4::ArrayData::IsExecutionContext,
+ QV4::ArrayData::IsString,
+ QV4::ArrayData::IsObject,
+ QV4::ArrayData::IsFunctionObject,
+ QV4::ArrayData::IsErrorObject,
+ QV4::ArrayData::IsArrayData,
+ 0,
+ QV4::ArrayData::MyType,
+ "ArrayData",
+ Q_VTABLE_FUNCTION(QV4::ArrayData, destroy),
+ 0,
+ isEqualTo
+};
+
const ArrayVTable SimpleArrayData::static_vtbl =
{
- DEFINE_MANAGED_VTABLE_INT(SimpleArrayData),
+ DEFINE_MANAGED_VTABLE_INT(SimpleArrayData, 0),
SimpleArrayData::Simple,
SimpleArrayData::reallocate,
SimpleArrayData::get,
@@ -64,7 +80,7 @@ const ArrayVTable SimpleArrayData::static_vtbl =
const ArrayVTable SparseArrayData::static_vtbl =
{
- DEFINE_MANAGED_VTABLE_INT(SparseArrayData),
+ DEFINE_MANAGED_VTABLE_INT(SparseArrayData, 0),
ArrayData::Sparse,
SparseArrayData::reallocate,
SparseArrayData::get,
@@ -82,7 +98,7 @@ const ArrayVTable SparseArrayData::static_vtbl =
void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes)
{
- ArrayData *d = o->arrayData;
+ ArrayData *d = o->arrayData();
uint oldAlloc = 0;
uint toCopy = 0;
@@ -90,19 +106,19 @@ void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool e
alloc = 8;
if (d) {
- bool hasAttrs = d->attrs;
+ bool hasAttrs = d->attrs();
enforceAttributes |= hasAttrs;
- if (!offset && alloc <= d->alloc && newType == d->type && hasAttrs == enforceAttributes)
+ if (!offset && alloc <= d->alloc() && newType == d->type() && hasAttrs == enforceAttributes)
return;
- oldAlloc = d->alloc;
- if (d->type < Sparse) {
- offset = qMax(offset, static_cast<SimpleArrayData *>(d)->offset);
- toCopy = static_cast<SimpleArrayData *>(d)->len;
+ oldAlloc = d->alloc();
+ if (d->type() < Sparse) {
+ offset = qMax(offset, static_cast<SimpleArrayData *>(d)->offset());
+ toCopy = static_cast<SimpleArrayData *>(d)->len();
} else {
Q_ASSERT(!offset);
- toCopy = d->alloc;
+ toCopy = d->alloc();
newType = Sparse;
}
}
@@ -115,69 +131,69 @@ void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool e
size += alloc*sizeof(PropertyAttributes);
if (newType < Sparse) {
- size += sizeof(SimpleArrayData);
+ size += sizeof(SimpleArrayData::Data);
SimpleArrayData *newData = static_cast<SimpleArrayData *>(o->engine()->memoryManager->allocManaged(size));
- new (newData) SimpleArrayData(o->engine());
- newData->alloc = alloc - offset;
- newData->type = newType;
- newData->data = reinterpret_cast<Value *>(newData + 1) + offset;
- newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) + offset : 0;
- newData->offset = offset;
- newData->len = d ? static_cast<SimpleArrayData *>(d)->len : 0;
- o->arrayData = newData;
+ new (newData->d()) SimpleArrayData::Data(o->engine());
+ newData->setAlloc(alloc - offset);
+ newData->setType(newType);
+ newData->setArrayData(reinterpret_cast<Value *>(newData->d() + 1) + offset);
+ newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->arrayData() + alloc) + offset : 0);
+ newData->offset() = offset;
+ newData->len() = d ? static_cast<SimpleArrayData *>(d)->len() : 0;
+ o->setArrayData(newData);
} else {
- size += sizeof(SparseArrayData);
+ size += sizeof(SparseArrayData::Data);
SparseArrayData *newData = static_cast<SparseArrayData *>(o->engine()->memoryManager->allocManaged(size));
- new (newData) SparseArrayData(o->engine());
- newData->alloc = alloc;
- newData->type = newType;
- newData->data = reinterpret_cast<Value *>(newData + 1);
- newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) : 0;
- o->arrayData = newData;
+ new (newData->d()) SparseArrayData::Data(o->engine());
+ newData->setAlloc(alloc);
+ newData->setType(newType);
+ newData->setArrayData(reinterpret_cast<Value *>(newData->d() + 1));
+ newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->arrayData() + alloc) : 0);
+ o->setArrayData(newData);
}
if (d) {
- memcpy(o->arrayData->data, d->data, sizeof(Value)*toCopy);
+ memcpy(o->arrayData()->arrayData(), d->arrayData(), sizeof(Value)*toCopy);
if (enforceAttributes) {
- if (d->attrs)
- memcpy(o->arrayData->attrs, d->attrs, sizeof(PropertyAttributes)*toCopy);
+ if (d->attrs())
+ memcpy(o->arrayData()->attrs(), d->attrs(), sizeof(PropertyAttributes)*toCopy);
else
for (uint i = 0; i < toCopy; ++i)
- o->arrayData->attrs[i] = Attr_Data;
+ o->arrayData()->attrs()[i] = Attr_Data;
}
}
if (newType != Sparse)
return;
- SparseArrayData *newData = static_cast<SparseArrayData *>(o->arrayData);
- if (d && d->type == Sparse) {
+ SparseArrayData *newData = static_cast<SparseArrayData *>(o->arrayData());
+ if (d && d->type() == Sparse) {
SparseArrayData *old = static_cast<SparseArrayData *>(d);
- newData->sparse = old->sparse;
- old->sparse = 0;
- newData->freeList = old->freeList;
+ newData->setSparse(old->sparse());
+ old->setSparse(0);
+ newData->freeList() = old->freeList();
} else {
- newData->sparse = new SparseArray;
- uint *lastFree = &newData->freeList;
+ newData->setSparse(new SparseArray);
+ uint *lastFree = &newData->freeList();
for (uint i = 0; i < toCopy; ++i) {
- if (!newData->data[i].isEmpty()) {
- SparseArrayNode *n = newData->sparse->insert(i);
+ if (!newData->arrayData()[i].isEmpty()) {
+ SparseArrayNode *n = newData->sparse()->insert(i);
n->value = i;
} else {
*lastFree = i;
- newData->data[i].tag = Value::Empty_Type;
- lastFree = &newData->data[i].uint_32;
+ newData->arrayData()[i].tag = Value::Empty_Type;
+ lastFree = &newData->arrayData()[i].uint_32;
}
}
}
- uint *lastFree = &newData->freeList;
- for (uint i = toCopy; i < newData->alloc; ++i) {
+ uint *lastFree = &newData->freeList();
+ for (uint i = toCopy; i < newData->alloc(); ++i) {
*lastFree = i;
- newData->data[i].tag = Value::Empty_Type;
- lastFree = &newData->data[i].uint_32;
+ newData->arrayData()[i].tag = Value::Empty_Type;
+ lastFree = &newData->arrayData()[i].uint_32;
}
- *lastFree = newData->alloc;
+ *lastFree = newData->alloc();
// ### Could explicitly free the old data
}
@@ -185,248 +201,244 @@ void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool e
void SimpleArrayData::getHeadRoom(Object *o)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
Q_ASSERT(dd);
- Q_ASSERT(!dd->offset);
- uint offset = qMax(dd->len >> 2, (uint)16);
+ Q_ASSERT(!dd->offset());
+ uint offset = qMax(dd->len() >> 2, (uint)16);
realloc(o, Simple, offset, 0, false);
}
ArrayData *SimpleArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
{
realloc(o, Simple, 0, n, enforceAttributes);
- return o->arrayData;
+ return o->arrayData();
}
void ArrayData::ensureAttributes(Object *o)
{
- if (o->arrayData && o->arrayData->attrs)
+ if (o->arrayData() && o->arrayData()->attrs())
return;
ArrayData::realloc(o, Simple, 0, 0, true);
}
-void SimpleArrayData::destroy(Managed *)
-{
-}
-
void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e)
{
SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
- uint l = dd->len;
+ uint l = dd->len();
for (uint i = 0; i < l; ++i)
- dd->data[i].mark(e);
+ dd->arrayData()[i].mark(e);
}
ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index)
{
const SimpleArrayData *dd = static_cast<const SimpleArrayData *>(d);
- if (index >= dd->len)
+ if (index >= dd->len())
return Primitive::emptyValue().asReturnedValue();
- return dd->data[index].asReturnedValue();
+ return dd->arrayData()[index].asReturnedValue();
}
bool SimpleArrayData::put(Object *o, uint index, ValueRef value)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor());
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ Q_ASSERT(index >= dd->len() || !dd->attrs() || !dd->attrs()[index].isAccessor());
// ### honour attributes
- dd->data[index] = value;
- if (index >= dd->len) {
- if (dd->attrs)
- dd->attrs[index] = Attr_Data;
- dd->len = index + 1;
+ dd->arrayData()[index] = value;
+ if (index >= dd->len()) {
+ if (dd->attrs())
+ dd->attrs()[index] = Attr_Data;
+ dd->len() = index + 1;
}
return true;
}
bool SimpleArrayData::del(Object *o, uint index)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- if (index >= dd->len)
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ if (index >= dd->len())
return true;
- if (!dd->attrs || dd->attrs[index].isConfigurable()) {
- dd->data[index] = Primitive::emptyValue();
- if (dd->attrs)
- dd->attrs[index] = Attr_Data;
+ if (!dd->attrs() || dd->attrs()[index].isConfigurable()) {
+ dd->arrayData()[index] = Primitive::emptyValue();
+ if (dd->attrs())
+ dd->attrs()[index] = Attr_Data;
return true;
}
- if (dd->data[index].isEmpty())
+ if (dd->arrayData()[index].isEmpty())
return true;
return false;
}
void SimpleArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
{
- o->arrayData->attrs[index] = attrs;
+ o->arrayData()->attrs()[index] = attrs;
}
PropertyAttributes SimpleArrayData::attribute(const ArrayData *d, uint index)
{
- return d->attrs[index];
+ return d->attrs()[index];
}
void SimpleArrayData::push_front(Object *o, Value *values, uint n)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- Q_ASSERT(!dd->attrs);
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ Q_ASSERT(!dd->attrs());
for (int i = n - 1; i >= 0; --i) {
- if (!dd->offset) {
+ if (!dd->offset()) {
getHeadRoom(o);
- dd = static_cast<SimpleArrayData *>(o->arrayData);
+ dd = static_cast<SimpleArrayData *>(o->arrayData());
}
- --dd->offset;
- --dd->data;
- ++dd->len;
- ++dd->alloc;
- *dd->data = values[i].asReturnedValue();
+ --dd->offset();
+ --dd->arrayData();
+ ++dd->len();
+ ++dd->alloc();
+ *dd->arrayData() = values[i].asReturnedValue();
}
}
ReturnedValue SimpleArrayData::pop_front(Object *o)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- Q_ASSERT(!dd->attrs);
- if (!dd->len)
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ Q_ASSERT(!dd->attrs());
+ if (!dd->len())
return Encode::undefined();
- ReturnedValue v = dd->data[0].isEmpty() ? Encode::undefined() : dd->data[0].asReturnedValue();
- ++dd->offset;
- ++dd->data;
- --dd->len;
- --dd->alloc;
+ ReturnedValue v = dd->arrayData()[0].isEmpty() ? Encode::undefined() : dd->arrayData()[0].asReturnedValue();
+ ++dd->offset();
+ ++dd->arrayData();
+ --dd->len();
+ --dd->alloc();
return v;
}
uint SimpleArrayData::truncate(Object *o, uint newLen)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- if (dd->len < newLen)
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ if (dd->len() < newLen)
return newLen;
- if (dd->attrs) {
- Value *it = dd->data + dd->len;
- const Value *begin = dd->data + newLen;
+ if (dd->attrs()) {
+ Value *it = dd->arrayData() + dd->len();
+ const Value *begin = dd->arrayData() + newLen;
while (--it >= begin) {
- if (!it->isEmpty() && !dd->attrs[it - dd->data].isConfigurable()) {
- newLen = it - dd->data + 1;
+ if (!it->isEmpty() && !dd->attrs()[it - dd->arrayData()].isConfigurable()) {
+ newLen = it - dd->arrayData() + 1;
break;
}
*it = Primitive::emptyValue();
}
}
- dd->len = newLen;
+ dd->len() = newLen;
return newLen;
}
uint SimpleArrayData::length(const ArrayData *d)
{
- return static_cast<const SimpleArrayData *>(d)->len;
+ return static_cast<const SimpleArrayData *>(d)->len();
}
bool SimpleArrayData::putArray(Object *o, uint index, Value *values, uint n)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- if (index + n > dd->alloc) {
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
+ if (index + n > dd->alloc()) {
reallocate(o, index + n + 1, false);
- dd = static_cast<SimpleArrayData *>(o->arrayData);
+ dd = static_cast<SimpleArrayData *>(o->arrayData());
}
- for (uint i = dd->len; i < index; ++i)
- dd->data[i] = Primitive::emptyValue();
+ for (uint i = dd->len(); i < index; ++i)
+ dd->arrayData()[i] = Primitive::emptyValue();
for (uint i = 0; i < n; ++i)
- dd->data[index + i] = values[i];
- dd->len = qMax(dd->len, index + n);
+ dd->arrayData()[index + i] = values[i];
+ dd->len() = qMax(dd->len(), index + n);
return true;
}
void SparseArrayData::free(ArrayData *d, uint idx)
{
- Q_ASSERT(d && d->type == ArrayData::Sparse);
+ Q_ASSERT(d && d->type() == ArrayData::Sparse);
SparseArrayData *dd = static_cast<SparseArrayData *>(d);
- Value *v = dd->data + idx;
- if (dd->attrs && dd->attrs[idx].isAccessor()) {
+ Value *v = dd->arrayData() + idx;
+ if (dd->attrs() && dd->attrs()[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
v[1].tag = Value::Empty_Type;
- v[1].uint_32 = dd->freeList;
+ v[1].uint_32 = dd->freeList();
v[0].tag = Value::Empty_Type;
v[0].uint_32 = idx + 1;
} else {
v->tag = Value::Empty_Type;
- v->uint_32 = dd->freeList;
+ v->uint_32 = dd->freeList();
}
- dd->freeList = idx;
- if (dd->attrs)
- dd->attrs[idx].clear();
+ dd->freeList() = idx;
+ if (dd->attrs())
+ dd->attrs()[idx].clear();
}
void SparseArrayData::destroy(Managed *d)
{
SparseArrayData *dd = static_cast<SparseArrayData *>(d);
- delete dd->sparse;
+ delete dd->sparse();
}
void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
{
SparseArrayData *dd = static_cast<SparseArrayData *>(d);
- uint l = dd->alloc;
+ uint l = dd->alloc();
for (uint i = 0; i < l; ++i)
- dd->data[i].mark(e);
+ dd->arrayData()[i].mark(e);
}
ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
{
realloc(o, Sparse, 0, n, enforceAttributes);
- return o->arrayData;
+ return o->arrayData();
}
// double slots are required for accessor properties
uint SparseArrayData::allocate(Object *o, bool doubleSlot)
{
- Q_ASSERT(o->arrayData->type == ArrayData::Sparse);
- SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
+ Q_ASSERT(o->arrayData()->type() == ArrayData::Sparse);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
if (doubleSlot) {
- uint *last = &dd->freeList;
+ uint *last = &dd->freeList();
while (1) {
- if (*last + 1 >= dd->alloc) {
- reallocate(o, o->arrayData->alloc + 2, true);
- dd = static_cast<SparseArrayData *>(o->arrayData);
- last = &dd->freeList;
+ if (*last + 1 >= dd->alloc()) {
+ reallocate(o, o->arrayData()->alloc() + 2, true);
+ dd = static_cast<SparseArrayData *>(o->arrayData());
+ last = &dd->freeList();
}
- if (dd->data[*last].uint_32 == (*last + 1)) {
+ if (dd->arrayData()[*last].uint_32 == (*last + 1)) {
// found two slots in a row
uint idx = *last;
- *last = dd->data[*last + 1].uint_32;
- o->arrayData->attrs[idx] = Attr_Accessor;
+ *last = dd->arrayData()[*last + 1].uint_32;
+ o->arrayData()->attrs()[idx] = Attr_Accessor;
return idx;
}
- last = &dd->data[*last].uint_32;
+ last = &dd->arrayData()[*last].uint_32;
}
} else {
- if (dd->alloc == dd->freeList) {
- reallocate(o, o->arrayData->alloc + 2, false);
- dd = static_cast<SparseArrayData *>(o->arrayData);
+ if (dd->alloc() == dd->freeList()) {
+ reallocate(o, o->arrayData()->alloc() + 2, false);
+ dd = static_cast<SparseArrayData *>(o->arrayData());
}
- uint idx = dd->freeList;
- dd->freeList = dd->data[idx].uint_32;
- if (dd->attrs)
- dd->attrs[idx] = Attr_Data;
+ uint idx = dd->freeList();
+ dd->freeList() = dd->arrayData()[idx].uint_32;
+ if (dd->attrs())
+ dd->attrs()[idx] = Attr_Data;
return idx;
}
}
ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
{
- SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse->findNode(index);
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse()->findNode(index);
if (!n)
return Primitive::emptyValue().asReturnedValue();
- return d->data[n->value].asReturnedValue();
+ return d->arrayData()[n->value].asReturnedValue();
}
bool SparseArrayData::put(Object *o, uint index, ValueRef value)
@@ -434,93 +446,93 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
if (value->isEmpty())
return true;
- SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
- Q_ASSERT(n->value == UINT_MAX || !o->arrayData->attrs || !o->arrayData->attrs[n->value].isAccessor());
+ SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData())->sparse()->insert(index);
+ Q_ASSERT(n->value == UINT_MAX || !o->arrayData()->attrs() || !o->arrayData()->attrs()[n->value].isAccessor());
if (n->value == UINT_MAX)
n->value = allocate(o);
- o->arrayData->data[n->value] = value;
- if (o->arrayData->attrs)
- o->arrayData->attrs[n->value] = Attr_Data;
+ o->arrayData()->arrayData()[n->value] = value;
+ if (o->arrayData()->attrs())
+ o->arrayData()->attrs()[n->value] = Attr_Data;
return true;
}
bool SparseArrayData::del(Object *o, uint index)
{
- SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
- SparseArrayNode *n = dd->sparse->findNode(index);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
+ SparseArrayNode *n = dd->sparse()->findNode(index);
if (!n)
return true;
uint pidx = n->value;
- Q_ASSERT(!dd->data[pidx].isEmpty());
+ Q_ASSERT(!dd->arrayData()[pidx].isEmpty());
bool isAccessor = false;
- if (dd->attrs) {
- if (!dd->attrs[pidx].isConfigurable())
+ if (dd->attrs()) {
+ if (!dd->attrs()[pidx].isConfigurable())
return false;
- isAccessor = dd->attrs[pidx].isAccessor();
- dd->attrs[pidx] = Attr_Data;
+ isAccessor = dd->attrs()[pidx].isAccessor();
+ dd->attrs()[pidx] = Attr_Data;
}
if (isAccessor) {
// free up both indices
- dd->data[pidx + 1].tag = Value::Undefined_Type;
- dd->data[pidx + 1].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
- dd->data[pidx].tag = Value::Undefined_Type;
- dd->data[pidx].uint_32 = pidx + 1;
+ dd->arrayData()[pidx + 1].tag = Value::Undefined_Type;
+ dd->arrayData()[pidx + 1].uint_32 = static_cast<SparseArrayData *>(dd)->freeList();
+ dd->arrayData()[pidx].tag = Value::Undefined_Type;
+ dd->arrayData()[pidx].uint_32 = pidx + 1;
} else {
- dd->data[pidx].tag = Value::Undefined_Type;
- dd->data[pidx].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
+ dd->arrayData()[pidx].tag = Value::Undefined_Type;
+ dd->arrayData()[pidx].uint_32 = static_cast<SparseArrayData *>(dd)->freeList();
}
- dd->freeList = pidx;
- dd->sparse->erase(n);
+ dd->freeList() = pidx;
+ dd->sparse()->erase(n);
return true;
}
void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
- SparseArrayNode *n = d->sparse->insert(index);
+ SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
+ SparseArrayNode *n = d->sparse()->insert(index);
if (n->value == UINT_MAX) {
n->value = allocate(o, attrs.isAccessor());
- d = static_cast<SparseArrayData *>(o->arrayData);
+ d = static_cast<SparseArrayData *>(o->arrayData());
}
- else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
+ else if (attrs.isAccessor() != d->attrs()[n->value].isAccessor()) {
// need to convert the slot
free(d, n->value);
n->value = allocate(o, attrs.isAccessor());
}
- o->arrayData->attrs[n->value] = attrs;
+ o->arrayData()->attrs()[n->value] = attrs;
}
PropertyAttributes SparseArrayData::attribute(const ArrayData *d, uint index)
{
- SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse->insert(index);
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse()->insert(index);
if (!n)
return PropertyAttributes();
- return d->attrs[n->value];
+ return d->attrs()[n->value];
}
void SparseArrayData::push_front(Object *o, Value *values, uint n)
{
- Q_ASSERT(!o->arrayData->attrs);
+ Q_ASSERT(!o->arrayData()->attrs());
for (int i = n - 1; i >= 0; --i) {
uint idx = allocate(o);
- o->arrayData->data[idx] = values[i];
- static_cast<SparseArrayData *>(o->arrayData)->sparse->push_front(idx);
+ o->arrayData()->arrayData()[idx] = values[i];
+ static_cast<SparseArrayData *>(o->arrayData())->sparse()->push_front(idx);
}
}
ReturnedValue SparseArrayData::pop_front(Object *o)
{
- Q_ASSERT(!o->arrayData->attrs);
- uint idx = static_cast<SparseArrayData *>(o->arrayData)->sparse->pop_front();
+ Q_ASSERT(!o->arrayData()->attrs());
+ uint idx = static_cast<SparseArrayData *>(o->arrayData())->sparse()->pop_front();
ReturnedValue v;
if (idx != UINT_MAX) {
- v = o->arrayData->data[idx].asReturnedValue();
- free(o->arrayData, idx);
+ v = o->arrayData()->arrayData()[idx].asReturnedValue();
+ free(o->arrayData(), idx);
} else {
v = Encode::undefined();
}
@@ -529,13 +541,13 @@ ReturnedValue SparseArrayData::pop_front(Object *o)
uint SparseArrayData::truncate(Object *o, uint newLen)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
- SparseArrayNode *begin = d->sparse->lowerBound(newLen);
- if (begin != d->sparse->end()) {
- SparseArrayNode *it = d->sparse->end()->previousNode();
+ SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
+ SparseArrayNode *begin = d->sparse()->lowerBound(newLen);
+ if (begin != d->sparse()->end()) {
+ SparseArrayNode *it = d->sparse()->end()->previousNode();
while (1) {
- if (d->attrs) {
- if (!d->attrs[it->value].isConfigurable()) {
+ if (d->attrs()) {
+ if (!d->attrs()[it->value].isConfigurable()) {
newLen = it->key() + 1;
break;
}
@@ -543,7 +555,7 @@ uint SparseArrayData::truncate(Object *o, uint newLen)
free(d, it->value);
bool brk = (it == begin);
SparseArrayNode *prev = it->previousNode();
- static_cast<SparseArrayData *>(d)->sparse->erase(it);
+ static_cast<SparseArrayData *>(d)->sparse()->erase(it);
if (brk)
break;
it = prev;
@@ -555,9 +567,9 @@ uint SparseArrayData::truncate(Object *o, uint newLen)
uint SparseArrayData::length(const ArrayData *d)
{
const SparseArrayData *dd = static_cast<const SparseArrayData *>(d);
- if (!dd->sparse)
+ if (!dd->sparse())
return 0;
- SparseArrayNode *n = dd->sparse->end();
+ SparseArrayNode *n = dd->sparse()->end();
n = n->previousNode();
return n ? n->key() + 1 : 0;
}
@@ -572,12 +584,12 @@ bool SparseArrayData::putArray(Object *o, uint index, Value *values, uint n)
uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
{
- Q_ASSERT(!obj->arrayData->hasAttributes());
+ Q_ASSERT(!obj->arrayData()->hasAttributes());
if (!n)
return obj->getLength();
- const ArrayData *other = otherObj->arrayData;
+ const ArrayData *other = otherObj->arrayData();
if (other->isSparse())
obj->initSparseArray();
@@ -587,21 +599,21 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
uint oldSize = obj->getLength();
if (other->isSparse()) {
- if (otherObj->hasAccessorProperty && other->hasAttributes()) {
+ if (otherObj->hasAccessorProperty() && other->hasAttributes()) {
Scope scope(obj->engine());
ScopedValue v(scope);
- for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
- it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode()) {
- v = otherObj->getValue(reinterpret_cast<Property *>(other->data + it->value), other->attrs[it->value]);
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse()->begin();
+ it != static_cast<const SparseArrayData *>(other)->sparse()->end(); it = it->nextNode()) {
+ v = otherObj->getValue(reinterpret_cast<Property *>(other->arrayData() + it->value), other->attrs()[it->value]);
obj->arraySet(oldSize + it->key(), v);
}
} else {
- for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
- it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode())
- obj->arraySet(oldSize + it->key(), ValueRef(other->data[it->value]));
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse()->begin();
+ it != static_cast<const SparseArrayData *>(other)->sparse()->end(); it = it->nextNode())
+ obj->arraySet(oldSize + it->key(), ValueRef(other->arrayData()[it->value]));
}
} else {
- obj->arrayPut(oldSize, other->data, n);
+ obj->arrayPut(oldSize, other->arrayData(), n);
}
return oldSize + n;
@@ -609,42 +621,42 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
{
- if (!isAccessor && o->arrayData->type != ArrayData::Sparse) {
- SimpleArrayData *d = static_cast<SimpleArrayData *>(o->arrayData);
- if (index < 0x1000 || index < d->len + (d->len >> 2)) {
- if (index >= o->arrayData->alloc) {
+ if (!isAccessor && o->arrayData()->type() != ArrayData::Sparse) {
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(o->arrayData());
+ if (index < 0x1000 || index < d->len() + (d->len() >> 2)) {
+ if (index >= o->arrayData()->alloc()) {
o->arrayReserve(index + 1);
- d = static_cast<SimpleArrayData *>(o->arrayData);
+ d = static_cast<SimpleArrayData *>(o->arrayData());
}
- if (index >= d->len) {
+ if (index >= d->len()) {
// mark possible hole in the array
- for (uint i = d->len; i < index; ++i)
- d->data[i] = Primitive::emptyValue();
- d->len = index + 1;
+ for (uint i = d->len(); i < index; ++i)
+ d->arrayData()[i] = Primitive::emptyValue();
+ d->len() = index + 1;
}
- return reinterpret_cast<Property *>(o->arrayData->data + index);
+ return reinterpret_cast<Property *>(o->arrayData()->arrayData() + index);
}
}
o->initSparseArray();
- SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
+ SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData())->sparse()->insert(index);
if (n->value == UINT_MAX)
n->value = SparseArrayData::allocate(o, isAccessor);
- return reinterpret_cast<Property *>(o->arrayData->data + n->value);
+ return reinterpret_cast<Property *>(o->arrayData()->arrayData() + n->value);
}
class ArrayElementLessThan
{
public:
- inline ArrayElementLessThan(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn)
+ inline ArrayElementLessThan(ExecutionContext *context, Object *thisObject, const ValueRef comparefn)
: m_context(context), thisObject(thisObject), m_comparefn(comparefn) {}
bool operator()(const Value &v1, const Value &v2) const;
private:
ExecutionContext *m_context;
- ObjectRef thisObject;
+ Object *thisObject;
const ValueRef m_comparefn;
};
@@ -674,12 +686,12 @@ bool ArrayElementLessThan::operator()(const Value &v1, const Value &v2) const
return p1s->toQString() < p2s->toQString();
}
-void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint len)
+void ArrayData::sort(ExecutionContext *context, Object *thisObject, const ValueRef comparefn, uint len)
{
if (!len)
return;
- if (!thisObject->arrayData->length())
+ if (!thisObject->arrayData()->length())
return;
if (!(comparefn->isUndefined() || comparefn->asObject())) {
@@ -690,50 +702,50 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu
// The spec says the sorting goes through a series of get,put and delete operations.
// this implies that the attributes don't get sorted around.
- if (thisObject->arrayData->type == ArrayData::Sparse) {
+ if (thisObject->arrayData()->type() == ArrayData::Sparse) {
// since we sort anyway, we can simply iterate over the entries in the sparse
// array and append them one by one to a regular one.
- SparseArrayData *sparse = static_cast<SparseArrayData *>(thisObject->arrayData);
+ SparseArrayData *sparse = static_cast<SparseArrayData *>(thisObject->arrayData());
- if (!sparse->sparse->nEntries())
+ if (!sparse->sparse()->nEntries())
return;
- thisObject->arrayData = 0;
- ArrayData::realloc(thisObject, ArrayData::Simple, 0, sparse->sparse->nEntries(), sparse->attrs ? true : false);
- SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
+ thisObject->setArrayData(0);
+ ArrayData::realloc(thisObject, ArrayData::Simple, 0, sparse->sparse()->nEntries(), sparse->attrs() ? true : false);
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData());
- SparseArrayNode *n = sparse->sparse->begin();
+ SparseArrayNode *n = sparse->sparse()->begin();
uint i = 0;
- if (sparse->attrs) {
- while (n != sparse->sparse->end()) {
+ if (sparse->attrs()) {
+ while (n != sparse->sparse()->end()) {
if (n->value >= len)
break;
- PropertyAttributes a = sparse->attrs ? sparse->attrs[n->value] : Attr_Data;
- d->data[i] = thisObject->getValue(reinterpret_cast<Property *>(sparse->data + n->value), a);
- d->attrs[i] = a.isAccessor() ? Attr_Data : a;
+ PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
+ d->arrayData()[i] = thisObject->getValue(reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
+ d->attrs()[i] = a.isAccessor() ? Attr_Data : a;
n = n->nextNode();
++i;
}
} else {
- while (n != sparse->sparse->end()) {
+ while (n != sparse->sparse()->end()) {
if (n->value >= len)
break;
- d->data[i] = sparse->data[n->value];
+ d->arrayData()[i] = sparse->arrayData()[n->value];
n = n->nextNode();
++i;
}
}
- d->len = i;
+ d->len() = i;
if (len > i)
len = i;
- if (n != sparse->sparse->end()) {
+ if (n != sparse->sparse()->end()) {
// have some entries outside the sort range that we need to ignore when sorting
thisObject->initSparseArray();
- while (n != sparse->sparse->end()) {
- PropertyAttributes a = sparse->attrs ? sparse->attrs[n->value] : Attr_Data;
- thisObject->arraySet(n->value, *reinterpret_cast<Property *>(sparse->data + n->value), a);
+ while (n != sparse->sparse()->end()) {
+ PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
+ thisObject->arraySet(n->value, *reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
n = n->nextNode();
}
@@ -741,19 +753,19 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu
}
// ### explicitly delete sparse
} else {
- SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
- if (len > d->len)
- len = d->len;
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData());
+ if (len > d->len())
+ len = d->len();
// sort empty values to the end
for (uint i = 0; i < len; i++) {
- if (thisObject->arrayData->data[i].isEmpty()) {
+ if (thisObject->arrayData()->arrayData()[i].isEmpty()) {
while (--len > i)
- if (!thisObject->arrayData->data[len].isEmpty())
+ if (!thisObject->arrayData()->arrayData()[len].isEmpty())
break;
- Q_ASSERT(!thisObject->arrayData->attrs || !thisObject->arrayData->attrs[len].isAccessor());
- thisObject->arrayData->data[i] = thisObject->arrayData->data[len];
- thisObject->arrayData->data[len] = Primitive::emptyValue();
+ Q_ASSERT(!thisObject->arrayData()->attrs() || !thisObject->arrayData()->attrs()[len].isAccessor());
+ thisObject->arrayData()->arrayData()[i] = thisObject->arrayData()->arrayData()[len];
+ thisObject->arrayData()->arrayData()[len] = Primitive::emptyValue();
}
}
@@ -764,7 +776,7 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu
ArrayElementLessThan lessThan(context, thisObject, comparefn);
- Value *begin = thisObject->arrayData->data;
+ Value *begin = thisObject->arrayData()->arrayData();
std::sort(begin, begin + len, lessThan);
#ifdef CHECK_SPARSE_ARRAYS
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index 50b7b8a947..aab9157ced 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -57,6 +57,10 @@ namespace QV4 {
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+ V4_MANAGED_SIZE_TEST \
+ const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
+ Data *d() { return &static_cast<Data &>(Managed::data); }
+
struct ArrayData;
@@ -80,11 +84,6 @@ struct ArrayVTable
struct Q_QML_EXPORT ArrayData : public Managed
{
- ArrayData(InternalClass *ic)
- : Managed(ic)
- {
- }
-
enum Type {
Simple = 0,
Complex = 1,
@@ -92,13 +91,30 @@ struct Q_QML_EXPORT ArrayData : public Managed
Custom = 3
};
- uint alloc;
- Type type;
- PropertyAttributes *attrs;
- Value *data;
-
- const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
- bool isSparse() const { return this && type == Sparse; }
+ struct Data : public Managed::Data {
+ Data(InternalClass *ic)
+ : Managed::Data(ic)
+ {}
+ uint alloc;
+ Type type;
+ PropertyAttributes *attrs;
+ Value *arrayData;
+ };
+ V4_MANAGED(Managed)
+
+ uint alloc() const { return d()->alloc; }
+ uint &alloc() { return d()->alloc; }
+ void setAlloc(uint a) { d()->alloc = a; }
+ Type type() const { return d()->type; }
+ void setType(Type t) { d()->type = t; }
+ PropertyAttributes *attrs() const { return d()->attrs; }
+ void setAttrs(PropertyAttributes *a) { d()->attrs = a; }
+ Value *arrayData() const { return d()->arrayData; }
+ Value *&arrayData() { return d()->arrayData; }
+ void setArrayData(Value *v) { d()->arrayData = v; }
+
+ const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass()->vtable); }
+ bool isSparse() const { return this && type() == Sparse; }
uint length() const {
if (!this)
@@ -107,11 +123,11 @@ struct Q_QML_EXPORT ArrayData : public Managed
}
bool hasAttributes() const {
- return this && attrs;
+ return this && attrs();
}
PropertyAttributes attributes(int i) const {
Q_ASSERT(this);
- return attrs ? vtable()->attribute(this, i) : Attr_Data;
+ return attrs() ? vtable()->attribute(this, i) : Attr_Data;
}
bool isEmpty(uint i) const {
@@ -130,26 +146,31 @@ struct Q_QML_EXPORT ArrayData : public Managed
static void ensureAttributes(Object *o);
static void realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes);
- static void sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint dataLen);
+ static void sort(ExecutionContext *context, Object *thisObject, const ValueRef comparefn, uint dataLen);
static uint append(Object *obj, const ArrayObject *otherObj, uint n);
static Property *insert(Object *o, uint index, bool isAccessor = false);
};
struct Q_QML_EXPORT SimpleArrayData : public ArrayData
{
- V4_ARRAYDATA
- SimpleArrayData(ExecutionEngine *engine)
- : ArrayData(engine->simpleArrayDataClass)
- {}
+ struct Data : public ArrayData::Data {
+ Data(ExecutionEngine *engine)
+ : ArrayData::Data(engine->simpleArrayDataClass)
+ {}
+ uint len;
+ uint offset;
+ };
+ V4_ARRAYDATA
- uint len;
- uint offset;
+ uint &len() { return d()->len; }
+ uint len() const { return d()->len; }
+ uint &offset() { return d()->offset; }
+ uint offset() const { return d()->offset; }
static void getHeadRoom(Object *o);
static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
- static void destroy(Managed *d);
static void markObjects(Managed *d, ExecutionEngine *e);
static ReturnedValue get(const ArrayData *d, uint index);
@@ -166,14 +187,20 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
struct Q_QML_EXPORT SparseArrayData : public ArrayData
{
- V4_ARRAYDATA
+ struct Data : public ArrayData::Data {
+ Data(ExecutionEngine *engine)
+ : ArrayData::Data(engine->emptyClass)
+ { setVTable(staticVTable()); }
- SparseArrayData(ExecutionEngine *engine)
- : ArrayData(engine->emptyClass)
- { setVTable(staticVTable()); }
+ uint freeList;
+ SparseArray *sparse;
+ };
+ V4_ARRAYDATA
- uint freeList;
- SparseArray *sparse;
+ uint &freeList() { return d()->freeList; }
+ uint freeList() const { return d()->freeList; }
+ SparseArray *sparse() const { return d()->sparse; }
+ void setSparse(SparseArray *s) { d()->sparse = s; }
static uint allocate(Object *o, bool doubleSlot = false);
static void free(ArrayData *d, uint idx);
@@ -199,16 +226,16 @@ inline Property *ArrayData::getProperty(uint index) const
{
if (!this)
return 0;
- if (type != Sparse) {
+ if (type() != Sparse) {
const SimpleArrayData *that = static_cast<const SimpleArrayData *>(this);
- if (index >= that->len || data[index].isEmpty())
+ if (index >= that->len() || arrayData()[index].isEmpty())
return 0;
- return reinterpret_cast<Property *>(data + index);
+ return reinterpret_cast<Property *>(arrayData() + index);
} else {
- SparseArrayNode *n = static_cast<const SparseArrayData *>(this)->sparse->findNode(index);
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(this)->sparse()->findNode(index);
if (!n)
return 0;
- return reinterpret_cast<Property *>(data + n->value);
+ return reinterpret_cast<Property *>(arrayData() + n->value);
}
}
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index fbd757a829..abe8a44065 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -48,8 +48,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(ArrayCtor);
-ArrayCtor::ArrayCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Array"))
+ArrayCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Array"))
{
setVTable(staticVTable());
}
@@ -84,12 +84,7 @@ ReturnedValue ArrayCtor::call(Managed *that, CallData *callData)
return construct(that, callData);
}
-ArrayPrototype::ArrayPrototype(InternalClass *ic)
- : ArrayObject(ic)
-{
-}
-
-void ArrayPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -122,21 +117,21 @@ void ArrayPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx)
{
- bool isArray = ctx->callData->argc && ctx->callData->args[0].asArrayObject();
+ bool isArray = ctx->d()->callData->argc && ctx->d()->callData->args[0].asArrayObject();
return Encode(isArray);
}
ReturnedValue ArrayPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject o(scope, ctx->callData->thisObject, ScopedObject::Convert);
- if (ctx->engine->hasException)
+ ScopedObject o(scope, ctx->d()->callData->thisObject, ScopedObject::Convert);
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
- ScopedString s(scope, ctx->engine->newString(QStringLiteral("join")));
- ScopedFunctionObject f(scope, o->get(s));
+ ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("join")));
+ ScopedFunctionObject f(scope, o->get(s.getPointer()));
if (!!f) {
ScopedCallData d(scope, 0);
- d->thisObject = ctx->callData->thisObject;
+ d->thisObject = ctx->d()->callData->thisObject;
return f->call(d);
}
return ObjectPrototype::method_toString(ctx);
@@ -150,9 +145,9 @@ ReturnedValue ArrayPrototype::method_toLocaleString(CallContext *ctx)
ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject result(scope, ctx->engine->newArrayObject());
+ ScopedObject result(scope, ctx->d()->engine->newArrayObject());
- ScopedObject thisObject(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject thisObject(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!thisObject)
return Encode::undefined();
ScopedArrayObject instance(scope, thisObject);
@@ -165,9 +160,9 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
ScopedArrayObject elt(scope);
ScopedObject eltAsObj(scope);
ScopedValue entry(scope);
- for (int i = 0; i < ctx->callData->argc; ++i) {
- eltAsObj = ctx->callData->args[i];
- elt = ctx->callData->args[i];
+ for (int i = 0; i < ctx->d()->callData->argc; ++i) {
+ eltAsObj = ctx->d()->callData->args[i];
+ elt = ctx->d()->callData->args[i];
if (elt) {
uint n = elt->getLength();
uint newLen = ArrayData::append(result.getPointer(), elt.getPointer(), n);
@@ -179,7 +174,7 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), ValueRef(ctx->callData->args[i]));
+ result->arraySet(result->getLength(), ValueRef(ctx->d()->callData->args[i]));
}
}
@@ -197,12 +192,12 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
else
r4 = arg->toQString();
- ScopedObject self(scope, ctx->callData->thisObject);
- ScopedValue length(scope, self->get(ctx->engine->id_length));
+ ScopedObject self(scope, ctx->d()->callData->thisObject);
+ ScopedValue length(scope, self->get(ctx->d()->engine->id_length));
const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
if (!r2)
- return ctx->engine->newString(QString())->asReturnedValue();
+ return ctx->d()->engine->newString(QString())->asReturnedValue();
QString R;
@@ -223,8 +218,8 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
//
// crazy!
//
- ScopedString name(scope, ctx->engine->newString(QStringLiteral("0")));
- ScopedValue r6(scope, self->get(name));
+ ScopedString name(scope, ctx->d()->engine->newString(QStringLiteral("0")));
+ ScopedValue r6(scope, self->get(name.getPointer()));
if (!r6->isNullOrUndefined())
R = r6->toString(ctx)->toQString();
@@ -233,7 +228,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
R += r4;
name = Primitive::fromDouble(k).toString(ctx);
- r12 = self->get(name);
+ r12 = self->get(name.getPointer());
if (scope.hasException())
return Encode::undefined();
@@ -242,20 +237,20 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
}
}
- return ctx->engine->newString(R)->asReturnedValue();
+ return ctx->d()->engine->newString(R)->asReturnedValue();
}
ReturnedValue ArrayPrototype::method_pop(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
uint len = instance->getLength();
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromInt32(0)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromInt32(0)));
return Encode::undefined();
}
@@ -269,14 +264,14 @@ ReturnedValue ArrayPrototype::method_pop(CallContext *ctx)
if (instance->isArrayObject())
instance->setArrayLength(len - 1);
else
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1)));
return result.asReturnedValue();
}
ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -284,38 +279,38 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
uint len = instance->getLength();
- if (len + ctx->callData->argc < len) {
+ if (len + ctx->d()->callData->argc < len) {
// ughh...
double l = len;
ScopedString s(scope);
- for (int i = 0; i < ctx->callData->argc; ++i) {
+ for (int i = 0; i < ctx->d()->callData->argc; ++i) {
s = Primitive::fromDouble(l + i).toString(ctx);
- instance->put(s, ctx->callData->args[i]);
+ instance->put(s.getPointer(), ctx->d()->callData->args[i]);
}
- double newLen = l + ctx->callData->argc;
+ double newLen = l + ctx->d()->callData->argc;
if (!instance->isArrayObject())
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(newLen)));
else {
- ScopedString str(scope, ctx->engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
+ ScopedString str(scope, ctx->d()->engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
return ctx->throwRangeError(str);
}
return Encode(newLen);
}
- if (!ctx->callData->argc) {
+ if (!ctx->d()->callData->argc) {
;
- } else if (!instance->protoHasArray() && instance->arrayData->length() <= len && instance->arrayType() == ArrayData::Simple) {
- instance->arrayData->vtable()->putArray(instance.getPointer(), len, ctx->callData->args, ctx->callData->argc);
- len = instance->arrayData->length();
+ } else if (!instance->protoHasArray() && instance->arrayData()->length() <= len && instance->arrayType() == ArrayData::Simple) {
+ instance->arrayData()->vtable()->putArray(instance.getPointer(), len, ctx->d()->callData->args, ctx->d()->callData->argc);
+ len = instance->arrayData()->length();
} else {
- for (int i = 0; i < ctx->callData->argc; ++i)
- instance->putIndexed(len + i, ctx->callData->args[i]);
- len += ctx->callData->argc;
+ for (int i = 0; i < ctx->d()->callData->argc; ++i)
+ instance->putIndexed(len + i, ctx->d()->callData->args[i]);
+ len += ctx->d()->callData->argc;
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len);
else
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len)));
return Encode(len);
}
@@ -323,7 +318,7 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
uint length = instance->getLength();
@@ -355,7 +350,7 @@ ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -365,14 +360,14 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromInt32(0)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromInt32(0)));
return Encode::undefined();
}
ScopedValue result(scope);
- if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len && instance->arrayData->type != ArrayData::Custom) {
- result = instance->arrayData->vtable()->pop_front(instance.getPointer());
+ if (!instance->protoHasArray() && !instance->arrayData()->hasAttributes() && instance->arrayData()->length() <= len && instance->arrayData()->type() != ArrayData::Custom) {
+ result = instance->arrayData()->vtable()->pop_front(instance.getPointer());
} else {
result = instance->getIndexed(0);
if (scope.hasException())
@@ -399,18 +394,18 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len - 1);
else
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1)));
return result.asReturnedValue();
}
ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject o(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject o(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!o)
return Encode::undefined();
- Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> result(scope, ctx->d()->engine->newArrayObject());
uint len = o->getLength();
double s = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
@@ -421,8 +416,8 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
else
start = (uint) s;
uint end = len;
- if (ctx->callData->argc > 1 && !ctx->callData->args[1].isUndefined()) {
- double e = ctx->callData->args[1].toInteger();
+ if (ctx->d()->callData->argc > 1 && !ctx->d()->callData->args[1].isUndefined()) {
+ double e = ctx->d()->callData->args[1].toInteger();
if (e < 0)
end = (uint)qMax(len + e, 0.);
else if (e > len)
@@ -448,7 +443,7 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
ReturnedValue ArrayPrototype::method_sort(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -456,18 +451,18 @@ ReturnedValue ArrayPrototype::method_sort(CallContext *ctx)
ScopedValue comparefn(scope, ctx->argument(0));
ArrayData::sort(ctx, instance, comparefn, len);
- return ctx->callData->thisObject.asReturnedValue();
+ return ctx->d()->callData->thisObject.asReturnedValue();
}
ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
uint len = instance->getLength();
- Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> newArray(scope, ctx->d()->engine->newArrayObject());
double rs = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
@@ -490,7 +485,7 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
}
newArray->setArrayLengthUnchecked(deleteCount);
- uint itemCount = ctx->callData->argc < 2 ? 0 : ctx->callData->argc - 2;
+ uint itemCount = ctx->d()->callData->argc < 2 ? 0 : ctx->d()->callData->argc - 2;
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
@@ -528,13 +523,13 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
}
for (uint i = 0; i < itemCount; ++i) {
- instance->putIndexed(start + i, ctx->callData->args[i + 2]);
+ instance->putIndexed(start + i, ctx->d()->callData->args[i + 2]);
if (scope.hasException())
return Encode::undefined();
}
- ctx->strictMode = true;
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
+ ctx->d()->strictMode = true;
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
return newArray.asReturnedValue();
}
@@ -542,7 +537,7 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -550,27 +545,27 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
uint len = instance->getLength();
- if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len && instance->arrayData->type != ArrayData::Custom) {
- instance->arrayData->vtable()->push_front(instance.getPointer(), ctx->callData->args, ctx->callData->argc);
+ if (!instance->protoHasArray() && !instance->arrayData()->hasAttributes() && instance->arrayData()->length() <= len && instance->arrayData()->type() != ArrayData::Custom) {
+ instance->arrayData()->vtable()->push_front(instance.getPointer(), ctx->d()->callData->args, ctx->d()->callData->argc);
} else {
ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
if (exists)
- instance->putIndexed(k + ctx->callData->argc - 1, v);
+ instance->putIndexed(k + ctx->d()->callData->argc - 1, v);
else
- instance->deleteIndexedProperty(k + ctx->callData->argc - 1);
+ instance->deleteIndexedProperty(k + ctx->d()->callData->argc - 1);
}
- for (int i = 0; i < ctx->callData->argc; ++i)
- instance->putIndexed(i, ctx->callData->args[i]);
+ for (int i = 0; i < ctx->d()->callData->argc; ++i)
+ instance->putIndexed(i, ctx->d()->callData->args[i]);
}
- uint newLen = len + ctx->callData->argc;
+ uint newLen = len + ctx->d()->callData->argc;
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(newLen);
else
- instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(newLen)));
return Encode(newLen);
}
@@ -579,18 +574,18 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
uint len = instance->getLength();
if (!len)
return Encode(-1);
- ScopedValue searchValue(scope, ctx->callData->argument(0));
+ ScopedValue searchValue(scope, ctx->d()->callData->argument(0));
uint fromIndex = 0;
- if (ctx->callData->argc >= 2) {
- double f = ctx->callData->args[1].toInteger();
+ if (ctx->d()->callData->argc >= 2) {
+ double f = ctx->d()->callData->args[1].toInteger();
if (scope.hasException())
return Encode::undefined();
if (f >= len)
@@ -613,7 +608,7 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
ScopedValue value(scope);
- if (instance->hasAccessorProperty || (instance->arrayType() >= ArrayData::Sparse) || instance->protoHasArray()) {
+ if (instance->hasAccessorProperty() || (instance->arrayType() >= ArrayData::Sparse) || instance->protoHasArray()) {
// lets be safe and slow
for (uint i = fromIndex; i < len; ++i) {
bool exists;
@@ -623,13 +618,13 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
if (exists && RuntimeHelpers::strictEqual(value, searchValue))
return Encode(i);
}
- } else if (!instance->arrayData) {
+ } else if (!instance->arrayData()) {
return Encode(-1);
} else {
Q_ASSERT(instance->arrayType() == ArrayData::Simple || instance->arrayType() == ArrayData::Complex);
- if (len > instance->arrayData->length())
- len = instance->arrayData->length();
- Value *val = instance->arrayData->data;
+ if (len > instance->arrayData()->length())
+ len = instance->arrayData()->length();
+ Value *val = instance->arrayData()->arrayData();
Value *end = val + len;
val += fromIndex;
while (val < end) {
@@ -638,7 +633,7 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
if (scope.hasException())
return Encode::undefined();
if (RuntimeHelpers::strictEqual(value, searchValue))
- return Encode((uint)(val - instance->arrayData->data));
+ return Encode((uint)(val - instance->arrayData()->arrayData()));
}
++val;
}
@@ -650,7 +645,7 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
uint len = instance->getLength();
@@ -660,13 +655,13 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
ScopedValue searchValue(scope);
uint fromIndex = len;
- if (ctx->callData->argc >= 1)
+ if (ctx->d()->callData->argc >= 1)
searchValue = ctx->argument(0);
else
searchValue = Primitive::undefinedValue();
- if (ctx->callData->argc >= 2) {
- double f = ctx->callData->args[1].toInteger();
+ if (ctx->d()->callData->argc >= 2) {
+ double f = ctx->d()->callData->args[1].toInteger();
if (scope.hasException())
return Encode::undefined();
if (f > 0)
@@ -695,7 +690,7 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -729,7 +724,7 @@ ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -763,7 +758,7 @@ ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -794,7 +789,7 @@ ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -804,7 +799,7 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
if (!callback)
return ctx->throwTypeError();
- Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
@@ -831,7 +826,7 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -841,7 +836,7 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
if (!callback)
return ctx->throwTypeError();
- Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
a->arrayReserve(len);
ScopedValue selected(scope);
@@ -872,7 +867,7 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -886,7 +881,7 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
ScopedValue acc(scope);
ScopedValue v(scope);
- if (ctx->callData->argc > 1) {
+ if (ctx->d()->callData->argc > 1) {
acc = ctx->argument(1);
} else {
bool kPresent = false;
@@ -922,7 +917,7 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> instance(scope, ctx->callData->thisObject.toObject(ctx));
+ Scoped<Object> instance(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
@@ -933,7 +928,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
return ctx->throwTypeError();
if (len == 0) {
- if (ctx->callData->argc == 1)
+ if (ctx->d()->callData->argc == 1)
return ctx->throwTypeError();
return ctx->argument(1);
}
@@ -941,7 +936,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
uint k = len;
ScopedValue acc(scope);
ScopedValue v(scope);
- if (ctx->callData->argc > 1) {
+ if (ctx->d()->callData->argc > 1) {
acc = ctx->argument(1);
} else {
bool kPresent = false;
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index e7f8ba711f..dccda2896e 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -51,8 +51,11 @@ namespace QV4 {
struct ArrayCtor: FunctionObject
{
- V4_OBJECT
- ArrayCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *m, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -60,9 +63,7 @@ struct ArrayCtor: FunctionObject
struct ArrayPrototype: ArrayObject
{
- ArrayPrototype(InternalClass *ic);
-
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_isArray(CallContext *ctx);
static ReturnedValue method_toString(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 662ec64efb..38a0f7f549 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -46,8 +46,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(BooleanCtor);
DEFINE_OBJECT_VTABLE(BooleanObject);
-BooleanCtor::BooleanCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Boolean"))
+BooleanCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Boolean"))
{
setVTable(staticVTable());
}
@@ -66,7 +66,7 @@ ReturnedValue BooleanCtor::call(Managed *, CallData *callData)
return Encode(value);
}
-void BooleanPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -80,28 +80,28 @@ void BooleanPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
ReturnedValue BooleanPrototype::method_toString(CallContext *ctx)
{
bool result;
- if (ctx->callData->thisObject.isBoolean()) {
- result = ctx->callData->thisObject.booleanValue();
+ if (ctx->d()->callData->thisObject.isBoolean()) {
+ result = ctx->d()->callData->thisObject.booleanValue();
} else {
Scope scope(ctx);
- Scoped<BooleanObject> thisObject(scope, ctx->callData->thisObject);
+ Scoped<BooleanObject> thisObject(scope, ctx->d()->callData->thisObject);
if (!thisObject)
return ctx->throwTypeError();
- result = thisObject->value.booleanValue();
+ result = thisObject->value().booleanValue();
}
- return Encode(ctx->engine->newString(QLatin1String(result ? "true" : "false")));
+ return Encode(ctx->d()->engine->newString(QLatin1String(result ? "true" : "false")));
}
ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx)
{
- if (ctx->callData->thisObject.isBoolean())
- return ctx->callData->thisObject.asReturnedValue();
+ if (ctx->d()->callData->thisObject.isBoolean())
+ return ctx->d()->callData->thisObject.asReturnedValue();
Scope scope(ctx);
- Scoped<BooleanObject> thisObject(scope, ctx->callData->thisObject);
+ Scoped<BooleanObject> thisObject(scope, ctx->d()->callData->thisObject);
if (!thisObject)
return ctx->throwTypeError();
- return thisObject->value.asReturnedValue();
+ return thisObject->value().asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 617f7f6b01..35cfd5729e 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -51,8 +51,11 @@ namespace QV4 {
struct BooleanCtor: FunctionObject
{
- V4_OBJECT
- BooleanCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -60,8 +63,7 @@ struct BooleanCtor: FunctionObject
struct BooleanPrototype: BooleanObject
{
- BooleanPrototype(InternalClass *ic): BooleanObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_toString(CallContext *ctx);
static ReturnedValue method_valueOf(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index b43b4893a3..62d5859e87 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -52,27 +52,30 @@
using namespace QV4;
DEFINE_MANAGED_VTABLE(ExecutionContext);
+DEFINE_MANAGED_VTABLE(CallContext);
+DEFINE_MANAGED_VTABLE(WithContext);
+DEFINE_MANAGED_VTABLE(GlobalContext);
-CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
+HeapObject *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
{
- Q_ASSERT(function->function);
+ Q_ASSERT(function->function());
- CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc)));
- new (c) CallContext(engine, Type_CallContext);
+ CallContext::Data *c = reinterpret_cast<CallContext::Data *>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc)));
+ new (c) CallContext::Data(d()->engine, Type_CallContext);
c->function = function;
c->realArgumentCount = callData->argc;
- c->strictMode = function->strictMode;
- c->outer = function->scope;
+ c->strictMode = function->strictMode();
+ c->outer = function->scope();
c->activation = 0;
- c->compilationUnit = function->function->compilationUnit;
+ c->compilationUnit = function->function()->compilationUnit;
c->lookups = c->compilationUnit->runtimeLookups;
c->locals = (Value *)((quintptr(c + 1) + 7) & ~7);
- const CompiledData::Function *compiledFunction = function->function->compiledFunction;
+ const CompiledData::Function *compiledFunction = function->function()->compiledFunction;
int nLocals = compiledFunction->nLocals;
if (nLocals)
std::fill(c->locals, c->locals + nLocals, Primitive::undefinedValue());
@@ -86,43 +89,41 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData
return c;
}
-WithContext *ExecutionContext::newWithContext(ObjectRef with)
+WithContext *ExecutionContext::newWithContext(Object *with)
{
- WithContext *w = new (engine->memoryManager) WithContext(engine, with);
- return w;
+ return d()->engine->memoryManager->alloc<WithContext>(d()->engine, with);
}
-CatchContext *ExecutionContext::newCatchContext(const StringRef exceptionVarName, const ValueRef exceptionValue)
+CatchContext *ExecutionContext::newCatchContext(String *exceptionVarName, const ValueRef exceptionValue)
{
- CatchContext *c = new (engine->memoryManager) CatchContext(engine, exceptionVarName, exceptionValue);
- return c;
+ return d()->engine->memoryManager->alloc<CatchContext>(d()->engine, exceptionVarName, exceptionValue);
}
-CallContext *ExecutionContext::newQmlContext(FunctionObject *f, ObjectRef qml)
+CallContext *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml)
{
- CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)));
- new (c) CallContext(engine, qml, f);
+ CallContext *c = reinterpret_cast<CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)));
+ new (c->d()) CallContext::Data(d()->engine, qml, f);
return c;
}
-void ExecutionContext::createMutableBinding(const StringRef name, bool deletable)
+void ExecutionContext::createMutableBinding(String *name, bool deletable)
{
Scope scope(this);
// find the right context to create the binding on
- ScopedObject activation(scope, engine->globalObject);
+ ScopedObject activation(scope, d()->engine->globalObject);
ExecutionContext *ctx = this;
while (ctx) {
- if (ctx->type >= Type_CallContext) {
+ if (ctx->d()->type >= Type_CallContext) {
CallContext *c = static_cast<CallContext *>(ctx);
- if (!c->activation)
- c->activation = engine->newObject()->getPointer();
- activation = c->activation;
+ if (!c->d()->activation)
+ c->d()->activation = d()->engine->newObject()->getPointer();
+ activation = c->d()->activation;
break;
}
- ctx = ctx->outer;
+ ctx = ctx->d()->outer;
}
if (activation->hasProperty(name))
@@ -134,38 +135,38 @@ void ExecutionContext::createMutableBinding(const StringRef name, bool deletable
}
-GlobalContext::GlobalContext(ExecutionEngine *eng)
- : ExecutionContext(eng, Type_GlobalContext)
+GlobalContext::Data::Data(ExecutionEngine *eng)
+ : ExecutionContext::Data(eng, Type_GlobalContext)
{
global = eng->globalObject;
}
-WithContext::WithContext(ExecutionEngine *engine, ObjectRef with)
- : ExecutionContext(engine, Type_WithContext)
+WithContext::Data::Data(ExecutionEngine *engine, Object *with)
+ : ExecutionContext::Data(engine, Type_WithContext)
{
- callData = parent->callData;
+ callData = parent->d()->callData;
outer = parent;
- lookups = parent->lookups;
- compilationUnit = parent->compilationUnit;
+ lookups = parent->d()->lookups;
+ compilationUnit = parent->d()->compilationUnit;
- withObject = with.getPointer();
+ withObject = with;
}
-CatchContext::CatchContext(ExecutionEngine *engine, const StringRef exceptionVarName, const ValueRef exceptionValue)
- : ExecutionContext(engine, Type_CatchContext)
+CatchContext::Data::Data(ExecutionEngine *engine, String *exceptionVarName, const ValueRef exceptionValue)
+ : ExecutionContext::Data(engine, Type_CatchContext)
{
- strictMode = parent->strictMode;
- callData = parent->callData;
+ strictMode = parent->d()->strictMode;
+ callData = parent->d()->callData;
outer = parent;
- lookups = parent->lookups;
- compilationUnit = parent->compilationUnit;
+ lookups = parent->d()->lookups;
+ compilationUnit = parent->d()->compilationUnit;
this->exceptionVarName = exceptionVarName;
this->exceptionValue = exceptionValue;
}
-CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject *function)
- : ExecutionContext(engine, Type_QmlContext)
+CallContext::Data::Data(ExecutionEngine *engine, Object *qml, FunctionObject *function)
+ : ExecutionContext::Data(engine, Type_QmlContext)
{
this->function = function;
callData = reinterpret_cast<CallData *>(this + 1);
@@ -174,12 +175,12 @@ CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject
callData->thisObject = Primitive::undefinedValue();
strictMode = true;
- outer = function->scope;
+ outer = function->scope();
- activation = qml.getPointer();
+ activation = qml;
- if (function->function) {
- compilationUnit = function->function->compilationUnit;
+ if (function->function()) {
+ compilationUnit = function->function()->compilationUnit;
lookups = compilationUnit->runtimeLookups;
}
@@ -190,170 +191,170 @@ CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject
String * const *CallContext::formals() const
{
- return (function && function->function) ? function->function->internalClass->nameMap.constData() : 0;
+ return (d()->function && d()->function->function()) ? d()->function->function()->internalClass->nameMap.constData() : 0;
}
unsigned int CallContext::formalCount() const
{
- return function ? function->formalParameterCount() : 0;
+ return d()->function ? d()->function->formalParameterCount() : 0;
}
String * const *CallContext::variables() const
{
- return (function && function->function) ? function->function->internalClass->nameMap.constData() + function->function->compiledFunction->nFormals : 0;
+ return (d()->function && d()->function->function()) ? d()->function->function()->internalClass->nameMap.constData() + d()->function->function()->compiledFunction->nFormals : 0;
}
unsigned int CallContext::variableCount() const
{
- return function ? function->varCount() : 0;
+ return d()->function ? d()->function->varCount() : 0;
}
-bool ExecutionContext::deleteProperty(const StringRef name)
+bool ExecutionContext::deleteProperty(String *name)
{
Scope scope(this);
bool hasWith = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
- if (ctx->type == Type_WithContext) {
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ if (ctx->d()->type == Type_WithContext) {
hasWith = true;
WithContext *w = static_cast<WithContext *>(ctx);
- if (w->withObject->hasProperty(name))
- return w->withObject->deleteProperty(name);
- } else if (ctx->type == Type_CatchContext) {
+ if (w->d()->withObject->hasProperty(name))
+ return w->d()->withObject->deleteProperty(name);
+ } else if (ctx->d()->type == Type_CatchContext) {
CatchContext *c = static_cast<CatchContext *>(ctx);
- if (c->exceptionVarName->isEqualTo(name))
+ if (c->d()->exceptionVarName->isEqualTo(name))
return false;
- } else if (ctx->type >= Type_CallContext) {
+ } else if (ctx->d()->type >= Type_CallContext) {
CallContext *c = static_cast<CallContext *>(ctx);
- FunctionObject *f = c->function;
- if (f->needsActivation || hasWith) {
- uint index = f->function->internalClass->find(name);
+ FunctionObject *f = c->d()->function;
+ if (f->needsActivation() || hasWith) {
+ uint index = f->function()->internalClass->find(name);
if (index < UINT_MAX)
// ### throw in strict mode?
return false;
}
- if (c->activation && c->activation->hasProperty(name))
- return c->activation->deleteProperty(name);
- } else if (ctx->type == Type_GlobalContext) {
+ if (c->d()->activation && c->d()->activation->hasProperty(name))
+ return c->d()->activation->deleteProperty(name);
+ } else if (ctx->d()->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
- if (g->global->hasProperty(name))
- return g->global->deleteProperty(name);
+ if (g->d()->global->hasProperty(name))
+ return g->d()->global->deleteProperty(name);
}
}
- if (strictMode)
+ if (d()->strictMode)
throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString()));
return true;
}
bool CallContext::needsOwnArguments() const
{
- return function->needsActivation || callData->argc < static_cast<int>(function->formalParameterCount());
+ return d()->function->needsActivation() || d()->callData->argc < static_cast<int>(d()->function->formalParameterCount());
}
void ExecutionContext::markObjects(Managed *m, ExecutionEngine *engine)
{
ExecutionContext *ctx = static_cast<ExecutionContext *>(m);
- if (ctx->outer)
- ctx->outer->mark(engine);
+ if (ctx->d()->outer)
+ ctx->d()->outer->mark(engine);
// ### shouldn't need these 3 lines
- ctx->callData->thisObject.mark(engine);
- for (int arg = 0; arg < ctx->callData->argc; ++arg)
- ctx->callData->args[arg].mark(engine);
+ ctx->d()->callData->thisObject.mark(engine);
+ for (int arg = 0; arg < ctx->d()->callData->argc; ++arg)
+ ctx->d()->callData->args[arg].mark(engine);
- if (ctx->type >= Type_CallContext) {
+ if (ctx->d()->type >= Type_CallContext) {
QV4::CallContext *c = static_cast<CallContext *>(ctx);
- for (unsigned local = 0, lastLocal = c->function->varCount(); local < lastLocal; ++local)
- c->locals[local].mark(engine);
- if (c->activation)
- c->activation->mark(engine);
- c->function->mark(engine);
- } else if (ctx->type == Type_WithContext) {
+ for (unsigned local = 0, lastLocal = c->d()->function->varCount(); local < lastLocal; ++local)
+ c->d()->locals[local].mark(engine);
+ if (c->d()->activation)
+ c->d()->activation->mark(engine);
+ c->d()->function->mark(engine);
+ } else if (ctx->d()->type == Type_WithContext) {
WithContext *w = static_cast<WithContext *>(ctx);
- w->withObject->mark(engine);
- } else if (ctx->type == Type_CatchContext) {
+ w->d()->withObject->mark(engine);
+ } else if (ctx->d()->type == Type_CatchContext) {
CatchContext *c = static_cast<CatchContext *>(ctx);
- c->exceptionVarName->mark(engine);
- c->exceptionValue.mark(engine);
- } else if (ctx->type == Type_GlobalContext) {
+ c->d()->exceptionVarName->mark(engine);
+ c->d()->exceptionValue.mark(engine);
+ } else if (ctx->d()->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
- g->global->mark(engine);
+ g->d()->global->mark(engine);
}
}
-void ExecutionContext::setProperty(const StringRef name, const ValueRef value)
+void ExecutionContext::setProperty(String *name, const ValueRef value)
{
Scope scope(this);
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
- if (ctx->type == Type_WithContext) {
- ScopedObject w(scope, static_cast<WithContext *>(ctx)->withObject);
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ if (ctx->d()->type == Type_WithContext) {
+ ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
if (w->hasProperty(name)) {
w->put(name, value);
return;
}
- } else if (ctx->type == Type_CatchContext && static_cast<CatchContext *>(ctx)->exceptionVarName->isEqualTo(name)) {
- static_cast<CatchContext *>(ctx)->exceptionValue = *value;
+ } else if (ctx->d()->type == Type_CatchContext && static_cast<CatchContext *>(ctx)->d()->exceptionVarName->isEqualTo(name)) {
+ static_cast<CatchContext *>(ctx)->d()->exceptionValue = *value;
return;
} else {
ScopedObject activation(scope, (Object *)0);
- if (ctx->type >= Type_CallContext) {
+ if (ctx->d()->type >= Type_CallContext) {
CallContext *c = static_cast<CallContext *>(ctx);
- if (c->function->function) {
- uint index = c->function->function->internalClass->find(name);
+ if (c->d()->function->function()) {
+ uint index = c->d()->function->function()->internalClass->find(name);
if (index < UINT_MAX) {
- if (index < c->function->formalParameterCount()) {
- c->callData->args[c->function->formalParameterCount() - index - 1] = *value;
+ if (index < c->d()->function->formalParameterCount()) {
+ c->d()->callData->args[c->d()->function->formalParameterCount() - index - 1] = *value;
} else {
- index -= c->function->formalParameterCount();
- c->locals[index] = *value;
+ index -= c->d()->function->formalParameterCount();
+ c->d()->locals[index] = *value;
}
return;
}
}
- activation = c->activation;
- } else if (ctx->type == Type_GlobalContext) {
- activation = static_cast<GlobalContext *>(ctx)->global;
+ activation = c->d()->activation;
+ } else if (ctx->d()->type == Type_GlobalContext) {
+ activation = static_cast<GlobalContext *>(ctx)->d()->global;
}
if (activation) {
- if (ctx->type == Type_QmlContext) {
+ if (ctx->d()->type == Type_QmlContext) {
activation->put(name, value);
return;
} else {
- uint member = activation->internalClass->find(name);
+ uint member = activation->internalClass()->find(name);
if (member < UINT_MAX) {
- activation->putValue(activation->propertyAt(member), activation->internalClass->propertyData[member], value);
+ activation->putValue(activation->propertyAt(member), activation->internalClass()->propertyData[member], value);
return;
}
}
}
}
}
- if (strictMode || name->equals(engine->id_this)) {
- ScopedValue n(scope, name.asReturnedValue());
+ if (d()->strictMode || name->equals(d()->engine->id_this.getPointer())) {
+ ScopedValue n(scope, name->asReturnedValue());
throwReferenceError(n);
return;
}
- engine->globalObject->put(name, value);
+ d()->engine->globalObject->put(name, value);
}
-ReturnedValue ExecutionContext::getProperty(const StringRef name)
+ReturnedValue ExecutionContext::getProperty(String *name)
{
Scope scope(this);
ScopedValue v(scope);
name->makeIdentifier();
- if (name->equals(engine->id_this))
- return callData->thisObject.asReturnedValue();
+ if (name->equals(d()->engine->id_this.getPointer()))
+ return d()->callData->thisObject.asReturnedValue();
bool hasWith = false;
bool hasCatchScope = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
- if (ctx->type == Type_WithContext) {
- ScopedObject w(scope, static_cast<WithContext *>(ctx)->withObject);
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ if (ctx->d()->type == Type_WithContext) {
+ ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
hasWith = true;
bool hasProperty = false;
v = w->get(name, &hasProperty);
@@ -363,62 +364,62 @@ ReturnedValue ExecutionContext::getProperty(const StringRef name)
continue;
}
- else if (ctx->type == Type_CatchContext) {
+ else if (ctx->d()->type == Type_CatchContext) {
hasCatchScope = true;
CatchContext *c = static_cast<CatchContext *>(ctx);
- if (c->exceptionVarName->isEqualTo(name))
- return c->exceptionValue.asReturnedValue();
+ if (c->d()->exceptionVarName->isEqualTo(name))
+ return c->d()->exceptionValue.asReturnedValue();
}
- else if (ctx->type >= Type_CallContext) {
+ else if (ctx->d()->type >= Type_CallContext) {
QV4::CallContext *c = static_cast<CallContext *>(ctx);
- ScopedFunctionObject f(scope, c->function);
- if (f->function && (f->needsActivation || hasWith || hasCatchScope)) {
- uint index = f->function->internalClass->find(name);
+ ScopedFunctionObject f(scope, c->d()->function);
+ if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
+ uint index = f->function()->internalClass->find(name);
if (index < UINT_MAX) {
- if (index < c->function->formalParameterCount())
- return c->callData->args[c->function->formalParameterCount() - index - 1].asReturnedValue();
- return c->locals[index - c->function->formalParameterCount()].asReturnedValue();
+ if (index < c->d()->function->formalParameterCount())
+ return c->d()->callData->args[c->d()->function->formalParameterCount() - index - 1].asReturnedValue();
+ return c->d()->locals[index - c->d()->function->formalParameterCount()].asReturnedValue();
}
}
- if (c->activation) {
+ if (c->d()->activation) {
bool hasProperty = false;
- v = c->activation->get(name, &hasProperty);
+ v = c->d()->activation->get(name, &hasProperty);
if (hasProperty)
return v.asReturnedValue();
}
- if (f->function && f->function->isNamedExpression()
- && name->equals(f->function->name()))
+ if (f->function() && f->function()->isNamedExpression()
+ && name->equals(f->function()->name()))
return f.asReturnedValue();
}
- else if (ctx->type == Type_GlobalContext) {
+ else if (ctx->d()->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
bool hasProperty = false;
- v = g->global->get(name, &hasProperty);
+ v = g->d()->global->get(name, &hasProperty);
if (hasProperty)
return v.asReturnedValue();
}
}
- ScopedValue n(scope, name.asReturnedValue());
+ ScopedValue n(scope, name);
return throwReferenceError(n);
}
-ReturnedValue ExecutionContext::getPropertyAndBase(const StringRef name, ObjectRef base)
+ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
{
Scope scope(this);
ScopedValue v(scope);
base = (Object *)0;
name->makeIdentifier();
- if (name->equals(engine->id_this))
- return callData->thisObject.asReturnedValue();
+ if (name->equals(d()->engine->id_this.getPointer()))
+ return d()->callData->thisObject.asReturnedValue();
bool hasWith = false;
bool hasCatchScope = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
- if (ctx->type == Type_WithContext) {
- Object *w = static_cast<WithContext *>(ctx)->withObject;
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ if (ctx->d()->type == Type_WithContext) {
+ Object *w = static_cast<WithContext *>(ctx)->d()->withObject;
hasWith = true;
bool hasProperty = false;
v = w->get(name, &hasProperty);
@@ -429,103 +430,103 @@ ReturnedValue ExecutionContext::getPropertyAndBase(const StringRef name, ObjectR
continue;
}
- else if (ctx->type == Type_CatchContext) {
+ else if (ctx->d()->type == Type_CatchContext) {
hasCatchScope = true;
CatchContext *c = static_cast<CatchContext *>(ctx);
- if (c->exceptionVarName->isEqualTo(name))
- return c->exceptionValue.asReturnedValue();
+ if (c->d()->exceptionVarName->isEqualTo(name))
+ return c->d()->exceptionValue.asReturnedValue();
}
- else if (ctx->type >= Type_CallContext) {
+ else if (ctx->d()->type >= Type_CallContext) {
QV4::CallContext *c = static_cast<CallContext *>(ctx);
- FunctionObject *f = c->function;
- if (f->function && (f->needsActivation || hasWith || hasCatchScope)) {
- uint index = f->function->internalClass->find(name);
+ FunctionObject *f = c->d()->function;
+ if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
+ uint index = f->function()->internalClass->find(name);
if (index < UINT_MAX) {
- if (index < c->function->formalParameterCount())
- return c->callData->args[c->function->formalParameterCount() - index - 1].asReturnedValue();
- return c->locals[index - c->function->formalParameterCount()].asReturnedValue();
+ if (index < c->d()->function->formalParameterCount())
+ return c->d()->callData->args[c->d()->function->formalParameterCount() - index - 1].asReturnedValue();
+ return c->d()->locals[index - c->d()->function->formalParameterCount()].asReturnedValue();
}
}
- if (c->activation) {
+ if (c->d()->activation) {
bool hasProperty = false;
- v = c->activation->get(name, &hasProperty);
+ v = c->d()->activation->get(name, &hasProperty);
if (hasProperty) {
- if (ctx->type == Type_QmlContext)
- base = c->activation;
+ if (ctx->d()->type == Type_QmlContext)
+ base = c->d()->activation;
return v.asReturnedValue();
}
}
- if (f->function && f->function->isNamedExpression()
- && name->equals(f->function->name()))
- return c->function->asReturnedValue();
+ if (f->function() && f->function()->isNamedExpression()
+ && name->equals(f->function()->name()))
+ return c->d()->function->asReturnedValue();
}
- else if (ctx->type == Type_GlobalContext) {
+ else if (ctx->d()->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
bool hasProperty = false;
- v = g->global->get(name, &hasProperty);
+ v = g->d()->global->get(name, &hasProperty);
if (hasProperty)
return v.asReturnedValue();
}
}
- ScopedValue n(scope, name.asReturnedValue());
+ ScopedValue n(scope, name);
return throwReferenceError(n);
}
ReturnedValue ExecutionContext::throwError(const ValueRef value)
{
- return engine->throwException(value);
+ return d()->engine->throwException(value);
}
ReturnedValue ExecutionContext::throwError(const QString &message)
{
Scope scope(this);
- ScopedValue v(scope, engine->newString(message));
- v = engine->newErrorObject(v);
+ ScopedValue v(scope, d()->engine->newString(message));
+ v = d()->engine->newErrorObject(v);
return throwError(v);
}
ReturnedValue ExecutionContext::throwSyntaxError(const QString &message, const QString &fileName, int line, int column)
{
Scope scope(this);
- Scoped<Object> error(scope, engine->newSyntaxErrorObject(message, fileName, line, column));
+ Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message, fileName, line, column));
return throwError(error);
}
ReturnedValue ExecutionContext::throwSyntaxError(const QString &message)
{
Scope scope(this);
- Scoped<Object> error(scope, engine->newSyntaxErrorObject(message));
+ Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message));
return throwError(error);
}
ReturnedValue ExecutionContext::throwTypeError()
{
Scope scope(this);
- Scoped<Object> error(scope, engine->newTypeErrorObject(QStringLiteral("Type error")));
+ Scoped<Object> error(scope, d()->engine->newTypeErrorObject(QStringLiteral("Type error")));
return throwError(error);
}
ReturnedValue ExecutionContext::throwTypeError(const QString &message)
{
Scope scope(this);
- Scoped<Object> error(scope, engine->newTypeErrorObject(message));
+ Scoped<Object> error(scope, d()->engine->newTypeErrorObject(message));
return throwError(error);
}
ReturnedValue ExecutionContext::throwUnimplemented(const QString &message)
{
Scope scope(this);
- ScopedValue v(scope, engine->newString(QStringLiteral("Unimplemented ") + message));
- v = engine->newErrorObject(v);
+ ScopedValue v(scope, d()->engine->newString(QStringLiteral("Unimplemented ") + message));
+ v = d()->engine->newErrorObject(v);
return throwError(v);
}
ReturnedValue ExecutionContext::catchException(StackTrace *trace)
{
- return engine->catchException(this, trace);
+ return d()->engine->catchException(this, trace);
}
ReturnedValue ExecutionContext::throwReferenceError(const ValueRef value)
@@ -533,7 +534,7 @@ ReturnedValue ExecutionContext::throwReferenceError(const ValueRef value)
Scope scope(this);
Scoped<String> s(scope, value->toString(this));
QString msg = s->toQString() + QStringLiteral(" is not defined");
- Scoped<Object> error(scope, engine->newReferenceErrorObject(msg));
+ Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg));
return throwError(error);
}
@@ -541,7 +542,7 @@ ReturnedValue ExecutionContext::throwReferenceError(const QString &message, cons
{
Scope scope(this);
QString msg = message;
- Scoped<Object> error(scope, engine->newReferenceErrorObject(msg, fileName, line, column));
+ Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg, fileName, line, column));
return throwError(error);
}
@@ -550,20 +551,20 @@ ReturnedValue ExecutionContext::throwRangeError(const ValueRef value)
Scope scope(this);
ScopedString s(scope, value->toString(this));
QString msg = s->toQString() + QStringLiteral(" out of range");
- ScopedObject error(scope, engine->newRangeErrorObject(msg));
+ ScopedObject error(scope, d()->engine->newRangeErrorObject(msg));
return throwError(error);
}
ReturnedValue ExecutionContext::throwRangeError(const QString &message)
{
Scope scope(this);
- ScopedObject error(scope, engine->newRangeErrorObject(message));
+ ScopedObject error(scope, d()->engine->newRangeErrorObject(message));
return throwError(error);
}
ReturnedValue ExecutionContext::throwURIError(const ValueRef msg)
{
Scope scope(this);
- ScopedObject error(scope, engine->newURIErrorObject(msg));
+ ScopedObject error(scope, d()->engine->newURIErrorObject(msg));
return throwError(error);
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index a07cbf2da5..7e67028364 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -69,8 +69,6 @@ struct WithContext;
struct Q_QML_EXPORT ExecutionContext : public Managed
{
- V4_MANAGED
- Q_MANAGED_TYPE(ExecutionContext)
enum {
IsExecutionContext = true
};
@@ -83,48 +81,66 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
Type_CallContext = 0x5,
Type_QmlContext = 0x6
};
-
- ExecutionContext(ExecutionEngine *engine, ContextType t)
- : Managed(engine->executionContextClass)
- {
- this->type = t;
- strictMode = false;
- this->engine = engine;
- this->parent = engine->currentContext();
- outer = 0;
- lookups = 0;
- compilationUnit = 0;
- currentEvalCode = 0;
- lineNumber = -1;
- engine->current = this;
- }
-
- ContextType type;
- bool strictMode;
-
- CallData *callData;
-
- ExecutionEngine *engine;
- ExecutionContext *parent;
- ExecutionContext *outer;
- Lookup *lookups;
- CompiledData::CompilationUnit *compilationUnit;
-
struct EvalCode
{
Function *function;
EvalCode *next;
};
- EvalCode *currentEvalCode;
- int lineNumber;
+ struct Data : Managed::Data {
+ Data(ExecutionEngine *engine, ContextType t)
+ : Managed::Data(engine->executionContextClass)
+ , type(t)
+ , strictMode(false)
+ , engine(engine)
+ , parent(engine->currentContext())
+ , outer(0)
+ , lookups(0)
+ , compilationUnit(0)
+ , currentEvalCode(0)
+ , lineNumber(-1)
+ {
+ engine->current = reinterpret_cast<ExecutionContext *>(this);
+ }
+ ContextType type;
+ bool strictMode;
+
+ CallData *callData;
+
+ ExecutionEngine *engine;
+ ExecutionContext *parent;
+ ExecutionContext *outer;
+ Lookup *lookups;
+ CompiledData::CompilationUnit *compilationUnit;
+ EvalCode *currentEvalCode;
+
+ int lineNumber;
- CallContext *newCallContext(FunctionObject *f, CallData *callData);
- WithContext *newWithContext(ObjectRef with);
- CatchContext *newCatchContext(const StringRef exceptionVarName, const ValueRef exceptionValue);
- CallContext *newQmlContext(FunctionObject *f, ObjectRef qml);
+ };
+ V4_MANAGED(Managed)
+ Q_MANAGED_TYPE(ExecutionContext)
- void createMutableBinding(const StringRef name, bool deletable);
+ ExecutionContext(ExecutionEngine *engine, ContextType t)
+ : Managed(engine->executionContextClass)
+ {
+ d()->type = t;
+ d()->strictMode = false;
+ d()->engine = engine;
+ d()->parent = engine->currentContext();
+ d()->outer = 0;
+ d()->lookups = 0;
+ d()->compilationUnit = 0;
+ d()->currentEvalCode = 0;
+ d()->lineNumber = -1;
+ engine->current = this;
+ }
+
+ HeapObject *newCallContext(FunctionObject *f, CallData *callData);
+ WithContext *newWithContext(Object *with);
+ CatchContext *newCatchContext(String *exceptionVarName, const ValueRef exceptionValue);
+ CallContext *newQmlContext(FunctionObject *f, Object *qml);
+
+ void createMutableBinding(String *name, bool deletable);
ReturnedValue throwError(const QV4::ValueRef value);
ReturnedValue throwError(const QString &message);
@@ -139,10 +155,10 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
ReturnedValue throwURIError(const ValueRef msg);
ReturnedValue throwUnimplemented(const QString &message);
- void setProperty(const StringRef name, const ValueRef value);
- ReturnedValue getProperty(const StringRef name);
- ReturnedValue getPropertyAndBase(const StringRef name, ObjectRef base);
- bool deleteProperty(const StringRef name);
+ void setProperty(String *name, const ValueRef value);
+ ReturnedValue getProperty(String *name);
+ ReturnedValue getPropertyAndBase(String *name, Object *&base);
+ bool deleteProperty(String *name);
// Can only be called from within catch(...), rethrows if no JS exception.
ReturnedValue catchException(StackTrace *trace = 0);
@@ -155,19 +171,22 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
struct CallContext : public ExecutionContext
{
- CallContext(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext)
- : ExecutionContext(engine, t)
- {
- function = 0;
- locals = 0;
- activation = 0;
- }
- CallContext(ExecutionEngine *engine, ObjectRef qml, QV4::FunctionObject *function);
-
- FunctionObject *function;
- int realArgumentCount;
- Value *locals;
- Object *activation;
+ struct Data : ExecutionContext::Data {
+ Data(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext)
+ : ExecutionContext::Data(engine, t)
+ {
+ function = 0;
+ locals = 0;
+ activation = 0;
+ }
+ Data(ExecutionEngine *engine, Object *qml, QV4::FunctionObject *function);
+
+ FunctionObject *function;
+ int realArgumentCount;
+ Value *locals;
+ Object *activation;
+ };
+ V4_MANAGED(ExecutionContext)
// formals are in reverse order
String * const *formals() const;
@@ -180,52 +199,60 @@ struct CallContext : public ExecutionContext
};
inline ReturnedValue CallContext::argument(int i) {
- return i < callData->argc ? callData->args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
+ return i < d()->callData->argc ? d()->callData->args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
}
struct GlobalContext : public ExecutionContext
{
- GlobalContext(ExecutionEngine *engine);
+ struct Data : ExecutionContext::Data {
+ Data(ExecutionEngine *engine);
+ Object *global;
+ };
+ V4_MANAGED(ExecutionContext)
- Object *global;
};
struct CatchContext : public ExecutionContext
{
- CatchContext(ExecutionEngine *engine, const StringRef exceptionVarName, const ValueRef exceptionValue);
-
- StringValue exceptionVarName;
- Value exceptionValue;
+ struct Data : ExecutionContext::Data {
+ Data(ExecutionEngine *engine, String *exceptionVarName, const ValueRef exceptionValue);
+ StringValue exceptionVarName;
+ Value exceptionValue;
+ };
+ V4_MANAGED(ExecutionContext)
};
struct WithContext : public ExecutionContext
{
- WithContext(ExecutionEngine *engine, ObjectRef with);
- Object *withObject;
+ struct Data : ExecutionContext::Data {
+ Data(ExecutionEngine *engine, Object *with);
+ Object *withObject;
+ };
+ V4_MANAGED(ExecutionContext)
};
inline CallContext *ExecutionContext::asCallContext()
{
- return type >= Type_SimpleCallContext ? static_cast<CallContext *>(this) : 0;
+ return d()->type >= Type_SimpleCallContext ? static_cast<CallContext *>(this) : 0;
}
inline const CallContext *ExecutionContext::asCallContext() const
{
- return type >= Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
+ return d()->type >= Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
}
inline void ExecutionEngine::pushContext(CallContext *context)
{
- context->parent = current;
+ context->d()->parent = current;
current = context;
- current->currentEvalCode = 0;
+ current->d()->currentEvalCode = 0;
}
inline ExecutionContext *ExecutionEngine::popContext()
{
- Q_ASSERT(current->parent);
- current = current->parent;
+ Q_ASSERT(current->d()->parent);
+ current = current->d()->parent;
return current;
}
@@ -235,7 +262,7 @@ struct ExecutionContextSaver
ExecutionContext *savedContext;
ExecutionContextSaver(ExecutionContext *context)
- : engine(context->engine)
+ : engine(context->d()->engine)
, savedContext(context)
{
}
@@ -246,7 +273,7 @@ struct ExecutionContextSaver
};
inline Scope::Scope(ExecutionContext *ctx)
- : engine(ctx->engine)
+ : engine(ctx->d()->engine)
#ifndef QT_NO_DEBUG
, size(0)
#endif
@@ -256,7 +283,7 @@ inline Scope::Scope(ExecutionContext *ctx)
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
- ((sizeof(CallContext) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData)
+ ((sizeof(CallContext::Data) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData)
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index ceef88455b..b7fac9432f 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -643,8 +643,8 @@ static double getLocalTZA()
DEFINE_OBJECT_VTABLE(DateObject);
-DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
- : Object(engine->dateClass)
+DateObject::Data::Data(ExecutionEngine *engine, const QDateTime &date)
+ : Object::Data(engine->dateClass)
{
setVTable(staticVTable());
value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
@@ -652,13 +652,13 @@ DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
QDateTime DateObject::toQDateTime() const
{
- return ToDateTime(value.asDouble(), Qt::LocalTime);
+ return ToDateTime(date().asDouble(), Qt::LocalTime);
}
DEFINE_OBJECT_VTABLE(DateCtor);
-DateCtor::DateCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Date"))
+DateCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Date"))
{
setVTable(staticVTable());
}
@@ -674,7 +674,7 @@ ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
Scope scope(m->engine());
ScopedValue arg(scope, callData->args[0]);
if (DateObject *d = arg->asDateObject())
- arg = d->value;
+ arg = d->date();
else
arg = RuntimeHelpers::toPrimitive(arg, PREFERREDTYPE_HINT);
@@ -707,7 +707,7 @@ ReturnedValue DateCtor::call(Managed *m, CallData *)
return m->engine()->newString(ToString(t))->asReturnedValue();
}
-void DatePrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -770,8 +770,8 @@ void DatePrototype::init(ExecutionEngine *engine, ObjectRef ctor)
double DatePrototype::getThisDate(ExecutionContext *ctx)
{
- if (DateObject *thisObject = ctx->callData->thisObject.asDateObject())
- return thisObject->value.asDouble();
+ if (DateObject *thisObject = ctx->d()->callData->thisObject.asDateObject())
+ return thisObject->date().asDouble();
else {
ctx->throwTypeError();
return 0;
@@ -780,22 +780,22 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
ReturnedValue DatePrototype::method_parse(CallContext *ctx)
{
- if (!ctx->callData->argc)
+ if (!ctx->d()->callData->argc)
return Encode(qSNaN());
- return Encode(ParseString(ctx->callData->args[0].toString(ctx)->toQString()));
+ return Encode(ParseString(ctx->d()->callData->args[0].toString(ctx)->toQString()));
}
ReturnedValue DatePrototype::method_UTC(CallContext *ctx)
{
- const int numArgs = ctx->callData->argc;
+ const int numArgs = ctx->d()->callData->argc;
if (numArgs >= 2) {
- double year = ctx->callData->args[0].toNumber();
- double month = ctx->callData->args[1].toNumber();
- double day = numArgs >= 3 ? ctx->callData->args[2].toNumber() : 1;
- double hours = numArgs >= 4 ? ctx->callData->args[3].toNumber() : 0;
- double mins = numArgs >= 5 ? ctx->callData->args[4].toNumber() : 0;
- double secs = numArgs >= 6 ? ctx->callData->args[5].toNumber() : 0;
- double ms = numArgs >= 7 ? ctx->callData->args[6].toNumber() : 0;
+ double year = ctx->d()->callData->args[0].toNumber();
+ double month = ctx->d()->callData->args[1].toNumber();
+ double day = numArgs >= 3 ? ctx->d()->callData->args[2].toNumber() : 1;
+ double hours = numArgs >= 4 ? ctx->d()->callData->args[3].toNumber() : 0;
+ double mins = numArgs >= 5 ? ctx->d()->callData->args[4].toNumber() : 0;
+ double secs = numArgs >= 6 ? ctx->d()->callData->args[5].toNumber() : 0;
+ double ms = numArgs >= 7 ? ctx->d()->callData->args[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
@@ -815,37 +815,37 @@ ReturnedValue DatePrototype::method_now(CallContext *ctx)
ReturnedValue DatePrototype::method_toString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_toDateString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToDateString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToDateString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_toTimeString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToTimeString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToTimeString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_toLocaleString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToLocaleString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToLocaleString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_toLocaleDateString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToLocaleDateString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToLocaleDateString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_toLocaleTimeString(CallContext *ctx)
{
double t = getThisDate(ctx);
- return ctx->engine->newString(ToLocaleTimeString(t))->asReturnedValue();
+ return ctx->d()->engine->newString(ToLocaleTimeString(t))->asReturnedValue();
}
ReturnedValue DatePrototype::method_valueOf(CallContext *ctx)
@@ -1007,196 +1007,196 @@ ReturnedValue DatePrototype::method_getTimezoneOffset(CallContext *ctx)
ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->callData->thisObject);
+ Scoped<DateObject> self(scope, ctx->d()->callData->thisObject);
if (!self)
return ctx->throwTypeError();
- double t = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- self->value.setDouble(TimeClip(t));
- return self->value.asReturnedValue();
+ double t = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ self->date().setDouble(TimeClip(t));
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->callData->thisObject);
+ Scoped<DateObject> self(scope, ctx->d()->callData->thisObject);
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double ms = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return self->value.asReturnedValue();
+ double t = LocalTime(self->date().asDouble());
+ double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ self->date().setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double ms = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return self->value.asReturnedValue();
+ double t = self->date().asDouble();
+ double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ self->date().setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double sec = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double ms = (ctx->callData->argc < 2) ? msFromTime(t) : ctx->callData->args[1].toNumber();
+ double t = LocalTime(self->date().asDouble());
+ double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double ms = (ctx->d()->callData->argc < 2) ? msFromTime(t) : ctx->d()->callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double sec = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double ms = (ctx->callData->argc < 2) ? msFromTime(t) : ctx->callData->args[1].toNumber();
+ double t = self->date().asDouble();
+ double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double ms = (ctx->d()->callData->argc < 2) ? msFromTime(t) : ctx->d()->callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double min = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double sec = (ctx->callData->argc < 2) ? SecFromTime(t) : ctx->callData->args[1].toNumber();
- double ms = (ctx->callData->argc < 3) ? msFromTime(t) : ctx->callData->args[2].toNumber();
+ double t = LocalTime(self->date().asDouble());
+ double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double sec = (ctx->d()->callData->argc < 2) ? SecFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double ms = (ctx->d()->callData->argc < 3) ? msFromTime(t) : ctx->d()->callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double min = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double sec = (ctx->callData->argc < 2) ? SecFromTime(t) : ctx->callData->args[1].toNumber();
- double ms = (ctx->callData->argc < 3) ? msFromTime(t) : ctx->callData->args[2].toNumber();
+ double t = self->date().asDouble();
+ double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double sec = (ctx->d()->callData->argc < 2) ? SecFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double ms = (ctx->d()->callData->argc < 3) ? msFromTime(t) : ctx->d()->callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double hour = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double min = (ctx->callData->argc < 2) ? MinFromTime(t) : ctx->callData->args[1].toNumber();
- double sec = (ctx->callData->argc < 3) ? SecFromTime(t) : ctx->callData->args[2].toNumber();
- double ms = (ctx->callData->argc < 4) ? msFromTime(t) : ctx->callData->args[3].toNumber();
+ double t = LocalTime(self->date().asDouble());
+ double hour = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double min = (ctx->d()->callData->argc < 2) ? MinFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double sec = (ctx->d()->callData->argc < 3) ? SecFromTime(t) : ctx->d()->callData->args[2].toNumber();
+ double ms = (ctx->d()->callData->argc < 4) ? msFromTime(t) : ctx->d()->callData->args[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double hour = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double min = (ctx->callData->argc < 2) ? MinFromTime(t) : ctx->callData->args[1].toNumber();
- double sec = (ctx->callData->argc < 3) ? SecFromTime(t) : ctx->callData->args[2].toNumber();
- double ms = (ctx->callData->argc < 4) ? msFromTime(t) : ctx->callData->args[3].toNumber();
+ double t = self->date().asDouble();
+ double hour = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double min = (ctx->d()->callData->argc < 2) ? MinFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double sec = (ctx->d()->callData->argc < 3) ? SecFromTime(t) : ctx->d()->callData->args[2].toNumber();
+ double ms = (ctx->d()->callData->argc < 4) ? msFromTime(t) : ctx->d()->callData->args[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double date = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
+ double t = LocalTime(self->date().asDouble());
+ double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double date = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
+ double t = self->date().asDouble();
+ double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
- double month = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double date = (ctx->callData->argc < 2) ? DateFromTime(t) : ctx->callData->args[1].toNumber();
+ double t = LocalTime(self->date().asDouble());
+ double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double date = (ctx->d()->callData->argc < 2) ? DateFromTime(t) : ctx->d()->callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double month = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double date = (ctx->callData->argc < 2) ? DateFromTime(t) : ctx->callData->args[1].toNumber();
+ double t = self->date().asDouble();
+ double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double date = (ctx->d()->callData->argc < 2) ? DateFromTime(t) : ctx->d()->callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
+ double t = self->date().asDouble();
if (std::isnan(t))
t = 0;
else
t = LocalTime(t);
- double year = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
+ double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
double r;
if (std::isnan(year)) {
r = qSNaN();
@@ -1207,50 +1207,50 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
r = UTC(MakeDate(r, TimeWithinDay(t)));
r = TimeClip(r);
}
- self->value.setDouble(r);
- return self->value.asReturnedValue();
+ self->date().setDouble(r);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- double year = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double month = (ctx->callData->argc < 2) ? MonthFromTime(t) : ctx->callData->args[1].toNumber();
- double date = (ctx->callData->argc < 3) ? DateFromTime(t) : ctx->callData->args[2].toNumber();
+ double t = self->date().asDouble();
+ double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double month = (ctx->d()->callData->argc < 2) ? MonthFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double date = (ctx->d()->callData->argc < 3) ? DateFromTime(t) : ctx->d()->callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = LocalTime(self->value.asDouble());
+ double t = LocalTime(self->date().asDouble());
if (std::isnan(t))
t = 0;
- double year = ctx->callData->argc ? ctx->callData->args[0].toNumber() : qSNaN();
- double month = (ctx->callData->argc < 2) ? MonthFromTime(t) : ctx->callData->args[1].toNumber();
- double date = (ctx->callData->argc < 3) ? DateFromTime(t) : ctx->callData->args[2].toNumber();
+ double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
+ double month = (ctx->d()->callData->argc < 2) ? MonthFromTime(t) : ctx->d()->callData->args[1].toNumber();
+ double date = (ctx->d()->callData->argc < 3) ? DateFromTime(t) : ctx->d()->callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
- self->value.setDouble(t);
- return self->value.asReturnedValue();
+ self->date().setDouble(t);
+ return self->date().asReturnedValue();
}
ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
- return ctx->engine->newString(ToUTCString(t))->asReturnedValue();
+ double t = self->date().asDouble();
+ return ctx->d()->engine->newString(ToUTCString(t))->asReturnedValue();
}
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
@@ -1268,19 +1268,19 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
{
- DateObject *self = ctx->callData->thisObject.asDateObject();
+ DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
return ctx->throwTypeError();
- double t = self->value.asDouble();
+ double t = self->date().asDouble();
if (!std::isfinite(t))
- return ctx->throwRangeError(ctx->callData->thisObject);
+ return ctx->throwRangeError(ctx->d()->callData->thisObject);
QString result;
int year = (int)YearFromTime(t);
if (year < 0 || year > 9999) {
if (qAbs(year) >= 1000000)
- return ctx->engine->newString(QStringLiteral("Invalid Date"))->asReturnedValue();
+ return ctx->d()->engine->newString(QStringLiteral("Invalid Date"))->asReturnedValue();
result += year < 0 ? QLatin1Char('-') : QLatin1Char('+');
year = qAbs(year);
addZeroPrefixedInt(result, year, 6);
@@ -1301,27 +1301,27 @@ ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
addZeroPrefixedInt(result, msFromTime(t), 3);
result += QLatin1Char('Z');
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
{
Scope scope(ctx);
- ScopedValue O(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->callData->thisObject)));
+ ScopedValue O(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->d()->callData->thisObject)));
ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));
if (tv->isNumber() && !std::isfinite(tv->toNumber()))
return Encode::null();
- ScopedString s(scope, ctx->engine->newString(QStringLiteral("toISOString")));
- ScopedValue v(scope, O->objectValue()->get(s));
+ ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString")));
+ ScopedValue v(scope, O->objectValue()->get(s.getPointer()));
FunctionObject *toIso = v->asFunctionObject();
if (!toIso)
return ctx->throwTypeError();
ScopedCallData callData(scope, 0);
- callData->thisObject = ctx->callData->thisObject;
+ callData->thisObject = ctx->d()->callData->thisObject;
return toIso->call(callData);
}
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index c52e8c3ee1..6df4da45c9 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -52,27 +52,38 @@ class QDateTime;
namespace QV4 {
struct DateObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, const ValueRef date)
+ : Object::Data(engine->dateClass)
+ {
+ value = date;
+ }
+ Data(ExecutionEngine *engine, const QDateTime &date);
+ Data(InternalClass *ic)
+ : Object::Data(ic)
+ {
+ Q_ASSERT(internalClass->vtable == staticVTable());
+ value = Primitive::fromDouble(qSNaN());
+ }
+ Value value;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(DateObject)
- Value value;
- DateObject(ExecutionEngine *engine, const ValueRef date): Object(engine->dateClass) {
- value = date;
- }
- DateObject(ExecutionEngine *engine, const QDateTime &value);
- QDateTime toQDateTime() const;
-protected:
- DateObject(InternalClass *ic): Object(ic) {
- Q_ASSERT(internalClass->vtable == staticVTable());
- value = Primitive::fromDouble(qSNaN());
- }
+ Value date() const { return d()->value; }
+ Value &date() { return d()->value; }
+ void setDate(const ValueRef date) { d()->value = date; }
+
+ QDateTime toQDateTime() const;
};
struct DateCtor: FunctionObject
{
- V4_OBJECT
- DateCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *);
@@ -80,8 +91,7 @@ struct DateCtor: FunctionObject
struct DatePrototype: DateObject
{
- DatePrototype(InternalClass *ic): DateObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static double getThisDate(ExecutionContext *ctx);
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 06c6dbb4d9..04422b9f5e 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -210,7 +210,7 @@ Debugger::ExecutionState Debugger::currentExecutionState() const
{
ExecutionState state;
state.fileName = getFunction()->sourceFile();
- state.lineNumber = engine()->currentContext()->lineNumber;
+ state.lineNumber = engine()->currentContext()->d()->lineNumber;
return state;
}
@@ -224,12 +224,12 @@ static inline CallContext *findContext(ExecutionContext *ctxt, int frame)
{
while (ctxt) {
CallContext *cCtxt = ctxt->asCallContext();
- if (cCtxt && cCtxt->function) {
+ if (cCtxt && cCtxt->d()->function) {
if (frame < 1)
return cCtxt;
--frame;
}
- ctxt = ctxt->parent;
+ ctxt = ctxt->d()->parent;
}
return 0;
@@ -238,7 +238,7 @@ static inline CallContext *findContext(ExecutionContext *ctxt, int frame)
static inline CallContext *findScope(ExecutionContext *ctxt, int scope)
{
for (; scope > 0 && ctxt; --scope)
- ctxt = ctxt->outer;
+ ctxt = ctxt->d()->outer;
return ctxt ? ctxt->asCallContext() : 0;
}
@@ -327,7 +327,7 @@ void Debugger::collectLocalsInContext(Collector *collector, int frameNr, int sco
QString qName;
if (String *name = ctxt->variables()[i])
qName = name->toQString();
- v = ctxt->locals[i];
+ v = ctxt->d()->locals[i];
collector->collect(qName, v);
}
}
@@ -367,16 +367,16 @@ bool Debugger::collectThisInContext(Debugger::Collector *collector, int frame)
ExecutionContext *ctxt = findContext(engine->currentContext(), frameNr);
while (ctxt) {
if (CallContext *cCtxt = ctxt->asCallContext())
- if (cCtxt->activation)
+ if (cCtxt->d()->activation)
break;
- ctxt = ctxt->outer;
+ ctxt = ctxt->d()->outer;
}
if (!ctxt)
return false;
Scope scope(engine);
- ScopedObject o(scope, ctxt->asCallContext()->activation);
+ ScopedObject o(scope, ctxt->asCallContext()->d()->activation);
collector->collect(o);
return true;
}
@@ -434,12 +434,12 @@ QVector<ExecutionContext::ContextType> Debugger::getScopeTypes(int frame) const
return types;
CallContext *sctxt = findContext(m_engine->currentContext(), frame);
- if (!sctxt || sctxt->type < ExecutionContext::Type_SimpleCallContext)
+ if (!sctxt || sctxt->d()->type < ExecutionContext::Type_SimpleCallContext)
return types;
CallContext *ctxt = static_cast<CallContext *>(sctxt);
- for (ExecutionContext *it = ctxt; it; it = it->outer)
- types.append(it->type);
+ for (ExecutionContext *it = ctxt; it; it = it->d()->outer)
+ types.append(it->d()->type);
return types;
}
@@ -450,7 +450,7 @@ void Debugger::maybeBreakAtInstruction()
return;
QMutexLocker locker(&m_lock);
- int lineNumber = engine()->currentContext()->lineNumber;
+ int lineNumber = engine()->currentContext()->d()->lineNumber;
if (m_gatherSources) {
m_gatherSources->run();
@@ -495,7 +495,7 @@ void Debugger::leavingFunction(const ReturnedValue &retVal)
QMutexLocker locker(&m_lock);
if (m_stepping != NotStepping && m_currentContext == m_engine->currentContext()) {
- m_currentContext = m_engine->currentContext()->parent;
+ m_currentContext = m_engine->currentContext()->d()->parent;
m_stepping = StepOver;
m_returnedValue = retVal;
}
@@ -517,10 +517,10 @@ Function *Debugger::getFunction() const
{
ExecutionContext *context = m_engine->currentContext();
if (CallContext *callCtx = context->asCallContext())
- return callCtx->function->function;
+ return callCtx->d()->function->function();
else {
- Q_ASSERT(context->type == QV4::ExecutionContext::Type_GlobalContext);
- return context->engine->globalCode;
+ Q_ASSERT(context->d()->type == QV4::ExecutionContext::Type_GlobalContext);
+ return context->d()->engine->globalCode;
}
}
@@ -726,7 +726,7 @@ void Debugger::Collector::collect(const QString &name, const ScopedValue &value)
}
}
-void Debugger::Collector::collect(const ObjectRef object)
+void Debugger::Collector::collect(Object *object)
{
bool property = true;
qSwap(property, m_isProperty);
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index 47a7d77b28..f834b8d15f 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -105,7 +105,7 @@ public:
virtual ~Collector();
void collect(const QString &name, const ScopedValue &value);
- void collect(const ObjectRef object);
+ void collect(Object *object);
protected:
virtual void addUndefined(const QString &name) = 0;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 72be889e72..7be518916d 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -71,6 +71,7 @@
#include "qv4memberdata_p.h"
#include <QtCore/QTextStream>
+#include <QDateTime>
#ifdef V4_ENABLE_JIT
#include "qv4isel_masm_p.h"
@@ -258,13 +259,13 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
memberDataClass = InternalClass::create(this, MemberData::staticVTable(), 0);
- ObjectPrototype *objectPrototype = new (memoryManager) ObjectPrototype(InternalClass::create(this, ObjectPrototype::staticVTable(), 0));
+ ScopedObject objectPrototype(scope, memoryManager->alloc<ObjectPrototype>(InternalClass::create(this, ObjectPrototype::staticVTable(), 0)));
objectClass = InternalClass::create(this, Object::staticVTable(), objectPrototype);
Q_ASSERT(objectClass->vtable == Object::staticVTable());
arrayClass = InternalClass::create(this, ArrayObject::staticVTable(), objectPrototype);
arrayClass = arrayClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
- ArrayPrototype *arrayPrototype = new (memoryManager) ArrayPrototype(arrayClass);
+ ScopedObject arrayPrototype(scope, memoryManager->alloc<ArrayPrototype>(arrayClass));
arrayClass = arrayClass->changePrototype(arrayPrototype);
simpleArrayDataClass = InternalClass::create(this, SimpleArrayData::staticVTable(), 0);
@@ -279,100 +280,100 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
initRootContext();
- StringPrototype *stringPrototype = new (memoryManager) StringPrototype(InternalClass::create(this, StringPrototype::staticVTable(), objectPrototype));
+ ScopedObject stringPrototype(scope, memoryManager->alloc<StringPrototype>(InternalClass::create(this, StringPrototype::staticVTable(), objectPrototype)));
stringObjectClass = InternalClass::create(this, String::staticVTable(), stringPrototype);
- NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(InternalClass::create(this, NumberPrototype::staticVTable(), objectPrototype));
+ ScopedObject numberPrototype(scope, memoryManager->alloc<NumberPrototype>(InternalClass::create(this, NumberPrototype::staticVTable(), objectPrototype)));
numberClass = InternalClass::create(this, NumberObject::staticVTable(), numberPrototype);
- BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(InternalClass::create(this, BooleanPrototype::staticVTable(), objectPrototype));
+ ScopedObject booleanPrototype(scope, memoryManager->alloc<BooleanPrototype>(InternalClass::create(this, BooleanPrototype::staticVTable(), objectPrototype)));
booleanClass = InternalClass::create(this, BooleanObject::staticVTable(), booleanPrototype);
- DatePrototype *datePrototype = new (memoryManager) DatePrototype(InternalClass::create(this, DatePrototype::staticVTable(), objectPrototype));
+ ScopedObject datePrototype(scope, memoryManager->alloc<DatePrototype>(InternalClass::create(this, DatePrototype::staticVTable(), objectPrototype)));
dateClass = InternalClass::create(this, DateObject::staticVTable(), datePrototype);
InternalClass *functionProtoClass = InternalClass::create(this, FunctionObject::staticVTable(), objectPrototype);
uint index;
functionProtoClass = functionProtoClass->addMember(id_prototype, Attr_NotEnumerable, &index);
Q_ASSERT(index == FunctionObject::Index_Prototype);
- FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(functionProtoClass);
+ ScopedObject functionPrototype(scope, memoryManager->alloc<FunctionPrototype>(functionProtoClass));
functionClass = InternalClass::create(this, FunctionObject::staticVTable(), functionPrototype);
functionClass = functionClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == FunctionObject::Index_Prototype);
protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == FunctionObject::Index_ProtoConstructor);
- RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype));
- regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype);
+ Scoped<RegExpPrototype> regExpPrototype(scope, memoryManager->alloc<RegExpPrototype>(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype)));
+ regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype.getPointer());
regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(InternalClass::create(this, ErrorObject::staticVTable(), objectPrototype));
+ ScopedObject errorPrototype(scope, memoryManager->alloc<ErrorPrototype>(InternalClass::create(this, ErrorObject::staticVTable(), objectPrototype)));
errorClass = InternalClass::create(this, ErrorObject::staticVTable(), errorPrototype);
- EvalErrorPrototype *evalErrorPrototype = new (memoryManager) EvalErrorPrototype(errorClass);
+ ScopedObject evalErrorPrototype(scope, memoryManager->alloc<EvalErrorPrototype>(errorClass));
evalErrorClass = InternalClass::create(this, EvalErrorObject::staticVTable(), evalErrorPrototype);
- RangeErrorPrototype *rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(errorClass);
+ ScopedObject rangeErrorPrototype(scope, memoryManager->alloc<RangeErrorPrototype>(errorClass));
rangeErrorClass = InternalClass::create(this, RangeErrorObject::staticVTable(), rangeErrorPrototype);
- ReferenceErrorPrototype *referenceErrorPrototype = new (memoryManager) ReferenceErrorPrototype(errorClass);
+ ScopedObject referenceErrorPrototype(scope, memoryManager->alloc<ReferenceErrorPrototype>(errorClass));
referenceErrorClass = InternalClass::create(this, ReferenceErrorObject::staticVTable(), referenceErrorPrototype);
- SyntaxErrorPrototype *syntaxErrorPrototype = new (memoryManager) SyntaxErrorPrototype(errorClass);
+ ScopedObject syntaxErrorPrototype(scope, memoryManager->alloc<SyntaxErrorPrototype>(errorClass));
syntaxErrorClass = InternalClass::create(this, SyntaxErrorObject::staticVTable(), syntaxErrorPrototype);
- TypeErrorPrototype *typeErrorPrototype = new (memoryManager) TypeErrorPrototype(errorClass);
+ ScopedObject typeErrorPrototype(scope, memoryManager->alloc<TypeErrorPrototype>(errorClass));
typeErrorClass = InternalClass::create(this, TypeErrorObject::staticVTable(), typeErrorPrototype);
- URIErrorPrototype *uRIErrorPrototype = new (memoryManager) URIErrorPrototype(errorClass);
+ ScopedObject uRIErrorPrototype(scope, memoryManager->alloc<URIErrorPrototype>(errorClass));
uriErrorClass = InternalClass::create(this, URIErrorObject::staticVTable(), uRIErrorPrototype);
- VariantPrototype *variantPrototype = new (memoryManager) VariantPrototype(InternalClass::create(this, VariantPrototype::staticVTable(), objectPrototype));
+ ScopedObject variantPrototype(scope, memoryManager->alloc<VariantPrototype>(InternalClass::create(this, VariantPrototype::staticVTable(), objectPrototype)));
variantClass = InternalClass::create(this, VariantObject::staticVTable(), variantPrototype);
Q_ASSERT(variantClass->prototype == variantPrototype);
- Q_ASSERT(variantPrototype->internalClass->prototype == objectPrototype);
-
- sequencePrototype = new (memoryManager) SequencePrototype(arrayClass);
-
- objectCtor = new (memoryManager) ObjectCtor(rootContext);
- stringCtor = new (memoryManager) StringCtor(rootContext);
- numberCtor = new (memoryManager) NumberCtor(rootContext);
- booleanCtor = new (memoryManager) BooleanCtor(rootContext);
- arrayCtor = new (memoryManager) ArrayCtor(rootContext);
- functionCtor = new (memoryManager) FunctionCtor(rootContext);
- dateCtor = new (memoryManager) DateCtor(rootContext);
- regExpCtor = new (memoryManager) RegExpCtor(rootContext);
- errorCtor = new (memoryManager) ErrorCtor(rootContext);
- evalErrorCtor = new (memoryManager) EvalErrorCtor(rootContext);
- rangeErrorCtor = new (memoryManager) RangeErrorCtor(rootContext);
- referenceErrorCtor = new (memoryManager) ReferenceErrorCtor(rootContext);
- syntaxErrorCtor = new (memoryManager) SyntaxErrorCtor(rootContext);
- typeErrorCtor = new (memoryManager) TypeErrorCtor(rootContext);
- uRIErrorCtor = new (memoryManager) URIErrorCtor(rootContext);
-
- objectPrototype->init(this, objectCtor);
- stringPrototype->init(this, stringCtor);
- numberPrototype->init(this, numberCtor);
- booleanPrototype->init(this, booleanCtor);
- arrayPrototype->init(this, arrayCtor);
- datePrototype->init(this, dateCtor);
- functionPrototype->init(this, functionCtor);
- regExpPrototype->init(this, regExpCtor);
- errorPrototype->init(this, errorCtor);
- evalErrorPrototype->init(this, evalErrorCtor);
- rangeErrorPrototype->init(this, rangeErrorCtor);
- referenceErrorPrototype->init(this, referenceErrorCtor);
- syntaxErrorPrototype->init(this, syntaxErrorCtor);
- typeErrorPrototype->init(this, typeErrorCtor);
- uRIErrorPrototype->init(this, uRIErrorCtor);
-
- variantPrototype->init();
+ Q_ASSERT(variantPrototype->internalClass()->prototype == objectPrototype);
+
+ sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass));
+
+ objectCtor = memoryManager->alloc<ObjectCtor>(rootContext);
+ stringCtor = memoryManager->alloc<StringCtor>(rootContext);
+ numberCtor = memoryManager->alloc<NumberCtor>(rootContext);
+ booleanCtor = memoryManager->alloc<BooleanCtor>(rootContext);
+ arrayCtor = memoryManager->alloc<ArrayCtor>(rootContext);
+ functionCtor = memoryManager->alloc<FunctionCtor>(rootContext);
+ dateCtor = memoryManager->alloc<DateCtor>(rootContext);
+ regExpCtor = memoryManager->alloc<RegExpCtor>(rootContext);
+ errorCtor = memoryManager->alloc<ErrorCtor>(rootContext);
+ evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(rootContext);
+ rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(rootContext);
+ referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(rootContext);
+ syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(rootContext);
+ typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(rootContext);
+ uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(rootContext);
+
+ static_cast<ObjectPrototype *>(objectPrototype.getPointer())->init(this, objectCtor.asObject());
+ static_cast<StringPrototype *>(stringPrototype.getPointer())->init(this, stringCtor.asObject());
+ static_cast<NumberPrototype *>(numberPrototype.getPointer())->init(this, numberCtor.asObject());
+ static_cast<BooleanPrototype *>(booleanPrototype.getPointer())->init(this, booleanCtor.asObject());
+ static_cast<ArrayPrototype *>(arrayPrototype.getPointer())->init(this, arrayCtor.asObject());
+ static_cast<DatePrototype *>(datePrototype.getPointer())->init(this, dateCtor.asObject());
+ static_cast<FunctionPrototype *>(functionPrototype.getPointer())->init(this, functionCtor.asObject());
+ static_cast<RegExpPrototype *>(regExpPrototype.getPointer())->init(this, regExpCtor.asObject());
+ static_cast<ErrorPrototype *>(errorPrototype.getPointer())->init(this, errorCtor.asObject());
+ static_cast<EvalErrorPrototype *>(evalErrorPrototype.getPointer())->init(this, evalErrorCtor.asObject());
+ static_cast<RangeErrorPrototype *>(rangeErrorPrototype.getPointer())->init(this, rangeErrorCtor.asObject());
+ static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.getPointer())->init(this, referenceErrorCtor.asObject());
+ static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.getPointer())->init(this, syntaxErrorCtor.asObject());
+ static_cast<TypeErrorPrototype *>(typeErrorPrototype.getPointer())->init(this, typeErrorCtor.asObject());
+ static_cast<URIErrorPrototype *>(uRIErrorPrototype.getPointer())->init(this, uRIErrorCtor.asObject());
+
+ static_cast<VariantPrototype *>(variantPrototype.getPointer())->init();
static_cast<SequencePrototype *>(sequencePrototype.managed())->init();
//
// set up the global object
//
globalObject = newObject()->getPointer();
- rootContext->global = globalObject;
- rootContext->callData->thisObject = globalObject;
- Q_ASSERT(globalObject->internalClass->vtable);
+ rootContext->d()->global = globalObject;
+ rootContext->d()->callData->thisObject = globalObject;
+ Q_ASSERT(globalObject->internalClass()->vtable);
globalObject->defineDefaultProperty(QStringLiteral("Object"), objectCtor);
globalObject->defineDefaultProperty(QStringLiteral("String"), stringCtor);
@@ -390,14 +391,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
globalObject->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
ScopedObject o(scope);
- globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(QV4::InternalClass::create(this, MathObject::staticVTable(), objectPrototype))));
- globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(QV4::InternalClass::create(this, JsonObject::staticVTable(), objectPrototype))));
+ globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(QV4::InternalClass::create(this, MathObject::staticVTable(), objectPrototype))));
+ globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(QV4::InternalClass::create(this, JsonObject::staticVTable(), objectPrototype))));
globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
globalObject->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY));
- evalFunction = new (memoryManager) EvalFunction(rootContext);
+
+ evalFunction = Scoped<EvalFunction>(scope, memoryManager->alloc<EvalFunction>(rootContext));
globalObject->defineDefaultProperty(QStringLiteral("eval"), (o = evalFunction));
globalObject->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
@@ -412,13 +414,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
Scoped<String> name(scope, newString(QStringLiteral("thrower")));
- thrower = newBuiltinFunction(rootContext, name, throwTypeError)->getPointer();
+ thrower = ScopedFunctionObject(scope, BuiltinFunction::create(rootContext, name.getPointer(), throwTypeError)).getPointer();
}
ExecutionEngine::~ExecutionEngine()
{
delete debugger;
+ debugger = 0;
delete profiler;
+ profiler = 0;
delete m_multiplyWrappedQObjects;
m_multiplyWrappedQObjects = 0;
delete identifierTable;
@@ -451,18 +455,20 @@ void ExecutionEngine::enableDebugger()
void ExecutionEngine::enableProfiler()
{
Q_ASSERT(!profiler);
- profiler = new QV4::Profiling::Profiler();
+ profiler = new QV4::Profiling::Profiler(this);
}
void ExecutionEngine::initRootContext()
{
- rootContext = static_cast<GlobalContext *>(memoryManager->allocManaged(sizeof(GlobalContext) + sizeof(CallData)));
- new (rootContext) GlobalContext(this);
- rootContext->callData = reinterpret_cast<CallData *>(rootContext + 1);
- rootContext->callData->tag = QV4::Value::_Integer_Type;
- rootContext->callData->argc = 0;
- rootContext->callData->thisObject = globalObject;
- rootContext->callData->args[0] = Encode::undefined();
+ GlobalContext *r = static_cast<GlobalContext*>(memoryManager->allocManaged(sizeof(GlobalContext::Data) + sizeof(CallData)));
+ new (r->d()) GlobalContext::Data(this);
+ r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1);
+ r->d()->callData->tag = QV4::Value::_Integer_Type;
+ r->d()->callData->argc = 0;
+ r->d()->callData->thisObject = globalObject;
+ r->d()->callData->args[0] = Encode::undefined();
+
+ rootContext = r;
}
InternalClass *ExecutionEngine::newClass(const InternalClass &other)
@@ -472,43 +478,32 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
ExecutionContext *ExecutionEngine::pushGlobalContext()
{
- GlobalContext *g = new (memoryManager) GlobalContext(this);
- g->callData = rootContext->callData;
+ GlobalContext *g = memoryManager->alloc<GlobalContext>(this);
+ g->d()->callData = rootContext->d()->callData;
Q_ASSERT(currentContext() == g);
return g;
}
-Returned<FunctionObject> *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *))
-{
- BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name, code);
- return f->asReturned<FunctionObject>();
-}
-
-Returned<BoundFunction> *ExecutionEngine::newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs)
-{
- Q_ASSERT(target);
-
- BoundFunction *f = new (memoryManager) BoundFunction(scope, target, boundThis, boundArgs);
- return f->asReturned<BoundFunction>();
-}
-
Returned<Object> *ExecutionEngine::newObject()
{
- Object *object = new (memoryManager) Object(this);
+ Scope scope(this);
+ ScopedObject object(scope, memoryManager->alloc<Object>(this));
return object->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newObject(InternalClass *internalClass)
{
- Object *object = new (memoryManager) Object(internalClass);
+ Scope scope(this);
+ ScopedObject object(scope, memoryManager->alloc<Object>(internalClass));
return object->asReturned<Object>();
}
Returned<String> *ExecutionEngine::newString(const QString &s)
{
- return (new (memoryManager) String(this, s))->asReturned<String>();
+ Scope scope(this);
+ return ScopedString(scope, memoryManager->alloc<String>(this, s))->asReturned<String>();
}
String *ExecutionEngine::newIdentifier(const QString &text)
@@ -518,29 +513,31 @@ String *ExecutionEngine::newIdentifier(const QString &text)
Returned<Object> *ExecutionEngine::newStringObject(const ValueRef value)
{
- StringObject *object = new (memoryManager) StringObject(this, value);
+ Scope scope(this);
+ Scoped<StringObject> object(scope, memoryManager->alloc<StringObject>(this, value));
return object->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newNumberObject(const ValueRef value)
{
- NumberObject *object = new (memoryManager) NumberObject(this, value);
+ Scope scope(this);
+ Scoped<NumberObject> object(scope, memoryManager->alloc<NumberObject>(this, value));
return object->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newBooleanObject(const ValueRef value)
{
- Object *object = new (memoryManager) BooleanObject(this, value);
+ Scope scope(this);
+ ScopedObject object(scope, memoryManager->alloc<BooleanObject>(this, value));
return object->asReturned<Object>();
}
Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count)
{
- ArrayObject *object = new (memoryManager) ArrayObject(this);
+ Scope scope(this);
+ ScopedArrayObject object(scope, memoryManager->alloc<ArrayObject>(this));
if (count) {
- Scope scope(this);
- ScopedValue protectArray(scope, object);
if (count < 0x1000)
object->arrayReserve(count);
object->setArrayLengthUnchecked(count);
@@ -550,26 +547,30 @@ Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count)
Returned<ArrayObject> *ExecutionEngine::newArrayObject(const QStringList &list)
{
- ArrayObject *object = new (memoryManager) ArrayObject(this, list);
+ Scope scope(this);
+ ScopedArrayObject object(scope, memoryManager->alloc<ArrayObject>(this, list));
return object->asReturned<ArrayObject>();
}
Returned<ArrayObject> *ExecutionEngine::newArrayObject(InternalClass *ic)
{
- ArrayObject *object = new (memoryManager) ArrayObject(ic);
+ Scope scope(this);
+ ScopedArrayObject object(scope, memoryManager->alloc<ArrayObject>(ic));
return object->asReturned<ArrayObject>();
}
Returned<DateObject> *ExecutionEngine::newDateObject(const ValueRef value)
{
- DateObject *object = new (memoryManager) DateObject(this, value);
+ Scope scope(this);
+ Scoped<DateObject> object(scope, memoryManager->alloc<DateObject>(this, value));
return object->asReturned<DateObject>();
}
Returned<DateObject> *ExecutionEngine::newDateObject(const QDateTime &dt)
{
- DateObject *object = new (memoryManager) DateObject(this, dt);
+ Scope scope(this);
+ Scoped<DateObject> object(scope, memoryManager->alloc<DateObject>(this, dt));
return object->asReturned<DateObject>();
}
@@ -588,21 +589,24 @@ Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QString &pattern,
return newRegExpObject(re, global);
}
-Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExpRef re, bool global)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExp *re, bool global)
{
- RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
+ Scope scope(this);
+ Scoped<RegExpObject> object(scope, memoryManager->alloc<RegExpObject>(this, re, global));
return object->asReturned<RegExpObject>();
}
Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QRegExp &re)
{
- RegExpObject *object = new (memoryManager) RegExpObject(this, re);
+ Scope scope(this);
+ Scoped<RegExpObject> object(scope, memoryManager->alloc<RegExpObject>(this, re));
return object->asReturned<RegExpObject>();
}
Returned<Object> *ExecutionEngine::newErrorObject(const ValueRef value)
{
- ErrorObject *object = new (memoryManager) ErrorObject(errorClass, value);
+ Scope scope(this);
+ ScopedObject object(scope, memoryManager->alloc<ErrorObject>(errorClass, value));
return object->asReturned<Object>();
}
@@ -610,57 +614,65 @@ Returned<Object> *ExecutionEngine::newSyntaxErrorObject(const QString &message)
{
Scope scope(this);
ScopedString s(scope, newString(message));
- Object *error = new (memoryManager) SyntaxErrorObject(this, s);
+ ScopedObject error(scope, memoryManager->alloc<SyntaxErrorObject>(this, s));
return error->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column)
{
- Object *error = new (memoryManager) SyntaxErrorObject(this, message, fileName, line, column);
+ Scope scope(this);
+ ScopedObject error(scope, memoryManager->alloc<SyntaxErrorObject>(this, message, fileName, line, column));
return error->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message)
{
- Object *o = new (memoryManager) ReferenceErrorObject(this, message);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<ReferenceErrorObject>(this, message));
return o->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber)
{
- Object *o = new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber, columnNumber);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<ReferenceErrorObject>(this, message, fileName, lineNumber, columnNumber));
return o->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newTypeErrorObject(const QString &message)
{
- Object *o = new (memoryManager) TypeErrorObject(this, message);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<TypeErrorObject>(this, message));
return o->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newRangeErrorObject(const QString &message)
{
- Object *o = new (memoryManager) RangeErrorObject(this, message);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<RangeErrorObject>(this, message));
return o->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newURIErrorObject(const ValueRef message)
{
- Object *o = new (memoryManager) URIErrorObject(this, message);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<URIErrorObject>(this, message));
return o->asReturned<Object>();
}
Returned<Object> *ExecutionEngine::newVariantObject(const QVariant &v)
{
- Object *o = new (memoryManager) VariantObject(this, v);
+ Scope scope(this);
+ ScopedObject o(scope, memoryManager->alloc<VariantObject>(this, v));
return o->asReturned<Object>();
}
-Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
+Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o)
{
- Object *obj = new (memoryManager) ForEachIteratorObject(ctx, o);
+ Scope scope(this);
+ ScopedObject obj(scope, memoryManager->alloc<ForEachIteratorObject>(ctx, o));
return obj->asReturned<Object>();
}
@@ -668,20 +680,20 @@ Returned<Object> *ExecutionEngine::qmlContextObject() const
{
ExecutionContext *ctx = currentContext();
- if (ctx->type == QV4::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
- ctx = ctx->parent;
+ if (ctx->d()->type == QV4::ExecutionContext::Type_SimpleCallContext && !ctx->d()->outer)
+ ctx = ctx->d()->parent;
- if (!ctx->outer)
+ if (!ctx->d()->outer)
return 0;
- while (ctx->outer && ctx->outer->type != ExecutionContext::Type_GlobalContext)
- ctx = ctx->outer;
+ while (ctx->d()->outer && ctx->d()->outer->d()->type != ExecutionContext::Type_GlobalContext)
+ ctx = ctx->d()->outer;
Q_ASSERT(ctx);
- if (ctx->type != ExecutionContext::Type_QmlContext)
+ if (ctx->d()->type != ExecutionContext::Type_QmlContext)
return 0;
- return static_cast<CallContext *>(ctx)->activation->asReturned<Object>();
+ return static_cast<CallContext *>(ctx)->d()->activation->asReturned<Object>();
}
QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
@@ -693,30 +705,30 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
QV4::ExecutionContext *c = currentContext();
while (c && frameLimit) {
CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->function) {
+ if (callCtx && callCtx->d()->function) {
StackFrame frame;
- if (callCtx->function->function)
- frame.source = callCtx->function->function->sourceFile();
- name = callCtx->function->name();
+ if (callCtx->d()->function->function())
+ frame.source = callCtx->d()->function->function()->sourceFile();
+ name = callCtx->d()->function->name();
frame.function = name->toQString();
frame.line = -1;
frame.column = -1;
- if (callCtx->function->function)
+ if (callCtx->d()->function->function())
// line numbers can be negative for places where you can't set a real breakpoint
- frame.line = qAbs(callCtx->lineNumber);
+ frame.line = qAbs(callCtx->d()->lineNumber);
stack.append(frame);
--frameLimit;
}
- c = c->parent;
+ c = c->d()->parent;
}
if (frameLimit && globalCode) {
StackFrame frame;
frame.source = globalCode->sourceFile();
frame.function = globalCode->name()->toQString();
- frame.line = rootContext->lineNumber;
+ frame.line = rootContext->d()->lineNumber;
frame.column = -1;
@@ -750,8 +762,8 @@ static inline char *v4StackTrace(const ExecutionContext *context)
QString result;
QTextStream str(&result);
str << "stack=[";
- if (context && context->engine) {
- const QVector<StackFrame> stackTrace = context->engine->stackTrace(20);
+ if (context && context->d()->engine) {
+ const QVector<StackFrame> stackTrace = context->d()->engine->stackTrace(20);
for (int i = 0; i < stackTrace.size(); ++i) {
if (i)
str << ',';
@@ -781,12 +793,12 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
QV4::ExecutionContext *c = currentContext();
while (c) {
CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->function) {
- if (callCtx->function->function)
- base.setUrl(callCtx->function->function->sourceFile());
+ if (callCtx && callCtx->d()->function) {
+ if (callCtx->d()->function->function())
+ base.setUrl(callCtx->d()->function->function()->sourceFile());
break;
}
- c = c->parent;
+ c = c->d()->parent;
}
if (base.isEmpty() && globalCode)
@@ -817,8 +829,8 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
delete [] oldAccessors;
}
for (int i = oldSize; i < nArgumentsAccessors; ++i) {
- argumentsAccessors[i].value = Value::fromManaged(new (memoryManager) ArgumentsGetterFunction(rootContext, i));
- argumentsAccessors[i].set = Value::fromManaged(new (memoryManager) ArgumentsSetterFunction(rootContext, i));
+ argumentsAccessors[i].value = ScopedValue(scope, memoryManager->alloc<ArgumentsGetterFunction>(rootContext, i));
+ argumentsAccessors[i].set = ScopedValue(scope, memoryManager->alloc<ArgumentsSetterFunction>(rootContext, i));
}
}
}
@@ -839,12 +851,12 @@ void ExecutionEngine::markObjects()
ExecutionContext *c = currentContext();
while (c) {
- Q_ASSERT(c->inUse);
- if (!c->markBit) {
- c->markBit = 1;
+ Q_ASSERT(c->inUse());
+ if (!c->markBit()) {
+ c->d()->markBit = 1;
c->markObjects(c, this);
}
- c = c->parent;
+ c = c->d()->parent;
}
id_empty->mark(this);
@@ -932,7 +944,7 @@ ReturnedValue ExecutionEngine::throwException(const ValueRef value)
QV4::Scope scope(this);
QV4::Scoped<ErrorObject> error(scope, value);
if (!!error)
- exceptionStackTrace = error->stackTrace;
+ exceptionStackTrace = error->d()->stackTrace;
else
exceptionStackTrace = stackTrace();
@@ -971,7 +983,7 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError(ExecutionContext *context)
QV4::Scoped<QV4::ErrorObject> errorObj(scope, exception);
if (!!errorObj && errorObj->asSyntaxError()) {
QV4::ScopedString m(scope, errorObj->engine()->newString(QStringLiteral("message")));
- QV4::ScopedValue v(scope, errorObj->get(m));
+ QV4::ScopedValue v(scope, errorObj->get(m.getPointer()));
error.setDescription(v->toQStringNoThrow());
} else
error.setDescription(exception->toQStringNoThrow());
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index d678d6595e..a3f83de338 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -86,6 +86,7 @@ struct SyntaxErrorObject;
struct ArgumentsObject;
struct ExecutionContext;
struct ExecutionEngine;
+struct Members;
class MemoryManager;
class ExecutableAllocator;
@@ -111,7 +112,7 @@ struct IdentifierTable;
struct InternalClass;
struct InternalClassPool;
class MultiplyWrappedQObjectMap;
-class RegExp;
+struct RegExp;
class RegExpCache;
struct QmlExtensions;
struct Exception;
@@ -169,7 +170,6 @@ public:
return jsStackTop->managed();
}
-
IdentifierTable *identifierTable;
QV4::Debugging::Debugger *debugger;
@@ -285,7 +285,7 @@ public:
// calling preserve() on the object which removes it from this scarceResource list.
class ScarceResourceData {
public:
- ScarceResourceData(const QVariant &data) : data(data) {}
+ ScarceResourceData(const QVariant &data = QVariant()) : data(data) {}
QVariant data;
QIntrusiveListNode node;
};
@@ -306,9 +306,6 @@ public:
void pushContext(CallContext *context);
ExecutionContext *popContext();
- Returned<FunctionObject> *newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *));
- Returned<BoundFunction> *newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs);
-
Returned<Object> *newObject();
Returned<Object> *newObject(InternalClass *internalClass);
@@ -327,7 +324,7 @@ public:
Returned<DateObject> *newDateObject(const QDateTime &dt);
Returned<RegExpObject> *newRegExpObject(const QString &pattern, int flags);
- Returned<RegExpObject> *newRegExpObject(RegExpRef re, bool global);
+ Returned<RegExpObject> *newRegExpObject(RegExp *re, bool global);
Returned<RegExpObject> *newRegExpObject(const QRegExp &re);
Returned<Object> *newErrorObject(const ValueRef value);
@@ -341,7 +338,7 @@ public:
Returned<Object> *newVariantObject(const QVariant &v);
- Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o);
+ Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, Object *o);
Returned<Object> *qmlContextObject() const;
@@ -378,10 +375,10 @@ private:
inline
void Managed::mark(QV4::ExecutionEngine *engine)
{
- Q_ASSERT(inUse);
- if (markBit)
+ Q_ASSERT(inUse());
+ if (markBit())
return;
- markBit = 1;
+ d()->markBit = 1;
engine->pushForGC(this);
}
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 9d6403e7dd..b99a82a1f5 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -71,104 +71,100 @@
using namespace QV4;
-ErrorObject::ErrorObject(InternalClass *ic)
- : Object(ic)
- , stack(0)
+ErrorObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
- Scope scope(engine());
- ScopedValue protectThis(scope, this);
+ Scope scope(ic->engine);
+ Scoped<ErrorObject> e(scope, this);
- ScopedString s(scope, ic->engine->newString(QStringLiteral("Error")));
- defineDefaultProperty(QStringLiteral("name"), s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("Error")));
+ e->defineDefaultProperty(QStringLiteral("name"), s);
}
-ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t)
- : Object(ic)
- , stack(0)
+ErrorObject::Data::Data(InternalClass *ic, const ValueRef message, ErrorType t)
+ : Object::Data(ic)
{
subtype = t;
- Scope scope(engine());
- ScopedValue protectThis(scope, this);
+ Scope scope(ic->engine);
+ Scoped<ErrorObject> e(scope, this);
- defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
+ e->defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
if (!message->isUndefined())
- defineDefaultProperty(QStringLiteral("message"), message);
+ e->defineDefaultProperty(QStringLiteral("message"), message);
ScopedString s(scope);
- defineDefaultProperty(QStringLiteral("name"), (s = ic->engine->newString(className())));
+ e->defineDefaultProperty(QStringLiteral("name"), (s = scope.engine->newString(e->className())));
- stackTrace = ic->engine->stackTrace();
- if (!stackTrace.isEmpty()) {
- defineDefaultProperty(QStringLiteral("fileName"), (s = ic->engine->newString(stackTrace.at(0).source)));
- defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(stackTrace.at(0).line));
+ e->d()->stackTrace = scope.engine->stackTrace();
+ if (!e->d()->stackTrace.isEmpty()) {
+ e->defineDefaultProperty(QStringLiteral("fileName"), (s = scope.engine->newString(e->d()->stackTrace.at(0).source)));
+ e->defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(e->d()->stackTrace.at(0).line));
}
}
-ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorObject::ErrorType t)
- : Object(ic)
- , stack(0)
+ErrorObject::Data::Data(InternalClass *ic, const QString &message, ErrorObject::ErrorType t)
+ : Object::Data(ic)
{
subtype = t;
- Scope scope(engine());
- ScopedValue protectThis(scope, this);
+ Scope scope(ic->engine);
+ Scoped<ErrorObject> e(scope, this);
ScopedString s(scope);
- defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
+ e->defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
- ScopedValue v(scope, ic->engine->newString(message));
- defineDefaultProperty(QStringLiteral("message"), v);
- defineDefaultProperty(QStringLiteral("name"), (s = ic->engine->newString(className())));
+ ScopedValue v(scope, scope.engine->newString(message));
+ e->defineDefaultProperty(QStringLiteral("message"), v);
+ e->defineDefaultProperty(QStringLiteral("name"), (s = scope.engine->newString(e->className())));
- stackTrace = ic->engine->stackTrace();
- if (!stackTrace.isEmpty()) {
- defineDefaultProperty(QStringLiteral("fileName"), (s = ic->engine->newString(stackTrace.at(0).source)));
- defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(stackTrace.at(0).line));
+ e->d()->stackTrace = scope.engine->stackTrace();
+ if (!e->d()->stackTrace.isEmpty()) {
+ e->defineDefaultProperty(QStringLiteral("fileName"), (s = scope.engine->newString(e->d()->stackTrace.at(0).source)));
+ e->defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(e->d()->stackTrace.at(0).line));
}
}
-ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
- : Object(ic)
- , stack(0)
+ErrorObject::Data::Data(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
+ : Object::Data(ic)
{
subtype = t;
- Scope scope(engine());
- ScopedValue protectThis(scope, this);
+ Scope scope(ic->engine);
+ Scoped<ErrorObject> e(scope, this);
ScopedString s(scope);
- defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
- defineDefaultProperty(QStringLiteral("name"), (s = ic->engine->newString(className())));
+ e->defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
+ e->defineDefaultProperty(QStringLiteral("name"), (s = scope.engine->newString(e->className())));
- stackTrace = ic->engine->stackTrace();
+ e->d()->stackTrace = scope.engine->stackTrace();
StackFrame frame;
frame.source = fileName;
frame.line = line;
frame.column = column;
- stackTrace.prepend(frame);
+ e->d()->stackTrace.prepend(frame);
- if (!stackTrace.isEmpty()) {
- defineDefaultProperty(QStringLiteral("fileName"), (s = ic->engine->newString(stackTrace.at(0).source)));
- defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(stackTrace.at(0).line));
+ if (!e->d()->stackTrace.isEmpty()) {
+ e->defineDefaultProperty(QStringLiteral("fileName"), (s = scope.engine->newString(e->d()->stackTrace.at(0).source)));
+ e->defineDefaultProperty(QStringLiteral("lineNumber"), Primitive::fromInt32(e->d()->stackTrace.at(0).line));
}
- ScopedValue v(scope, ic->engine->newString(message));
- defineDefaultProperty(QStringLiteral("message"), v);
+ ScopedValue v(scope, scope.engine->newString(message));
+ e->defineDefaultProperty(QStringLiteral("message"), v);
}
ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<ErrorObject> This(scope, ctx->callData->thisObject);
+ Scoped<ErrorObject> This(scope, ctx->d()->callData->thisObject);
if (!This)
return ctx->throwTypeError();
- if (!This->stack) {
+ if (!This->d()->stack) {
QString trace;
- for (int i = 0; i < This->stackTrace.count(); ++i) {
+ for (int i = 0; i < This->d()->stackTrace.count(); ++i) {
if (i > 0)
trace += QLatin1Char('\n');
- const StackFrame &frame = This->stackTrace[i];
+ const StackFrame &frame = This->d()->stackTrace[i];
trace += frame.function;
trace += QLatin1Char('@');
trace += frame.source;
@@ -177,16 +173,16 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
trace += QString::number(frame.line);
}
}
- This->stack = ctx->engine->newString(trace)->getPointer();
+ This->d()->stack = ctx->d()->engine->newString(trace)->getPointer();
}
- return This->stack->asReturnedValue();
+ return This->d()->stack->asReturnedValue();
}
void ErrorObject::markObjects(Managed *that, ExecutionEngine *e)
{
ErrorObject *This = that->asErrorObject();
- if (This->stack)
- This->stack->mark(e);
+ if (This->d()->stack)
+ This->d()->stack->mark(e);
Object::markObjects(that, e);
}
@@ -194,58 +190,58 @@ DEFINE_OBJECT_VTABLE(ErrorObject);
DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
-SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg)
- : ErrorObject(engine->syntaxErrorClass, msg, SyntaxError)
+SyntaxErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef msg)
+ : ErrorObject::Data(engine->syntaxErrorClass, msg, SyntaxError)
{
}
-SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : ErrorObject(engine->syntaxErrorClass, msg, fileName, lineNumber, columnNumber, SyntaxError)
+SyntaxErrorObject::Data::Data(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
+ : ErrorObject::Data(engine->syntaxErrorClass, msg, fileName, lineNumber, columnNumber, SyntaxError)
{
}
-EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const ValueRef message)
- : ErrorObject(engine->evalErrorClass, message, EvalError)
+EvalErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef message)
+ : ErrorObject::Data(engine->evalErrorClass, message, EvalError)
{
}
-RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const ValueRef message)
- : ErrorObject(engine->rangeErrorClass, message, RangeError)
+RangeErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef message)
+ : ErrorObject::Data(engine->rangeErrorClass, message, RangeError)
{
}
-RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const QString &message)
- : ErrorObject(engine->rangeErrorClass, message, RangeError)
+RangeErrorObject::Data::Data(ExecutionEngine *engine, const QString &message)
+ : ErrorObject::Data(engine->rangeErrorClass, message, RangeError)
{
}
-ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const ValueRef message)
- : ErrorObject(engine->referenceErrorClass, message, ReferenceError)
+ReferenceErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef message)
+ : ErrorObject::Data(engine->referenceErrorClass, message, ReferenceError)
{
}
-ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &message)
- : ErrorObject(engine->referenceErrorClass, message, ReferenceError)
+ReferenceErrorObject::Data::Data(ExecutionEngine *engine, const QString &message)
+ : ErrorObject::Data(engine->referenceErrorClass, message, ReferenceError)
{
}
-ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : ErrorObject(engine->referenceErrorClass, msg, fileName, lineNumber, columnNumber, ReferenceError)
+ReferenceErrorObject::Data::Data(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
+ : ErrorObject::Data(engine->referenceErrorClass, msg, fileName, lineNumber, columnNumber, ReferenceError)
{
}
-TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const ValueRef message)
- : ErrorObject(engine->typeErrorClass, message, TypeError)
+TypeErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef message)
+ : ErrorObject::Data(engine->typeErrorClass, message, TypeError)
{
}
-TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const QString &message)
- : ErrorObject(engine->typeErrorClass, message, TypeError)
+TypeErrorObject::Data::Data(ExecutionEngine *engine, const QString &message)
+ : ErrorObject::Data(engine->typeErrorClass, message, TypeError)
{
}
-URIErrorObject::URIErrorObject(ExecutionEngine *engine, const ValueRef message)
- : ErrorObject(engine->uriErrorClass, message, URIError)
+URIErrorObject::Data::Data(ExecutionEngine *engine, const ValueRef message)
+ : ErrorObject::Data(engine->uriErrorClass, message, URIError)
{
}
@@ -257,14 +253,14 @@ DEFINE_OBJECT_VTABLE(SyntaxErrorCtor);
DEFINE_OBJECT_VTABLE(TypeErrorCtor);
DEFINE_OBJECT_VTABLE(URIErrorCtor);
-ErrorCtor::ErrorCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Error"))
+ErrorCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Error"))
{
setVTable(staticVTable());
}
-ErrorCtor::ErrorCtor(ExecutionContext *scope, const QString &name)
- : FunctionObject(scope, name)
+ErrorCtor::Data::Data(ExecutionContext *scope, const QString &name)
+ : FunctionObject::Data(scope, name)
{
setVTable(staticVTable());
}
@@ -281,8 +277,8 @@ ReturnedValue ErrorCtor::call(Managed *that, CallData *callData)
return static_cast<Object *>(that)->construct(callData);
}
-EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("EvalError"))
+EvalErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("EvalError"))
{
setVTable(staticVTable());
}
@@ -291,11 +287,11 @@ ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) EvalErrorObject(m->engine(), v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<EvalErrorObject>(m->engine(), v))->asReturnedValue();
}
-RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("RangeError"))
+RangeErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("RangeError"))
{
setVTable(staticVTable());
}
@@ -304,11 +300,11 @@ ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) RangeErrorObject(scope.engine, v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<RangeErrorObject>(scope.engine, v))->asReturnedValue();
}
-ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("ReferenceError"))
+ReferenceErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("ReferenceError"))
{
setVTable(staticVTable());
}
@@ -317,11 +313,11 @@ ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) ReferenceErrorObject(scope.engine, v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<ReferenceErrorObject>(scope.engine, v))->asReturnedValue();
}
-SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("SyntaxError"))
+SyntaxErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("SyntaxError"))
{
setVTable(staticVTable());
}
@@ -330,11 +326,11 @@ ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) SyntaxErrorObject(scope.engine, v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<SyntaxErrorObject>(scope.engine, v))->asReturnedValue();
}
-TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("TypeError"))
+TypeErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("TypeError"))
{
setVTable(staticVTable());
}
@@ -343,11 +339,11 @@ ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) TypeErrorObject(scope.engine, v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<TypeErrorObject>(scope.engine, v))->asReturnedValue();
}
-URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, QStringLiteral("URIError"))
+URIErrorCtor::Data::Data(ExecutionContext *scope)
+ : ErrorCtor::Data(scope, QStringLiteral("URIError"))
{
setVTable(staticVTable());
}
@@ -356,10 +352,10 @@ ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData)
{
Scope scope(m->engine());
ScopedValue v(scope, callData->argument(0));
- return (new (m->engine()->memoryManager) URIErrorObject(scope.engine, v))->asReturnedValue();
+ return (m->engine()->memoryManager->alloc<URIErrorObject>(scope.engine, v))->asReturnedValue();
}
-void ErrorPrototype::init(ExecutionEngine *engine, ObjectRef ctor, Object *obj)
+void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj)
{
Scope scope(engine);
ScopedString s(scope);
@@ -375,19 +371,19 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- Object *o = ctx->callData->thisObject.asObject();
+ Object *o = ctx->d()->callData->thisObject.asObject();
if (!o)
return ctx->throwTypeError();
- ScopedValue name(scope, o->get(ctx->engine->id_name));
+ ScopedValue name(scope, o->get(ctx->d()->engine->id_name));
QString qname;
if (name->isUndefined())
qname = QString::fromLatin1("Error");
else
qname = name->toQString();
- ScopedString s(scope, ctx->engine->newString(QString::fromLatin1("message")));
- ScopedValue message(scope, o->get(s));
+ ScopedString s(scope, ctx->d()->engine->newString(QString::fromLatin1("message")));
+ ScopedValue message(scope, o->get(s.getPointer()));
QString qmessage;
if (!message->isUndefined())
qmessage = message->toQString();
@@ -401,5 +397,5 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
str = qname + QLatin1String(": ") + qmessage;
}
- return ctx->engine->newString(str)->asReturnedValue();
+ return ctx->d()->engine->newString(str)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index c44cc5cdb2..ddf30d2059 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -51,8 +51,6 @@ namespace QV4 {
struct SyntaxErrorObject;
struct ErrorObject: Object {
- V4_OBJECT
- Q_MANAGED_TYPE(ErrorObject)
enum {
IsErrorObject = true
};
@@ -66,17 +64,19 @@ struct ErrorObject: Object {
TypeError,
URIError
};
-
- ErrorObject(InternalClass *ic);
- ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t = Error);
- ErrorObject(InternalClass *ic, const QString &message, ErrorType t = Error);
- ErrorObject(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorType t = Error);
+ struct Data : Object::Data {
+ Data(InternalClass *ic);
+ Data(InternalClass *ic, const ValueRef message, ErrorType t = Error);
+ Data(InternalClass *ic, const QString &message, ErrorType t = Error);
+ Data(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorType t = Error);
+ StackTrace stackTrace;
+ String *stack;
+ };
+ V4_OBJECT(Object)
+ Q_MANAGED_TYPE(ErrorObject)
SyntaxErrorObject *asSyntaxError();
- StackTrace stackTrace;
- String *stack;
-
static ReturnedValue method_get_stack(CallContext *ctx);
static void markObjects(Managed *that, ExecutionEngine *e);
static void destroy(Managed *that) { static_cast<ErrorObject *>(that)->~ErrorObject(); }
@@ -88,40 +88,55 @@ inline ErrorObject *value_cast(const Value &v) {
}
struct EvalErrorObject: ErrorObject {
- EvalErrorObject(ExecutionEngine *engine, const ValueRef message);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ };
};
struct RangeErrorObject: ErrorObject {
- RangeErrorObject(ExecutionEngine *engine, const ValueRef message);
- RangeErrorObject(ExecutionEngine *engine, const QString &msg);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ Data(ExecutionEngine *engine, const QString &msg);
+ };
};
struct ReferenceErrorObject: ErrorObject {
- ReferenceErrorObject(ExecutionEngine *engine, const ValueRef message);
- ReferenceErrorObject(ExecutionEngine *engine, const QString &msg);
- ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ Data(ExecutionEngine *engine, const QString &msg);
+ Data(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
+ };
};
struct SyntaxErrorObject: ErrorObject {
- V4_OBJECT
- SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg);
- SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ Data(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
+ };
+ V4_OBJECT(ErrorObject)
};
struct TypeErrorObject: ErrorObject {
- TypeErrorObject(ExecutionEngine *engine, const ValueRef message);
- TypeErrorObject(ExecutionEngine *engine, const QString &msg);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ Data(ExecutionEngine *engine, const QString &msg);
+ };
};
struct URIErrorObject: ErrorObject {
- URIErrorObject(ExecutionEngine *engine, const ValueRef message);
+ struct Data : ErrorObject::Data {
+ Data(ExecutionEngine *engine, const ValueRef message);
+ };
};
struct ErrorCtor: FunctionObject
{
- V4_OBJECT
- ErrorCtor(ExecutionContext *scope);
- ErrorCtor(ExecutionContext *scope, const QString &name);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ Data(ExecutionContext *scope, const QString &name);
+ };
+
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -129,103 +144,107 @@ struct ErrorCtor: FunctionObject
struct EvalErrorCtor: ErrorCtor
{
- V4_OBJECT
- EvalErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
struct RangeErrorCtor: ErrorCtor
{
- V4_OBJECT
- RangeErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
struct ReferenceErrorCtor: ErrorCtor
{
- V4_OBJECT
- ReferenceErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
struct SyntaxErrorCtor: ErrorCtor
{
- V4_OBJECT
- SyntaxErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
struct TypeErrorCtor: ErrorCtor
{
- V4_OBJECT
- TypeErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
struct URIErrorCtor: ErrorCtor
{
- V4_OBJECT
- URIErrorCtor(ExecutionContext *scope);
+ struct Data : ErrorCtor::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(ErrorCtor)
static ReturnedValue construct(Managed *m, CallData *callData);
};
-struct ErrorPrototype: ErrorObject
+struct ErrorPrototype : ErrorObject
{
- // ### shouldn't be undefined
- ErrorPrototype(InternalClass *ic): ErrorObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor) { init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this); }
- static void init(ExecutionEngine *engine, ObjectRef ctor, Object *obj);
+ static void init(ExecutionEngine *engine, Object *ctor, Object *obj);
static ReturnedValue method_toString(CallContext *ctx);
};
-struct EvalErrorPrototype: ErrorObject
+struct EvalErrorPrototype : ErrorObject
{
- EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct RangeErrorPrototype: ErrorObject
+struct RangeErrorPrototype : ErrorObject
{
- RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct ReferenceErrorPrototype: ErrorObject
+struct ReferenceErrorPrototype : ErrorObject
{
- ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct SyntaxErrorPrototype: ErrorObject
+struct SyntaxErrorPrototype : ErrorObject
{
- SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct TypeErrorPrototype: ErrorObject
+struct TypeErrorPrototype : ErrorObject
{
- TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct URIErrorPrototype: ErrorObject
+struct URIErrorPrototype : ErrorObject
{
- URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
- void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
+ void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, this); }
};
inline SyntaxErrorObject *ErrorObject::asSyntaxError()
{
- return subtype == SyntaxError ? static_cast<SyntaxErrorObject *>(this) : 0;
+ return subtype() == SyntaxError ? static_cast<SyntaxErrorObject *>(this) : 0;
}
}
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 6fdf61f2c3..bf77b4434c 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -45,6 +45,7 @@
#include "qv4value_inl_p.h"
#include "qv4engine_p.h"
#include "qv4lookup_p.h"
+#include "qv4mm_p.h"
QT_BEGIN_NAMESPACE
@@ -62,6 +63,8 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
internalClass = engine->emptyClass;
const quint32 *formalsIndices = compiledFunction->formalsTable();
// iterate backwards, so we get the right ordering for duplicate names
+ Scope scope(engine);
+ ScopedString s(scope);
for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) {
String *arg = compilationUnit->runtimeStrings[formalsIndices[i]].asString();
while (1) {
@@ -71,7 +74,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
break;
}
// duplicate arguments, need some trick to store them
- arg = new (engine->memoryManager) String(engine, arg, engine->newString(QString(0xfffe))->getPointer());
+ arg = (s = engine->memoryManager->alloc<String>(engine, arg, engine->newString(QString(0xfffe))->getPointer())).getPointer();
}
}
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index e6385d861c..482f247319 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -94,8 +94,8 @@ struct Q_QML_EXPORT Function {
ReturnedValue (*codePtr)(ExecutionContext *, const uchar *));
~Function();
- inline StringRef name() {
- return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
+ inline String *name() {
+ return compilationUnit->runtimeStrings[compiledFunction->nameIndex].getPointer();
}
inline QString sourceFile() const { return compilationUnit->fileName(); }
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 39a123c4d2..10974780f3 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -74,88 +74,88 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
-FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
- : Object(scope->engine->functionClass)
+FunctionObject::Data::Data(ExecutionContext *scope, String *name, bool createProto)
+ : Object::Data(scope->d()->engine->functionClass)
, scope(scope)
- , function(0)
{
- init(name, createProto);
+ Scope s(scope);
+ ScopedFunctionObject f(s, this);
+ f->init(name, createProto);
}
-FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
- : Object(scope->engine->functionClass)
+
+FunctionObject::Data::Data(ExecutionContext *scope, const QString &name, bool createProto)
+ : Object::Data(scope->d()->engine->functionClass)
, scope(scope)
- , function(0)
{
Scope s(scope);
- ScopedValue protectThis(s, this);
+ ScopedFunctionObject f(s, this);
ScopedString n(s, s.engine->newString(name));
- init(n, createProto);
+ f->init(n.getPointer(), createProto);
}
-FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name)
- : Object(scope->engine->functionClass)
+FunctionObject::Data::Data(ExecutionContext *scope, const ReturnedValue name)
+ : Object::Data(scope->d()->engine->functionClass)
, scope(scope)
- , function(0)
{
Scope s(scope);
- ScopedValue protectThis(s, this);
+ ScopedFunctionObject f(s, this);
ScopedString n(s, name);
- init(n, false);
+ f->init(n.getPointer(), false);
}
-FunctionObject::FunctionObject(InternalClass *ic)
- : Object(ic)
+FunctionObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
, scope(ic->engine->rootContext)
- , function(0)
{
- needsActivation = false;
- strictMode = false;
+ memberData.ensureIndex(ic->engine, Index_Prototype);
memberData[Index_Prototype] = Encode::undefined();
}
-FunctionObject::~FunctionObject()
+
+FunctionObject::Data::~Data()
{
if (function)
function->compilationUnit->deref();
}
-void FunctionObject::init(const StringRef n, bool createProto)
+void FunctionObject::init(String *n, bool createProto)
{
- Scope s(internalClass->engine);
+ Scope s(internalClass()->engine);
ScopedValue protectThis(s, this);
- needsActivation = true;
- strictMode = false;
+ d()->needsActivation = true;
+ d()->strictMode = false;
+ memberData().ensureIndex(s.engine, Index_Prototype);
if (createProto) {
- Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
- proto->memberData[Index_ProtoConstructor] = this->asReturnedValue();
- memberData[Index_Prototype] = proto.asReturnedValue();
+ Scoped<Object> proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass));
+ proto->memberData()[Index_ProtoConstructor] = this->asReturnedValue();
+ memberData()[Index_Prototype] = proto.asReturnedValue();
} else {
- memberData[Index_Prototype] = Encode::undefined();
+ memberData()[Index_Prototype] = Encode::undefined();
}
- ScopedValue v(s, n.asReturnedValue());
- defineReadonlyProperty(scope->engine->id_name, v);
+ ScopedValue v(s, n);
+ defineReadonlyProperty(s.engine->id_name, v);
}
ReturnedValue FunctionObject::name()
{
- return get(scope->engine->id_name);
+ return get(scope()->d()->engine->id_name);
}
ReturnedValue FunctionObject::newInstance()
{
- Scope scope(internalClass->engine);
+ Scope scope(internalClass()->engine);
ScopedCallData callData(scope, 0);
return construct(callData);
}
ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
- that->internalClass->engine->currentContext()->throwTypeError();
+ that->internalClass()->engine->currentContext()->throwTypeError();
return Encode::undefined();
}
@@ -167,8 +167,8 @@ ReturnedValue FunctionObject::call(Managed *, CallData *)
void FunctionObject::markObjects(Managed *that, ExecutionEngine *e)
{
FunctionObject *o = static_cast<FunctionObject *>(that);
- if (o->scope)
- o->scope->mark(e);
+ if (o->scope())
+ o->scope()->mark(e);
Object::markObjects(that, e);
}
@@ -179,14 +179,14 @@ FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Fu
function->compiledFunction->flags & CompiledData::Function::HasCatchOrWith ||
function->compiledFunction->nFormals > QV4::Global::ReservedArgumentCount ||
function->isNamedExpression())
- return new (scope->engine->memoryManager) ScriptFunction(scope, function);
- return new (scope->engine->memoryManager) SimpleScriptFunction(scope, function, createProto);
+ return scope->d()->engine->memoryManager->alloc<ScriptFunction>(scope, function);
+ return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto);
}
DEFINE_OBJECT_VTABLE(FunctionCtor);
-FunctionCtor::FunctionCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Function"))
+FunctionCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Function"))
{
setVTable(staticVTable());
}
@@ -195,7 +195,7 @@ FunctionCtor::FunctionCtor(ExecutionContext *scope)
ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
{
FunctionCtor *f = static_cast<FunctionCtor *>(that);
- ExecutionEngine *v4 = f->internalClass->engine;
+ ExecutionEngine *v4 = f->internalClass()->engine;
ExecutionContext *ctx = v4->currentContext();
QString arguments;
QString body;
@@ -207,7 +207,7 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
}
body = callData->args[callData->argc - 1].toString(ctx)->toQString();
}
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1String("}");
@@ -229,7 +229,7 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
IR::Module module(v4->debugger != 0);
- QQmlJS::RuntimeCodegen cg(v4->currentContext(), f->strictMode);
+ QQmlJS::RuntimeCodegen cg(v4->currentContext(), f->strictMode());
cg.generateFromFunctionExpression(QString(), function, fe, &module);
QV4::Compiler::JSUnitGenerator jsGenerator(&module);
@@ -246,12 +246,14 @@ ReturnedValue FunctionCtor::call(Managed *that, CallData *callData)
return construct(that, callData);
}
-FunctionPrototype::FunctionPrototype(InternalClass *ic)
- : FunctionObject(ic)
+DEFINE_OBJECT_VTABLE(FunctionPrototype);
+
+FunctionPrototype::Data::Data(InternalClass *ic)
+ : FunctionObject::Data(ic)
{
}
-void FunctionPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -270,17 +272,17 @@ void FunctionPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
{
- FunctionObject *fun = ctx->callData->thisObject.asFunctionObject();
+ FunctionObject *fun = ctx->d()->callData->thisObject.asFunctionObject();
if (!fun)
return ctx->throwTypeError();
- return ctx->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue();
+ return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue();
}
ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
{
Scope scope(ctx);
- FunctionObject *o = ctx->callData->thisObject.asFunctionObject();
+ FunctionObject *o = ctx->d()->callData->thisObject.asFunctionObject();
if (!o)
return ctx->throwTypeError();
@@ -300,13 +302,13 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
ScopedCallData callData(scope, len);
if (len) {
- if (arr->arrayType() != ArrayData::Simple || arr->protoHasArray() || arr->hasAccessorProperty) {
+ if (arr->arrayType() != ArrayData::Simple || arr->protoHasArray() || arr->hasAccessorProperty()) {
for (quint32 i = 0; i < len; ++i)
callData->args[i] = arr->getIndexed(i);
} else {
- int alen = qMin(len, arr->arrayData->length());
+ int alen = qMin(len, arr->arrayData()->length());
if (alen)
- memcpy(callData->args, arr->arrayData->data, alen*sizeof(Value));
+ memcpy(callData->args, arr->arrayData()->arrayData(), alen*sizeof(Value));
for (quint32 i = alen; i < len; ++i)
callData->args[i] = Primitive::undefinedValue();
}
@@ -320,14 +322,14 @@ ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
{
Scope scope(ctx);
- FunctionObject *o = ctx->callData->thisObject.asFunctionObject();
+ FunctionObject *o = ctx->d()->callData->thisObject.asFunctionObject();
if (!o)
return ctx->throwTypeError();
- ScopedCallData callData(scope, ctx->callData->argc ? ctx->callData->argc - 1 : 0);
- if (ctx->callData->argc) {
- for (int i = 1; i < ctx->callData->argc; ++i)
- callData->args[i - 1] = ctx->callData->args[i];
+ ScopedCallData callData(scope, ctx->d()->callData->argc ? ctx->d()->callData->argc - 1 : 0);
+ if (ctx->d()->callData->argc) {
+ for (int i = 1; i < ctx->d()->callData->argc; ++i)
+ callData->args[i - 1] = ctx->d()->callData->args[i];
}
callData->thisObject = ctx->argument(0);
return o->call(callData);
@@ -336,49 +338,34 @@ ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<FunctionObject> target(scope, ctx->callData->thisObject);
+ Scoped<FunctionObject> target(scope, ctx->d()->callData->thisObject);
if (!target)
return ctx->throwTypeError();
ScopedValue boundThis(scope, ctx->argument(0));
- QVector<Value> boundArgs;
- for (int i = 1; i < ctx->callData->argc; ++i)
- boundArgs += ctx->callData->args[i];
+ Members boundArgs;
+ boundArgs.reset();
+ if (ctx->d()->callData->argc > 1) {
+ boundArgs.ensureIndex(scope.engine, ctx->d()->callData->argc - 1);
+ boundArgs.d()->d()->size = ctx->d()->callData->argc - 1;
+ memcpy(boundArgs.data(), ctx->d()->callData->args + 1, (ctx->d()->callData->argc - 1)*sizeof(Value));
+ }
+ ScopedValue protectBoundArgs(scope, boundArgs.d());
- return ctx->engine->newBoundFunction(ctx->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
+ return BoundFunction::create(ctx->d()->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
}
DEFINE_OBJECT_VTABLE(ScriptFunction);
-ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
- : SimpleScriptFunction(scope, function, true)
+ScriptFunction::Data::Data(ExecutionContext *scope, Function *function)
+ : SimpleScriptFunction::Data(scope, function, true)
{
setVTable(staticVTable());
-
- Scope s(scope);
- ScopedValue protectThis(s, this);
-
- // global function
- if (!scope)
- return;
-
- ExecutionEngine *v4 = scope->engine;
-
- needsActivation = function->needsActivation();
- strictMode = function->isStrict();
-
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
-
- if (scope->strictMode) {
- Property pd(v4->thrower, v4->thrower);
- insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- }
}
ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = that->internalClass->engine;
+ ExecutionEngine *v4 = that->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -391,13 +378,13 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
callData->thisObject = obj.asReturnedValue();
- ExecutionContext *ctx = context->newCallContext(f.getPointer(), callData);
+ ExecutionContext *ctx = reinterpret_cast<ExecutionContext *>(context->newCallContext(f.getPointer(), callData));
ExecutionContextSaver ctxSaver(context);
- ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function));
+ ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function()));
- if (f->function->compiledFunction->hasQmlDependencies())
- QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction);
+ if (f->function()->compiledFunction->hasQmlDependencies())
+ QmlContextWrapper::registerQmlDependencies(v4, f->function()->compiledFunction);
if (result->isObject())
return result.asReturnedValue();
@@ -407,7 +394,7 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
{
ScriptFunction *f = static_cast<ScriptFunction *>(that);
- ExecutionEngine *v4 = f->internalClass->engine;
+ ExecutionEngine *v4 = f->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -415,53 +402,51 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
Scope scope(context);
- CallContext *ctx = context->newCallContext(f, callData);
+ CallContext *ctx = reinterpret_cast<CallContext *>(context->newCallContext(f, callData));
ExecutionContextSaver ctxSaver(context);
- ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function));
+ ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function()));
- if (f->function->compiledFunction->hasQmlDependencies())
- QmlContextWrapper::registerQmlDependencies(ctx->engine, f->function->compiledFunction);
+ if (f->function()->compiledFunction->hasQmlDependencies())
+ QmlContextWrapper::registerQmlDependencies(ctx->d()->engine, f->function()->compiledFunction);
return result.asReturnedValue();
}
DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
-SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *function, bool createProto)
- : FunctionObject(scope, function->name(), createProto)
+SimpleScriptFunction::Data::Data(ExecutionContext *scope, Function *function, bool createProto)
+ : FunctionObject::Data(scope, function->name(), createProto)
{
setVTable(staticVTable());
- Scope s(scope);
- ScopedValue protectThis(s, this);
-
this->function = function;
- this->function->compilationUnit->ref();
+ function->compilationUnit->ref();
Q_ASSERT(function);
Q_ASSERT(function->code);
+ needsActivation = function->needsActivation();
+ strictMode = function->isStrict();
+
// global function
if (!scope)
return;
- ExecutionEngine *v4 = scope->engine;
-
- needsActivation = function->needsActivation();
- strictMode = function->isStrict();
+ Scope s(scope);
+ ScopedFunctionObject f(s, this);
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
+ f->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(f->formalParameterCount()));
- if (scope->strictMode) {
- Property pd(v4->thrower, v4->thrower);
- insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ if (scope->d()->strictMode) {
+ Property pd(s.engine->thrower, s.engine->thrower);
+ f->insertMember(scope->d()->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ f->insertMember(scope->d()->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
}
ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = that->internalClass->engine;
+ ExecutionEngine *v4 = that->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -475,24 +460,24 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
ExecutionContextSaver ctxSaver(context);
- CallContext ctx(v4);
- ctx.strictMode = f->strictMode;
+ CallContext::Data ctx(v4);
+ ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f.getPointer();
- ctx.compilationUnit = f->function->compilationUnit;
+ ctx.compilationUnit = f->function()->compilationUnit;
ctx.lookups = ctx.compilationUnit->runtimeLookups;
- ctx.outer = f->scope;
+ ctx.outer = f->scope();
ctx.locals = v4->stackPush(f->varCount());
while (callData->argc < (int)f->formalParameterCount()) {
callData->args[callData->argc] = Encode::undefined();
++callData->argc;
}
- Q_ASSERT(v4->currentContext() == &ctx);
+ Q_ASSERT(v4->currentContext()->d() == &ctx);
- Scoped<Object> result(scope, Q_V4_PROFILE(v4, &ctx, f->function));
+ Scoped<Object> result(scope, Q_V4_PROFILE(v4, reinterpret_cast<CallContext *>(&ctx), f->function()));
- if (f->function->compiledFunction->hasQmlDependencies())
- QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction);
+ if (f->function()->compiledFunction->hasQmlDependencies())
+ QmlContextWrapper::registerQmlDependencies(v4, f->function()->compiledFunction);
if (!result)
return callData->thisObject.asReturnedValue();
@@ -501,7 +486,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = that->internalClass->engine;
+ ExecutionEngine *v4 = that->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -512,24 +497,24 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
ExecutionContextSaver ctxSaver(context);
- CallContext ctx(v4);
- ctx.strictMode = f->strictMode;
+ CallContext::Data ctx(v4);
+ ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f;
- ctx.compilationUnit = f->function->compilationUnit;
+ ctx.compilationUnit = f->function()->compilationUnit;
ctx.lookups = ctx.compilationUnit->runtimeLookups;
- ctx.outer = f->scope;
+ ctx.outer = f->scope();
ctx.locals = v4->stackPush(f->varCount());
while (callData->argc < (int)f->formalParameterCount()) {
callData->args[callData->argc] = Encode::undefined();
++callData->argc;
}
- Q_ASSERT(v4->currentContext() == &ctx);
+ Q_ASSERT(v4->currentContext()->d() == &ctx);
- ScopedValue result(scope, Q_V4_PROFILE(v4, &ctx, f->function));
+ ScopedValue result(scope, Q_V4_PROFILE(v4, reinterpret_cast<CallContext *>(&ctx), f->function()));
- if (f->function->compiledFunction->hasQmlDependencies())
- QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction);
+ if (f->function()->compiledFunction->hasQmlDependencies())
+ QmlContextWrapper::registerQmlDependencies(v4, f->function()->compiledFunction);
return result.asReturnedValue();
}
@@ -538,10 +523,10 @@ InternalClass *SimpleScriptFunction::internalClassForConstructor()
{
ReturnedValue proto = protoProperty();
InternalClass *classForConstructor;
- Scope scope(internalClass->engine);
+ Scope scope(internalClass()->engine);
ScopedObject p(scope, proto);
if (p)
- classForConstructor = internalClass->engine->constructClass->changePrototype(p.getPointer());
+ classForConstructor = internalClass()->engine->constructClass->changePrototype(p.getPointer());
else
classForConstructor = scope.engine->objectClass;
@@ -552,8 +537,8 @@ InternalClass *SimpleScriptFunction::internalClassForConstructor()
DEFINE_OBJECT_VTABLE(BuiltinFunction);
-BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *))
- : FunctionObject(scope, name)
+BuiltinFunction::Data::Data(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ : FunctionObject::Data(scope, name)
, code(code)
{
setVTable(staticVTable());
@@ -561,13 +546,13 @@ BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name,
ReturnedValue BuiltinFunction::construct(Managed *f, CallData *)
{
- return f->internalClass->engine->currentContext()->throwTypeError();
+ return f->internalClass()->engine->currentContext()->throwTypeError();
}
ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
{
BuiltinFunction *f = static_cast<BuiltinFunction *>(that);
- ExecutionEngine *v4 = f->internalClass->engine;
+ ExecutionEngine *v4 = f->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -575,18 +560,18 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
ExecutionContextSaver ctxSaver(context);
- CallContext ctx(v4);
- ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
+ CallContext::Data ctx(v4);
+ ctx.strictMode = f->scope()->d()->strictMode; // ### needed? scope or parent context?
ctx.callData = callData;
- Q_ASSERT(v4->currentContext() == &ctx);
+ Q_ASSERT(v4->currentContext()->d() == &ctx);
- return f->code(&ctx);
+ return f->d()->code(reinterpret_cast<CallContext *>(&ctx));
}
ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
{
IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that);
- ExecutionEngine *v4 = f->internalClass->engine;
+ ExecutionEngine *v4 = f->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
@@ -594,82 +579,76 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
ExecutionContextSaver ctxSaver(context);
- CallContext ctx(v4);
- ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
+ CallContext::Data ctx(v4);
+ ctx.strictMode = f->scope()->d()->strictMode; // ### needed? scope or parent context?
ctx.callData = callData;
- Q_ASSERT(v4->currentContext() == &ctx);
+ Q_ASSERT(v4->currentContext()->d() == &ctx);
- return f->code(&ctx, f->index);
+ return f->d()->code(reinterpret_cast<CallContext *>(&ctx), f->d()->index);
}
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
DEFINE_OBJECT_VTABLE(BoundFunction);
-BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs)
- : FunctionObject(scope, QStringLiteral("__bound function__"))
+BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs)
+ : FunctionObject::Data(scope, QStringLiteral("__bound function__"))
, target(target)
, boundArgs(boundArgs)
{
+ this->boundThis = boundThis;
setVTable(staticVTable());
subtype = FunctionObject::BoundFunction;
- this->boundThis = boundThis;
Scope s(scope);
- ScopedValue protectThis(s, this);
+ ScopedObject f(s, this);
- ScopedValue l(s, target->get(scope->engine->id_length));
+ ScopedValue l(s, target->get(s.engine->id_length));
int len = l->toUInt32();
len -= boundArgs.size();
if (len < 0)
len = 0;
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(len));
+ f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(len));
- ExecutionEngine *v4 = scope->engine;
+ ExecutionEngine *v4 = s.engine;
Property pd(v4->thrower, v4->thrower);
- insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
-}
-
-void BoundFunction::destroy(Managed *that)
-{
- static_cast<BoundFunction *>(that)->~BoundFunction();
+ f->insertMember(s.engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ f->insertMember(s.engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
{
BoundFunction *f = static_cast<BoundFunction *>(that);
- Scope scope(f->scope->engine);
+ Scope scope(f->scope()->d()->engine);
if (scope.hasException())
return Encode::undefined();
- ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
- callData->thisObject = f->boundThis;
- memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
- memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value));
- return f->target->call(callData);
+ ScopedCallData callData(scope, f->boundArgs().size() + dd->argc);
+ callData->thisObject = f->boundThis();
+ memcpy(callData->args, f->boundArgs().data(), f->boundArgs().size()*sizeof(Value));
+ memcpy(callData->args + f->boundArgs().size(), dd->args, dd->argc*sizeof(Value));
+ return f->target()->call(callData);
}
ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
{
BoundFunction *f = static_cast<BoundFunction *>(that);
- Scope scope(f->scope->engine);
+ Scope scope(f->scope()->d()->engine);
if (scope.hasException())
return Encode::undefined();
- ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
- memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
- memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value));
- return f->target->construct(callData);
+ ScopedCallData callData(scope, f->boundArgs().size() + dd->argc);
+ memcpy(callData->args, f->boundArgs().data(), f->boundArgs().size()*sizeof(Value));
+ memcpy(callData->args + f->boundArgs().size(), dd->args, dd->argc*sizeof(Value));
+ return f->target()->construct(callData);
}
void BoundFunction::markObjects(Managed *that, ExecutionEngine *e)
{
BoundFunction *o = static_cast<BoundFunction *>(that);
- o->target->mark(e);
- o->boundThis.mark(e);
- for (int i = 0; i < o->boundArgs.size(); ++i)
- o->boundArgs.at(i).mark(e);
+ o->target()->mark(e);
+ o->boundThis().mark(e);
+ o->boundArgs().mark(e);
FunctionObject::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 5b832d0595..907b660911 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -51,6 +51,7 @@
#include "qv4property_p.h"
#include "qv4function_p.h"
#include "qv4objectiterator_p.h"
+#include "qv4mm_p.h"
#include <QtCore/QString>
#include <QtCore/QHash>
@@ -94,7 +95,17 @@ struct InternalClass;
struct Lookup;
struct Q_QML_EXPORT FunctionObject: Object {
- V4_OBJECT
+ struct Q_QML_PRIVATE_EXPORT Data : Object::Data {
+ Data(ExecutionContext *scope, String *name, bool createProto = false);
+ Data(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
+ Data(ExecutionContext *scope, const ReturnedValue name);
+ Data(InternalClass *ic);
+ ~Data();
+
+ ExecutionContext *scope;
+ Function *function;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(FunctionObject)
enum {
IsFunctionObject = true
@@ -111,18 +122,15 @@ struct Q_QML_EXPORT FunctionObject: Object {
Index_ProtoConstructor = 0
};
- ExecutionContext *scope;
- ReturnedValue name();
- unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; }
- unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
- Function *function;
- FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto = false);
- FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
- FunctionObject(ExecutionContext *scope, const ReturnedValue name);
- ~FunctionObject();
+ ExecutionContext *scope() { return d()->scope; }
+ Function *function() { return d()->function; }
+
+ ReturnedValue name();
+ unsigned int formalParameterCount() { return function() ? function()->compiledFunction->nFormals : 0; }
+ unsigned int varCount() { return function() ? function()->compiledFunction->nLocals : 0; }
- void init(const StringRef name, bool createProto);
+ void init(String *name, bool createProto);
ReturnedValue newInstance();
@@ -130,6 +138,9 @@ struct Q_QML_EXPORT FunctionObject: Object {
using Object::call;
static ReturnedValue construct(Managed *that, CallData *);
static ReturnedValue call(Managed *that, CallData *d);
+ static void destroy(Managed *m) {
+ static_cast<FunctionObject *>(m)->d()->~Data();
+ }
static FunctionObject *cast(const Value &v) {
return v.asFunctionObject();
@@ -137,14 +148,13 @@ struct Q_QML_EXPORT FunctionObject: Object {
static FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
- ReturnedValue protoProperty() { return memberData[Index_Prototype].asReturnedValue(); }
+ ReturnedValue protoProperty() { return memberData()[Index_Prototype].asReturnedValue(); }
-protected:
- FunctionObject(InternalClass *ic);
+ bool needsActivation() const { return d()->needsActivation; }
+ bool strictMode() const { return d()->strictMode; }
+ bool bindingKeyFlag() const { return d()->bindingKeyFlag; }
static void markObjects(Managed *that, ExecutionEngine *e);
- static void destroy(Managed *that)
- { static_cast<FunctionObject*>(that)->~FunctionObject(); }
};
template<>
@@ -152,12 +162,13 @@ inline FunctionObject *value_cast(const Value &v) {
return v.asFunctionObject();
}
-DEFINE_REF(FunctionObject, Object);
-
struct FunctionCtor: FunctionObject
{
- V4_OBJECT
- FunctionCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *that, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -165,8 +176,12 @@ struct FunctionCtor: FunctionObject
struct FunctionPrototype: FunctionObject
{
- FunctionPrototype(InternalClass *ic);
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ struct Data : FunctionObject::Data {
+ Data(InternalClass *ic);
+ };
+ V4_OBJECT(FunctionObject)
+
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_toString(CallContext *ctx);
static ReturnedValue method_apply(CallContext *ctx);
@@ -174,11 +189,17 @@ struct FunctionPrototype: FunctionObject
static ReturnedValue method_bind(CallContext *ctx);
};
-struct BuiltinFunction: FunctionObject {
- V4_OBJECT
- ReturnedValue (*code)(CallContext *);
+struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
+ struct Q_QML_EXPORT Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *));
+ ReturnedValue (*code)(CallContext *);
+ };
+ V4_OBJECT(FunctionObject)
- BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *));
+ static BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ {
+ return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code);
+ }
static ReturnedValue construct(Managed *, CallData *);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -186,18 +207,18 @@ struct BuiltinFunction: FunctionObject {
struct IndexedBuiltinFunction: FunctionObject
{
- V4_OBJECT
-
- ReturnedValue (*code)(CallContext *ctx, uint index);
- uint index;
-
- IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(CallContext *ctx, uint index))
- : FunctionObject(scope)
- , code(code)
- , index(index)
- {
- setVTable(staticVTable());
- }
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, uint index, ReturnedValue (*code)(CallContext *ctx, uint index))
+ : FunctionObject::Data(scope),
+ code(code)
+ , index(index)
+ {
+ setVTable(staticVTable());
+ }
+ ReturnedValue (*code)(CallContext *, uint index);
+ uint index;
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *m, CallData *)
{
@@ -209,8 +230,10 @@ struct IndexedBuiltinFunction: FunctionObject
struct SimpleScriptFunction: FunctionObject {
- V4_OBJECT
- SimpleScriptFunction(ExecutionContext *scope, Function *function, bool createProto);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, Function *function, bool createProto);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -219,8 +242,10 @@ struct SimpleScriptFunction: FunctionObject {
};
struct ScriptFunction: SimpleScriptFunction {
- V4_OBJECT
- ScriptFunction(ExecutionContext *scope, Function *function);
+ struct Data : SimpleScriptFunction::Data {
+ Data(ExecutionContext *scope, Function *function);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -228,19 +253,26 @@ struct ScriptFunction: SimpleScriptFunction {
struct BoundFunction: FunctionObject {
- V4_OBJECT
- FunctionObject *target;
- Value boundThis;
- QVector<Value> boundArgs;
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs);
+ FunctionObject *target;
+ Value boundThis;
+ Members boundArgs;
+ };
+ V4_OBJECT(FunctionObject)
- BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs);
- ~BoundFunction() {}
+ static BoundFunction *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs)
+ {
+ return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs);
+ }
+ FunctionObject *target() { return d()->target; }
+ Value boundThis() const { return d()->boundThis; }
+ Members boundArgs() const { return d()->boundArgs; }
static ReturnedValue construct(Managed *, CallData *d);
static ReturnedValue call(Managed *that, CallData *dd);
- static void destroy(Managed *);
static void markObjects(Managed *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index a00231c3a1..039f5c1e78 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -74,15 +74,19 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
// Decide whether to enable or disable the JIT
// White list architectures
+//
+// NOTE: This should match the logic in qv4targetplatform_p.h!
-#if defined(Q_PROCESSOR_X86)
+#if defined(Q_PROCESSOR_X86) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
#define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_X86_64)
+#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
#define V4_ENABLE_JIT
#elif defined(Q_PROCESSOR_ARM_32)
#if defined(thumb2) || defined(__thumb2__) || ((defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4)
#define V4_ENABLE_JIT
+#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2 // clang 3.5 and later will set this if the core supports the Thumb-2 ISA.
+#define V4_ENABLE_JIT
#endif
#endif
@@ -161,12 +165,6 @@ template<typename T> struct Returned;
typedef Returned<String> ReturnedString;
typedef Returned<Object> ReturnedObject;
typedef Returned<FunctionObject> ReturnedFunctionObject;
-struct ManagedRef;
-struct StringRef;
-struct ObjectRef;
-struct ArrayObjectRef;
-struct FunctionObjectRef;
-struct RegExpRef;
struct PersistentValuePrivate;
class PersistentValue;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index eb0994c1e6..fc4a097915 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -346,11 +346,13 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
DEFINE_OBJECT_VTABLE(EvalFunction);
-EvalFunction::EvalFunction(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->id_eval)
+EvalFunction::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, scope->d()->engine->id_eval)
{
setVTable(staticVTable());
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(1));
+ Scope s(scope);
+ ScopedFunctionObject f(s, this);
+ f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(1));
}
ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
@@ -363,16 +365,16 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
ContextStateSaver(ExecutionContext *context)
: savedContext(context)
- , strictMode(context->strictMode)
- , evalCode(context->currentEvalCode)
- , compilationUnit(context->compilationUnit)
+ , strictMode(context->d()->strictMode)
+ , evalCode(context->d()->currentEvalCode)
+ , compilationUnit(context->d()->compilationUnit)
{}
~ContextStateSaver()
{
- savedContext->strictMode = strictMode;
- savedContext->currentEvalCode = evalCode;
- savedContext->compilationUnit = compilationUnit;
+ savedContext->d()->strictMode = strictMode;
+ savedContext->d()->currentEvalCode = evalCode;
+ savedContext->d()->compilationUnit = compilationUnit;
}
};
@@ -396,10 +398,10 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
return callData->args[0].asReturnedValue();
const QString code = callData->args[0].stringValue()->toQString();
- bool inheritContext = !ctx->strictMode;
+ bool inheritContext = !ctx->d()->strictMode;
Script script(ctx, code, QStringLiteral("eval code"));
- script.strictMode = (directCall && parentContext->strictMode);
+ script.strictMode = (directCall && parentContext->d()->strictMode);
script.inheritContext = inheritContext;
script.parse();
if (scope.engine->hasException)
@@ -409,14 +411,14 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
if (!function)
return Encode::undefined();
- strictMode = function->isStrict() || (ctx->strictMode);
+ d()->strictMode = function->isStrict() || (ctx->d()->strictMode);
- needsActivation = function->needsActivation();
+ d()->needsActivation = function->needsActivation();
- if (strictMode) {
+ if (strictMode()) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
ScopedCallData callData(scope, 0);
- callData->thisObject = ctx->callData->thisObject;
+ callData->thisObject = ctx->d()->callData->thisObject;
return e->call(callData);
}
@@ -424,12 +426,12 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
ExecutionContext::EvalCode evalCode;
evalCode.function = function;
- evalCode.next = ctx->currentEvalCode;
- ctx->currentEvalCode = &evalCode;
+ evalCode.next = ctx->d()->currentEvalCode;
+ ctx->d()->currentEvalCode = &evalCode;
// set the correct strict mode flag on the context
- ctx->strictMode = strictMode;
- ctx->compilationUnit = function->compilationUnit;
+ ctx->d()->strictMode = strictMode();
+ ctx->d()->compilationUnit = function->compilationUnit;
return function->code(ctx, function->codeData);
}
@@ -470,7 +472,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
String *inputString = string->toString(ctx); // 1
QString trimmed = inputString->toQString().trimmed(); // 2
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
const QChar *pos = trimmed.constData();
@@ -574,117 +576,117 @@ ReturnedValue GlobalFunctions::method_parseFloat(CallContext *ctx)
/// isNaN [15.1.2.4]
ReturnedValue GlobalFunctions::method_isNaN(CallContext *ctx)
{
- if (!ctx->callData->argc)
+ if (!ctx->d()->callData->argc)
// undefined gets converted to NaN
return Encode(true);
- if (ctx->callData->args[0].integerCompatible())
+ if (ctx->d()->callData->args[0].integerCompatible())
return Encode(false);
- double d = ctx->callData->args[0].toNumber();
+ double d = ctx->d()->callData->args[0].toNumber();
return Encode((bool)std::isnan(d));
}
/// isFinite [15.1.2.5]
ReturnedValue GlobalFunctions::method_isFinite(CallContext *ctx)
{
- if (!ctx->callData->argc)
+ if (!ctx->d()->callData->argc)
// undefined gets converted to NaN
return Encode(false);
- if (ctx->callData->args[0].integerCompatible())
+ if (ctx->d()->callData->args[0].integerCompatible())
return Encode(true);
- double d = ctx->callData->args[0].toNumber();
+ double d = ctx->d()->callData->args[0].toNumber();
return Encode((bool)std::isfinite(d));
}
/// decodeURI [15.1.3.1]
ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context)
{
- if (context->callData->argc == 0)
+ if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toString(context)->toQString();
bool ok;
QString out = decode(uriString, DecodeNonReserved, &ok);
if (!ok) {
Scope scope(context);
- ScopedString s(scope, context->engine->newString(QStringLiteral("malformed URI sequence")));
+ ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
return context->throwURIError(s);
}
- return context->engine->newString(out)->asReturnedValue();
+ return context->d()->engine->newString(out)->asReturnedValue();
}
/// decodeURIComponent [15.1.3.2]
ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context)
{
- if (context->callData->argc == 0)
+ if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toString(context)->toQString();
bool ok;
QString out = decode(uriString, DecodeAll, &ok);
if (!ok) {
Scope scope(context);
- ScopedString s(scope, context->engine->newString(QStringLiteral("malformed URI sequence")));
+ ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
return context->throwURIError(s);
}
- return context->engine->newString(out)->asReturnedValue();
+ return context->d()->engine->newString(out)->asReturnedValue();
}
/// encodeURI [15.1.3.3]
ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context)
{
- if (context->callData->argc == 0)
+ if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toString(context)->toQString();
bool ok;
QString out = encode(uriString, uriUnescapedReserved, &ok);
if (!ok) {
Scope scope(context);
- ScopedString s(scope, context->engine->newString(QStringLiteral("malformed URI sequence")));
+ ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
return context->throwURIError(s);
}
- return context->engine->newString(out)->asReturnedValue();
+ return context->d()->engine->newString(out)->asReturnedValue();
}
/// encodeURIComponent [15.1.3.4]
ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context)
{
- if (context->callData->argc == 0)
+ if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toString(context)->toQString();
bool ok;
QString out = encode(uriString, uriUnescaped, &ok);
if (!ok) {
Scope scope(context);
- ScopedString s(scope, context->engine->newString(QStringLiteral("malformed URI sequence")));
+ ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
return context->throwURIError(s);
}
- return context->engine->newString(out)->asReturnedValue();
+ return context->d()->engine->newString(out)->asReturnedValue();
}
ReturnedValue GlobalFunctions::method_escape(CallContext *context)
{
- if (!context->callData->argc)
- return context->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!context->d()->callData->argc)
+ return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
- QString str = context->callData->args[0].toString(context)->toQString();
- return context->engine->newString(escape(str))->asReturnedValue();
+ QString str = context->d()->callData->args[0].toString(context)->toQString();
+ return context->d()->engine->newString(escape(str))->asReturnedValue();
}
ReturnedValue GlobalFunctions::method_unescape(CallContext *context)
{
- if (!context->callData->argc)
- return context->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!context->d()->callData->argc)
+ return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
- QString str = context->callData->args[0].toString(context)->toQString();
- return context->engine->newString(unescape(str))->asReturnedValue();
+ QString str = context->d()->callData->args[0].toString(context)->toQString();
+ return context->d()->engine->newString(unescape(str))->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index 63823acc19..b3fcb0c89b 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -50,8 +50,11 @@ namespace QV4 {
struct Q_QML_EXPORT EvalFunction : FunctionObject
{
- V4_OBJECT
- EvalFunction(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
ReturnedValue evalCall(CallData *callData, bool directCall);
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp
index 87fbd6f8e4..bbb756bab3 100644
--- a/src/qml/jsruntime/qv4identifier.cpp
+++ b/src/qml/jsruntime/qv4identifier.cpp
@@ -149,8 +149,8 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(String *str) const
{
if (!d)
return 0;
- if (str->identifier)
- return lookup(str->identifier);
+ if (str->d()->identifier)
+ return lookup(str->d()->identifier);
return lookup(str->toQString());
}
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index e300a4811e..8627438fe1 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -69,7 +69,7 @@ IdentifierTable::~IdentifierTable()
{
for (int i = 0; i < alloc; ++i)
if (entries[i])
- delete entries[i]->identifier;
+ delete entries[i]->d()->identifier;
free(entries);
}
@@ -77,12 +77,12 @@ void IdentifierTable::addEntry(String *str)
{
uint hash = str->hashValue();
- if (str->subtype == String::StringType_ArrayIndex)
+ if (str->subtype() == String::StringType_ArrayIndex)
return;
- str->identifier = new Identifier;
- str->identifier->string = str->toQString();
- str->identifier->hashValue = hash;
+ str->d()->identifier = new Identifier;
+ str->d()->identifier->string = str->toQString();
+ str->d()->identifier->hashValue = hash;
bool grow = (alloc <= size*2);
@@ -95,7 +95,7 @@ void IdentifierTable::addEntry(String *str)
String *e = entries[i];
if (!e)
continue;
- uint idx = e->stringHash % newAlloc;
+ uint idx = e->d()->stringHash % newAlloc;
while (newEntries[idx]) {
++idx;
idx %= newAlloc;
@@ -123,7 +123,7 @@ String *IdentifierTable::insertString(const QString &s)
uint hash = String::createHashValue(s.constData(), s.length());
uint idx = hash % alloc;
while (String *e = entries[idx]) {
- if (e->stringHash == hash && e->toQString() == s)
+ if (e->d()->stringHash == hash && e->toQString() == s)
return e;
++idx;
idx %= alloc;
@@ -137,29 +137,29 @@ String *IdentifierTable::insertString(const QString &s)
Identifier *IdentifierTable::identifierImpl(const String *str)
{
- if (str->identifier)
- return str->identifier;
+ if (str->d()->identifier)
+ return str->d()->identifier;
uint hash = str->hashValue();
- if (str->subtype == String::StringType_ArrayIndex)
+ if (str->subtype() == String::StringType_ArrayIndex)
return 0;
uint idx = hash % alloc;
while (String *e = entries[idx]) {
- if (e->stringHash == hash && e->isEqualTo(str)) {
- str->identifier = e->identifier;
- return e->identifier;
+ if (e->d()->stringHash == hash && e->isEqualTo(str)) {
+ str->d()->identifier = e->d()->identifier;
+ return e->d()->identifier;
}
++idx;
idx %= alloc;
}
addEntry(const_cast<QV4::String *>(str));
- return str->identifier;
+ return str->d()->identifier;
}
Identifier *IdentifierTable::identifier(const QString &s)
{
- return insertString(s)->identifier;
+ return insertString(s)->d()->identifier;
}
Identifier *IdentifierTable::identifier(const char *s, int len)
@@ -171,15 +171,15 @@ Identifier *IdentifierTable::identifier(const char *s, int len)
QLatin1String latin(s, len);
uint idx = hash % alloc;
while (String *e = entries[idx]) {
- if (e->stringHash == hash && e->toQString() == latin)
- return e->identifier;
+ if (e->d()->stringHash == hash && e->toQString() == latin)
+ return e->d()->identifier;
++idx;
idx %= alloc;
}
String *str = engine->newString(QString::fromLatin1(s, len))->getPointer();
addEntry(str);
- return str->identifier;
+ return str->d()->identifier;
}
}
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index 09956fc342..7675d1642e 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -69,8 +69,8 @@ public:
String *insertString(const QString &s);
Identifier *identifier(const String *str) {
- if (str->identifier)
- return str->identifier;
+ if (str->d()->identifier)
+ return str->d()->identifier;
return identifierImpl(str);
}
@@ -82,11 +82,11 @@ public:
void mark(ExecutionEngine *e) {
for (int i = 0; i < alloc; ++i) {
String *entry = entries[i];
- if (!entry || entry->markBit)
+ if (!entry || entry->markBit())
continue;
- entry->markBit = 1;
- Q_ASSERT(entry->internalClass->vtable->markObjects);
- entry->internalClass->vtable->markObjects(entry, e);
+ entry->d()->markBit = 1;
+ Q_ASSERT(entry->internalClass()->vtable->markObjects);
+ entry->internalClass()->vtable->markObjects(entry, e);
}
}
};
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index d5bae0e35e..b9576e1bee 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -89,11 +89,11 @@ QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status stat
QV4::ScopedObject o(scope, v4->newObject());
QV4::ScopedString s(scope);
QV4::ScopedValue v(scope);
- o->put((s = v4->newString(QStringLiteral("OK"))), (v = QV4::Primitive::fromInt32(Ok)));
- o->put((s = v4->newString(QStringLiteral("LOADING"))), (v = QV4::Primitive::fromInt32(Loading)));
- o->put((s = v4->newString(QStringLiteral("NETWORK_ERROR"))), (v = QV4::Primitive::fromInt32(NetworkError)));
- o->put((s = v4->newString(QStringLiteral("EXCEPTION"))), (v = QV4::Primitive::fromInt32(Exception)));
- o->put((s = v4->newString(QStringLiteral("status"))), (v = QV4::Primitive::fromInt32(status)));
+ o->put((s = v4->newString(QStringLiteral("OK"))).getPointer(), (v = QV4::Primitive::fromInt32(Ok)));
+ o->put((s = v4->newString(QStringLiteral("LOADING"))).getPointer(), (v = QV4::Primitive::fromInt32(Loading)));
+ o->put((s = v4->newString(QStringLiteral("NETWORK_ERROR"))).getPointer(), (v = QV4::Primitive::fromInt32(NetworkError)));
+ o->put((s = v4->newString(QStringLiteral("EXCEPTION"))).getPointer(), (v = QV4::Primitive::fromInt32(Exception)));
+ o->put((s = v4->newString(QStringLiteral("status"))).getPointer(), (v = QV4::Primitive::fromInt32(status)));
return o.asReturnedValue();
}
@@ -160,13 +160,13 @@ void QV4Include::finished()
script.run();
if (scope.engine->hasException) {
QV4::ScopedValue ex(scope, ctx->catchException());
- resultObj->put(status, QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Exception)));
- resultObj->put(QV4::ScopedString(scope, v4->newString(QStringLiteral("exception"))), ex);
+ resultObj->put(status.getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Exception)));
+ resultObj->put(v4->newString(QStringLiteral("exception"))->getPointer(), ex);
} else {
- resultObj->put(status, QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Ok)));
+ resultObj->put(status.getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Ok)));
}
} else {
- resultObj->put(QV4::ScopedString(scope, v4->newString(QStringLiteral("status"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(NetworkError)));
+ resultObj->put(v4->newString(QStringLiteral("status"))->getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(NetworkError)));
}
QV4::ScopedValue cb(scope, m_callbackFunction.value());
@@ -181,27 +181,26 @@ void QV4Include::finished()
*/
QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
{
- if (!ctx->callData->argc)
+ if (!ctx->d()->callData->argc)
return QV4::Encode::undefined();
- QV4::ExecutionEngine *v4 = ctx->engine;
- QV4::Scope scope(v4);
- QV8Engine *engine = v4->v8Engine;
- QQmlContextData *context = QV4::QmlContextWrapper::callingContext(v4);
+ QV4::Scope scope(ctx->engine());
+ QV8Engine *engine = scope.engine->v8Engine;
+ QQmlContextData *context = QV4::QmlContextWrapper::callingContext(scope.engine);
if (!context || !context->isJSContext)
V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
- QUrl url(ctx->engine->resolvedUrl(ctx->callData->args[0].toQStringNoThrow()));
+ QUrl url(scope.engine->resolvedUrl(ctx->d()->callData->args[0].toQStringNoThrow()));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (ctx->callData->argc >= 2 && ctx->callData->args[1].asFunctionObject())
- callbackFunction = ctx->callData->args[1];
+ if (ctx->d()->callData->argc >= 2 && ctx->d()->callData->args[1].asFunctionObject())
+ callbackFunction = ctx->d()->callData->args[1];
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
QV4::ScopedValue result(scope);
- QV4::ScopedObject qmlcontextobject(scope, v4->qmlContextObject());
+ QV4::ScopedObject qmlcontextobject(scope, scope.engine->qmlContextObject());
if (localFile.isEmpty()) {
QV4Include *i = new QV4Include(url, engine, context,
@@ -218,21 +217,21 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
QString code = QString::fromUtf8(data);
QmlIR::Document::removeScriptPragmas(code);
- QV4::Script script(v4, qmlcontextobject, code, url.toString());
+ QV4::Script script(scope.engine, qmlcontextobject, code, url.toString());
- QV4::ExecutionContext *ctx = v4->currentContext();
+ QV4::ExecutionContext *ctx = scope.engine->currentContext();
script.parse();
- if (!v4->hasException)
+ if (!scope.engine->hasException)
script.run();
- if (v4->hasException) {
+ if (scope.engine->hasException) {
QV4::ScopedValue ex(scope, ctx->catchException());
- result = resultValue(v4, Exception);
- result->asObject()->put(QV4::ScopedString(scope, v4->newString(QStringLiteral("exception"))), ex);
+ result = resultValue(scope.engine, Exception);
+ result->asObject()->put(scope.engine->newString(QStringLiteral("exception"))->getPointer(), ex);
} else {
- result = resultValue(v4, Ok);
+ result = resultValue(scope.engine, Ok);
}
} else {
- result = resultValue(v4, NetworkError);
+ result = resultValue(scope.engine, NetworkError);
}
callback(callbackFunction, result);
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 3dc20b8e76..2edaf6fe96 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -155,18 +155,18 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
{
uint idx;
- InternalClass *newClass = object->internalClass->changeMember(string, data, &idx);
+ InternalClass *newClass = object->internalClass()->changeMember(string, data, &idx);
if (index)
*index = idx;
- if (newClass->size > object->internalClass->size) {
- Q_ASSERT(newClass->size == object->internalClass->size + 1);
- memmove(object->memberData.data() + idx + 2, object->memberData.data() + idx + 1, (object->internalClass->size - idx - 1)*sizeof(Value));
- } else if (newClass->size < object->internalClass->size) {
- Q_ASSERT(newClass->size == object->internalClass->size - 1);
- memmove(object->memberData.data() + idx + 1, object->memberData.data() + idx + 2, (object->internalClass->size - idx - 2)*sizeof(Value));
+ if (newClass->size > object->internalClass()->size) {
+ Q_ASSERT(newClass->size == object->internalClass()->size + 1);
+ memmove(object->memberData().data() + idx + 2, object->memberData().data() + idx + 1, (object->internalClass()->size - idx - 1)*sizeof(Value));
+ } else if (newClass->size < object->internalClass()->size) {
+ Q_ASSERT(newClass->size == object->internalClass()->size - 1);
+ memmove(object->memberData().data() + idx + 1, object->memberData().data() + idx + 2, (object->internalClass()->size - idx - 2)*sizeof(Value));
}
- object->internalClass = newClass;
+ object->setInternalClass(newClass);
}
InternalClass *InternalClass::changeMember(String *string, PropertyAttributes data, uint *index)
@@ -181,7 +181,7 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da
if (data == propertyData.at(idx))
return this;
- Transition t = { { string->identifier }, (int)data.flags() };
+ Transition t = { { string->d()->identifier }, (int)data.flags() };
QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t);
if (tit != transitions.constEnd())
return tit.value();
@@ -271,40 +271,30 @@ InternalClass *InternalClass::changeVTable(const ManagedVTable *vt)
return newClass;
}
-void InternalClass::addMember(Object *object, StringRef string, PropertyAttributes data, uint *index)
-{
- return addMember(object, string.getPointer(), data, index);
-}
-
void InternalClass::addMember(Object *object, String *string, PropertyAttributes data, uint *index)
{
data.resolve();
- object->internalClass->engine->identifierTable->identifier(string);
- if (object->internalClass->propertyTable.lookup(string->identifier) < object->internalClass->size) {
+ object->internalClass()->engine->identifierTable->identifier(string);
+ if (object->internalClass()->propertyTable.lookup(string->d()->identifier) < object->internalClass()->size) {
changeMember(object, string, data, index);
return;
}
uint idx;
- InternalClass *newClass = object->internalClass->addMemberImpl(string, data, &idx);
+ InternalClass *newClass = object->internalClass()->addMemberImpl(string, data, &idx);
if (index)
*index = idx;
- object->internalClass = newClass;
+ object->setInternalClass(newClass);
}
-InternalClass *InternalClass::addMember(StringRef string, PropertyAttributes data, uint *index)
-{
- return addMember(string.getPointer(), data, index);
-}
-
InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, uint *index)
{
data.resolve();
engine->identifierTable->identifier(string);
- if (propertyTable.lookup(string->identifier) < size)
+ if (propertyTable.lookup(string->d()->identifier) < size)
return changeMember(string, data, index);
return addMemberImpl(string, data, index);
@@ -312,7 +302,7 @@ InternalClass *InternalClass::addMember(String *string, PropertyAttributes data,
InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes data, uint *index)
{
- Transition t = { { string->identifier }, (int)data.flags() };
+ Transition t = { { string->d()->identifier }, (int)data.flags() };
QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t);
if (index)
@@ -322,7 +312,7 @@ InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes d
// create a new class and add it to the tree
InternalClass *newClass = engine->newClass(*this);
- PropertyHash::Entry e = { string->identifier, newClass->size };
+ PropertyHash::Entry e = { string->d()->identifier, newClass->size };
newClass->propertyTable.addEntry(e, newClass->size);
// The incoming string can come from anywhere, so make sure to
@@ -346,15 +336,15 @@ InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes d
void InternalClass::removeMember(Object *object, Identifier *id)
{
- InternalClass *oldClass = object->internalClass;
+ InternalClass *oldClass = object->internalClass();
uint propIdx = oldClass->propertyTable.lookup(id);
Q_ASSERT(propIdx < oldClass->size);
Transition t = { { id } , -1 };
- QHash<Transition, InternalClass *>::const_iterator tit = object->internalClass->transitions.constFind(t);
+ QHash<Transition, InternalClass *>::const_iterator tit = object->internalClass()->transitions.constFind(t);
- if (tit != object->internalClass->transitions.constEnd()) {
- object->internalClass = tit.value();
+ if (tit != object->internalClass()->transitions.constEnd()) {
+ object->setInternalClass(tit.value());
} else {
// create a new class and add it to the tree
InternalClass *newClass = oldClass->engine->emptyClass->changeVTable(oldClass->vtable);
@@ -365,24 +355,19 @@ void InternalClass::removeMember(Object *object, Identifier *id)
if (!oldClass->propertyData.at(i).isEmpty())
newClass = newClass->addMember(oldClass->nameMap.at(i), oldClass->propertyData.at(i));
}
- object->internalClass = newClass;
+ object->setInternalClass(newClass);
}
// remove the entry in memberdata
- memmove(object->memberData.data() + propIdx, object->memberData.data() + propIdx + 1, (object->internalClass->size - propIdx)*sizeof(Value));
-
- oldClass->transitions.insert(t, object->internalClass);
-}
+ memmove(object->memberData().data() + propIdx, object->memberData().data() + propIdx + 1, (object->internalClass()->size - propIdx)*sizeof(Value));
-uint InternalClass::find(const StringRef string)
-{
- return find(string.getPointer());
+ oldClass->transitions.insert(t, object->internalClass());
}
uint InternalClass::find(const String *string)
{
engine->identifierTable->identifier(string);
- const Identifier *id = string->identifier;
+ const Identifier *id = string->d()->identifier;
uint index = propertyTable.lookup(id);
if (index < size)
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index bd1828a146..830d5f792f 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -234,14 +234,11 @@ struct InternalClass : public QQmlJS::Managed {
static InternalClass *create(ExecutionEngine *engine, const ManagedVTable *vtable, Object *proto);
InternalClass *changePrototype(Object *proto);
InternalClass *changeVTable(const ManagedVTable *vt);
- static void addMember(Object *object, StringRef string, PropertyAttributes data, uint *index);
static void addMember(Object *object, String *string, PropertyAttributes data, uint *index);
- InternalClass *addMember(StringRef string, PropertyAttributes data, uint *index = 0);
InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
InternalClass *changeMember(String *string, PropertyAttributes data, uint *index = 0);
static void changeMember(Object *object, String *string, PropertyAttributes data, uint *index = 0);
static void removeMember(Object *object, Identifier *id);
- uint find(const StringRef string);
uint find(const String *s);
InternalClass *sealed();
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index ca82af1b30..2cbb72e15f 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -81,7 +81,7 @@ private:
ReturnedValue parseObject();
ReturnedValue parseArray();
- bool parseMember(ObjectRef o);
+ bool parseMember(Object *o);
bool parseString(QString *string);
bool parseValue(ValueRef val);
bool parseNumber(ValueRef val);
@@ -237,7 +237,7 @@ ReturnedValue JsonParser::parseObject()
BEGIN << "parseObject pos=" << json;
Scope scope(context);
- ScopedObject o(scope, context->engine->newObject());
+ ScopedObject o(scope, context->d()->engine->newObject());
QChar token = nextToken();
while (token == Quote) {
@@ -268,7 +268,7 @@ ReturnedValue JsonParser::parseObject()
/*
member = string name-separator value
*/
-bool JsonParser::parseMember(ObjectRef o)
+bool JsonParser::parseMember(Object *o)
{
BEGIN << "parseMember";
Scope scope(context);
@@ -285,12 +285,12 @@ bool JsonParser::parseMember(ObjectRef o)
if (!parseValue(val))
return false;
- ScopedString s(scope, context->engine->newIdentifier(key));
+ ScopedString s(scope, context->d()->engine->newIdentifier(key));
uint idx = s->asArrayIndex();
if (idx < UINT_MAX) {
o->putIndexed(idx, val);
} else {
- o->insertMember(s, val);
+ o->insertMember(s.getPointer(), val);
}
END;
@@ -304,7 +304,7 @@ ReturnedValue JsonParser::parseArray()
{
Scope scope(context);
BEGIN << "parseArray";
- Scoped<ArrayObject> array(scope, context->engine->newArrayObject());
+ Scoped<ArrayObject> array(scope, context->d()->engine->newArrayObject());
if (++nestingLevel > nestingLimit) {
lastError = QJsonParseError::DeepNesting;
@@ -407,7 +407,7 @@ bool JsonParser::parseValue(ValueRef val)
return false;
DEBUG << "value: string";
END;
- val = context->engine->newString(value);
+ val = context->d()->engine->newString(value);
return true;
}
case BeginArray: {
@@ -656,8 +656,8 @@ struct Stringify
Stringify(ExecutionContext *ctx) : ctx(ctx), replacerFunction(0) {}
QString Str(const QString &key, ValueRef v);
- QString JA(ArrayObjectRef a);
- QString JO(ObjectRef o);
+ QString JA(ArrayObject *a);
+ QString JO(Object *o);
QString makeMember(const QString &key, ValueRef v);
};
@@ -710,21 +710,21 @@ QString Stringify::Str(const QString &key, ValueRef v)
ScopedValue value(scope, *v);
ScopedObject o(scope, value);
if (o) {
- ScopedString s(scope, ctx->engine->newString(QStringLiteral("toJSON")));
- Scoped<FunctionObject> toJSON(scope, o->get(s));
+ ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toJSON")));
+ Scoped<FunctionObject> toJSON(scope, o->get(s.getPointer()));
if (!!toJSON) {
ScopedCallData callData(scope, 1);
callData->thisObject = value;
- callData->args[0] = ctx->engine->newString(key);
+ callData->args[0] = ctx->d()->engine->newString(key);
value = toJSON->call(callData);
}
}
if (replacerFunction) {
- ScopedObject holder(scope, ctx->engine->newObject());
+ ScopedObject holder(scope, ctx->d()->engine->newObject());
holder->put(ctx, QString(), value);
ScopedCallData callData(scope, 2);
- callData->args[0] = ctx->engine->newString(key);
+ callData->args[0] = ctx->d()->engine->newString(key);
callData->args[1] = value;
callData->thisObject = holder;
value = replacerFunction->call(callData);
@@ -733,11 +733,11 @@ QString Stringify::Str(const QString &key, ValueRef v)
o = value.asReturnedValue();
if (o) {
if (NumberObject *n = o->asNumberObject())
- value = n->value;
+ value = n->value();
else if (StringObject *so = o->asStringObject())
- value = so->value;
+ value = so->d()->value;
else if (BooleanObject *b =o->asBooleanObject())
- value = b->value;
+ value = b->value();
}
if (value->isNull())
@@ -780,9 +780,9 @@ QString Stringify::makeMember(const QString &key, ValueRef v)
return QString();
}
-QString Stringify::JO(ObjectRef o)
+QString Stringify::JO(Object *o)
{
- if (stack.contains(o.getPointer())) {
+ if (stack.contains(o)) {
ctx->throwTypeError();
return QString();
}
@@ -790,7 +790,7 @@ QString Stringify::JO(ObjectRef o)
Scope scope(ctx);
QString result;
- stack.push(o.getPointer());
+ stack.push(o);
QString stepback = indent;
indent += gap;
@@ -814,7 +814,7 @@ QString Stringify::JO(ObjectRef o)
for (int i = 0; i < propertyList.size(); ++i) {
bool exists;
s = propertyList.at(i);
- ScopedValue v(scope, o->get(s, &exists));
+ ScopedValue v(scope, o->get(s.getPointer(), &exists));
if (!exists)
continue;
QString member = makeMember(s->toQString(), v);
@@ -837,9 +837,9 @@ QString Stringify::JO(ObjectRef o)
return result;
}
-QString Stringify::JA(ArrayObjectRef a)
+QString Stringify::JA(ArrayObject *a)
{
- if (stack.contains(a.getPointer())) {
+ if (stack.contains(a)) {
ctx->throwTypeError();
return QString();
}
@@ -847,7 +847,7 @@ QString Stringify::JA(ArrayObjectRef a)
Scope scope(a->engine());
QString result;
- stack.push(a.getPointer());
+ stack.push(a);
QString stepback = indent;
indent += gap;
@@ -883,14 +883,14 @@ QString Stringify::JA(ArrayObjectRef a)
}
-JsonObject::JsonObject(InternalClass *ic)
- : Object(ic)
+JsonObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
Scope scope(ic->engine);
- ScopedObject protectThis(scope, this);
+ ScopedObject o(scope, this);
- defineDefaultProperty(QStringLiteral("parse"), method_parse, 2);
- defineDefaultProperty(QStringLiteral("stringify"), method_stringify, 3);
+ o->defineDefaultProperty(QStringLiteral("parse"), method_parse, 2);
+ o->defineDefaultProperty(QStringLiteral("stringify"), method_stringify, 3);
}
@@ -939,9 +939,9 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
ScopedValue s(scope, ctx->argument(2));
if (NumberObject *n = s->asNumberObject())
- s = n->value;
+ s = n->value();
else if (StringObject *so = s->asStringObject())
- s = so->value;
+ s = so->d()->value;
if (s->isNumber()) {
stringify.gap = QString(qMin(10, (int)s->toInteger()), ' ');
@@ -954,7 +954,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
QString result = stringify.Str(QString(), arg0);
if (result.isEmpty() || scope.engine->hasException)
return Encode::undefined();
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
@@ -962,7 +962,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
ReturnedValue JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
{
if (value.isString())
- return engine->currentContext()->engine->newString(value.toString())->asReturnedValue();
+ return engine->currentContext()->d()->engine->newString(value.toString())->asReturnedValue();
else if (value.isDouble())
return Encode(value.toDouble());
else if (value.isBool())
@@ -1008,12 +1008,12 @@ QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJs
ScopedValue v(scope);
for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it) {
v = fromJsonValue(engine, it.value());
- o->put((s = engine->newString(it.key())), v);
+ o->put((s = engine->newString(it.key())).getPointer(), v);
}
return o.asReturnedValue();
}
-QJsonObject JsonObject::toJsonObject(ObjectRef o, V4ObjectSet &visitedObjects)
+QJsonObject JsonObject::toJsonObject(Object *o, V4ObjectSet &visitedObjects)
{
QJsonObject result;
if (!o || o->asFunctionObject())
@@ -1061,7 +1061,7 @@ QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJso
return a.asReturnedValue();
}
-QJsonArray JsonObject::toJsonArray(ArrayObjectRef a, V4ObjectSet &visitedObjects)
+QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
{
QJsonArray result;
if (!a)
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 34a4f4dd4b..03d5ad29c8 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -51,12 +51,14 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct JsonObject : Object {
+ struct Data : Object::Data {
+ Data(InternalClass *ic);
+ };
Q_MANAGED_TYPE(JsonObject)
- V4_OBJECT
+ V4_OBJECT(Object)
private:
typedef QSet<QV4::Object *> V4ObjectSet;
public:
- JsonObject(InternalClass *ic);
static ReturnedValue method_parse(CallContext *ctx);
static ReturnedValue method_stringify(CallContext *ctx);
@@ -67,15 +69,15 @@ public:
static inline QJsonValue toJsonValue(const QV4::ValueRef value)
{ V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }
- static inline QJsonObject toJsonObject(QV4::ObjectRef o)
+ static inline QJsonObject toJsonObject(QV4::Object *o)
{ V4ObjectSet visitedObjects; return toJsonObject(o, visitedObjects); }
- static inline QJsonArray toJsonArray(QV4::ArrayObjectRef a)
+ static inline QJsonArray toJsonArray(QV4::ArrayObject *a)
{ V4ObjectSet visitedObjects; return toJsonArray(a, visitedObjects); }
private:
static QJsonValue toJsonValue(const QV4::ValueRef value, V4ObjectSet &visitedObjects);
- static QJsonObject toJsonObject(QV4::ObjectRef o, V4ObjectSet &visitedObjects);
- static QJsonArray toJsonArray(QV4::ArrayObjectRef a, V4ObjectSet &visitedObjects);
+ static QJsonObject toJsonObject(Object *o, V4ObjectSet &visitedObjects);
+ static QJsonArray toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects);
};
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 1155bbf9e9..57154c4779 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -51,13 +51,13 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
{
int i = 0;
while (i < Size && obj) {
- classList[i] = obj->internalClass;
+ classList[i] = obj->internalClass();
- index = obj->internalClass->find(name);
+ index = obj->internalClass()->find(name);
if (index != UINT_MAX) {
level = i;
- *attrs = obj->internalClass->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass()->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -66,10 +66,10 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
level = Size;
while (obj) {
- index = obj->internalClass->find(name);
+ index = obj->internalClass()->find(name);
if (index != UINT_MAX) {
- *attrs = obj->internalClass->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass()->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -82,13 +82,13 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
Object *thisObject = obj;
int i = 0;
while (i < Size && obj) {
- classList[i] = obj->internalClass;
+ classList[i] = obj->internalClass();
- index = obj->internalClass->find(name);
+ index = obj->internalClass()->find(name);
if (index != UINT_MAX) {
level = i;
- *attrs = obj->internalClass->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass()->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -97,10 +97,10 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
level = Size;
while (obj) {
- index = obj->internalClass->find(name);
+ index = obj->internalClass()->find(name);
if (index != UINT_MAX) {
- *attrs = obj->internalClass->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass()->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -147,8 +147,8 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const ValueRef object, co
}
if (idx < UINT_MAX) {
- if (!o->arrayData->hasAttributes()) {
- ScopedValue v(scope, o->arrayData->get(idx));
+ if (!o->arrayData()->hasAttributes()) {
+ ScopedValue v(scope, o->arrayData()->get(idx));
if (!v->isEmpty())
return v->asReturnedValue();
}
@@ -159,7 +159,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const ValueRef object, co
ScopedString name(scope, index->toString(ctx));
if (scope.hasException())
return Encode::undefined();
- return o->get(name);
+ return o->get(name.getPointer());
}
@@ -171,10 +171,10 @@ ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const ValueRef object, c
return indexedGetterGeneric(l, object, index);
Object *o = object->objectValue();
- if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
- if (idx < static_cast<SimpleArrayData *>(o->arrayData)->len)
- if (!o->arrayData->data[idx].isEmpty())
- return o->arrayData->data[idx].asReturnedValue();
+ if (o->arrayData() && o->arrayData()->type() == ArrayData::Simple) {
+ if (idx < static_cast<SimpleArrayData *>(o->arrayData())->len())
+ if (!o->arrayData()->arrayData()[idx].isEmpty())
+ return o->arrayData()->arrayData()[idx].asReturnedValue();
}
return indexedGetterFallback(l, object, index);
@@ -184,7 +184,7 @@ void Lookup::indexedSetterGeneric(Lookup *l, const ValueRef object, const ValueR
{
if (object->isObject()) {
Object *o = object->objectValue();
- if (o->arrayData && o->arrayData->type == ArrayData::Simple && index->asArrayIndex() < UINT_MAX) {
+ if (o->arrayData() && o->arrayData()->type() == ArrayData::Simple && index->asArrayIndex() < UINT_MAX) {
l->indexedSetter = indexedSetterObjectInt;
indexedSetterObjectInt(l, object, index, v);
return;
@@ -203,10 +203,10 @@ void Lookup::indexedSetterFallback(Lookup *l, const ValueRef object, const Value
uint idx = index->asArrayIndex();
if (idx < UINT_MAX) {
- if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
- SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
- if (s && idx < s->len && !s->data[idx].isEmpty()) {
- s->data[idx] = value;
+ if (o->arrayData() && o->arrayData()->type() == ArrayData::Simple) {
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData());
+ if (s && idx < s->len() && !s->arrayData()[idx].isEmpty()) {
+ s->arrayData()[idx] = value;
return;
}
}
@@ -215,7 +215,7 @@ void Lookup::indexedSetterFallback(Lookup *l, const ValueRef object, const Value
}
ScopedString name(scope, index->toString(ctx));
- o->put(name, value);
+ o->put(name.getPointer(), value);
}
void Lookup::indexedSetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v)
@@ -227,10 +227,10 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const ValueRef object, const Valu
}
Object *o = object->objectValue();
- if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
- SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
- if (idx < s->len && !s->data[idx].isEmpty()) {
- s->data[idx] = v;
+ if (o->arrayData() && o->arrayData()->type() == ArrayData::Simple) {
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData());
+ if (idx < s->len() && !s->arrayData()[idx].isEmpty()) {
+ s->arrayData()[idx] = v;
return;
}
}
@@ -254,7 +254,7 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
case Value::Managed_Type:
Q_ASSERT(object->isString());
proto = engine->stringObjectClass->prototype;
- if (l->name->equals(engine->id_length)) {
+ if (l->name->equals(engine->id_length.getPointer())) {
// special case, as the property is on the object itself
l->getter = stringLengthGetter;
return stringLengthGetter(l, object);
@@ -331,7 +331,7 @@ ReturnedValue Lookup::getterFallback(Lookup *l, const ValueRef object)
if (!o)
return Encode::undefined();
QV4::ScopedString s(scope, l->name);
- return o->get(s);
+ return o->get(s.getPointer());
}
ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
@@ -340,8 +340,8 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
+ if (l->classList[0] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@@ -352,9 +352,9 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index].asReturnedValue();
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@@ -365,12 +365,12 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass) {
+ if (l->classList[0] == o->internalClass()) {
o = o->prototype();
- if (l->classList[1] == o->internalClass) {
+ if (l->classList[1] == o->internalClass()) {
o = o->prototype();
- if (l->classList[2] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
+ if (l->classList[2] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
}
}
}
@@ -384,10 +384,10 @@ ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
- if (l->classList[2] == o->internalClass)
- return o->memberData[l->index2].asReturnedValue();
+ if (l->classList[0] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
+ if (l->classList[2] == o->internalClass())
+ return o->memberData()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@@ -399,11 +399,11 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
- if (l->classList[2] == o->internalClass &&
- l->classList[3] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index2].asReturnedValue();
+ if (l->classList[0] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
+ if (l->classList[2] == o->internalClass() &&
+ l->classList[3] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@@ -415,12 +415,12 @@ ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index].asReturnedValue();
- if (l->classList[2] == o->internalClass &&
- l->classList[3] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index2].asReturnedValue();
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index].asReturnedValue();
+ if (l->classList[2] == o->internalClass() &&
+ l->classList[3] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index2].asReturnedValue();
return getterFallback(l, object);
}
l->getter = getterFallback;
@@ -434,7 +434,7 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass) {
+ if (l->classList[0] == o->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
@@ -455,8 +455,8 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
if (!getter)
@@ -477,11 +477,11 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object)
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass) {
+ if (l->classList[0] == o->internalClass()) {
o = o->prototype();
- if (l->classList[1] == o->internalClass) {
+ if (l->classList[1] == o->internalClass()) {
o = o->prototype();
- if (l->classList[2] == o->internalClass) {
+ if (l->classList[2] == o->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
@@ -502,8 +502,8 @@ ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object)
{
if (object->type() == l->type) {
Object *o = l->proto;
- if (l->classList[0] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
+ if (l->classList[0] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -513,9 +513,9 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object)
{
if (object->type() == l->type) {
Object *o = l->proto;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index].asReturnedValue();
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -525,7 +525,7 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object)
{
if (object->type() == l->type) {
Object *o = l->proto;
- if (l->classList[0] == o->internalClass) {
+ if (l->classList[0] == o->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
@@ -544,8 +544,8 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object)
{
if (object->type() == l->type) {
Object *o = l->proto;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
if (!getter)
@@ -563,7 +563,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object)
ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object)
{
if (String *s = object->asString())
- return Encode(s->length());
+ return Encode(s->d()->length());
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -572,7 +572,7 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object)
ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object)
{
if (ArrayObject *a = object->asArrayObject())
- return a->memberData[ArrayObject::LengthPropertyIndex].asReturnedValue();
+ return a->memberData()[ArrayObject::LengthPropertyIndex].asReturnedValue();
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -581,7 +581,7 @@ ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object)
ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
+ Object *o = ctx->d()->engine->globalObject;
PropertyAttributes attrs;
ReturnedValue v = l->lookup(o, &attrs);
if (v != Primitive::emptyValue().asReturnedValue()) {
@@ -610,9 +610,9 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass)
- return o->memberData[l->index].asReturnedValue();
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass())
+ return o->memberData()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@@ -620,10 +620,10 @@ ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->memberData[l->index].asReturnedValue();
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass())
+ return o->prototype()->memberData()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@@ -631,13 +631,13 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass) {
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass()) {
o = o->prototype();
- if (l->classList[1] == o->internalClass) {
+ if (l->classList[1] == o->internalClass()) {
o = o->prototype();
- if (l->classList[2] == o->internalClass) {
- return o->prototype()->memberData[l->index].asReturnedValue();
+ if (l->classList[2] == o->internalClass()) {
+ return o->prototype()->memberData()[l->index].asReturnedValue();
}
}
}
@@ -647,8 +647,8 @@ ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass) {
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
@@ -664,9 +664,9 @@ ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass() &&
+ l->classList[1] == o->prototype()->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
if (!getter)
@@ -682,12 +682,12 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx)
ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx)
{
- Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass) {
+ Object *o = ctx->d()->engine->globalObject;
+ if (l->classList[0] == o->internalClass()) {
o = o->prototype();
- if (l->classList[1] == o->internalClass) {
+ if (l->classList[1] == o->internalClass()) {
o = o->prototype();
- if (l->classList[2] == o->internalClass) {
+ if (l->classList[2] == o->internalClass()) {
Scope scope(o->engine());
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
@@ -712,7 +712,7 @@ void Lookup::setterGeneric(Lookup *l, const ValueRef object, const ValueRef valu
if (!o) // type error
return;
ScopedString s(scope, l->name);
- o->put(s, value);
+ o->put(s.getPointer(), value);
return;
}
o->setLookup(l, value);
@@ -743,15 +743,15 @@ void Lookup::setterFallback(Lookup *l, const ValueRef object, const ValueRef val
QV4::ScopedObject o(scope, object->toObject(scope.engine->currentContext()));
if (o) {
QV4::ScopedString s(scope, l->name);
- o->put(s, value);
+ o->put(s.getPointer(), value);
}
}
void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
{
Object *o = static_cast<Object *>(object->asManaged());
- if (o && o->internalClass == l->classList[0]) {
- o->memberData[l->index] = *value;
+ if (o && o->internalClass() == l->classList[0]) {
+ o->memberData()[l->index] = *value;
return;
}
@@ -761,12 +761,12 @@ void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef value)
{
Object *o = static_cast<Object *>(object->asManaged());
- if (o && o->internalClass == l->classList[0]) {
+ if (o && o->internalClass() == l->classList[0]) {
if (!o->prototype()) {
- if (l->index >= o->memberData.size())
+ if (l->index >= o->memberData().size())
o->ensureMemberIndex(l->index);
- o->memberData[l->index] = *value;
- o->internalClass = l->classList[3];
+ o->memberData()[l->index] = *value;
+ o->setInternalClass(l->classList[3]);
return;
}
}
@@ -778,13 +778,13 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu
void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef value)
{
Object *o = static_cast<Object *>(object->asManaged());
- if (o && o->internalClass == l->classList[0]) {
+ if (o && o->internalClass() == l->classList[0]) {
Object *p = o->prototype();
- if (p && p->internalClass == l->classList[1]) {
- if (l->index >= o->memberData.size())
+ if (p && p->internalClass() == l->classList[1]) {
+ if (l->index >= o->memberData().size())
o->ensureMemberIndex(l->index);
- o->memberData[l->index] = *value;
- o->internalClass = l->classList[3];
+ o->memberData()[l->index] = *value;
+ o->setInternalClass(l->classList[3]);
return;
}
}
@@ -796,15 +796,15 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu
void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef value)
{
Object *o = static_cast<Object *>(object->asManaged());
- if (o && o->internalClass == l->classList[0]) {
+ if (o && o->internalClass() == l->classList[0]) {
Object *p = o->prototype();
- if (p && p->internalClass == l->classList[1]) {
+ if (p && p->internalClass() == l->classList[1]) {
p = p->prototype();
- if (p && p->internalClass == l->classList[2]) {
- if (l->index >= o->memberData.size())
+ if (p && p->internalClass() == l->classList[2]) {
+ if (l->index >= o->memberData().size())
o->ensureMemberIndex(l->index);
- o->memberData[l->index] = *value;
- o->internalClass = l->classList[3];
+ o->memberData()[l->index] = *value;
+ o->setInternalClass(l->classList[3]);
return;
}
}
@@ -818,12 +818,12 @@ void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef val
{
Object *o = static_cast<Object *>(object->asManaged());
if (o) {
- if (o->internalClass == l->classList[0]) {
- o->memberData[l->index] = *value;
+ if (o->internalClass() == l->classList[0]) {
+ o->memberData()[l->index] = *value;
return;
}
- if (o->internalClass == l->classList[1]) {
- o->memberData[l->index2] = *value;
+ if (o->internalClass() == l->classList[1]) {
+ o->memberData()[l->index2] = *value;
return;
}
}
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index 1f4030a4ed..6fc402e48f 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -45,8 +45,10 @@
using namespace QV4;
+
const ManagedVTable Managed::static_vtbl =
{
+ 0,
Managed::IsExecutionContext,
Managed::IsString,
Managed::IsObject,
@@ -56,7 +58,7 @@ const ManagedVTable Managed::static_vtbl =
0,
Managed::MyType,
"Managed",
- destroy,
+ 0,
0 /*markObjects*/,
isEqualTo
};
@@ -69,33 +71,15 @@ void *Managed::operator new(size_t size, MemoryManager *mm)
return mm->allocManaged(size);
}
-void Managed::operator delete(void *ptr)
-{
- if (!ptr)
- return;
-
- Managed *m = static_cast<Managed *>(ptr);
- m->_data = 0;
- m->markBit = 0;
- m->~Managed();
-}
-
-void Managed::operator delete(void *ptr, MemoryManager *mm)
-{
- Q_UNUSED(mm);
-
- operator delete(ptr);
-}
-
ExecutionEngine *Managed::engine() const
{
- return internalClass ? internalClass->engine : 0;
+ return internalClass()->engine;
}
QString Managed::className() const
{
const char *s = 0;
- switch (Type(internalClass->vtable->type)) {
+ switch (Type(internalClass()->vtable->type)) {
case Type_Invalid:
case Type_String:
return QString();
@@ -124,7 +108,7 @@ QString Managed::className() const
s = "RegExp";
break;
case Type_ErrorObject:
- switch (ErrorObject::ErrorType(subtype)) {
+ switch (ErrorObject::ErrorType(subtype())) {
case ErrorObject::Error:
s = "Error";
break;
@@ -177,10 +161,17 @@ QString Managed::className() const
void Managed::setVTable(const ManagedVTable *vt)
{
+ Q_ASSERT(internalClass());
+ d()->internalClass = internalClass()->changeVTable(vt);
+}
+
+void Managed::Data::setVTable(const ManagedVTable *vt)
+{
Q_ASSERT(internalClass);
internalClass = internalClass->changeVTable(vt);
}
+
bool Managed::isEqualTo(Managed *, Managed *)
{
return false;
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 06d3e4884b..b88531d8ed 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -62,26 +62,44 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
-#define V4_MANAGED \
+#ifdef Q_COMPILER_STATIC_ASSERT
+#define V4_MANAGED_SIZE_TEST void __dataTest() { Q_STATIC_ASSERT(sizeof(*this) == sizeof(Managed)); }
+#else
+#define V4_MANAGED_SIZE_TEST
+#endif
+
+#define V4_MANAGED(superClass) \
public: \
Q_MANAGED_CHECK \
+ typedef superClass SuperClass; \
static const QV4::ManagedVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+ V4_MANAGED_SIZE_TEST \
+ const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
+ Data *d() { return &static_cast<Data &>(Managed::data); }
-#define V4_OBJECT \
+#define V4_OBJECT(superClass) \
public: \
Q_MANAGED_CHECK \
+ typedef superClass SuperClass; \
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+ V4_MANAGED_SIZE_TEST \
+ const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
+ Data *d() { return &static_cast<Data &>(Managed::data); }
#define Q_MANAGED_TYPE(type) \
public: \
enum { MyType = Type_##type };
+#define Q_VTABLE_FUNCTION(classname, func) \
+ (classname::func == QV4::Managed::func ? 0 : classname::func)
+
+
struct GCDeletable
{
GCDeletable() : next(0), lastCall(false) {}
@@ -92,6 +110,7 @@ struct GCDeletable
struct ManagedVTable
{
+ const ManagedVTable * const parent;
uint isExecutionContext : 1;
uint isString : 1;
uint isObject : 1;
@@ -111,22 +130,23 @@ struct ObjectVTable
ManagedVTable managedVTable;
ReturnedValue (*call)(Managed *, CallData *data);
ReturnedValue (*construct)(Managed *, CallData *data);
- ReturnedValue (*get)(Managed *, const StringRef name, bool *hasProperty);
+ ReturnedValue (*get)(Managed *, String *name, bool *hasProperty);
ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
- void (*put)(Managed *, const StringRef name, const ValueRef value);
+ void (*put)(Managed *, String *name, const ValueRef value);
void (*putIndexed)(Managed *, uint index, const ValueRef value);
- PropertyAttributes (*query)(const Managed *, StringRef name);
+ PropertyAttributes (*query)(const Managed *, String *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
- bool (*deleteProperty)(Managed *m, const StringRef name);
+ bool (*deleteProperty)(Managed *m, String *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
ReturnedValue (*getLookup)(Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
uint (*getLength)(const Managed *m);
- void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
+ void (*advanceIterator)(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
};
-#define DEFINE_MANAGED_VTABLE_INT(classname) \
+#define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
{ \
+ parentVTable, \
classname::IsExecutionContext, \
classname::IsString, \
classname::IsObject, \
@@ -135,21 +155,20 @@ struct ObjectVTable
classname::IsArrayData, \
0, \
classname::MyType, \
- #classname, \
- destroy, \
+ #classname, \
+ Q_VTABLE_FUNCTION(classname, destroy), \
markObjects, \
isEqualTo \
}
-
#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
+const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0)
#define DEFINE_OBJECT_VTABLE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- DEFINE_MANAGED_VTABLE_INT(classname), \
+ DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.managedVTable), \
call, \
construct, \
get, \
@@ -166,30 +185,43 @@ const QV4::ObjectVTable classname::static_vtbl = \
advanceIterator \
}
-#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
-const QV4::ObjectVTable classname::static_vtbl = \
-{ \
- DEFINE_MANAGED_VTABLE_INT(name), \
- call, \
- construct, \
- get, \
- getIndexed, \
- put, \
- putIndexed, \
- query, \
- queryIndexed, \
- deleteProperty, \
- deleteIndexedProperty, \
- getLookup, \
- setLookup, \
- getLength, \
- advanceIterator \
-}
-
-
struct Q_QML_PRIVATE_EXPORT Managed
{
- V4_MANAGED
+ struct Q_QML_PRIVATE_EXPORT Data : HeapObject {
+ Data() {}
+ Data(InternalClass *internal)
+ : internalClass(internal)
+ , inUse(1)
+ , extensible(1)
+ {
+ // ####
+// Q_ASSERT(internal && internal->vtable);
+ }
+ InternalClass *internalClass;
+ struct {
+ uchar markBit : 1;
+ uchar inUse : 1;
+ uchar extensible : 1; // used by Object
+ uchar _unused : 1;
+ uchar needsActivation : 1; // used by FunctionObject
+ uchar strictMode : 1; // used by FunctionObject
+ uchar bindingKeyFlag : 1;
+ uchar hasAccessorProperty : 1;
+ uchar _type;
+ mutable uchar subtype;
+ uchar _flags;
+ };
+
+ void setVTable(const ManagedVTable *vt);
+ ReturnedValue asReturnedValue() const {
+ return reinterpret_cast<Managed *>(const_cast<Data *>(this))->asReturnedValue();
+ }
+
+ void *operator new(size_t, Managed *m) { return m; }
+ void *operator new(size_t, Managed::Data *m) { return m; }
+ };
+ Data data;
+ V4_MANAGED(Managed)
enum {
IsExecutionContext = false,
IsString = false,
@@ -205,17 +237,13 @@ private:
protected:
Managed(InternalClass *internal)
- : internalClass(internal), _data(0)
+ : data(internal)
{
- Q_ASSERT(internalClass && internalClass->vtable);
- inUse = 1; extensible = 1;
}
public:
void *operator new(size_t size, MemoryManager *mm);
void *operator new(size_t, Managed *m) { return m; }
- void operator delete(void *ptr);
- void operator delete(void *ptr, MemoryManager *mm);
inline void mark(QV4::ExecutionEngine *engine);
@@ -248,12 +276,18 @@ public:
template <typename T>
T *as() {
// ### FIXME:
- if (!this || !internalClass)
+ if (!this || !internalClass())
return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
#endif
- return internalClass->vtable == T::staticVTable() ? static_cast<T *>(this) : 0;
+ const ManagedVTable *vt = internalClass()->vtable;
+ while (vt) {
+ if (vt == T::staticVTable())
+ return static_cast<T *>(this);
+ vt = vt->parent;
+ }
+ return 0;
}
template <typename T>
const T *as() const {
@@ -263,24 +297,30 @@ public:
#if !defined(QT_NO_QOBJECT_CHECK)
static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
#endif
- return internalClass->vtable == T::staticVTable() ? static_cast<const T *>(this) : 0;
+ const ManagedVTable *vt = internalClass()->vtable;
+ while (vt) {
+ if (vt == T::staticVTable())
+ return static_cast<T *>(this);
+ vt = vt->parent;
+ }
+ return 0;
}
- String *asString() { return internalClass->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
- Object *asObject() { return internalClass->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
- ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
- FunctionObject *asFunctionObject() { return internalClass->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
- BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
- NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
- StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
- DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
- ErrorObject *asErrorObject() { return internalClass->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
- ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+ String *asString() { return internalClass()->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
+ Object *asObject() { return internalClass()->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
+ ArrayObject *asArrayObject() { return internalClass()->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+ FunctionObject *asFunctionObject() { return internalClass()->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+ BooleanObject *asBooleanObject() { return internalClass()->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+ NumberObject *asNumberObject() { return internalClass()->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+ StringObject *asStringObject() { return internalClass()->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+ DateObject *asDateObject() { return internalClass()->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+ ErrorObject *asErrorObject() { return internalClass()->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+ ArgumentsObject *asArgumentsObject() { return internalClass()->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
- bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
+ bool isListType() const { return internalClass()->vtable->type == Type_QmlSequence; }
- bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
- bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
+ bool isArrayObject() const { return internalClass()->vtable->type == Type_ArrayObject; }
+ bool isStringObject() const { return internalClass()->vtable->type == Type_StringObject; }
QString className() const;
@@ -297,33 +337,22 @@ public:
void setVTable(const ManagedVTable *vt);
bool isEqualTo(Managed *other)
- { return internalClass->vtable->isEqualTo(this, other); }
+ { return internalClass()->vtable->isEqualTo(this, other); }
- static void destroy(Managed *that) { that->_data = 0; }
static bool isEqualTo(Managed *m, Managed *other);
ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
+ InternalClass *internalClass() const { return d()->internalClass; }
+ void setInternalClass(InternalClass *ic) { d()->internalClass = ic; }
- InternalClass *internalClass;
+ uchar subtype() const { return d()->subtype; }
+ void setSubtype(uchar subtype) const { d()->subtype = subtype; }
- union {
- uint _data;
- struct {
- uchar markBit : 1;
- uchar inUse : 1;
- uchar extensible : 1; // used by Object
- uchar _unused : 1;
- uchar needsActivation : 1; // used by FunctionObject
- uchar strictMode : 1; // used by FunctionObject
- uchar bindingKeyFlag : 1;
- uchar hasAccessorProperty : 1;
- uchar _type;
- mutable uchar subtype;
- uchar _flags;
- };
- };
+ bool inUse() const { return d()->inUse; }
+ bool markBit() const { return d()->markBit; }
+ static void destroy(Managed *) {}
private:
friend class MemoryManager;
friend struct Identifiers;
@@ -358,69 +387,6 @@ inline FunctionObject *managed_cast(Managed *m)
return m->asFunctionObject();
}
-
-Value *extractValuePointer(const ScopedValue &);
-template<typename T>
-Value *extractValuePointer(const Scoped<T> &);
-
-#define DEFINE_REF_METHODS(Class, Base) \
- Class##Ref(const QV4::ScopedValue &v) \
- { QV4::Value *val = extractValuePointer(v); ptr = QV4::value_cast<Class>(*val) ? val : 0; } \
- Class##Ref(const QV4::Scoped<Class> &v) { ptr = extractValuePointer(v); } \
- Class##Ref(QV4::TypedValue<Class> &v) { ptr = &v; } \
- Class##Ref(QV4::Value &v) { ptr = QV4::value_cast<Class>(v) ? &v : 0; } \
- Class##Ref &operator=(Class *t) { \
- if (sizeof(void *) == 4) \
- ptr->tag = QV4::Value::Managed_Type; \
- ptr->m = t; \
- return *this; \
- } \
- Class##Ref &operator=(QV4::Returned<Class> *t) { \
- if (sizeof(void *) == 4) \
- ptr->tag = QV4::Value::Managed_Type; \
- ptr->m = t->getPointer(); \
- return *this; \
- } \
- operator const Class *() const { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
- const Class *operator->() const { return static_cast<Class*>(ptr->managed()); } \
- operator Class *() { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
- Class *operator->() { return static_cast<Class*>(ptr->managed()); } \
- Class *getPointer() const { return static_cast<Class *>(ptr->managed()); } \
- operator QV4::Returned<Class> *() const { return ptr ? QV4::Returned<Class>::create(getPointer()) : 0; } \
- static Class##Ref null() { Class##Ref c; c.ptr = 0; return c; } \
-protected: \
- Class##Ref() {} \
-public: \
-
-#define DEFINE_REF(Class, Base) \
-struct Class##Ref : public Base##Ref \
-{ DEFINE_REF_METHODS(Class, Base) } \
-
-
-struct ManagedRef {
- // Important: Do NOT add a copy constructor to this class or any derived class
- // adding a copy constructor actually changes the calling convention, ie.
- // is not even binary compatible. Adding it would break assumptions made
- // in the jit'ed code.
- DEFINE_REF_METHODS(Managed, Managed);
-
- bool operator==(const ManagedRef &other) {
- if (ptr == other.ptr)
- return true;
- return ptr && other.ptr && ptr->m == other.ptr->m;
- }
- bool operator!=(const ManagedRef &other) {
- return !operator==(other);
- }
- bool operator!() const { return !ptr || !ptr->managed(); }
-
- bool isNull() const { return !ptr; }
- ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
-
-public:
- Value *ptr;
-};
-
}
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 16d76e6914..3b8100c3fb 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -55,39 +55,39 @@ DEFINE_OBJECT_VTABLE(MathObject);
static const double qt_PI = 2.0 * ::asin(1.0);
-MathObject::MathObject(InternalClass *ic)
- : Object(ic)
+MathObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
Scope scope(ic->engine);
- ScopedObject protectThis(scope, this);
-
- defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
- defineReadonlyProperty(QStringLiteral("LN2"), Primitive::fromDouble(::log(2.0)));
- defineReadonlyProperty(QStringLiteral("LN10"), Primitive::fromDouble(::log(10.0)));
- defineReadonlyProperty(QStringLiteral("LOG2E"), Primitive::fromDouble(1.0/::log(2.0)));
- defineReadonlyProperty(QStringLiteral("LOG10E"), Primitive::fromDouble(1.0/::log(10.0)));
- defineReadonlyProperty(QStringLiteral("PI"), Primitive::fromDouble(qt_PI));
- defineReadonlyProperty(QStringLiteral("SQRT1_2"), Primitive::fromDouble(::sqrt(0.5)));
- defineReadonlyProperty(QStringLiteral("SQRT2"), Primitive::fromDouble(::sqrt(2.0)));
-
- defineDefaultProperty(QStringLiteral("abs"), method_abs, 1);
- defineDefaultProperty(QStringLiteral("acos"), method_acos, 1);
- defineDefaultProperty(QStringLiteral("asin"), method_asin, 0);
- defineDefaultProperty(QStringLiteral("atan"), method_atan, 1);
- defineDefaultProperty(QStringLiteral("atan2"), method_atan2, 2);
- defineDefaultProperty(QStringLiteral("ceil"), method_ceil, 1);
- defineDefaultProperty(QStringLiteral("cos"), method_cos, 1);
- defineDefaultProperty(QStringLiteral("exp"), method_exp, 1);
- defineDefaultProperty(QStringLiteral("floor"), method_floor, 1);
- defineDefaultProperty(QStringLiteral("log"), method_log, 1);
- defineDefaultProperty(QStringLiteral("max"), method_max, 2);
- defineDefaultProperty(QStringLiteral("min"), method_min, 2);
- defineDefaultProperty(QStringLiteral("pow"), method_pow, 2);
- defineDefaultProperty(QStringLiteral("random"), method_random, 0);
- defineDefaultProperty(QStringLiteral("round"), method_round, 1);
- defineDefaultProperty(QStringLiteral("sin"), method_sin, 1);
- defineDefaultProperty(QStringLiteral("sqrt"), method_sqrt, 1);
- defineDefaultProperty(QStringLiteral("tan"), method_tan, 1);
+ ScopedObject m(scope, this);
+
+ m->defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
+ m->defineReadonlyProperty(QStringLiteral("LN2"), Primitive::fromDouble(::log(2.0)));
+ m->defineReadonlyProperty(QStringLiteral("LN10"), Primitive::fromDouble(::log(10.0)));
+ m->defineReadonlyProperty(QStringLiteral("LOG2E"), Primitive::fromDouble(1.0/::log(2.0)));
+ m->defineReadonlyProperty(QStringLiteral("LOG10E"), Primitive::fromDouble(1.0/::log(10.0)));
+ m->defineReadonlyProperty(QStringLiteral("PI"), Primitive::fromDouble(qt_PI));
+ m->defineReadonlyProperty(QStringLiteral("SQRT1_2"), Primitive::fromDouble(::sqrt(0.5)));
+ m->defineReadonlyProperty(QStringLiteral("SQRT2"), Primitive::fromDouble(::sqrt(2.0)));
+
+ m->defineDefaultProperty(QStringLiteral("abs"), method_abs, 1);
+ m->defineDefaultProperty(QStringLiteral("acos"), method_acos, 1);
+ m->defineDefaultProperty(QStringLiteral("asin"), method_asin, 0);
+ m->defineDefaultProperty(QStringLiteral("atan"), method_atan, 1);
+ m->defineDefaultProperty(QStringLiteral("atan2"), method_atan2, 2);
+ m->defineDefaultProperty(QStringLiteral("ceil"), method_ceil, 1);
+ m->defineDefaultProperty(QStringLiteral("cos"), method_cos, 1);
+ m->defineDefaultProperty(QStringLiteral("exp"), method_exp, 1);
+ m->defineDefaultProperty(QStringLiteral("floor"), method_floor, 1);
+ m->defineDefaultProperty(QStringLiteral("log"), method_log, 1);
+ m->defineDefaultProperty(QStringLiteral("max"), method_max, 2);
+ m->defineDefaultProperty(QStringLiteral("min"), method_min, 2);
+ m->defineDefaultProperty(QStringLiteral("pow"), method_pow, 2);
+ m->defineDefaultProperty(QStringLiteral("random"), method_random, 0);
+ m->defineDefaultProperty(QStringLiteral("round"), method_round, 1);
+ m->defineDefaultProperty(QStringLiteral("sin"), method_sin, 1);
+ m->defineDefaultProperty(QStringLiteral("sqrt"), method_sqrt, 1);
+ m->defineDefaultProperty(QStringLiteral("tan"), method_tan, 1);
}
/* copies the sign from y to x and returns the result */
@@ -104,15 +104,15 @@ static double copySign(double x, double y)
ReturnedValue MathObject::method_abs(CallContext *context)
{
- if (!context->callData->argc)
+ if (!context->d()->callData->argc)
return Encode(qSNaN());
- if (context->callData->args[0].isInteger()) {
- int i = context->callData->args[0].integerValue();
+ if (context->d()->callData->args[0].isInteger()) {
+ int i = context->d()->callData->args[0].integerValue();
return Encode(i < 0 ? - i : i);
}
- double v = context->callData->args[0].toNumber();
+ double v = context->d()->callData->args[0].toNumber();
if (v == 0) // 0 | -0
return Encode(0);
@@ -121,7 +121,7 @@ ReturnedValue MathObject::method_abs(CallContext *context)
ReturnedValue MathObject::method_acos(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : 2;
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : 2;
if (v > 1)
return Encode(qSNaN());
@@ -130,7 +130,7 @@ ReturnedValue MathObject::method_acos(CallContext *context)
ReturnedValue MathObject::method_asin(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : 2;
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : 2;
if (v > 1)
return Encode(qSNaN());
else
@@ -139,7 +139,7 @@ ReturnedValue MathObject::method_asin(CallContext *context)
ReturnedValue MathObject::method_atan(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
if (v == 0.0)
return Encode(v);
else
@@ -148,8 +148,8 @@ ReturnedValue MathObject::method_atan(CallContext *context)
ReturnedValue MathObject::method_atan2(CallContext *context)
{
- double v1 = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
- double v2 = context->callData->argc > 1 ? context->callData->args[1].toNumber() : qSNaN();
+ double v1 = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
+ double v2 = context->d()->callData->argc > 1 ? context->d()->callData->args[1].toNumber() : qSNaN();
if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0))
return Encode(copySign(0, -1.0));
@@ -166,7 +166,7 @@ ReturnedValue MathObject::method_atan2(CallContext *context)
ReturnedValue MathObject::method_ceil(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
if (v < 0.0 && v > -1.0)
return Encode(copySign(0, -1.0));
else
@@ -175,13 +175,13 @@ ReturnedValue MathObject::method_ceil(CallContext *context)
ReturnedValue MathObject::method_cos(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
return Encode(::cos(v));
}
ReturnedValue MathObject::method_exp(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
if (qIsInf(v)) {
if (copySign(1.0, v) == -1.0)
return Encode(0);
@@ -194,13 +194,13 @@ ReturnedValue MathObject::method_exp(CallContext *context)
ReturnedValue MathObject::method_floor(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
return Encode(::floor(v));
}
ReturnedValue MathObject::method_log(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
if (v < 0)
return Encode(qSNaN());
else
@@ -210,8 +210,8 @@ ReturnedValue MathObject::method_log(CallContext *context)
ReturnedValue MathObject::method_max(CallContext *context)
{
double mx = -qInf();
- for (int i = 0; i < context->callData->argc; ++i) {
- double x = context->callData->args[i].toNumber();
+ for (int i = 0; i < context->d()->callData->argc; ++i) {
+ double x = context->d()->callData->args[i].toNumber();
if (x > mx || std::isnan(x))
mx = x;
}
@@ -221,8 +221,8 @@ ReturnedValue MathObject::method_max(CallContext *context)
ReturnedValue MathObject::method_min(CallContext *context)
{
double mx = qInf();
- for (int i = 0; i < context->callData->argc; ++i) {
- double x = context->callData->args[i].toNumber();
+ for (int i = 0; i < context->d()->callData->argc; ++i) {
+ double x = context->d()->callData->args[i].toNumber();
if ((x == 0 && mx == x && copySign(1.0, x) == -1.0)
|| (x < mx) || std::isnan(x)) {
mx = x;
@@ -233,8 +233,8 @@ ReturnedValue MathObject::method_min(CallContext *context)
ReturnedValue MathObject::method_pow(CallContext *context)
{
- double x = context->callData->argc > 0 ? context->callData->args[0].toNumber() : qSNaN();
- double y = context->callData->argc > 1 ? context->callData->args[1].toNumber() : qSNaN();
+ double x = context->d()->callData->argc > 0 ? context->d()->callData->args[0].toNumber() : qSNaN();
+ double y = context->d()->callData->argc > 1 ? context->d()->callData->args[1].toNumber() : qSNaN();
if (std::isnan(y))
return Encode(qSNaN());
@@ -294,26 +294,26 @@ ReturnedValue MathObject::method_random(CallContext *context)
ReturnedValue MathObject::method_round(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
v = copySign(::floor(v + 0.5), v);
return Encode(v);
}
ReturnedValue MathObject::method_sin(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
return Encode(::sin(v));
}
ReturnedValue MathObject::method_sqrt(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
return Encode(::sqrt(v));
}
ReturnedValue MathObject::method_tan(CallContext *context)
{
- double v = context->callData->argc ? context->callData->args[0].toNumber() : qSNaN();
+ double v = context->d()->callData->argc ? context->d()->callData->args[0].toNumber() : qSNaN();
if (v == 0.0)
return Encode(v);
else
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index 18a80c2ba0..65366aab86 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -49,9 +49,12 @@ namespace QV4 {
struct MathObject: Object
{
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(InternalClass *ic);
+ };
+
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(MathObject)
- MathObject(InternalClass *ic);
static ReturnedValue method_abs(CallContext *context);
static ReturnedValue method_acos(CallContext *context);
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index aeb4c38a8e..7eca47c3ce 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -44,29 +44,13 @@
using namespace QV4;
-const ManagedVTable MemberData::static_vtbl =
-{
- MemberData::IsExecutionContext,
- MemberData::IsString,
- MemberData::IsObject,
- MemberData::IsFunctionObject,
- MemberData::IsErrorObject,
- MemberData::IsArrayData,
- 0,
- MemberData::MyType,
- "MemberData",
- destroy,
- markObjects,
- isEqualTo
-};
-
-
+DEFINE_MANAGED_VTABLE(MemberData);
void MemberData::markObjects(Managed *that, ExecutionEngine *e)
{
MemberData *m = static_cast<MemberData *>(that);
- for (uint i = 0; i < m->size; ++i)
- m->data[i].mark(e);
+ for (uint i = 0; i < m->d()->size; ++i)
+ m->d()->data[i].mark(e);
}
void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
@@ -74,13 +58,13 @@ void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
uint s = size();
if (idx >= s) {
int newAlloc = qMax((uint)4, 2*idx);
- uint alloc = sizeof(MemberData) + (newAlloc)*sizeof(Value);
- MemberData *newMemberData = reinterpret_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
+ uint alloc = sizeof(MemberData::Data) + (newAlloc)*sizeof(Value);
+ MemberData *newMemberData = static_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
if (d())
- memcpy(newMemberData, d(), sizeof(MemberData) + s*sizeof(Value));
+ memcpy(newMemberData, d(), sizeof(MemberData::Data) + s*sizeof(Value));
else
new (newMemberData) MemberData(e->memberDataClass);
- newMemberData->size = newAlloc;
+ newMemberData->d()->size = newAlloc;
m = newMemberData;
}
}
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index 03aa75a365..cd8667adb7 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -50,23 +50,29 @@ namespace QV4 {
struct MemberData : Managed
{
- V4_MANAGED
- uint size;
- Value data[1];
+ struct Data : Managed::Data {
+ union {
+ uint size;
+ double _dummy;
+ };
+ Value data[1];
+ };
+ V4_MANAGED(Managed)
MemberData(QV4::InternalClass *ic) : Managed(ic) {}
- Value &operator[] (uint idx) { return data[idx]; }
+ Value &operator[] (uint idx) { return d()->data[idx]; }
static void markObjects(Managed *that, ExecutionEngine *e);
};
struct Members : Value
{
+ void reset() { m = 0; }
void ensureIndex(QV4::ExecutionEngine *e, uint idx);
- Value &operator[] (uint idx) const { return static_cast<MemberData *>(managed())->data[idx]; }
- inline uint size() const { return d() ? d()->size : 0; }
+ Value &operator[] (uint idx) const { return static_cast<MemberData *>(managed())->d()->data[idx]; }
+ inline uint size() const { return d() ? d()->d()->size : 0; }
inline MemberData *d() const { return static_cast<MemberData *>(managed()); }
- Value *data() const { return static_cast<MemberData *>(managed())->data; }
+ Value *data() const { return static_cast<MemberData *>(managed())->d()->data; }
void mark(ExecutionEngine *e) const {
MemberData *m = d();
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index ca2ccd33f7..3e7ac17078 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -57,6 +57,7 @@
#include <cstdlib>
#include <algorithm>
#include "qv4alloca_p.h"
+#include "qv4profiling_p.h"
#ifdef V4_USE_VALGRIND
#include <valgrind/valgrind.h>
@@ -102,6 +103,7 @@ struct MemoryManager::Data
struct LargeItem {
LargeItem *next;
+ size_t size;
void *data;
Managed *managed() {
@@ -149,8 +151,10 @@ struct MemoryManager::Data
~Data()
{
- for (QVector<Chunk>::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i)
+ for (QVector<Chunk>::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) {
+ Q_V4_PROFILE_DEALLOC(engine, 0, i->memory.size(), Profiling::HeapPage);
i->memory.deallocate();
+ }
}
};
@@ -174,7 +178,7 @@ MemoryManager::MemoryManager()
#endif
}
-Managed *MemoryManager::alloc(std::size_t size)
+Managed *MemoryManager::allocData(std::size_t size)
{
if (m_d->aggressiveGC)
runGC();
@@ -190,9 +194,12 @@ Managed *MemoryManager::alloc(std::size_t size)
// doesn't fit into a small bucket
if (size >= MemoryManager::Data::MaxItemSize) {
// we use malloc for this
- MemoryManager::Data::LargeItem *item = static_cast<MemoryManager::Data::LargeItem *>(malloc(size + sizeof(MemoryManager::Data::LargeItem)));
+ 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;
return item->managed();
}
@@ -218,7 +225,9 @@ Managed *MemoryManager::alloc(std::size_t size)
std::size_t allocSize = m_d->maxChunkSize*(size_t(1) << shift);
allocSize = roundUpToMultipleOf(WTF::pageSize(), allocSize);
Data::Chunk allocation;
- allocation.memory = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages);
+ allocation.memory = PageAllocation::allocate(
+ Q_V4_PROFILE_ALLOC(m_d->engine, allocSize, Profiling::HeapPage),
+ OSAllocator::JSGCHeapPages);
allocation.chunkSize = int(size);
m_d->heapChunks.append(allocation);
std::sort(m_d->heapChunks.begin(), m_d->heapChunks.end());
@@ -228,7 +237,6 @@ Managed *MemoryManager::alloc(std::size_t size)
Managed **last = &m_d->smallItems[pos];
while (chunk <= end) {
Managed *o = reinterpret_cast<Managed *>(chunk);
- o->_data = 0;
*last = o;
last = o->nextFreeRef();
chunk += size;
@@ -247,6 +255,7 @@ Managed *MemoryManager::alloc(std::size_t size)
#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;
@@ -308,8 +317,8 @@ void MemoryManager::mark()
// now that we marked all roots, start marking recursively and popping from the mark stack
while (m_d->engine->jsStackTop > markBase) {
Managed *m = m_d->engine->popForGC();
- Q_ASSERT (m->internalClass->vtable->markObjects);
- m->internalClass->vtable->markObjects(m, m_d->engine);
+ Q_ASSERT (m->internalClass()->vtable->markObjects);
+ m->internalClass()->vtable->markObjects(m, m_d->engine);
}
}
@@ -325,7 +334,7 @@ void MemoryManager::sweep(bool lastSweep)
continue;
}
if (Managed *m = weak->value.asManaged()) {
- if (!m->markBit) {
+ if (!m->markBit()) {
weak->value = Primitive::undefinedValue();
PersistentValuePrivate *n = weak->next;
weak->removeFromList();
@@ -338,7 +347,7 @@ void MemoryManager::sweep(bool lastSweep)
if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = m_d->engine->m_multiplyWrappedQObjects) {
for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
- if (!it.value()->markBit)
+ if (!it.value()->markBit())
it = multiplyWrappedQObjects->erase(it);
else
++it;
@@ -352,18 +361,19 @@ void MemoryManager::sweep(bool lastSweep)
Data::LargeItem **last = &m_d->largeItems;
while (i) {
Managed *m = i->managed();
- Q_ASSERT(m->inUse);
- if (m->markBit) {
- m->markBit = 0;
+ Q_ASSERT(m->inUse());
+ if (m->markBit()) {
+ m->d()->markBit = 0;
last = &i->next;
i = i->next;
continue;
}
- if (m->internalClass->vtable->destroy)
- m->internalClass->vtable->destroy(m);
+ if (m->internalClass()->vtable->destroy)
+ m->internalClass()->vtable->destroy(m);
*last = i->next;
- free(i);
+ free(Q_V4_PROFILE_DEALLOC(m_d->engine, i, i->size + sizeof(Data::LargeItem),
+ Profiling::LargeItem));
i = *last;
}
@@ -392,16 +402,16 @@ void MemoryManager::sweep(char *chunkStart, std::size_t chunkSize, size_t size)
Q_ASSERT((qintptr) chunk % 16 == 0);
- if (m->inUse) {
- if (m->markBit) {
- m->markBit = 0;
+ if (m->inUse()) {
+ if (m->markBit()) {
+ m->d()->markBit = 0;
} else {
// qDebug() << "-- collecting it." << m << *f << m->nextFree();
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
- if (m->internalClass->vtable->destroy)
- m->internalClass->vtable->destroy(m);
+ if (m->internalClass()->vtable->destroy)
+ m->internalClass()->vtable->destroy(m);
memset(m, 0, size);
m->setNextFree(*f);
@@ -409,6 +419,7 @@ void MemoryManager::sweep(char *chunkStart, std::size_t chunkSize, size_t size)
VALGRIND_DISABLE_ERROR_REPORTING;
VALGRIND_MEMPOOL_FREE(this, m);
#endif
+ Q_V4_PROFILE_DEALLOC(m_d->engine, m, size, Profiling::SmallItem);
*f = m;
}
}
@@ -439,9 +450,7 @@ void MemoryManager::runGC()
mark();
sweep();
} else {
- int totalMem = 0;
- for (int i = 0; i < m_d->heapChunks.size(); ++i)
- totalMem += m_d->heapChunks.at(i).memory.size();
+ int totalMem = getAllocatedMem();
QTime t;
t.start();
@@ -467,22 +476,38 @@ void MemoryManager::runGC()
m_d->totalAlloc = 0;
}
-uint MemoryManager::getUsedMem()
+size_t MemoryManager::getUsedMem() const
{
- uint usedMem = 0;
- for (QVector<Data::Chunk>::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) {
+ size_t usedMem = 0;
+ for (QVector<Data::Chunk>::const_iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) {
char *chunkStart = reinterpret_cast<char *>(i->memory.base());
char *chunkEnd = chunkStart + i->memory.size() - i->chunkSize;
for (char *chunk = chunkStart; chunk <= chunkEnd; chunk += i->chunkSize) {
Managed *m = reinterpret_cast<Managed *>(chunk);
Q_ASSERT((qintptr) chunk % 16 == 0);
- if (m->inUse)
+ if (m->inUse())
usedMem += i->chunkSize;
}
}
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).memory.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()
{
PersistentValuePrivate *persistent = m_persistentValues;
@@ -526,11 +551,6 @@ void MemoryManager::registerDeletable(GCDeletable *d)
m_d->deletable = d;
}
-ExecutionEngine *MemoryManager::engine() const
-{
- return m_d->engine;
-}
-
#ifdef DETAILED_MM_STATS
void MemoryManager::willAllocate(std::size_t size)
{
@@ -545,11 +565,11 @@ void MemoryManager::willAllocate(std::size_t size)
void MemoryManager::collectFromJSStack() const
{
- Value *v = engine()->jsStackBase;
- Value *top = engine()->jsStackTop;
+ Value *v = m_d->engine->jsStackBase;
+ Value *top = m_d->engine->jsStackTop;
while (v < top) {
Managed *m = v->asManaged();
- if (m && m->inUse)
+ if (m && m->inUse())
// Skip pointers to already freed objects, they are bogus as well
m->mark(m_d->engine);
++v;
diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h
index 47020c12f0..f0025dc70e 100644
--- a/src/qml/jsruntime/qv4mm_p.h
+++ b/src/qml/jsruntime/qv4mm_p.h
@@ -99,10 +99,58 @@ public:
inline Managed *allocManaged(std::size_t size)
{
size = align(size);
- Managed *o = alloc(size);
+ Managed *o = allocData(size);
return o;
}
+ template <typename ManagedType>
+ ManagedType *alloc()
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data();
+ return t;
+ }
+
+ template <typename ManagedType, typename Arg1>
+ ManagedType *alloc(Arg1 arg1)
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data(arg1);
+ return t;
+ }
+
+ template <typename ManagedType, typename Arg1, typename Arg2>
+ ManagedType *alloc(Arg1 arg1, Arg2 arg2)
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data(arg1, arg2);
+ return t;
+ }
+
+ template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3>
+ ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3);
+ return t;
+ }
+
+ template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+ ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4);
+ return t;
+ }
+
+ template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+ ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
+ {
+ ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5);
+ return t;
+ }
+
bool isGCBlocked() const;
void setGCBlocked(bool blockGC);
void runGC();
@@ -113,12 +161,14 @@ public:
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
- Managed *alloc(std::size_t size);
-
- ExecutionEngine *engine() const;
+ Managed *allocData(std::size_t size);
#ifdef DETAILED_MM_STATS
void willAllocate(std::size_t size);
@@ -129,7 +179,6 @@ private:
void mark();
void sweep(bool lastSweep = false);
void sweep(char *chunkStart, std::size_t chunkSize, size_t size);
- uint getUsedMem();
protected:
QScopedPointer<Data> m_d;
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index c97e86f2cd..f1bac1109a 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -51,8 +51,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(NumberCtor);
DEFINE_OBJECT_VTABLE(NumberObject);
-NumberCtor::NumberCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Number"))
+NumberCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Number"))
{
setVTable(staticVTable());
}
@@ -71,7 +71,7 @@ ReturnedValue NumberCtor::call(Managed *, CallData *callData)
return Encode(dbl);
}
-void NumberPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -103,40 +103,40 @@ void NumberPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
inline ReturnedValue thisNumberValue(ExecutionContext *ctx)
{
- if (ctx->callData->thisObject.isNumber())
- return ctx->callData->thisObject.asReturnedValue();
- NumberObject *n = ctx->callData->thisObject.asNumberObject();
+ if (ctx->d()->callData->thisObject.isNumber())
+ return ctx->d()->callData->thisObject.asReturnedValue();
+ NumberObject *n = ctx->d()->callData->thisObject.asNumberObject();
if (!n)
return ctx->throwTypeError();
- return n->value.asReturnedValue();
+ return n->value().asReturnedValue();
}
inline double thisNumber(ExecutionContext *ctx)
{
- if (ctx->callData->thisObject.isNumber())
- return ctx->callData->thisObject.asDouble();
- NumberObject *n = ctx->callData->thisObject.asNumberObject();
+ if (ctx->d()->callData->thisObject.isNumber())
+ return ctx->d()->callData->thisObject.asDouble();
+ NumberObject *n = ctx->d()->callData->thisObject.asNumberObject();
if (!n)
return ctx->throwTypeError();
- return n->value.asDouble();
+ return n->value().asDouble();
}
ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
{
double num = thisNumber(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
- if (ctx->callData->argc && !ctx->callData->args[0].isUndefined()) {
- int radix = ctx->callData->args[0].toInt32();
+ if (ctx->d()->callData->argc && !ctx->d()->callData->args[0].isUndefined()) {
+ int radix = ctx->d()->callData->args[0].toInt32();
if (radix < 2 || radix > 36)
return ctx->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
if (std::isnan(num)) {
- return ctx->engine->newString(QStringLiteral("NaN"))->asReturnedValue();
+ return ctx->d()->engine->newString(QStringLiteral("NaN"))->asReturnedValue();
} else if (qIsInf(num)) {
- return ctx->engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))->asReturnedValue();
+ return ctx->d()->engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))->asReturnedValue();
}
if (radix != 10) {
@@ -166,7 +166,7 @@ ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
}
if (negative)
str.prepend(QLatin1Char('-'));
- return ctx->engine->newString(str)->asReturnedValue();
+ return ctx->d()->engine->newString(str)->asReturnedValue();
}
}
@@ -178,7 +178,7 @@ ReturnedValue NumberPrototype::method_toLocaleString(CallContext *ctx)
Scope scope(ctx);
ScopedValue v(scope, thisNumberValue(ctx));
ScopedString str(scope, v->toString(ctx));
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
return str.asReturnedValue();
}
@@ -191,19 +191,19 @@ ReturnedValue NumberPrototype::method_valueOf(CallContext *ctx)
ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
{
double v = thisNumber(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
double fdigits = 0;
- if (ctx->callData->argc > 0)
- fdigits = ctx->callData->args[0].toInteger();
+ if (ctx->d()->callData->argc > 0)
+ fdigits = ctx->d()->callData->args[0].toInteger();
if (std::isnan(fdigits))
fdigits = 0;
if (fdigits < 0 || fdigits > 20)
- return ctx->throwRangeError(ctx->callData->thisObject);
+ return ctx->throwRangeError(ctx->d()->callData->thisObject);
QString str;
if (std::isnan(v))
@@ -214,22 +214,22 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
str = QString::number(v, 'f', int (fdigits));
else
return RuntimeHelpers::stringFromNumber(ctx, v)->asReturnedValue();
- return ctx->engine->newString(str)->asReturnedValue();
+ return ctx->d()->engine->newString(str)->asReturnedValue();
}
ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
{
Scope scope(ctx);
double d = thisNumber(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
int fdigits = -1;
- if (ctx->callData->argc && !ctx->callData->args[0].isUndefined()) {
- fdigits = ctx->callData->args[0].toInt32();
+ if (ctx->d()->callData->argc && !ctx->d()->callData->args[0].isUndefined()) {
+ fdigits = ctx->d()->callData->args[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
- ScopedString error(scope, ctx->engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
+ ScopedString error(scope, ctx->d()->engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
return ctx->throwRangeError(error);
}
}
@@ -239,22 +239,22 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToExponential(d, fdigits, &builder);
QString result = QString::fromLatin1(builder.Finalize());
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
{
Scope scope(ctx);
ScopedValue v(scope, thisNumberValue(ctx));
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
- if (!ctx->callData->argc || ctx->callData->args[0].isUndefined())
+ if (!ctx->d()->callData->argc || ctx->d()->callData->args[0].isUndefined())
return RuntimeHelpers::toString(ctx, v);
- double precision = ctx->callData->args[0].toInt32();
+ double precision = ctx->d()->callData->args[0].toInt32();
if (precision < 1 || precision > 21) {
- ScopedString error(scope, ctx->engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
+ ScopedString error(scope, ctx->d()->engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
return ctx->throwRangeError(error);
}
@@ -263,5 +263,5 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToPrecision(v->asDouble(), precision, &builder);
QString result = QString::fromLatin1(builder.Finalize());
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index ccabcf6727..3e776f0f2f 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -51,8 +51,10 @@ namespace QV4 {
struct NumberCtor: FunctionObject
{
- V4_OBJECT
- NumberCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *that, CallData *callData);
static ReturnedValue call(Managed *, CallData *callData);
@@ -60,8 +62,7 @@ struct NumberCtor: FunctionObject
struct NumberPrototype: NumberObject
{
- NumberPrototype(InternalClass *ic): NumberObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_toString(CallContext *ctx);
static ReturnedValue method_toLocaleString(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index c8d360d511..e0f05a65f8 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -70,29 +70,16 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(Object);
-Object::Object(ExecutionEngine *engine)
- : Managed(engine->objectClass)
+Object::Data::Data(InternalClass *internalClass)
+ : Managed::Data(internalClass)
{
-}
-
-Object::Object(InternalClass *ic)
- : Managed(ic)
-{
- Q_ASSERT(internalClass->vtable && internalClass->vtable != &Managed::static_vtbl);
-
- Q_ASSERT(!memberData.d());
if (internalClass->size) {
- Scope scope(engine());
- ScopedObject protectThis(scope, this);
- memberData.ensureIndex(engine(), internalClass->size);
+ Scope scope(internalClass->engine);
+ ScopedObject o(scope, this);
+ o->memberData().ensureIndex(internalClass->engine, internalClass->size);
}
}
-Object::~Object()
-{
- _data = 0;
-}
-
bool Object::setPrototype(Object *proto)
{
Object *pp = proto;
@@ -101,20 +88,15 @@ bool Object::setPrototype(Object *proto)
return false;
pp = pp->prototype();
}
- internalClass = internalClass->changePrototype(proto);
+ setInternalClass(internalClass()->changePrototype(proto));
return true;
}
-void Object::destroy(Managed *that)
-{
- static_cast<Object *>(that)->~Object();
-}
-
void Object::put(ExecutionContext *ctx, const QString &name, const ValueRef value)
{
Scope scope(ctx);
- ScopedString n(scope, ctx->engine->newString(name));
- put(n, value);
+ ScopedString n(scope, ctx->d()->engine->newString(name));
+ put(n.getPointer(), value);
}
ReturnedValue Object::getValue(const ValueRef thisObject, const Property *p, PropertyAttributes attrs)
@@ -133,7 +115,7 @@ ReturnedValue Object::getValue(const ValueRef thisObject, const Property *p, Pro
void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef value)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return;
if (attrs.isAccessor()) {
@@ -155,7 +137,7 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef val
return;
reject:
- if (engine()->currentContext()->strictMode)
+ if (engine()->currentContext()->d()->strictMode)
engine()->currentContext()->throwTypeError();
}
@@ -164,7 +146,7 @@ void Object::defineDefaultProperty(const QString &name, ValueRef value)
ExecutionEngine *e = engine();
Scope scope(e);
ScopedString s(scope, e->newIdentifier(name));
- defineDefaultProperty(s, value);
+ defineDefaultProperty(s.getPointer(), value);
}
void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount)
@@ -172,16 +154,16 @@ void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(Ca
ExecutionEngine *e = engine();
Scope scope(e);
ScopedString s(scope, e->newIdentifier(name));
- Scoped<FunctionObject> function(scope, e->newBuiltinFunction(e->rootContext, s, code));
+ Scoped<FunctionObject> function(scope, BuiltinFunction::create(e->rootContext, s.getPointer(), code));
function->defineReadonlyProperty(e->id_length, Primitive::fromInt32(argumentCount));
- defineDefaultProperty(s, function);
+ defineDefaultProperty(s.getPointer(), function);
}
-void Object::defineDefaultProperty(const StringRef name, ReturnedValue (*code)(CallContext *), int argumentCount)
+void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount)
{
ExecutionEngine *e = engine();
Scope scope(e);
- Scoped<FunctionObject> function(scope, e->newBuiltinFunction(e->rootContext, name, code));
+ Scoped<FunctionObject> function(scope, BuiltinFunction::create(e->rootContext, name, code));
function->defineReadonlyProperty(e->id_length, Primitive::fromInt32(argumentCount));
defineDefaultProperty(name, function);
}
@@ -191,16 +173,16 @@ void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)
ExecutionEngine *e = engine();
Scope scope(e);
Scoped<String> s(scope, e->newIdentifier(name));
- defineAccessorProperty(s, getter, setter);
+ defineAccessorProperty(s.getPointer(), getter, setter);
}
-void Object::defineAccessorProperty(const StringRef name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *))
+void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *))
{
ExecutionEngine *v4 = engine();
QV4::Scope scope(v4);
ScopedProperty p(scope);
- p->setGetter(getter ? v4->newBuiltinFunction(v4->rootContext, name, getter)->getPointer() : 0);
- p->setSetter(setter ? v4->newBuiltinFunction(v4->rootContext, name, setter)->getPointer() : 0);
+ p->setGetter(getter ? ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext, name, getter)).getPointer() : 0);
+ p->setSetter(setter ? ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext, name, setter)).getPointer() : 0);
insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
@@ -209,10 +191,10 @@ void Object::defineReadonlyProperty(const QString &name, ValueRef value)
QV4::ExecutionEngine *e = engine();
Scope scope(e);
ScopedString s(scope, e->newIdentifier(name));
- defineReadonlyProperty(s, value);
+ defineReadonlyProperty(s.getPointer(), value);
}
-void Object::defineReadonlyProperty(const StringRef name, ValueRef value)
+void Object::defineReadonlyProperty(String *name, ValueRef value)
{
insertMember(name, value, Attr_ReadOnly);
}
@@ -221,45 +203,45 @@ void Object::markObjects(Managed *that, ExecutionEngine *e)
{
Object *o = static_cast<Object *>(that);
- o->memberData.mark(e);
- if (o->arrayData)
- o->arrayData->mark(e);
+ o->memberData().mark(e);
+ if (o->arrayData())
+ o->arrayData()->mark(e);
}
void Object::ensureMemberIndex(uint idx)
{
- memberData.ensureIndex(engine(), idx);
+ memberData().ensureIndex(engine(), idx);
}
-void Object::insertMember(const StringRef s, const Property &p, PropertyAttributes attributes)
+void Object::insertMember(String *s, const Property &p, PropertyAttributes attributes)
{
uint idx;
- InternalClass::addMember(this, s.getPointer(), attributes, &idx);
+ InternalClass::addMember(this, s, attributes, &idx);
- ensureMemberIndex(internalClass->size);
+ ensureMemberIndex(internalClass()->size);
if (attributes.isAccessor()) {
- hasAccessorProperty = 1;
+ setHasAccessorProperty();
Property *pp = propertyAt(idx);
pp->value = p.value;
pp->set = p.set;
} else {
- memberData[idx] = p.value;
+ memberData()[idx] = p.value;
}
}
// Section 8.12.1
-Property *Object::__getOwnProperty__(const StringRef name, PropertyAttributes *attrs)
+Property *Object::__getOwnProperty__(String *name, PropertyAttributes *attrs)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
return __getOwnProperty__(idx, attrs);
- uint member = internalClass->find(name);
+ uint member = internalClass()->find(name);
if (member < UINT_MAX) {
if (attrs)
- *attrs = internalClass->propertyData[member];
+ *attrs = internalClass()->propertyData[member];
return propertyAt(member);
}
@@ -270,10 +252,10 @@ Property *Object::__getOwnProperty__(const StringRef name, PropertyAttributes *a
Property *Object::__getOwnProperty__(uint index, PropertyAttributes *attrs)
{
- Property *p = arrayData->getProperty(index);
+ Property *p = arrayData()->getProperty(index);
if (p) {
if (attrs)
- *attrs = arrayData->attributes(index);
+ *attrs = arrayData()->attributes(index);
return p;
}
if (isStringObject()) {
@@ -288,7 +270,7 @@ Property *Object::__getOwnProperty__(uint index, PropertyAttributes *attrs)
}
// Section 8.12.2
-Property *Object::__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs) const
+Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *attrs) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -297,10 +279,10 @@ Property *Object::__getPropertyDescriptor__(const StringRef name, PropertyAttrib
const Object *o = this;
while (o) {
- uint idx = o->internalClass->find(name.getPointer());
+ uint idx = o->internalClass()->find(name);
if (idx < UINT_MAX) {
if (attrs)
- *attrs = o->internalClass->propertyData[idx];
+ *attrs = o->internalClass()->propertyData[idx];
return o->propertyAt(idx);
}
@@ -315,10 +297,10 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
{
const Object *o = this;
while (o) {
- Property *p = o->arrayData->getProperty(index);
+ Property *p = o->arrayData()->getProperty(index);
if (p) {
if (attrs)
- *attrs = o->arrayData->attributes(index);
+ *attrs = o->arrayData()->attributes(index);
return p;
}
if (o->isStringObject()) {
@@ -336,7 +318,7 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
return 0;
}
-bool Object::hasProperty(const StringRef name) const
+bool Object::hasProperty(String *name) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -366,13 +348,13 @@ bool Object::hasProperty(uint index) const
return false;
}
-bool Object::hasOwnProperty(const StringRef name) const
+bool Object::hasOwnProperty(String *name) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
return hasOwnProperty(idx);
- if (internalClass->find(name) < UINT_MAX)
+ if (internalClass()->find(name) < UINT_MAX)
return true;
if (!query(name).isEmpty())
return true;
@@ -381,11 +363,11 @@ bool Object::hasOwnProperty(const StringRef name) const
bool Object::hasOwnProperty(uint index) const
{
- if (!arrayData->isEmpty(index))
+ if (!arrayData()->isEmpty(index))
return true;
if (isStringObject()) {
- String *s = static_cast<const StringObject *>(this)->value.asString();
- if (index < (uint)s->length())
+ String *s = static_cast<const StringObject *>(this)->d()->value.asString();
+ if (index < (uint)s->d()->length())
return true;
}
if (!queryIndexed(index).isEmpty())
@@ -403,7 +385,7 @@ ReturnedValue Object::call(Managed *m, CallData *)
return m->engine()->currentContext()->throwTypeError();
}
-ReturnedValue Object::get(Managed *m, const StringRef name, bool *hasProperty)
+ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty)
{
return static_cast<Object *>(m)->internalGet(name, hasProperty);
}
@@ -413,7 +395,7 @@ ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty)
return static_cast<Object *>(m)->internalGetIndexed(index, hasProperty);
}
-void Object::put(Managed *m, const StringRef name, const ValueRef value)
+void Object::put(Managed *m, String *name, const ValueRef value)
{
static_cast<Object *>(m)->internalPut(name, value);
}
@@ -423,16 +405,16 @@ void Object::putIndexed(Managed *m, uint index, const ValueRef value)
static_cast<Object *>(m)->internalPutIndexed(index, value);
}
-PropertyAttributes Object::query(const Managed *m, StringRef name)
+PropertyAttributes Object::query(const Managed *m, String *name)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
return queryIndexed(m, idx);
const Object *o = static_cast<const Object *>(m);
- idx = o->internalClass->find(name.getPointer());
+ idx = o->internalClass()->find(name);
if (idx < UINT_MAX)
- return o->internalClass->propertyData[idx];
+ return o->internalClass()->propertyData[idx];
return Attr_Invalid;
}
@@ -440,18 +422,18 @@ PropertyAttributes Object::query(const Managed *m, StringRef name)
PropertyAttributes Object::queryIndexed(const Managed *m, uint index)
{
const Object *o = static_cast<const Object *>(m);
- if (o->arrayData->get(index) != Primitive::emptyValue().asReturnedValue())
- return o->arrayData->attributes(index);
+ if (o->arrayData()->get(index) != Primitive::emptyValue().asReturnedValue())
+ return o->arrayData()->attributes(index);
if (o->isStringObject()) {
- String *s = static_cast<const StringObject *>(o)->value.asString();
- if (index < (uint)s->length())
+ String *s = static_cast<const StringObject *>(o)->d()->value.asString();
+ if (index < (uint)s->d()->length())
return (Attr_NotWritable|Attr_NotConfigurable);
}
return Attr_Invalid;
}
-bool Object::deleteProperty(Managed *m, const StringRef name)
+bool Object::deleteProperty(Managed *m, String *name)
{
return static_cast<Object *>(m)->internalDeleteProperty(name);
}
@@ -497,46 +479,46 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
Scope scope(m->engine());
ScopedObject o(scope, static_cast<Object *>(m));
- InternalClass *c = o->internalClass;
+ InternalClass *c = o->internalClass();
uint idx = c->find(l->name);
if (!o->isArrayObject() || idx != ArrayObject::LengthPropertyIndex) {
- if (idx != UINT_MAX && o->internalClass->propertyData[idx].isData() && o->internalClass->propertyData[idx].isWritable()) {
- l->classList[0] = o->internalClass;
+ if (idx != UINT_MAX && o->internalClass()->propertyData[idx].isData() && o->internalClass()->propertyData[idx].isWritable()) {
+ l->classList[0] = o->internalClass();
l->index = idx;
l->setter = Lookup::setter0;
- o->memberData[idx] = *value;
+ o->memberData()[idx] = *value;
return;
}
if (idx != UINT_MAX) {
- o->putValue(o->propertyAt(idx), o->internalClass->propertyData[idx], value);
+ o->putValue(o->propertyAt(idx), o->internalClass()->propertyData[idx], value);
return;
}
}
ScopedString s(scope, l->name);
- o->put(s, value);
+ o->put(s.getPointer(), value);
- if (o->internalClass == c)
+ if (o->internalClass() == c)
return;
- idx = o->internalClass->find(l->name);
+ idx = o->internalClass()->find(l->name);
if (idx == UINT_MAX)
return;
l->classList[0] = c;
- l->classList[3] = o->internalClass;
+ l->classList[3] = o->internalClass();
l->index = idx;
if (!o->prototype()) {
l->setter = Lookup::setterInsert0;
return;
}
o = o->prototype();
- l->classList[1] = o->internalClass;
+ l->classList[1] = o->internalClass();
if (!o->prototype()) {
l->setter = Lookup::setterInsert1;
return;
}
o = o->prototype();
- l->classList[2] = o->internalClass;
+ l->classList[2] = o->internalClass();
if (!o->prototype()) {
l->setter = Lookup::setterInsert2;
return;
@@ -544,13 +526,13 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
l->setter = Lookup::setterGeneric;
}
-void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *pd, PropertyAttributes *attrs)
+void Object::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *pd, PropertyAttributes *attrs)
{
Object *o = static_cast<Object *>(m);
name = (String *)0;
*index = UINT_MAX;
- if (o->arrayData) {
+ if (o->arrayData()) {
if (!it->arrayIndex)
it->arrayNode = o->sparseBegin();
@@ -559,9 +541,9 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
while (it->arrayNode != o->sparseEnd()) {
int k = it->arrayNode->key();
uint pidx = it->arrayNode->value;
- Property *p = reinterpret_cast<Property *>(o->arrayData->data + pidx);
+ Property *p = reinterpret_cast<Property *>(o->arrayData()->arrayData() + pidx);
it->arrayNode = it->arrayNode->nextNode();
- PropertyAttributes a = o->arrayData->attributes(k);
+ PropertyAttributes a = o->arrayData()->attributes(k);
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
it->arrayIndex = k + 1;
*index = k;
@@ -574,9 +556,9 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
it->arrayIndex = UINT_MAX;
}
// dense arrays
- while (it->arrayIndex < o->arrayData->length()) {
- Value *val = o->arrayData->data + it->arrayIndex;
- PropertyAttributes a = o->arrayData->attributes(it->arrayIndex);
+ while (it->arrayIndex < o->arrayData()->length()) {
+ Value *val = o->arrayData()->arrayData() + it->arrayIndex;
+ PropertyAttributes a = o->arrayData()->attributes(it->arrayIndex);
++it->arrayIndex;
if (!val->isEmpty()
&& (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable())) {
@@ -588,8 +570,8 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
}
}
- while (it->memberIndex < o->internalClass->size) {
- String *n = o->internalClass->nameMap.at(it->memberIndex);
+ while (it->memberIndex < o->internalClass()->size) {
+ String *n = o->internalClass()->nameMap.at(it->memberIndex);
if (!n) {
// accessor properties have a dummy entry with n == 0
++it->memberIndex;
@@ -597,7 +579,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
}
Property *p = o->propertyAt(it->memberIndex);
- PropertyAttributes a = o->internalClass->propertyData[it->memberIndex];
+ PropertyAttributes a = o->internalClass()->propertyData[it->memberIndex];
++it->memberIndex;
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
name = n;
@@ -611,7 +593,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
}
// Section 8.12.3
-ReturnedValue Object::internalGet(const StringRef name, bool *hasProperty)
+ReturnedValue Object::internalGet(String *name, bool *hasProperty)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -621,11 +603,11 @@ ReturnedValue Object::internalGet(const StringRef name, bool *hasProperty)
Object *o = this;
while (o) {
- uint idx = o->internalClass->find(name.getPointer());
+ uint idx = o->internalClass()->find(name);
if (idx < UINT_MAX) {
if (hasProperty)
*hasProperty = true;
- return getValue(o->propertyAt(idx), o->internalClass->propertyData.at(idx));
+ return getValue(o->propertyAt(idx), o->internalClass()->propertyData.at(idx));
}
o = o->prototype();
@@ -642,10 +624,10 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
PropertyAttributes attrs;
Object *o = this;
while (o) {
- Property *p = o->arrayData->getProperty(index);
+ Property *p = o->arrayData()->getProperty(index);
if (p) {
pd = p;
- attrs = o->arrayData->attributes(index);
+ attrs = o->arrayData()->attributes(index);
break;
}
if (o->isStringObject()) {
@@ -671,9 +653,9 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
// Section 8.12.5
-void Object::internalPut(const StringRef name, const ValueRef value)
+void Object::internalPut(String *name, const ValueRef value)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return;
uint idx = name->asArrayIndex();
@@ -682,12 +664,12 @@ void Object::internalPut(const StringRef name, const ValueRef value)
name->makeIdentifier();
- uint member = internalClass->find(name.getPointer());
+ uint member = internalClass()->find(name);
Property *pd = 0;
PropertyAttributes attrs;
if (member < UINT_MAX) {
pd = propertyAt(member);
- attrs = internalClass->propertyData[member];
+ attrs = internalClass()->propertyData[member];
}
// clause 1
@@ -713,7 +695,7 @@ void Object::internalPut(const StringRef name, const ValueRef value)
}
return;
} else if (!prototype()) {
- if (!extensible)
+ if (!isExtensible())
goto reject;
} else {
// clause 4
@@ -721,10 +703,10 @@ void Object::internalPut(const StringRef name, const ValueRef value)
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
- } else if (!extensible || !attrs.isWritable()) {
+ } else if (!isExtensible() || !attrs.isWritable()) {
goto reject;
}
- } else if (!extensible) {
+ } else if (!isExtensible()) {
goto reject;
}
}
@@ -747,7 +729,7 @@ void Object::internalPut(const StringRef name, const ValueRef value)
return;
reject:
- if (engine()->currentContext()->strictMode) {
+ if (engine()->currentContext()->d()->strictMode) {
QString message = QStringLiteral("Cannot assign to read-only property \"");
message += name->toQString();
message += QLatin1Char('\"');
@@ -757,14 +739,14 @@ void Object::internalPut(const StringRef name, const ValueRef value)
void Object::internalPutIndexed(uint index, const ValueRef value)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return;
PropertyAttributes attrs;
- Property *pd = arrayData->getProperty(index);
+ Property *pd = arrayData()->getProperty(index);
if (pd)
- attrs = arrayData->attributes(index);
+ attrs = arrayData()->attributes(index);
if (!pd && isStringObject()) {
pd = static_cast<StringObject *>(this)->getIndex(index);
@@ -785,7 +767,7 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
pd->value = *value;
return;
} else if (!prototype()) {
- if (!extensible)
+ if (!isExtensible())
goto reject;
} else {
// clause 4
@@ -793,10 +775,10 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
- } else if (!extensible || !attrs.isWritable()) {
+ } else if (!isExtensible() || !attrs.isWritable()) {
goto reject;
}
- } else if (!extensible) {
+ } else if (!isExtensible()) {
goto reject;
}
}
@@ -819,14 +801,14 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
return;
reject:
- if (engine()->currentContext()->strictMode)
+ if (engine()->currentContext()->d()->strictMode)
engine()->currentContext()->throwTypeError();
}
// Section 8.12.7
-bool Object::internalDeleteProperty(const StringRef name)
+bool Object::internalDeleteProperty(String *name)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return false;
uint idx = name->asArrayIndex();
@@ -835,13 +817,13 @@ bool Object::internalDeleteProperty(const StringRef name)
name->makeIdentifier();
- uint memberIdx = internalClass->find(name);
+ uint memberIdx = internalClass()->find(name);
if (memberIdx != UINT_MAX) {
- if (internalClass->propertyData[memberIdx].isConfigurable()) {
- InternalClass::removeMember(this, name->identifier);
+ if (internalClass()->propertyData[memberIdx].isConfigurable()) {
+ InternalClass::removeMember(this, name->identifier());
return true;
}
- if (engine()->currentContext()->strictMode)
+ if (engine()->currentContext()->d()->strictMode)
engine()->currentContext()->throwTypeError();
return false;
}
@@ -851,19 +833,19 @@ bool Object::internalDeleteProperty(const StringRef name)
bool Object::internalDeleteIndexedProperty(uint index)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return false;
- if (!arrayData || arrayData->vtable()->del(this, index))
+ if (!arrayData() || arrayData()->vtable()->del(this, index))
return true;
- if (engine()->currentContext()->strictMode)
+ if (engine()->currentContext()->d()->strictMode)
engine()->currentContext()->throwTypeError();
return false;
}
// Section 8.12.9
-bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Property &p, PropertyAttributes attrs)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -876,10 +858,10 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
PropertyAttributes *cattrs;
uint memberIndex;
- if (isArrayObject() && name->equals(ctx->engine->id_length)) {
- assert(ArrayObject::LengthPropertyIndex == internalClass->find(ctx->engine->id_length));
+ if (isArrayObject() && name->equals(ctx->d()->engine->id_length)) {
+ assert(ArrayObject::LengthPropertyIndex == internalClass()->find(ctx->d()->engine->id_length));
Property *lp = propertyAt(ArrayObject::LengthPropertyIndex);
- cattrs = internalClass->propertyData.constData() + ArrayObject::LengthPropertyIndex;
+ cattrs = internalClass()->propertyData.constData() + ArrayObject::LengthPropertyIndex;
if (attrs.isEmpty() || p.isSubset(attrs, *lp, *cattrs))
return true;
if (!cattrs->isWritable() || attrs.type() == PropertyAttributes::Accessor || attrs.isConfigurable() || attrs.isEnumerable())
@@ -900,18 +882,18 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
if (!succeeded)
goto reject;
if (attrs.isAccessor())
- hasAccessorProperty = 1;
+ setHasAccessorProperty();
return true;
}
// Clause 1
- memberIndex = internalClass->find(name.getPointer());
+ memberIndex = internalClass()->find(name);
current = (memberIndex < UINT_MAX) ? propertyAt(memberIndex) : 0;
- cattrs = internalClass->propertyData.constData() + memberIndex;
+ cattrs = internalClass()->propertyData.constData() + memberIndex;
if (!current) {
// clause 3
- if (!extensible)
+ if (!isExtensible())
goto reject;
// clause 4
Property pd;
@@ -923,7 +905,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
return __defineOwnProperty__(ctx, memberIndex, name, p, attrs);
reject:
- if (ctx->strictMode)
+ if (ctx->d()->strictMode)
ctx->throwTypeError();
return false;
}
@@ -931,7 +913,7 @@ reject:
bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs)
{
// 15.4.5.1, 4b
- if (isArrayObject() && index >= getLength() && !internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
+ if (isArrayObject() && index >= getLength() && !internalClass()->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
goto reject;
if (ArgumentsObject::isNonStrictArgumentsObject(this))
@@ -939,7 +921,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
return defineOwnProperty2(ctx, index, p, attrs);
reject:
- if (ctx->strictMode)
+ if (ctx->d()->strictMode)
ctx->throwTypeError();
return false;
}
@@ -950,14 +932,14 @@ bool Object::defineOwnProperty2(ExecutionContext *ctx, uint index, const Propert
// Clause 1
{
- current = arrayData->getProperty(index);
+ current = arrayData()->getProperty(index);
if (!current && isStringObject())
current = static_cast<StringObject *>(this)->getIndex(index);
}
if (!current) {
// clause 3
- if (!extensible)
+ if (!isExtensible())
goto reject;
// clause 4
Property pp;
@@ -973,14 +955,14 @@ bool Object::defineOwnProperty2(ExecutionContext *ctx, uint index, const Propert
return true;
}
- return __defineOwnProperty__(ctx, index, StringRef::null(), p, attrs);
+ return __defineOwnProperty__(ctx, index, 0, p, attrs);
reject:
- if (ctx->strictMode)
+ if (ctx->d()->strictMode)
ctx->throwTypeError();
return false;
}
-bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const StringRef member, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, String *member, const Property &p, PropertyAttributes attrs)
{
// clause 5
if (attrs.isEmpty())
@@ -988,12 +970,12 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
Property *current;
PropertyAttributes cattrs;
- if (!member.isNull()) {
+ if (member) {
current = propertyAt(index);
- cattrs = internalClass->propertyData[index];
+ cattrs = internalClass()->propertyData[index];
} else {
- current = arrayData->getProperty(index);
- cattrs = arrayData->attributes(index);
+ current = arrayData()->getProperty(index);
+ cattrs = arrayData()->attributes(index);
}
// clause 6
@@ -1021,11 +1003,11 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
// 9b
cattrs.setType(PropertyAttributes::Accessor);
cattrs.clearWritable();
- if (member.isNull()) {
+ if (!member) {
// need to convert the array and the slot
initSparseArray();
setArrayAttributes(index, cattrs);
- current = arrayData->getProperty(index);
+ current = arrayData()->getProperty(index);
}
current->setGetter(0);
current->setSetter(0);
@@ -1033,10 +1015,10 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
// 9c
cattrs.setType(PropertyAttributes::Data);
cattrs.setWritable(false);
- if (member.isNull()) {
+ if (!member) {
// need to convert the array and the slot
setArrayAttributes(index, cattrs);
- current = arrayData->getProperty(index);
+ current = arrayData()->getProperty(index);
}
current->value = Primitive::undefinedValue();
}
@@ -1058,16 +1040,16 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
accept:
current->merge(cattrs, p, attrs);
- if (!member.isNull()) {
- InternalClass::changeMember(this, member.getPointer(), cattrs);
+ if (member) {
+ InternalClass::changeMember(this, member, cattrs);
} else {
setArrayAttributes(index, cattrs);
}
if (cattrs.isAccessor())
- hasAccessorProperty = 1;
+ setHasAccessorProperty();
return true;
reject:
- if (ctx->strictMode)
+ if (ctx->d()->strictMode)
ctx->throwTypeError();
return false;
}
@@ -1076,8 +1058,8 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
bool Object::__defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs)
{
Scope scope(ctx);
- ScopedString s(scope, ctx->engine->newString(name));
- return __defineOwnProperty__(ctx, s, p, attrs);
+ ScopedString s(scope, ctx->d()->engine->newString(name));
+ return __defineOwnProperty__(ctx, s.getPointer(), p, attrs);
}
@@ -1086,7 +1068,7 @@ void Object::copyArrayData(Object *other)
Q_ASSERT(isArrayObject());
Scope scope(engine());
- if (other->protoHasArray() || other->hasAccessorProperty) {
+ if (other->protoHasArray() || other->hasAccessorProperty()) {
uint len = other->getLength();
Q_ASSERT(len);
@@ -1094,30 +1076,30 @@ void Object::copyArrayData(Object *other)
for (uint i = 0; i < len; ++i) {
arraySet(i, (v = other->getIndexed(i)));
}
- } else if (!other->arrayData) {
+ } else if (!other->arrayData()) {
;
- } else if (other->hasAccessorProperty && other->arrayData->attrs && other->arrayData->isSparse()){
+ } else if (other->hasAccessorProperty() && other->arrayData()->attrs() && other->arrayData()->isSparse()){
// do it the slow way
ScopedValue v(scope);
- for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other->arrayData)->sparse->begin();
- it != static_cast<const SparseArrayData *>(other->arrayData)->sparse->end(); it = it->nextNode()) {
- v = other->getValue(reinterpret_cast<Property *>(other->arrayData->data + it->value), other->arrayData->attrs[it->value]);
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other->arrayData())->sparse()->begin();
+ it != static_cast<const SparseArrayData *>(other->arrayData())->sparse()->end(); it = it->nextNode()) {
+ v = other->getValue(reinterpret_cast<Property *>(other->arrayData()->arrayData() + it->value), other->arrayData()->attrs()[it->value]);
arraySet(it->key(), v);
}
} else {
- Q_ASSERT(!arrayData && other->arrayData);
- ArrayData::realloc(this, other->arrayData->type, 0, other->arrayData->alloc, other->arrayData->attrs);
+ Q_ASSERT(!arrayData() && other->arrayData());
+ ArrayData::realloc(this, other->arrayData()->type(), 0, other->arrayData()->alloc(), other->arrayData()->attrs());
if (other->arrayType() == ArrayData::Sparse) {
- SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData);
- SparseArrayData *dd = static_cast<SparseArrayData *>(arrayData);
- dd->sparse = new SparseArray(*od->sparse);
- dd->freeList = od->freeList;
+ SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData());
+ SparseArrayData *dd = static_cast<SparseArrayData *>(arrayData());
+ dd->setSparse(new SparseArray(*od->sparse()));
+ dd->freeList() = od->freeList();
} else {
- SimpleArrayData *d = static_cast<SimpleArrayData *>(arrayData);
- d->len = static_cast<SimpleArrayData *>(other->arrayData)->len;
- d->offset = 0;
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(arrayData());
+ d->len() = static_cast<SimpleArrayData *>(other->arrayData())->len();
+ d->offset() = 0;
}
- memcpy(arrayData->data, other->arrayData->data, arrayData->alloc*sizeof(Value));
+ memcpy(arrayData()->arrayData(), other->arrayData()->arrayData(), arrayData()->alloc()*sizeof(Value));
}
setArrayLengthUnchecked(other->getLength());
}
@@ -1132,15 +1114,15 @@ uint Object::getLength(const Managed *m)
bool Object::setArrayLength(uint newLen)
{
Q_ASSERT(isArrayObject());
- if (!internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
+ if (!internalClass()->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
return false;
uint oldLen = getLength();
bool ok = true;
if (newLen < oldLen) {
- if (!arrayData) {
+ if (!arrayData()) {
Q_ASSERT(!newLen);
} else {
- uint l = arrayData->vtable()->truncate(this, newLen);
+ uint l = arrayData()->vtable()->truncate(this, newLen);
if (l != newLen)
ok = false;
newLen = l;
@@ -1164,30 +1146,23 @@ void Object::initSparseArray()
DEFINE_OBJECT_VTABLE(ArrayObject);
-ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
- : Object(engine->arrayClass)
+ArrayObject::Data::Data(ExecutionEngine *engine, const QStringList &list)
+ : Object::Data(engine->arrayClass)
{
- init(engine);
+ init();
Scope scope(engine);
- ScopedValue protectThis(scope, this);
+ ScopedObject a(scope, this);
// Converts a QStringList to JS.
// The result is a new Array object with length equal to the length
// of the QStringList, and the elements being the QStringList's
// elements converted to JS Strings.
int len = list.count();
- arrayReserve(len);
+ a->arrayReserve(len);
ScopedValue v(scope);
for (int ii = 0; ii < len; ++ii)
- arrayPut(ii, (v = engine->newString(list.at(ii))));
- setArrayLengthUnchecked(len);
-}
-
-void ArrayObject::init(ExecutionEngine *engine)
-{
- Q_UNUSED(engine);
-
- memberData[LengthPropertyIndex] = Primitive::fromInt32(0);
+ a->arrayPut(ii, (v = engine->newString(list.at(ii))));
+ a->setArrayLengthUnchecked(len);
}
ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
@@ -1196,7 +1171,7 @@ ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
// special case, as the property is on the object itself
l->getter = Lookup::arrayLengthGetter;
ArrayObject *a = static_cast<ArrayObject *>(m);
- return a->memberData[ArrayObject::LengthPropertyIndex].asReturnedValue();
+ return a->memberData()[ArrayObject::LengthPropertyIndex].asReturnedValue();
}
return Object::getLookup(m, l);
}
@@ -1204,16 +1179,16 @@ ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
uint ArrayObject::getLength(const Managed *m)
{
const ArrayObject *a = static_cast<const ArrayObject *>(m);
- if (a->memberData[ArrayObject::LengthPropertyIndex].isInteger())
- return a->memberData[ArrayObject::LengthPropertyIndex].integerValue();
- return Primitive::toUInt32(a->memberData[ArrayObject::LengthPropertyIndex].doubleValue());
+ if (a->memberData()[ArrayObject::LengthPropertyIndex].isInteger())
+ return a->memberData()[ArrayObject::LengthPropertyIndex].integerValue();
+ return Primitive::toUInt32(a->memberData()[ArrayObject::LengthPropertyIndex].doubleValue());
}
QStringList ArrayObject::toQStringList() const
{
QStringList result;
- QV4::ExecutionEngine *engine = internalClass->engine;
+ QV4::ExecutionEngine *engine = internalClass()->engine;
Scope scope(engine);
ScopedValue v(scope);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 40f38ee347..67459d5e77 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -103,39 +103,49 @@ struct URIErrorPrototype;
struct Q_QML_EXPORT Object: Managed {
- V4_OBJECT
+ struct Data : Managed::Data {
+ Data(ExecutionEngine *engine)
+ : Managed::Data(engine->objectClass)
+ {
+ }
+ Data(InternalClass *internal = 0);
+
+ Members memberData;
+ ArrayData *arrayData;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(Object)
+
enum {
IsObject = true
};
- Members memberData;
- ArrayData *arrayData;
+ Members &memberData() { return d()->memberData; }
+ const Members &memberData() const { return d()->memberData; }
+ const ArrayData *arrayData() const { return d()->arrayData; }
+ ArrayData *arrayData() { return d()->arrayData; }
+ void setArrayData(ArrayData *a) { d()->arrayData = a; }
- Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData.data() + index); }
+ Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData().data() + index); }
- Object(ExecutionEngine *engine);
- Object(InternalClass *internalClass);
- ~Object();
-
- const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass->vtable); }
- Object *prototype() const { return internalClass->prototype; }
+ const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
+ Object *prototype() const { return internalClass()->prototype; }
bool setPrototype(Object *proto);
- Property *__getOwnProperty__(const StringRef name, PropertyAttributes *attrs = 0);
+ Property *__getOwnProperty__(String *name, PropertyAttributes *attrs = 0);
Property *__getOwnProperty__(uint index, PropertyAttributes *attrs = 0);
- Property *__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs = 0) const;
+ Property *__getPropertyDescriptor__(String *name, PropertyAttributes *attrs = 0) const;
Property *__getPropertyDescriptor__(uint index, PropertyAttributes *attrs = 0) const;
- bool hasProperty(const StringRef name) const;
+ bool hasProperty(String *name) const;
bool hasProperty(uint index) const;
- bool hasOwnProperty(const StringRef name) const;
+ bool hasOwnProperty(String *name) const;
bool hasOwnProperty(uint index) const;
- bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const StringRef member, const Property &p, PropertyAttributes attrs);
- bool __defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionContext *ctx, uint index, String *member, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs);
bool defineOwnProperty2(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
@@ -155,24 +165,31 @@ struct Q_QML_EXPORT Object: Managed {
void putValue(Property *pd, PropertyAttributes attrs, const ValueRef value);
/* The spec default: Writable: true, Enumerable: false, Configurable: true */
- void defineDefaultProperty(const StringRef name, ValueRef value) {
+ void defineDefaultProperty(String *name, ValueRef value) {
insertMember(name, value, Attr_Data|Attr_NotEnumerable);
}
void defineDefaultProperty(const QString &name, ValueRef value);
void defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
- void defineDefaultProperty(const StringRef name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
+ void defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
- void defineAccessorProperty(const StringRef name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
+ void defineAccessorProperty(String *name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
/* Fixed: Writable: false, Enumerable: false, Configurable: false */
void defineReadonlyProperty(const QString &name, ValueRef value);
- void defineReadonlyProperty(const StringRef name, ValueRef value);
+ void defineReadonlyProperty(String *name, ValueRef value);
- void insertMember(const StringRef s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
- insertMember(s, Property(*v), attributes);
+ void insertMember(String *s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
+ Property p(*v);
+ insertMember(s, p, attributes);
}
- void insertMember(const StringRef s, const Property &p, PropertyAttributes attributes);
+ void insertMember(String *s, const Property &p, PropertyAttributes attributes);
+
+ inline ExecutionEngine *engine() const { return internalClass()->engine; }
- inline ExecutionEngine *engine() const { return internalClass->engine; }
+ inline bool hasAccessorProperty() const { return d()->hasAccessorProperty; }
+ inline void setHasAccessorProperty() { d()->hasAccessorProperty = true; }
+
+ bool isExtensible() const { return d()->extensible; }
+ void setExtensible(bool b) { d()->extensible = b; }
// Array handling
@@ -186,30 +203,30 @@ public:
void arraySet(uint index, ValueRef value);
bool arrayPut(uint index, ValueRef value) {
- return arrayData->vtable()->put(this, index, value);
+ return arrayData()->vtable()->put(this, index, value);
}
bool arrayPut(uint index, Value *values, uint n) {
- return arrayData->vtable()->putArray(this, index, values, n);
+ return arrayData()->vtable()->putArray(this, index, values, n);
}
void setArrayAttributes(uint i, PropertyAttributes a) {
- Q_ASSERT(arrayData);
- if (arrayData->attrs || a != Attr_Data) {
+ Q_ASSERT(arrayData());
+ if (arrayData()->attrs() || a != Attr_Data) {
ArrayData::ensureAttributes(this);
a.resolve();
- arrayData->vtable()->setAttribute(this, i, a);
+ arrayData()->vtable()->setAttribute(this, i, a);
}
}
void push_back(const ValueRef v);
ArrayData::Type arrayType() const {
- return arrayData ? arrayData->type : ArrayData::Simple;
+ return arrayData() ? arrayData()->type() : ArrayData::Simple;
}
// ### remove me
void setArrayType(ArrayData::Type t) {
Q_ASSERT(t != ArrayData::Simple && t != ArrayData::Sparse);
arrayCreate();
- arrayData->type = t;
+ arrayData()->setType(t);
}
inline void arrayReserve(uint n) {
@@ -217,7 +234,7 @@ public:
}
void arrayCreate() {
- if (!arrayData)
+ if (!arrayData())
ArrayData::realloc(this, ArrayData::Simple, 0, 0, false);
#ifdef CHECK_SPARSE_ARRAYS
initSparseArray();
@@ -225,34 +242,34 @@ public:
}
void initSparseArray();
- SparseArrayNode *sparseBegin() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->begin() : 0; }
- SparseArrayNode *sparseEnd() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->end() : 0; }
+ SparseArrayNode *sparseBegin() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData())->sparse()->begin() : 0; }
+ SparseArrayNode *sparseEnd() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData())->sparse()->end() : 0; }
inline bool protoHasArray() {
Scope scope(engine());
Scoped<Object> p(scope, this);
while ((p = p->prototype()))
- if (p->arrayData)
+ if (p->arrayData())
return true;
return false;
}
void ensureMemberIndex(uint idx);
- inline ReturnedValue get(const StringRef name, bool *hasProperty = 0)
+ inline ReturnedValue get(String *name, bool *hasProperty = 0)
{ return vtable()->get(this, name, hasProperty); }
inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0)
{ return vtable()->getIndexed(this, idx, hasProperty); }
- inline void put(const StringRef name, const ValueRef v)
+ inline void put(String *name, const ValueRef v)
{ vtable()->put(this, name, v); }
inline void putIndexed(uint idx, const ValueRef v)
{ vtable()->putIndexed(this, idx, v); }
- PropertyAttributes query(StringRef name) const
+ PropertyAttributes query(String *name) const
{ return vtable()->query(this, name); }
PropertyAttributes queryIndexed(uint index) const
{ return vtable()->queryIndexed(this, index); }
- bool deleteProperty(const StringRef name)
+ bool deleteProperty(String *name)
{ return vtable()->deleteProperty(this, name); }
bool deleteIndexedProperty(uint index)
{ return vtable()->deleteIndexedProperty(this, index); }
@@ -260,7 +277,7 @@ public:
{ return vtable()->getLookup(this, l); }
void setLookup(Lookup *l, const ValueRef v)
{ vtable()->setLookup(this, l, v); }
- void advanceIterator(ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes)
+ void advanceIterator(ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes)
{ vtable()->advanceIterator(this, it, name, index, p, attributes); }
uint getLength() const { return vtable()->getLength(this); }
@@ -269,29 +286,28 @@ public:
inline ReturnedValue call(CallData *d)
{ return vtable()->call(this, d); }
protected:
- static void destroy(Managed *that);
static void markObjects(Managed *that, ExecutionEngine *e);
static ReturnedValue construct(Managed *m, CallData *);
static ReturnedValue call(Managed *m, CallData *);
- static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, const StringRef name, const ValueRef value);
+ static void put(Managed *m, String *name, const ValueRef value);
static void putIndexed(Managed *m, uint index, const ValueRef value);
- static PropertyAttributes query(const Managed *m, StringRef name);
+ static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static bool deleteProperty(Managed *m, const StringRef name);
+ static bool deleteProperty(Managed *m, String *name);
static bool deleteIndexedProperty(Managed *m, uint index);
static ReturnedValue getLookup(Managed *m, Lookup *l);
static void setLookup(Managed *m, Lookup *l, const ValueRef v);
- static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
static uint getLength(const Managed *m);
private:
- ReturnedValue internalGet(const StringRef name, bool *hasProperty);
+ ReturnedValue internalGet(String *name, bool *hasProperty);
ReturnedValue internalGetIndexed(uint index, bool *hasProperty);
- void internalPut(const StringRef name, const ValueRef value);
+ void internalPut(String *name, const ValueRef value);
void internalPutIndexed(uint index, const ValueRef value);
- bool internalDeleteProperty(const StringRef name);
+ bool internalDeleteProperty(String *name);
bool internalDeleteIndexedProperty(uint index);
friend struct ObjectIterator;
@@ -299,48 +315,62 @@ private:
};
struct BooleanObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, const ValueRef val)
+ : Object::Data(engine->booleanClass)
+ {
+ value = val;
+ }
+ Data(InternalClass *ic)
+ : Object::Data(ic)
+ {
+ Q_ASSERT(internalClass->vtable == staticVTable());
+ value = Encode(false);
+ }
+ Value value;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(BooleanObject)
- Value value;
- BooleanObject(ExecutionEngine *engine, const ValueRef val)
- : Object(engine->booleanClass) {
- value = val;
- }
-protected:
- BooleanObject(InternalClass *ic)
- : Object(ic) {
- Q_ASSERT(internalClass->vtable == staticVTable());
- value = Encode(false);
- }
+
+ Value value() const { return d()->value; }
+
};
struct NumberObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, const ValueRef val)
+ : Object::Data(engine->numberClass) {
+ value = val;
+ }
+ Data(InternalClass *ic)
+ : Object::Data(ic) {
+ Q_ASSERT(internalClass->vtable == staticVTable());
+ value = Encode((int)0);
+ }
+ Value value;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(NumberObject)
- Value value;
- NumberObject(ExecutionEngine *engine, const ValueRef val)
- : Object(engine->numberClass) {
- value = val;
- }
-protected:
- NumberObject(InternalClass *ic)
- : Object(ic) {
- Q_ASSERT(internalClass->vtable == staticVTable());
- value = Encode((int)0);
- }
+
+ Value value() const { return d()->value; }
+
};
struct ArrayObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine) : Object::Data(engine->arrayClass) { init(); }
+ Data(ExecutionEngine *engine, const QStringList &list);
+ Data(InternalClass *ic) : Object::Data(ic) { init(); }
+ void init()
+ { memberData[LengthPropertyIndex] = Primitive::fromInt32(0); }
+ };
+
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(ArrayObject)
enum {
LengthPropertyIndex = 0
};
- ArrayObject(ExecutionEngine *engine) : Object(engine->arrayClass) { init(engine); }
- ArrayObject(ExecutionEngine *engine, const QStringList &list);
- ArrayObject(InternalClass *ic) : Object(ic) { init(ic->engine); }
-
void init(ExecutionEngine *engine);
static ReturnedValue getLookup(Managed *m, Lookup *l);
@@ -353,7 +383,7 @@ struct ArrayObject: Object {
inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject())
- memberData[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
+ memberData()[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
}
inline void Object::push_back(const ValueRef v)
@@ -371,12 +401,12 @@ inline void Object::arraySet(uint index, const Property &p, PropertyAttributes a
// ### Clean up
arrayCreate();
if (attributes.isAccessor()) {
- hasAccessorProperty = 1;
+ setHasAccessorProperty();
initSparseArray();
- } else if (index > 0x1000 && index > 2*arrayData->alloc) {
+ } else if (index > 0x1000 && index > 2*arrayData()->alloc()) {
initSparseArray();
} else {
- arrayData->vtable()->reallocate(this, index + 1, false);
+ arrayData()->vtable()->reallocate(this, index + 1, false);
}
setArrayAttributes(index, attributes);
Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
@@ -391,7 +421,7 @@ inline void Object::arraySet(uint index, const Property &p, PropertyAttributes a
inline void Object::arraySet(uint index, ValueRef value)
{
arrayCreate();
- if (index > 0x1000 && index > 2*arrayData->alloc) {
+ if (index > 0x1000 && index > 2*arrayData()->alloc()) {
initSparseArray();
}
Property *pd = ArrayData::insert(this, index);
@@ -418,23 +448,6 @@ inline ReturnedValue value_convert<Object>(ExecutionEngine *e, const Value &v)
}
#endif
-struct ObjectRef : public ManagedRef
-{
- DEFINE_REF_METHODS(Object, Managed)
-
- static ObjectRef fromValuePointer(Value *s) {
- ObjectRef r;
- r.ptr = s;
- if (sizeof(void *) == 8)
- r.ptr->val = 0;
- else
- *r.ptr = Value::fromManaged(0);
- return r;
- }
-};
-
-DEFINE_REF(ArrayObject, Object);
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index e5f693c323..216700fe69 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -46,63 +46,71 @@
using namespace QV4;
-ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags)
- : object(ObjectRef::fromValuePointer(scratch1))
- , current(ObjectRef::fromValuePointer(scratch2))
+ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, Object *o, uint flags)
+ : object(scratch1)
+ , current(scratch2)
, arrayNode(0)
, arrayIndex(0)
, memberIndex(0)
, flags(flags)
{
- object = o.getPointer();
- current = o.getPointer();
-
- if (!!object && object->asArgumentsObject()) {
+ object->o = o;
+ current->o = o;
+#if QT_POINTER_SIZE == 4
+ object->tag = QV4::Value::Managed_Type;
+ current->tag = QV4::Value::Managed_Type;
+#endif
+
+ if (object->as<ArgumentsObject>()) {
Scope scope(object->engine());
Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
}
}
-ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
- : object(ObjectRef::fromValuePointer(scope.alloc(1)))
- , current(ObjectRef::fromValuePointer(scope.alloc(1)))
+ObjectIterator::ObjectIterator(Scope &scope, Object *o, uint flags)
+ : object(scope.alloc(1))
+ , current(scope.alloc(1))
, arrayNode(0)
, arrayIndex(0)
, memberIndex(0)
, flags(flags)
{
- object = o;
- current = o;
-
- if (!!object && object->asArgumentsObject()) {
+ object->o = o;
+ current->o = o;
+#if QT_POINTER_SIZE == 4
+ object->tag = QV4::Value::Managed_Type;
+ current->tag = QV4::Value::Managed_Type;
+#endif
+
+ if (object->as<ArgumentsObject>()) {
Scope scope(object->engine());
Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
}
}
-void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAttributes *attrs)
+void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttributes *attrs)
{
name = (String *)0;
*index = UINT_MAX;
- if (!object) {
+ if (!object->asObject()) {
*attrs = PropertyAttributes();
return;
}
while (1) {
- if (!current)
+ if (!current->asObject())
break;
while (1) {
- current->advanceIterator(this, name, index, pd, attrs);
+ current->asObject()->advanceIterator(this, name, index, pd, attrs);
if (attrs->isEmpty())
break;
// check the property is not already defined earlier in the proto chain
- if (current != object) {
- Object *o = object;
+ if (current->asObject() != object->asObject()) {
+ Object *o = object->asObject();
bool shadowed = false;
- while (o != current) {
+ while (o != current->asObject()) {
if ((!!name && o->hasOwnProperty(name)) ||
(*index != UINT_MAX && o->hasOwnProperty(*index))) {
shadowed = true;
@@ -117,9 +125,9 @@ void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAtt
}
if (flags & WithProtoChain)
- current = current->prototype();
+ current->o = current->objectValue()->prototype();
else
- current = (Object *)0;
+ current->o = (Object *)0;
arrayIndex = 0;
memberIndex = 0;
@@ -129,7 +137,7 @@ void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAtt
ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
{
- if (!object)
+ if (!object->asObject())
return Encode::null();
PropertyAttributes attrs;
@@ -137,11 +145,13 @@ ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- next(name, &index, &p, &attrs);
+ String *n;
+ next(n, &index, &p, &attrs);
+ name = n;
if (attrs.isEmpty())
return Encode::null();
- value = object->getValue(&p, attrs);
+ value = object->objectValue()->getValue(&p, attrs);
if (!!name)
return name->asReturnedValue();
@@ -151,7 +161,7 @@ ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
{
- if (!object)
+ if (!object->asObject())
return Encode::null();
PropertyAttributes attrs;
@@ -159,11 +169,13 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- next(name, &index, &p, &attrs);
+ String *n;
+ next(n, &index, &p, &attrs);
+ name = n;
if (attrs.isEmpty())
return Encode::null();
- value = object->getValue(&p, attrs);
+ value = object->objectValue()->getValue(&p, attrs);
if (!!name)
return name->asReturnedValue();
@@ -173,7 +185,7 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
ReturnedValue ObjectIterator::nextPropertyNameAsString()
{
- if (!object)
+ if (!object->asObject())
return Encode::null();
PropertyAttributes attrs;
@@ -181,7 +193,9 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- next(name, &index, &p, &attrs);
+ String *n;
+ next(n, &index, &p, &attrs);
+ name = n;
if (attrs.isEmpty())
return Encode::null();
@@ -197,7 +211,7 @@ DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
{
ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
- o->workArea[0].mark(e);
- o->workArea[1].mark(e);
+ o->d()->workArea[0].mark(e);
+ o->d()->workArea[1].mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index c87f284288..f20ad17b4a 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -67,37 +67,38 @@ struct Q_QML_EXPORT ObjectIterator
WithProtoChain = 0x2,
};
- ObjectRef object;
- ObjectRef current;
+ Value *object;
+ Value *current;
SparseArrayNode *arrayNode;
uint arrayIndex;
uint memberIndex;
uint flags;
- ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags);
- ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
- void next(StringRef name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
+ ObjectIterator(Value *scratch1, Value *scratch2, Object *o, uint flags);
+ ObjectIterator(Scope &scope, Object *o, uint flags);
+ void next(String *&name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
ReturnedValue nextPropertyName(ValueRef value);
ReturnedValue nextPropertyNameAsString(ValueRef value);
ReturnedValue nextPropertyNameAsString();
};
struct ForEachIteratorObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionContext *ctx, Object *o)
+ : Object::Data(ctx->engine())
+ , it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
+ setVTable(staticVTable());
+ }
+ ObjectIterator it;
+ Value workArea[2];
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(ForeachIteratorObject)
- ObjectIterator it;
- ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
- : Object(ctx->engine), it(workArea, workArea + 1,
- o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
- setVTable(staticVTable());
- }
- ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
+ ReturnedValue nextPropertyName() { return d()->it.nextPropertyNameAsString(); }
protected:
static void markObjects(Managed *that, ExecutionEngine *e);
-
- Value workArea[2];
};
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 5c824bdfbd..6b8a19c7e6 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -74,8 +74,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(ObjectCtor);
-ObjectCtor::ObjectCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("Object"))
+ObjectCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("Object"))
{
setVTable(staticVTable());
}
@@ -102,7 +102,7 @@ ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
return RuntimeHelpers::toObject(m->engine()->currentContext(), ValueRef(&callData->args[0]));
}
-void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
+void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
{
Scope scope(v4);
ScopedObject o(scope, this);
@@ -133,10 +133,9 @@ void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
defineDefaultProperty(QStringLiteral("__defineGetter__"), method_defineGetter, 2);
defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
- Scoped<String> id_proto(scope, v4->id___proto__);
- Property p(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
- v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
- insertMember(StringRef(v4->id___proto__), p, Attr_Accessor|Attr_NotEnumerable);
+ Property p(ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext, v4->id___proto__, method_get_proto)).getPointer(),
+ ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext, v4->id___proto__, method_set_proto)).getPointer());
+ insertMember(v4->id___proto__, p, Attr_Accessor|Attr_NotEnumerable);
}
ReturnedValue ObjectPrototype::method_getPrototypeOf(CallContext *ctx)
@@ -165,7 +164,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(CallContext *ctx)
if (scope.hasException())
return Encode::undefined();
PropertyAttributes attrs;
- Property *desc = O->__getOwnProperty__(name, &attrs);
+ Property *desc = O->__getOwnProperty__(name.getPointer(), &attrs);
return fromPropertyDescriptor(ctx, desc, attrs);
}
@@ -176,7 +175,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyNames(CallContext *context)
if (!O)
return context->throwTypeError();
- ScopedArrayObject array(scope, getOwnPropertyNames(context->engine, context->callData->args[0]));
+ ScopedArrayObject array(scope, getOwnPropertyNames(context->d()->engine, context->d()->callData->args[0]));
return array.asReturnedValue();
}
@@ -187,11 +186,11 @@ ReturnedValue ObjectPrototype::method_create(CallContext *ctx)
if (!O->isObject() && !O->isNull())
return ctx->throwTypeError();
- Scoped<Object> newObject(scope, ctx->engine->newObject());
+ Scoped<Object> newObject(scope, ctx->d()->engine->newObject());
newObject->setPrototype(O->asObject());
- if (ctx->callData->argc > 1 && !ctx->callData->args[1].isUndefined()) {
- ctx->callData->args[0] = newObject.asReturnedValue();
+ if (ctx->d()->callData->argc > 1 && !ctx->d()->callData->args[1].isUndefined()) {
+ ctx->d()->callData->args[0] = newObject.asReturnedValue();
return method_defineProperties(ctx);
}
@@ -216,7 +215,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(CallContext *ctx)
if (scope.engine->hasException)
return Encode::undefined();
- if (!O->__defineOwnProperty__(ctx, name, pd, attrs))
+ if (!O->__defineOwnProperty__(ctx, name.getPointer(), pd, attrs))
return ctx->throwTypeError();
return O.asReturnedValue();
@@ -240,7 +239,9 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
uint index;
PropertyAttributes attrs;
Property pd;
- it.next(name, &index, &pd, &attrs);
+ String *nm;
+ it.next(nm, &index, &pd, &attrs);
+ name = nm;
if (attrs.isEmpty())
break;
Property n;
@@ -251,7 +252,7 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
return Encode::undefined();
bool ok;
if (name)
- ok = O->__defineOwnProperty__(ctx, name, n, nattrs);
+ ok = O->__defineOwnProperty__(ctx, name.getPointer(), n, nattrs);
else
ok = O->__defineOwnProperty__(ctx, index, n, nattrs);
if (!ok)
@@ -268,15 +269,15 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- o->extensible = false;
+ o->setExtensible(false);
- o->internalClass = o->internalClass->sealed();
+ o->setInternalClass(o->internalClass()->sealed());
- if (o->arrayData) {
+ if (o->arrayData()) {
ArrayData::ensureAttributes(o.getPointer());
- for (uint i = 0; i < o->arrayData->alloc; ++i) {
- if (!o->arrayData->isEmpty(i))
- o->arrayData->attrs[i].setConfigurable(false);
+ for (uint i = 0; i < o->arrayData()->alloc(); ++i) {
+ if (!o->arrayData()->isEmpty(i))
+ o->arrayData()->attrs()[i].setConfigurable(false);
}
}
@@ -293,17 +294,17 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
if (ArgumentsObject::isNonStrictArgumentsObject(o.getPointer()))
Scoped<ArgumentsObject>(scope, o)->fullyCreate();
- o->extensible = false;
+ o->setExtensible(false);
- o->internalClass = o->internalClass->frozen();
+ o->setInternalClass(o->internalClass()->frozen());
- if (o->arrayData) {
+ if (o->arrayData()) {
ArrayData::ensureAttributes(o.getPointer());
- for (uint i = 0; i < o->arrayData->alloc; ++i) {
- if (!o->arrayData->isEmpty(i))
- o->arrayData->attrs[i].setConfigurable(false);
- if (o->arrayData->attrs[i].isData())
- o->arrayData->attrs[i].setWritable(false);
+ for (uint i = 0; i < o->arrayData()->alloc(); ++i) {
+ if (!o->arrayData()->isEmpty(i))
+ o->arrayData()->attrs()[i].setConfigurable(false);
+ if (o->arrayData()->attrs()[i].isData())
+ o->arrayData()->attrs()[i].setWritable(false);
}
}
return o.asReturnedValue();
@@ -316,7 +317,7 @@ ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- o->extensible = false;
+ o->setExtensible(false);
return o.asReturnedValue();
}
@@ -327,22 +328,22 @@ ReturnedValue ObjectPrototype::method_isSealed(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- if (o->extensible)
+ if (o->isExtensible())
return Encode(false);
- if (o->internalClass != o->internalClass->sealed())
+ if (o->internalClass() != o->internalClass()->sealed())
return Encode(false);
- if (!o->arrayData || !o->arrayData->length())
+ if (!o->arrayData() || !o->arrayData()->length())
return Encode(true);
- if (o->arrayData->length() && !o->arrayData->attrs)
+ if (o->arrayData()->length() && !o->arrayData()->attrs())
return Encode(false);
- for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ for (uint i = 0; i < o->arrayData()->alloc(); ++i) {
// ### Fix for sparse arrays
- if (!o->arrayData->isEmpty(i))
- if (o->arrayData->attributes(i).isConfigurable())
+ if (!o->arrayData()->isEmpty(i))
+ if (o->arrayData()->attributes(i).isConfigurable())
return Encode(false);
}
@@ -356,22 +357,22 @@ ReturnedValue ObjectPrototype::method_isFrozen(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- if (o->extensible)
+ if (o->isExtensible())
return Encode(false);
- if (o->internalClass != o->internalClass->frozen())
+ if (o->internalClass() != o->internalClass()->frozen())
return Encode(false);
- if (!o->arrayData->length())
+ if (!o->arrayData()->length())
return Encode(true);
- if (o->arrayData->length() && !o->arrayData->attrs)
+ if (o->arrayData()->length() && !o->arrayData()->attrs())
return Encode(false);
- for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ for (uint i = 0; i < o->arrayData()->alloc(); ++i) {
// ### Fix for sparse arrays
- if (!o->arrayData->isEmpty(i))
- if (o->arrayData->attributes(i).isConfigurable() || o->arrayData->attributes(i).isWritable())
+ if (!o->arrayData()->isEmpty(i))
+ if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable())
return Encode(false);
}
@@ -385,7 +386,7 @@ ReturnedValue ObjectPrototype::method_isExtensible(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- return Encode((bool)o->extensible);
+ return Encode((bool)o->isExtensible());
}
ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
@@ -395,7 +396,7 @@ ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
@@ -412,24 +413,24 @@ ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
ReturnedValue ObjectPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- if (ctx->callData->thisObject.isUndefined()) {
- return ctx->engine->newString(QStringLiteral("[object Undefined]"))->asReturnedValue();
- } else if (ctx->callData->thisObject.isNull()) {
- return ctx->engine->newString(QStringLiteral("[object Null]"))->asReturnedValue();
+ if (ctx->d()->callData->thisObject.isUndefined()) {
+ return ctx->d()->engine->newString(QStringLiteral("[object Undefined]"))->asReturnedValue();
+ } else if (ctx->d()->callData->thisObject.isNull()) {
+ return ctx->d()->engine->newString(QStringLiteral("[object Null]"))->asReturnedValue();
} else {
- ScopedObject obj(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->callData->thisObject)));
+ ScopedObject obj(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->d()->callData->thisObject)));
QString className = obj->className();
- return ctx->engine->newString(QString::fromLatin1("[object %1]").arg(className))->asReturnedValue();
+ return ctx->d()->engine->newString(QString::fromLatin1("[object %1]").arg(className))->asReturnedValue();
}
}
ReturnedValue ObjectPrototype::method_toLocaleString(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject o(scope, ctx->callData->thisObject.toObject(ctx));
+ ScopedObject o(scope, ctx->d()->callData->thisObject.toObject(ctx));
if (!o)
return Encode::undefined();
- Scoped<FunctionObject> f(scope, o->get(ctx->engine->id_toString));
+ Scoped<FunctionObject> f(scope, o->get(ctx->d()->engine->id_toString));
if (!f)
return ctx->throwTypeError();
ScopedCallData callData(scope, 0);
@@ -440,8 +441,8 @@ ReturnedValue ObjectPrototype::method_toLocaleString(CallContext *ctx)
ReturnedValue ObjectPrototype::method_valueOf(CallContext *ctx)
{
Scope scope(ctx);
- ScopedValue v(scope, ctx->callData->thisObject.toObject(ctx));
- if (ctx->engine->hasException)
+ ScopedValue v(scope, ctx->d()->callData->thisObject.toObject(ctx));
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
return v.asReturnedValue();
}
@@ -452,12 +453,12 @@ ReturnedValue ObjectPrototype::method_hasOwnProperty(CallContext *ctx)
Scoped<String> P(scope, ctx->argument(0), Scoped<String>::Convert);
if (scope.engine->hasException)
return Encode::undefined();
- Scoped<Object> O(scope, ctx->callData->thisObject, Scoped<Object>::Convert);
+ Scoped<Object> O(scope, ctx->d()->callData->thisObject, Scoped<Object>::Convert);
if (scope.engine->hasException)
return Encode::undefined();
- bool r = O->hasOwnProperty(P);
+ bool r = O->hasOwnProperty(P.getPointer());
if (!r)
- r = !O->query(P).isEmpty();
+ r = !O->query(P.getPointer()).isEmpty();
return Encode(r);
}
@@ -468,7 +469,7 @@ ReturnedValue ObjectPrototype::method_isPrototypeOf(CallContext *ctx)
if (!V)
return Encode(false);
- Scoped<Object> O(scope, ctx->callData->thisObject, Scoped<Object>::Convert);
+ Scoped<Object> O(scope, ctx->d()->callData->thisObject, Scoped<Object>::Convert);
if (scope.engine->hasException)
return Encode::undefined();
Scoped<Object> proto(scope, V->prototype());
@@ -487,17 +488,17 @@ ReturnedValue ObjectPrototype::method_propertyIsEnumerable(CallContext *ctx)
if (scope.engine->hasException)
return Encode::undefined();
- Scoped<Object> o(scope, ctx->callData->thisObject, Scoped<Object>::Convert);
+ Scoped<Object> o(scope, ctx->d()->callData->thisObject, Scoped<Object>::Convert);
if (scope.engine->hasException)
return Encode::undefined();
PropertyAttributes attrs;
- o->__getOwnProperty__(p, &attrs);
+ o->__getOwnProperty__(p.getPointer(), &attrs);
return Encode(attrs.isEnumerable());
}
ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
{
- if (ctx->callData->argc < 2)
+ if (ctx->d()->callData->argc < 2)
return ctx->throwTypeError();
Scope scope(ctx);
@@ -509,23 +510,23 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
if (scope.engine->hasException)
return Encode::undefined();
- Scoped<Object> o(scope, ctx->callData->thisObject);
+ Scoped<Object> o(scope, ctx->d()->callData->thisObject);
if (!o) {
- if (!ctx->callData->thisObject.isUndefined())
+ if (!ctx->d()->callData->thisObject.isUndefined())
return Encode::undefined();
- o = ctx->engine->globalObject;
+ o = ctx->d()->engine->globalObject;
}
Property pd;
pd.value = f;
pd.set = Primitive::emptyValue();
- o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
+ o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
return Encode::undefined();
}
ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
{
- if (ctx->callData->argc < 2)
+ if (ctx->d()->callData->argc < 2)
return ctx->throwTypeError();
Scope scope(ctx);
@@ -537,24 +538,24 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
if (scope.engine->hasException)
return Encode::undefined();
- Scoped<Object> o(scope, ctx->callData->thisObject);
+ Scoped<Object> o(scope, ctx->d()->callData->thisObject);
if (!o) {
- if (!ctx->callData->thisObject.isUndefined())
+ if (!ctx->d()->callData->thisObject.isUndefined())
return Encode::undefined();
- o = ctx->engine->globalObject;
+ o = ctx->d()->engine->globalObject;
}
Property pd;
pd.value = Primitive::emptyValue();
pd.set = f;
- o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
+ o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
return Encode::undefined();
}
ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject o(scope, ctx->callData->thisObject.asObject());
+ ScopedObject o(scope, ctx->d()->callData->thisObject.asObject());
if (!o)
return ctx->throwTypeError();
@@ -564,21 +565,21 @@ ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<Object> o(scope, ctx->callData->thisObject);
- if (!o || !ctx->callData->argc)
+ Scoped<Object> o(scope, ctx->d()->callData->thisObject);
+ if (!o || !ctx->d()->callData->argc)
return ctx->throwTypeError();
- if (ctx->callData->args[0].isNull()) {
+ if (ctx->d()->callData->args[0].isNull()) {
o->setPrototype(0);
return Encode::undefined();
}
- Scoped<Object> p(scope, ctx->callData->args[0]);
+ Scoped<Object> p(scope, ctx->d()->callData->args[0]);
bool ok = false;
if (!!p) {
if (o->prototype() == p.getPointer()) {
ok = true;
- } else if (o->extensible) {
+ } else if (o->isExtensible()) {
ok = o->setPrototype(p.getPointer());
}
}
@@ -601,14 +602,14 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
desc->set = Primitive::emptyValue();
ScopedValue tmp(scope);
- if (o->hasProperty(ctx->engine->id_enumerable))
- attrs->setEnumerable((tmp = o->get(ctx->engine->id_enumerable))->toBoolean());
+ if (o->hasProperty(ctx->d()->engine->id_enumerable))
+ attrs->setEnumerable((tmp = o->get(ctx->d()->engine->id_enumerable))->toBoolean());
- if (o->hasProperty(ctx->engine->id_configurable))
- attrs->setConfigurable((tmp = o->get(ctx->engine->id_configurable))->toBoolean());
+ if (o->hasProperty(ctx->d()->engine->id_configurable))
+ attrs->setConfigurable((tmp = o->get(ctx->d()->engine->id_configurable))->toBoolean());
- if (o->hasProperty(ctx->engine->id_get)) {
- ScopedValue get(scope, o->get(ctx->engine->id_get));
+ if (o->hasProperty(ctx->d()->engine->id_get)) {
+ ScopedValue get(scope, o->get(ctx->d()->engine->id_get));
FunctionObject *f = get->asFunctionObject();
if (f || get->isUndefined()) {
desc->value = get;
@@ -619,8 +620,8 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->hasProperty(ctx->engine->id_set)) {
- ScopedValue set(scope, o->get(ctx->engine->id_set));
+ if (o->hasProperty(ctx->d()->engine->id_set)) {
+ ScopedValue set(scope, o->get(ctx->d()->engine->id_set));
FunctionObject *f = set->asFunctionObject();
if (f || set->isUndefined()) {
desc->set = set;
@@ -631,22 +632,22 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->hasProperty(ctx->engine->id_writable)) {
+ if (o->hasProperty(ctx->d()->engine->id_writable)) {
if (attrs->isAccessor()) {
ctx->throwTypeError();
return;
}
- attrs->setWritable((tmp = o->get(ctx->engine->id_writable))->toBoolean());
+ attrs->setWritable((tmp = o->get(ctx->d()->engine->id_writable))->toBoolean());
// writable forces it to be a data descriptor
desc->value = Primitive::undefinedValue();
}
- if (o->hasProperty(ctx->engine->id_value)) {
+ if (o->hasProperty(ctx->d()->engine->id_value)) {
if (attrs->isAccessor()) {
ctx->throwTypeError();
return;
}
- desc->value = o->get(ctx->engine->id_value);
+ desc->value = o->get(ctx->d()->engine->id_value);
attrs->setType(PropertyAttributes::Data);
}
@@ -660,7 +661,7 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
if (!desc)
return Encode::undefined();
- ExecutionEngine *engine = ctx->engine;
+ ExecutionEngine *engine = ctx->d()->engine;
Scope scope(engine);
// Let obj be the result of creating a new object as if by the expression new Object() where Object
// is the standard built-in constructor with that name.
@@ -671,24 +672,24 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
if (attrs.isData()) {
pd.value = desc->value;
s = engine->newString(QStringLiteral("value"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
pd.value = Primitive::fromBoolean(attrs.isWritable());
s = engine->newString(QStringLiteral("writable"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
} else {
pd.value = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
s = engine->newString(QStringLiteral("get"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
pd.value = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
s = engine->newString(QStringLiteral("set"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
}
pd.value = Primitive::fromBoolean(attrs.isEnumerable());
s = engine->newString(QStringLiteral("enumerable"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
pd.value = Primitive::fromBoolean(attrs.isConfigurable());
s = engine->newString(QStringLiteral("configurable"));
- o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
+ o->__defineOwnProperty__(ctx, s.getPointer(), pd, Attr_Data);
return o.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index 2b9974be06..c34b367223 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -51,8 +51,10 @@ namespace QV4 {
struct ObjectCtor: FunctionObject
{
- V4_OBJECT
- ObjectCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *that, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -60,9 +62,7 @@ struct ObjectCtor: FunctionObject
struct ObjectPrototype: Object
{
- ObjectPrototype(InternalClass *ic) : Object(ic) {}
-
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_getPrototypeOf(CallContext *ctx);
static ReturnedValue method_getOwnPropertyDescriptor(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index 21f37f3d96..7b0f80e06a 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -84,13 +84,11 @@ public:
PersistentValue(ReturnedValue val);
template<typename T>
PersistentValue(Returned<T> *obj);
- PersistentValue(const ManagedRef obj);
PersistentValue &operator=(const ValueRef other);
PersistentValue &operator=(const ScopedValue &other);
PersistentValue &operator =(ReturnedValue other);
template<typename T>
PersistentValue &operator=(Returned<T> *obj);
- PersistentValue &operator=(const ManagedRef obj);
~PersistentValue();
ReturnedValue value() const {
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index 8a0cc56448..b70e9de1a0 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qv4profiling_p.h"
+#include "qv4mm_p.h"
QT_BEGIN_NAMESPACE
@@ -60,10 +61,12 @@ FunctionCallProperties FunctionCall::resolve() const
}
-Profiler::Profiler() : enabled(false)
+Profiler::Profiler(QV4::ExecutionEngine *engine) : enabled(false), m_engine(engine)
{
static int metatype = qRegisterMetaType<QList<QV4::Profiling::FunctionCallProperties> >();
+ static int metatype2 = qRegisterMetaType<QList<QV4::Profiling::MemoryAllocationProperties> >();
Q_UNUSED(metatype);
+ Q_UNUSED(metatype2);
m_timer.start();
}
@@ -87,13 +90,29 @@ void Profiler::reportData()
FunctionCallProperties props = call.resolve();
resolved.insert(std::upper_bound(resolved.begin(), resolved.end(), props, comp), props);
}
- emit dataReady(resolved);
+ emit dataReady(resolved, m_memory_data);
}
void Profiler::startProfiling()
{
if (!enabled) {
m_data.clear();
+ m_memory_data.clear();
+
+ qint64 timestamp = m_timer.nsecsElapsed();
+ MemoryAllocationProperties heap = {timestamp,
+ (qint64)m_engine->memoryManager->getAllocatedMem(),
+ HeapPage};
+ m_memory_data.append(heap);
+ MemoryAllocationProperties small = {timestamp,
+ (qint64)m_engine->memoryManager->getUsedMem(),
+ SmallItem};
+ m_memory_data.append(small);
+ MemoryAllocationProperties large = {timestamp,
+ (qint64)m_engine->memoryManager->getLargeItemsMem(),
+ LargeItem};
+ m_memory_data.append(large);
+
enabled = true;
}
}
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index 6869b3134d..b9ddac0309 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -54,6 +54,12 @@ namespace QV4 {
namespace Profiling {
+enum MemoryType {
+ HeapPage,
+ LargeItem,
+ SmallItem
+};
+
struct FunctionCallProperties {
qint64 start;
qint64 end;
@@ -63,6 +69,12 @@ struct FunctionCallProperties {
int column;
};
+struct MemoryAllocationProperties {
+ qint64 timestamp;
+ qint64 size;
+ MemoryType type;
+};
+
class FunctionCall {
public:
@@ -101,6 +113,14 @@ private:
qint64 m_end;
};
+#define Q_V4_PROFILE_ALLOC(engine, size, type)\
+ (engine->profiler && engine->profiler->enabled ?\
+ engine->profiler->trackAlloc(size, type) : size)
+
+#define Q_V4_PROFILE_DEALLOC(engine, pointer, size, type) \
+ (engine->profiler && engine->profiler->enabled ?\
+ engine->profiler->trackDealloc(pointer, size, type) : pointer)
+
#define Q_V4_PROFILE(engine, ctx, function)\
((engine->profiler && engine->profiler->enabled) ?\
Profiling::FunctionCallProfiler::profileCall(engine->profiler, ctx, function) :\
@@ -110,7 +130,21 @@ class Q_QML_EXPORT Profiler : public QObject {
Q_OBJECT
Q_DISABLE_COPY(Profiler)
public:
- Profiler();
+ Profiler(QV4::ExecutionEngine *engine);
+
+ size_t trackAlloc(size_t size, MemoryType type)
+ {
+ MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), (qint64)size, type};
+ m_memory_data.append(allocation);
+ return size;
+ }
+
+ void *trackDealloc(void *pointer, size_t size, MemoryType type)
+ {
+ MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), -(qint64)size, type};
+ m_memory_data.append(allocation);
+ return pointer;
+ }
bool enabled;
@@ -121,11 +155,14 @@ public slots:
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
signals:
- void dataReady(const QList<QV4::Profiling::FunctionCallProperties> &);
+ void dataReady(const QList<QV4::Profiling::FunctionCallProperties> &,
+ const QList<QV4::Profiling::MemoryAllocationProperties> &);
private:
+ QV4::ExecutionEngine *m_engine;
QElapsedTimer m_timer;
QVector<FunctionCall> m_data;
+ QList<MemoryAllocationProperties> m_memory_data;
friend class FunctionCallProfiler;
};
@@ -160,10 +197,12 @@ public:
} // namespace Profiling
} // namespace QV4
+Q_DECLARE_TYPEINFO(QV4::Profiling::MemoryAllocationProperties, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QV4::Profiling::FunctionCallProperties, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QV4::Profiling::FunctionCall, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QList<QV4::Profiling::FunctionCallProperties>)
+Q_DECLARE_METATYPE(QList<QV4::Profiling::MemoryAllocationProperties>)
#endif // QV4PROFILING_H
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index d64f821a38..e12b8f1756 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -87,7 +87,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-static QPair<QObject *, int> extractQtMethod(QV4::FunctionObjectRef function)
+static QPair<QObject *, int> extractQtMethod(QV4::FunctionObject *function)
{
QV4::ExecutionEngine *v4 = function->engine();
if (v4) {
@@ -239,14 +239,11 @@ static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object,
}
}
-QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
- : Object(engine)
- , m_object(object)
+QObjectWrapper::Data::Data(ExecutionEngine *engine, QObject *object)
+ : Object::Data(engine)
+ , object(object)
{
setVTable(staticVTable());
-
- Scope scope(engine);
- ScopedObject protectThis(scope, this);
}
void QObjectWrapper::initializeBindings(ExecutionEngine *engine)
@@ -259,21 +256,21 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont
{
Q_UNUSED(revisionMode);
- QQmlData *ddata = QQmlData::get(m_object, false);
+ QQmlData *ddata = QQmlData::get(d()->object, false);
if (!ddata)
return 0;
QQmlPropertyData *result = 0;
if (ddata && ddata->propertyCache)
- result = ddata->propertyCache->property(name, m_object, qmlContext);
+ result = ddata->propertyCache->property(name, d()->object, qmlContext);
else
- result = QQmlPropertyCache::property(engine->v8Engine->engine(), m_object, name, qmlContext, *local);
+ result = QQmlPropertyCache::property(engine->v8Engine->engine(), d()->object, name, qmlContext, *local);
return result;
}
ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *n, QObjectWrapper::RevisionMode revisionMode,
bool *hasProperty, bool includeImports)
{
- if (QQmlData::wasDeleted(m_object)) {
+ if (QQmlData::wasDeleted(d()->object)) {
if (hasProperty)
*hasProperty = false;
return QV4::Encode::undefined();
@@ -284,14 +281,14 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD
if (name->equals(scope.engine->id_destroy) || name->equals(scope.engine->id_toString)) {
int index = name->equals(scope.engine->id_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod;
- QV4::ScopedValue method(scope, QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index));
+ QV4::ScopedValue method(scope, QV4::QObjectMethod::create(ctx->d()->engine->rootContext, d()->object, index));
if (hasProperty)
*hasProperty = true;
return method.asReturnedValue();
}
QQmlPropertyData local;
- QQmlPropertyData *result = findProperty(ctx->engine, qmlContext, name.getPointer(), revisionMode, &local);
+ QQmlPropertyData *result = findProperty(ctx->d()->engine, qmlContext, name.getPointer(), revisionMode, &local);
if (!result) {
if (includeImports && name->startsWithUpper()) {
@@ -306,18 +303,18 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD
if (r.scriptIndex != -1) {
return QV4::Encode::undefined();
} else if (r.type) {
- return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums);
+ return QmlTypeWrapper::create(ctx->d()->engine->v8Engine, d()->object, r.type, QmlTypeWrapper::ExcludeEnums);
} else if (r.importNamespace) {
- return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, qmlContext->imports, r.importNamespace, QmlTypeWrapper::ExcludeEnums);
+ return QmlTypeWrapper::create(ctx->d()->engine->v8Engine, d()->object, qmlContext->imports, r.importNamespace, QmlTypeWrapper::ExcludeEnums);
}
Q_ASSERT(!"Unreachable");
}
}
}
- return QV4::Object::get(this, name, hasProperty);
+ return QV4::Object::get(this, name.getPointer(), hasProperty);
}
- QQmlData *ddata = QQmlData::get(m_object, false);
+ QQmlData *ddata = QQmlData::get(d()->object, false);
if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) {
if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) {
@@ -330,7 +327,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD
if (hasProperty)
*hasProperty = true;
- return getProperty(m_object, ctx, result);
+ return getProperty(d()->object, ctx, result);
}
ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx, QQmlPropertyData *property, bool captureRequired)
@@ -345,23 +342,23 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
Q_ASSERT(vmemo);
return vmemo->vmeMethod(property->coreIndex);
} else if (property->isV4Function()) {
- QV4::Scoped<QV4::Object> qmlcontextobject(scope, ctx->engine->qmlContextObject());
- return QV4::QObjectMethod::create(ctx->engine->rootContext, object, property->coreIndex, qmlcontextobject);
+ QV4::Scoped<QV4::Object> qmlcontextobject(scope, ctx->d()->engine->qmlContextObject());
+ return QV4::QObjectMethod::create(ctx->d()->engine->rootContext, object, property->coreIndex, qmlcontextobject);
} else if (property->isSignalHandler()) {
- QV4::Scoped<QV4::QmlSignalHandler> handler(scope, new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, object, property->coreIndex));
+ QV4::Scoped<QV4::QmlSignalHandler> handler(scope, scope.engine->memoryManager->alloc<QV4::QmlSignalHandler>(ctx->d()->engine, object, property->coreIndex));
- QV4::ScopedString connect(scope, ctx->engine->newIdentifier(QStringLiteral("connect")));
- QV4::ScopedString disconnect(scope, ctx->engine->newIdentifier(QStringLiteral("disconnect")));
- handler->put(connect, QV4::ScopedValue(scope, ctx->engine->functionClass->prototype->get(connect)));
- handler->put(disconnect, QV4::ScopedValue(scope, ctx->engine->functionClass->prototype->get(disconnect)));
+ QV4::ScopedString connect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("connect")));
+ QV4::ScopedString disconnect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("disconnect")));
+ handler->put(connect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionClass->prototype->get(connect.getPointer())));
+ handler->put(disconnect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionClass->prototype->get(disconnect.getPointer())));
return handler.asReturnedValue();
} else {
- return QV4::QObjectMethod::create(ctx->engine->rootContext, object, property->coreIndex);
+ return QV4::QObjectMethod::create(ctx->d()->engine->rootContext, object, property->coreIndex);
}
}
- QQmlEnginePrivate *ep = ctx->engine->v8Engine->engine() ? QQmlEnginePrivate::get(ctx->engine->v8Engine->engine()) : 0;
+ QQmlEnginePrivate *ep = ctx->d()->engine->v8Engine->engine() ? QQmlEnginePrivate::get(ctx->d()->engine->v8Engine->engine()) : 0;
if (property->hasAccessors()) {
QQmlNotifier *n = 0;
@@ -370,7 +367,7 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
if (ep && ep->propertyCapture && property->accessors->notifier)
nptr = &n;
- QV4::ScopedValue rv(scope, LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, object, *property, nptr));
+ QV4::ScopedValue rv(scope, LoadProperty<ReadAccessor::Accessor>(ctx->d()->engine->v8Engine, object, *property, nptr));
if (captureRequired) {
if (property->accessors->notifier) {
@@ -392,9 +389,9 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
Q_ASSERT(vmemo);
return vmemo->vmeProperty(property->coreIndex);
} else if (property->isDirect()) {
- return LoadProperty<ReadAccessor::Direct>(ctx->engine->v8Engine, object, *property, 0);
+ return LoadProperty<ReadAccessor::Direct>(ctx->d()->engine->v8Engine, object, *property, 0);
} else {
- return LoadProperty<ReadAccessor::Indirect>(ctx->engine->v8Engine, object, *property, 0);
+ return LoadProperty<ReadAccessor::Indirect>(ctx->d()->engine->v8Engine, object, *property, 0);
}
}
@@ -413,7 +410,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD
return QV4::Encode::null();
}
- QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(ctx->engine, object));
+ QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(ctx->d()->engine, object));
if (!wrapper) {
if (hasProperty)
*hasProperty = false;
@@ -431,7 +428,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC
QQmlPropertyData local;
QQmlPropertyData *result = 0;
{
- result = QQmlPropertyCache::property(ctx->engine->v8Engine->engine(), object, name, qmlContext, local);
+ result = QQmlPropertyCache::property(ctx->d()->engine->v8Engine->engine(), object, name, qmlContext, local);
}
if (!result)
@@ -460,7 +457,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
QV4::Scope scope(ctx);
QV4::ScopedFunctionObject f(scope, value);
if (f) {
- if (!f->bindingKeyFlag) {
+ if (!f->bindingKeyFlag()) {
if (!property->isVarProperty() && property->propType != qMetaTypeId<QJSValue>()) {
// assigning a JS function to a non var or QJSValue property or is not allowed.
QString error = QLatin1String("Cannot assign JavaScript function to ");
@@ -473,7 +470,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
}
} else {
// binding assignment.
- QQmlContextData *callingQmlContext = QV4::QmlContextWrapper::callingContext(ctx->engine);
+ QQmlContextData *callingQmlContext = QV4::QmlContextWrapper::callingContext(ctx->d()->engine);
QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, f);
bindingFunction->initBindingLocation();
@@ -513,7 +510,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
} else if (value->isUndefined() && property->propType == QMetaType::QJsonValue) {
PROPERTY_STORE(QJsonValue, QJsonValue(QJsonValue::Undefined));
} else if (!newBinding && property->propType == qMetaTypeId<QJSValue>()) {
- PROPERTY_STORE(QJSValue, new QJSValuePrivate(ctx->engine, value));
+ PROPERTY_STORE(QJSValue, new QJSValuePrivate(ctx->d()->engine, value));
} else if (value->isUndefined()) {
QString error = QLatin1String("Cannot assign [undefined] to ");
if (!QMetaType::typeName(property->propType))
@@ -541,11 +538,11 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
} else {
QVariant v;
if (property->isQList())
- v = ctx->engine->v8Engine->toVariant(value, qMetaTypeId<QList<QObject *> >());
+ v = ctx->d()->engine->v8Engine->toVariant(value, qMetaTypeId<QList<QObject *> >());
else
- v = ctx->engine->v8Engine->toVariant(value, property->propType);
+ v = ctx->d()->engine->v8Engine->toVariant(value, property->propType);
- QQmlContextData *callingQmlContext = QV4::QmlContextWrapper::callingContext(ctx->engine);
+ QQmlContextData *callingQmlContext = QV4::QmlContextWrapper::callingContext(ctx->d()->engine);
if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
const char *valueType = 0;
if (v.userType() == QVariant::Invalid) valueType = "null";
@@ -634,9 +631,9 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
void QObjectWrapper::setProperty(ExecutionContext *ctx, int propertyIndex, const ValueRef value)
{
- if (QQmlData::wasDeleted(m_object))
+ if (QQmlData::wasDeleted(d()->object))
return;
- QQmlData *ddata = QQmlData::get(m_object, /*create*/false);
+ QQmlData *ddata = QQmlData::get(d()->object, /*create*/false);
if (!ddata)
return;
@@ -644,7 +641,7 @@ void QObjectWrapper::setProperty(ExecutionContext *ctx, int propertyIndex, const
Q_ASSERT(cache);
QQmlPropertyData *property = cache->property(propertyIndex);
Q_ASSERT(property); // We resolved this property earlier, so it better exist!
- return setProperty(m_object, ctx, property, value);
+ return setProperty(d()->object, ctx, property, value);
}
bool QObjectWrapper::isEqualTo(Managed *a, Managed *b)
@@ -661,28 +658,28 @@ ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
QQmlEngine *qmlEngine = engine->v8Engine->engine();
if (qmlEngine)
QQmlData::ensurePropertyCache(qmlEngine, object);
- return (new (engine->memoryManager) QV4::QObjectWrapper(engine, object))->asReturnedValue();
+ return (engine->memoryManager->alloc<QV4::QObjectWrapper>(engine, object))->asReturnedValue();
}
-QV4::ReturnedValue QObjectWrapper::get(Managed *m, const StringRef name, bool *hasProperty)
+QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty)
{
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = m->engine();
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4);
- return that->getQmlProperty(v4->currentContext(), qmlContext, name.getPointer(), IgnoreRevision, hasProperty, /*includeImports*/ true);
+ return that->getQmlProperty(v4->currentContext(), qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
-void QObjectWrapper::put(Managed *m, const StringRef name, const ValueRef value)
+void QObjectWrapper::put(Managed *m, String *name, const ValueRef value)
{
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = m->engine();
- if (v4->hasException || QQmlData::wasDeleted(that->m_object))
+ if (v4->hasException || QQmlData::wasDeleted(that->d()->object))
return;
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4);
- if (!setQmlProperty(v4->currentContext(), qmlContext, that->m_object, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value)) {
- QQmlData *ddata = QQmlData::get(that->m_object);
+ if (!setQmlProperty(v4->currentContext(), qmlContext, that->d()->object, name, QV4::QObjectWrapper::IgnoreRevision, value)) {
+ QQmlData *ddata = QQmlData::get(that->d()->object);
// Types created by QML are not extensible at run-time, but for other QObjects we can store them
// as regular JavaScript properties, like on JavaScript objects.
if (ddata && ddata->context) {
@@ -695,7 +692,7 @@ void QObjectWrapper::put(Managed *m, const StringRef name, const ValueRef value)
}
}
-PropertyAttributes QObjectWrapper::query(const Managed *m, StringRef name)
+PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
{
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
ExecutionEngine *engine = that->engine();
@@ -708,27 +705,36 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, StringRef name)
return QV4::Object::query(m, name);
}
-void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes)
+void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes)
{
+ // Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
+ static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
+ static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
+ static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
+
name = (String *)0;
*index = UINT_MAX;
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
- if (that->m_object) {
- const QMetaObject *mo = that->m_object->metaObject();
+ if (that->d()->object) {
+ const QMetaObject *mo = that->d()->object->metaObject();
const int propertyCount = mo->propertyCount();
if (it->arrayIndex < static_cast<uint>(propertyCount)) {
- name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()));
+ name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()))->getPointer();
++it->arrayIndex;
*attributes = QV4::Attr_Data;
p->value = that->get(name);
return;
}
const int methodCount = mo->methodCount();
- if (it->arrayIndex < static_cast<uint>(propertyCount + methodCount)) {
- name = that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name()));
+ while (it->arrayIndex < static_cast<uint>(propertyCount + methodCount)) {
+ const int index = it->arrayIndex - propertyCount;
+ const QMetaMethod method = mo->method(index);
++it->arrayIndex;
+ if (method.access() == QMetaMethod::Private || index == deleteLaterIdx || index == destroyedIdx1 || index == destroyedIdx2)
+ continue;
+ name = that->engine()->newString(QString::fromUtf8(method.name()))->getPointer();
*attributes = QV4::Attr_Data;
p->value = that->get(name);
return;
@@ -857,10 +863,10 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
{
- if (ctx->callData->argc == 0)
+ if (ctx->d()->callData->argc == 0)
V4THROW_ERROR("Function.prototype.connect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(ctx->d()->callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second; // in method range, not signal range!
@@ -877,11 +883,11 @@ ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
QV4::ScopedFunctionObject f(scope);
QV4::ScopedValue thisObject (scope, QV4::Encode::undefined());
- if (ctx->callData->argc == 1) {
- f = ctx->callData->args[0];
- } else if (ctx->callData->argc >= 2) {
- thisObject = ctx->callData->args[0];
- f = ctx->callData->args[1];
+ if (ctx->d()->callData->argc == 1) {
+ f = ctx->d()->callData->args[0];
+ } else if (ctx->d()->callData->argc >= 2) {
+ thisObject = ctx->d()->callData->args[0];
+ f = ctx->d()->callData->args[1];
}
if (!f)
@@ -908,12 +914,12 @@ ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
{
- if (ctx->callData->argc == 0)
+ if (ctx->d()->callData->argc == 0)
V4THROW_ERROR("Function.prototype.disconnect: no arguments given");
QV4::Scope scope(ctx);
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(ctx->d()->callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second;
@@ -929,11 +935,11 @@ ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
QV4::ScopedFunctionObject functionValue(scope);
QV4::ScopedValue functionThisValue(scope, QV4::Encode::undefined());
- if (ctx->callData->argc == 1) {
- functionValue = ctx->callData->args[0];
- } else if (ctx->callData->argc >= 2) {
- functionThisValue = ctx->callData->args[0];
- functionValue = ctx->callData->args[1];
+ if (ctx->d()->callData->argc == 1) {
+ functionValue = ctx->d()->callData->args[0];
+ } else if (ctx->d()->callData->argc >= 2) {
+ functionThisValue = ctx->d()->callData->args[0];
+ functionValue = ctx->d()->callData->args[1];
}
if (!functionValue)
@@ -945,7 +951,7 @@ ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
QPair<QObject *, int> functionData = extractQtMethod(functionValue);
void *a[] = {
- ctx->engine,
+ ctx->d()->engine,
functionValue.ptr,
functionThisValue.ptr,
functionData.first,
@@ -975,7 +981,7 @@ void QObjectWrapper::markObjects(Managed *that, QV4::ExecutionEngine *e)
{
QObjectWrapper *This = static_cast<QObjectWrapper*>(that);
- if (QObject *o = This->m_object.data()) {
+ if (QObject *o = This->d()->object.data()) {
QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o);
if (vme)
vme->mark(e);
@@ -1017,9 +1023,9 @@ namespace {
void QObjectWrapper::destroy(Managed *that)
{
QObjectWrapper *This = static_cast<QObjectWrapper*>(that);
- QPointer<QObject> object = This->m_object;
+ QPointer<QObject> object = This->d()->object;
ExecutionEngine *engine = This->engine();
- This->~QObjectWrapper();
+ This->d()->~Data();
This = 0;
if (!object)
return;
@@ -1728,7 +1734,7 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
QVariant value = *qvariantPtr;
QV4::ScopedValue rv(scope, engine->fromVariant(value));
- QV4::QObjectWrapperRef qobjectWrapper = rv;
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, rv);
if (!!qobjectWrapper) {
if (QObject *object = qobjectWrapper->object())
QQmlData::get(object, true)->setImplicitDestructible();
@@ -1741,28 +1747,28 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal)
{
- return (new (scope->engine->memoryManager) QObjectMethod(scope, object, index, qmlGlobal))->asReturnedValue();
+ return (scope->d()->engine->memoryManager->alloc<QObjectMethod>(scope, object, index, qmlGlobal))->asReturnedValue();
}
-QObjectMethod::QObjectMethod(ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal)
- : FunctionObject(scope)
- , m_object(object)
- , m_index(index)
+QObjectMethod::Data::Data(ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal)
+ : FunctionObject::Data(scope)
+ , object(object)
+ , index(index)
+ , qmlGlobal(qmlGlobal)
{
setVTable(staticVTable());
subtype = WrappedQtMethod;
- m_qmlGlobal = qmlGlobal;
}
QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
{
QString result;
- if (m_object) {
- QString objectName = m_object->objectName();
+ if (d()->object) {
+ QString objectName = d()->object->objectName();
- result += QString::fromUtf8(m_object->metaObject()->className());
+ result += QString::fromUtf8(d()->object->metaObject()->className());
result += QLatin1String("(0x");
- result += QString::number((quintptr)m_object.data(),16);
+ result += QString::number((quintptr)d()->object.data(),16);
if (!objectName.isEmpty()) {
result += QLatin1String(", \"");
@@ -1775,14 +1781,14 @@ QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
result = QLatin1String("null");
}
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const ValueRef args, int argc)
{
- if (!m_object)
+ if (!d()->object)
return Encode::undefined();
- if (QQmlData::keepAliveDuringGarbageCollection(m_object))
+ if (QQmlData::keepAliveDuringGarbageCollection(d()->object))
return ctx->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
int delay = 0;
@@ -1790,9 +1796,9 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con
delay = args[0].toUInt32();
if (delay > 0)
- QTimer::singleShot(delay, m_object, SLOT(deleteLater()));
+ QTimer::singleShot(delay, d()->object, SLOT(deleteLater()));
else
- m_object->deleteLater();
+ d()->object->deleteLater();
return Encode::undefined();
}
@@ -1806,12 +1812,12 @@ ReturnedValue QObjectMethod::call(Managed *m, CallData *callData)
ReturnedValue QObjectMethod::callInternal(CallData *callData)
{
ExecutionContext *context = engine()->currentContext();
- if (m_index == DestroyMethod)
+ if (d()->index == DestroyMethod)
return method_destroy(context, callData->args, callData->argc);
- else if (m_index == ToStringMethod)
+ else if (d()->index == ToStringMethod)
return method_toString(context);
- QObject *object = m_object.data();
+ QObject *object = d()->object.data();
if (!object)
return Encode::undefined();
@@ -1819,7 +1825,7 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
if (!ddata)
return Encode::undefined();
- QV8Engine *v8Engine = context->engine->v8Engine;
+ QV8Engine *v8Engine = context->d()->engine->v8Engine;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8Engine);
QV4::Scope scope(v4);
@@ -1827,16 +1833,16 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
if (QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(object)->declarativeData)) {
if (ddata->propertyCache) {
- QQmlPropertyData *d = ddata->propertyCache->method(m_index);
- if (!d)
+ QQmlPropertyData *data = ddata->propertyCache->method(d()->index);
+ if (!data)
return QV4::Encode::undefined();
- method = *d;
+ method = *data;
}
}
if (method.coreIndex == -1) {
const QMetaObject *mo = object->metaObject();
- const QMetaMethod moMethod = mo->method(m_index);
+ const QMetaMethod moMethod = mo->method(d()->index);
method.load(moMethod);
if (method.coreIndex == -1)
@@ -1845,7 +1851,7 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
// Look for overloaded methods
QByteArray methodName = moMethod.name();
const int methodOffset = mo->methodOffset();
- for (int ii = m_index - 1; ii >= methodOffset; --ii) {
+ for (int ii = d()->index - 1; ii >= methodOffset; --ii) {
if (methodName == mo->method(ii).name()) {
method.setFlags(method.getFlags() | QQmlPropertyData::IsOverload);
method.overrideIndexIsProperty = 0;
@@ -1858,7 +1864,7 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
if (method.isV4Function()) {
QV4::ScopedValue rv(scope, QV4::Primitive::undefinedValue());
- QV4::ScopedValue qmlGlobal(scope, m_qmlGlobal.value());
+ QV4::ScopedValue qmlGlobal(scope, d()->qmlGlobal.value());
QQmlV4Function func(callData, rv, qmlGlobal,
QmlContextWrapper::getContext(qmlGlobal),
v8Engine);
@@ -1879,10 +1885,10 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
DEFINE_OBJECT_VTABLE(QObjectMethod);
-QmlSignalHandler::QmlSignalHandler(ExecutionEngine *engine, QObject *object, int signalIndex)
- : Object(engine)
- , m_object(object)
- , m_signalIndex(signalIndex)
+QmlSignalHandler::Data::Data(ExecutionEngine *engine, QObject *object, int signalIndex)
+ : Object::Data(engine)
+ , object(object)
+ , signalIndex(signalIndex)
{
setVTable(staticVTable());
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 0af01c5614..a774917713 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -77,13 +77,17 @@ struct QObjectSlotDispatcher;
struct Q_QML_EXPORT QObjectWrapper : public QV4::Object
{
- V4_OBJECT
+ struct Data : QV4::Object::Data {
+ Data(ExecutionEngine *engine, QObject *object);
+ QPointer<QObject> object;
+ };
+ V4_OBJECT(QV4::Object)
enum RevisionMode { IgnoreRevision, CheckRevision };
static void initializeBindings(ExecutionEngine *engine);
- QObject *object() const { return m_object.data(); }
+ QObject *object() const { return d()->object.data(); }
ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false);
static ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
@@ -106,16 +110,12 @@ private:
static ReturnedValue create(ExecutionEngine *engine, QObject *object);
- QObjectWrapper(ExecutionEngine *engine, QObject *object);
-
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
- QPointer<QObject> m_object;
-
- static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
- static void put(Managed *m, const StringRef name, const ValueRef value);
- static PropertyAttributes query(const Managed *, StringRef name);
- static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static void put(Managed *m, String *name, const ValueRef value);
+ static PropertyAttributes query(const Managed *, String *name);
+ static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Managed *that, QV4::ExecutionEngine *e);
static void destroy(Managed *that);
@@ -125,51 +125,52 @@ private:
struct QObjectMethod : public QV4::FunctionObject
{
- V4_OBJECT
+ struct Data : QV4::FunctionObject::Data {
+ Data(QV4::ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal);
+ QPointer<QObject> object;
+ int index;
+ QV4::PersistentValue qmlGlobal;
+ };
+ V4_OBJECT(QV4::FunctionObject)
enum { DestroyMethod = -1, ToStringMethod = -2 };
static ReturnedValue create(QV4::ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal = Primitive::undefinedValue());
- int methodIndex() const { return m_index; }
- QObject *object() const { return m_object.data(); }
-
-private:
- QObjectMethod(QV4::ExecutionContext *scope, QObject *object, int index, const ValueRef qmlGlobal);
+ 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 ValueRef args, int argc);
- QPointer<QObject> m_object;
- int m_index;
- QV4::PersistentValue m_qmlGlobal;
-
static ReturnedValue call(Managed *, CallData *callData);
ReturnedValue callInternal(CallData *callData);
static void destroy(Managed *that)
{
- static_cast<QObjectMethod *>(that)->~QObjectMethod();
+ static_cast<QObjectMethod *>(that)->d()->~Data();
}
};
struct QmlSignalHandler : public QV4::Object
{
- V4_OBJECT
+ struct Data : QV4::Object::Data {
+ Data(ExecutionEngine *engine, QObject *object, int signalIndex);
+ QPointer<QObject> object;
+ int signalIndex;
+ };
+ V4_OBJECT(QV4::Object)
- QmlSignalHandler(ExecutionEngine *engine, QObject *object, int signalIndex);
- int signalIndex() const { return m_signalIndex; }
- QObject *object() const { return m_object.data(); }
+ int signalIndex() const { return d()->signalIndex; }
+ QObject *object() const { return d()->object.data(); }
private:
- QPointer<QObject> m_object;
- int m_signalIndex;
static void destroy(Managed *that)
{
- static_cast<QmlSignalHandler *>(that)->~QmlSignalHandler();
+ static_cast<QmlSignalHandler *>(that)->d()->~Data();
}
};
@@ -195,8 +196,6 @@ private Q_SLOTS:
void removeDestroyedObject(QObject*);
};
-DEFINE_REF(QObjectWrapper, Object);
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index e5490cffd1..e2de584e31 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -42,6 +42,7 @@
#include "qv4regexp_p.h"
#include "qv4engine_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4mm_p.h"
using namespace QV4;
@@ -49,7 +50,7 @@ RegExpCache::~RegExpCache()
{
for (RegExpCache::Iterator it = begin(), e = end();
it != e; ++it)
- it.value()->m_cache = 0;
+ it.value()->d()->cache = 0;
clear();
}
@@ -63,11 +64,11 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
WTF::String s(string);
#if ENABLE(YARR_JIT)
- if (!m_jitCode.isFallBack() && m_jitCode.has16BitCode())
- return m_jitCode.execute(s.characters16(), start, s.length(), (int*)matchOffsets).start;
+ if (!jitCode().isFallBack() && jitCode().has16BitCode())
+ return jitCode().execute(s.characters16(), start, s.length(), (int*)matchOffsets).start;
#endif
- return JSC::Yarr::interpret(m_byteCode.get(), s.characters16(), string.length(), start, matchOffsets);
+ return JSC::Yarr::interpret(byteCode().get(), s.characters16(), string.length(), start, matchOffsets);
}
RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline)
@@ -80,53 +81,49 @@ RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ign
return result;
}
- RegExp *result = new (engine->memoryManager) RegExp(engine, pattern, ignoreCase, multiline);
+ RegExp *result = engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline);
if (!cache)
cache = engine->regExpCache = new RegExpCache;
- result->m_cache = cache;
+ result->d()->cache = cache;
cache->insert(key, result);
return result;
}
-RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline)
- : Managed(engine->regExpValueClass)
- , m_pattern(pattern)
- , m_cache(0)
- , m_subPatternCount(0)
- , m_ignoreCase(ignoreCase)
- , m_multiLine(multiline)
+RegExp::Data::Data(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline)
+ : Managed::Data(engine->regExpValueClass)
+ , pattern(pattern)
+ , ignoreCase(ignoreCase)
+ , multiLine(multiline)
{
- if (!engine)
- return;
+ setVTable(staticVTable());
const char* error = 0;
JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiline, &error);
if (error)
return;
- m_subPatternCount = yarrPattern.m_numSubpatterns;
- m_byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator);
+ subPatternCount = yarrPattern.m_numSubpatterns;
+ byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator);
#if ENABLE(YARR_JIT)
if (!yarrPattern.m_containsBackreferences && engine->iselFactory->jitCompileRegexps()) {
JSC::JSGlobalData dummy(engine->regExpAllocator);
- JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, m_jitCode);
+ JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, jitCode);
}
#endif
}
-RegExp::~RegExp()
+RegExp::Data::~Data()
{
- if (m_cache) {
+ if (cache) {
RegExpCacheKey key(this);
- m_cache->remove(key);
+ cache->remove(key);
}
- _data = 0;
}
void RegExp::destroy(Managed *that)
{
- static_cast<RegExp*>(that)->~RegExp();
+ static_cast<RegExp*>(that)->d()->~Data();
}
void RegExp::markObjects(Managed *that, ExecutionEngine *e)
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index 1bcc2c6f5a..e1d3a9ef90 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -62,6 +62,50 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct ExecutionEngine;
+struct RegExpCacheKey;
+
+struct RegExp : public Managed
+{
+ struct Data : Managed::Data {
+ Data(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline);
+ ~Data();
+ QString pattern;
+ OwnPtr<JSC::Yarr::BytecodePattern> byteCode;
+#if ENABLE(YARR_JIT)
+ JSC::Yarr::YarrCodeBlock jitCode;
+#endif
+ RegExpCache *cache;
+ int subPatternCount;
+ bool ignoreCase;
+ bool multiLine;
+ };
+ V4_MANAGED(Managed)
+ Q_MANAGED_TYPE(RegExp)
+
+
+ QString pattern() const { return d()->pattern; }
+ OwnPtr<JSC::Yarr::BytecodePattern> &byteCode() { return d()->byteCode; }
+#if ENABLE(YARR_JIT)
+ JSC::Yarr::YarrCodeBlock jitCode() const { return d()->jitCode; }
+#endif
+ RegExpCache *cache() const { return d()->cache; }
+ int subPatternCount() const { return d()->subPatternCount; }
+ bool ignoreCase() const { return d()->ignoreCase; }
+ bool multiLine() const { return d()->multiLine; }
+
+ static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
+
+ bool isValid() const { return d()->byteCode.get(); }
+
+ uint match(const QString& string, int start, uint *matchOffsets);
+
+ int captureCount() const { return subPatternCount() + 1; }
+
+ static void destroy(Managed *that);
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+
+ friend class RegExpCache;
+};
struct RegExpCacheKey
{
@@ -70,7 +114,7 @@ struct RegExpCacheKey
, ignoreCase(ignoreCase)
, multiLine(multiLine)
{ }
- explicit inline RegExpCacheKey(const RegExp *re);
+ explicit inline RegExpCacheKey(const RegExp::Data *re);
bool operator==(const RegExpCacheKey &other) const
{ return pattern == other.pattern && ignoreCase == other.ignoreCase && multiLine == other.multiLine; }
@@ -82,6 +126,12 @@ struct RegExpCacheKey
uint multiLine : 1;
};
+inline RegExpCacheKey::RegExpCacheKey(const RegExp::Data *re)
+ : pattern(re->pattern)
+ , ignoreCase(re->ignoreCase)
+ , multiLine(re->multiLine)
+{}
+
inline uint qHash(const RegExpCacheKey& key, uint seed = 0) Q_DECL_NOTHROW
{ return qHash(key.pattern, seed); }
@@ -91,49 +141,6 @@ public:
~RegExpCache();
};
-class RegExp : public Managed
-{
- V4_MANAGED
- Q_MANAGED_TYPE(RegExp)
-public:
- static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
- ~RegExp();
-
- QString pattern() const { return m_pattern; }
-
- bool isValid() const { return m_byteCode.get(); }
-
- uint match(const QString& string, int start, uint *matchOffsets);
-
- bool ignoreCase() const { return m_ignoreCase; }
- bool multiLine() const { return m_multiLine; }
- int captureCount() const { return m_subPatternCount + 1; }
-
-protected:
- static void destroy(Managed *that);
- static void markObjects(Managed *that, QV4::ExecutionEngine *e);
-
-private:
- friend class RegExpCache;
- Q_DISABLE_COPY(RegExp);
- RegExp(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline);
-
- const QString m_pattern;
- OwnPtr<JSC::Yarr::BytecodePattern> m_byteCode;
-#if ENABLE(YARR_JIT)
- JSC::Yarr::YarrCodeBlock m_jitCode;
-#endif
- RegExpCache *m_cache;
- int m_subPatternCount;
- const bool m_ignoreCase;
- const bool m_multiLine;
-};
-
-inline RegExpCacheKey::RegExpCacheKey(const RegExp *re)
- : pattern(re->pattern())
- , ignoreCase(re->ignoreCase())
- , multiLine(re->multiLine())
-{}
}
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 956d1c594e..6a592ee792 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -70,32 +70,43 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyn
using namespace QV4;
DEFINE_OBJECT_VTABLE(RegExpObject);
+DEFINE_OBJECT_VTABLE(RegExpPrototype);
-RegExpObject::RegExpObject(InternalClass *ic)
- : Object(ic)
- , value(RegExp::create(ic->engine, QString(), false, false))
- , global(false)
+RegExpObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
- Q_ASSERT(internalClass->vtable == staticVTable());
- init(ic->engine);
+ setVTable(staticVTable());
+
+ Scope scope(ic->engine);
+ Scoped<RegExpObject> o(scope, this);
+ o->d()->value = reinterpret_cast<RegExp *>(RegExp::create(ic->engine, QString(), false, false));
+ o->d()->global = false;
+ o->init(ic->engine);
}
-RegExpObject::RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global)
- : Object(engine->regExpClass)
+RegExpObject::Data::Data(ExecutionEngine *engine, RegExp *value, bool global)
+ : Object::Data(engine->regExpClass)
, value(value)
, global(global)
{
- init(engine);
+ setVTable(staticVTable());
+
+ Scope scope(engine);
+ Scoped<RegExpObject> o(scope, this);
+ o->init(engine);
}
// Converts a QRegExp to a JS RegExp.
// The conversion is not 100% exact since ECMA regexp and QRegExp
// have different semantics/flags, but we try to do our best.
-RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re)
- : Object(engine->regExpClass)
- , value(0)
- , global(false)
+RegExpObject::Data::Data(ExecutionEngine *engine, const QRegExp &re)
+ : Object::Data(engine->regExpClass)
{
+ setVTable(staticVTable());
+
+ value = 0;
+ global = false;
+
// Convert the pattern to a ECMAScript pattern.
QString pattern = QT_PREPEND_NAMESPACE(qt_regexp_toCanonical)(re.pattern(), re.patternSyntax());
if (re.isMinimal()) {
@@ -134,27 +145,25 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re)
}
Scope scope(engine);
- ScopedObject protectThis(scope, this);
+ Scoped<RegExpObject> o(scope, this);
- value = RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false);
+ o->d()->value = reinterpret_cast<RegExp *>(RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false));
- init(engine);
+ o->init(engine);
}
void RegExpObject::init(ExecutionEngine *engine)
{
- setVTable(staticVTable());
-
Scope scope(engine);
ScopedObject protectThis(scope, this);
ScopedString lastIndex(scope, engine->newIdentifier(QStringLiteral("lastIndex")));
ScopedValue v(scope, Primitive::fromInt32(0));
- insertMember(lastIndex, v, Attr_NotEnumerable|Attr_NotConfigurable);
- if (!this->value)
+ insertMember(lastIndex.getPointer(), v, Attr_NotEnumerable|Attr_NotConfigurable);
+ if (!this->value())
return;
- QString p = this->value->pattern();
+ QString p = this->value()->pattern();
if (p.isEmpty()) {
p = QStringLiteral("(?:)");
} else {
@@ -163,29 +172,24 @@ void RegExpObject::init(ExecutionEngine *engine)
}
defineReadonlyProperty(QStringLiteral("source"), (v = engine->newString(p)));
- defineReadonlyProperty(QStringLiteral("global"), Primitive::fromBoolean(global));
- defineReadonlyProperty(QStringLiteral("ignoreCase"), Primitive::fromBoolean(this->value->ignoreCase()));
- defineReadonlyProperty(QStringLiteral("multiline"), Primitive::fromBoolean(this->value->multiLine()));
+ defineReadonlyProperty(QStringLiteral("global"), Primitive::fromBoolean(global()));
+ defineReadonlyProperty(QStringLiteral("ignoreCase"), Primitive::fromBoolean(this->value()->ignoreCase()));
+ defineReadonlyProperty(QStringLiteral("multiline"), Primitive::fromBoolean(this->value()->multiLine()));
}
-void RegExpObject::destroy(Managed *that)
-{
- static_cast<RegExpObject *>(that)->~RegExpObject();
-}
-
void RegExpObject::markObjects(Managed *that, ExecutionEngine *e)
{
RegExpObject *re = static_cast<RegExpObject*>(that);
- if (re->value)
- re->value->mark(e);
+ if (re->value())
+ re->value()->mark(e);
Object::markObjects(that, e);
}
Property *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
{
Q_UNUSED(ctx);
- Q_ASSERT(0 == internalClass->find(ctx->engine->newIdentifier(QStringLiteral("lastIndex"))));
+ Q_ASSERT(0 == internalClass()->find(ctx->d()->engine->newIdentifier(QStringLiteral("lastIndex"))));
return propertyAt(0);
}
@@ -194,19 +198,19 @@ Property *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
// have different semantics/flags, but we try to do our best.
QRegExp RegExpObject::toQRegExp() const
{
- Qt::CaseSensitivity caseSensitivity = value->ignoreCase() ? Qt::CaseInsensitive : Qt::CaseSensitive;
- return QRegExp(value->pattern(), caseSensitivity, QRegExp::RegExp2);
+ Qt::CaseSensitivity caseSensitivity = value()->ignoreCase() ? Qt::CaseInsensitive : Qt::CaseSensitive;
+ return QRegExp(value()->pattern(), caseSensitivity, QRegExp::RegExp2);
}
QString RegExpObject::toString() const
{
QString result = QLatin1Char('/') + source();
result += QLatin1Char('/');
- if (global)
+ if (global())
result += QLatin1Char('g');
- if (value->ignoreCase())
+ if (value()->ignoreCase())
result += QLatin1Char('i');
- if (value->multiLine())
+ if (value()->multiLine())
result += QLatin1Char('m');
return result;
}
@@ -215,35 +219,35 @@ QString RegExpObject::source() const
{
Scope scope(engine());
ScopedString source(scope, scope.engine->newIdentifier(QStringLiteral("source")));
- ScopedValue s(scope, const_cast<RegExpObject *>(this)->get(source));
+ ScopedValue s(scope, const_cast<RegExpObject *>(this)->get(source.getPointer()));
return s->toQString();
}
uint RegExpObject::flags() const
{
uint f = 0;
- if (global)
+ if (global())
f |= QV4::RegExpObject::RegExp_Global;
- if (value->ignoreCase())
+ if (value()->ignoreCase())
f |= QV4::RegExpObject::RegExp_IgnoreCase;
- if (value->multiLine())
+ if (value()->multiLine())
f |= QV4::RegExpObject::RegExp_Multiline;
return f;
}
DEFINE_OBJECT_VTABLE(RegExpCtor);
-RegExpCtor::RegExpCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("RegExp"))
+RegExpCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("RegExp"))
{
setVTable(staticVTable());
clearLastMatch();
}
-void RegExpCtor::clearLastMatch()
+void RegExpCtor::Data::clearLastMatch()
{
lastMatch = Primitive::nullValue();
- lastInput = engine()->id_empty;
+ lastInput = internalClass->engine->id_empty;
lastMatchStart = 0;
lastMatchEnd = 0;
}
@@ -260,8 +264,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
if (!f->isUndefined())
return ctx->throwTypeError();
- Scoped<RegExp> newRe(scope, re->value);
- return Encode(ctx->engine->newRegExpObject(newRe, re->global));
+ return Encode(ctx->d()->engine->newRegExpObject(re->value(), re->global()));
}
QString pattern;
@@ -291,11 +294,11 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
}
}
- Scoped<RegExp> regexp(scope, RegExp::create(ctx->engine, pattern, ignoreCase, multiLine));
+ RegExp *regexp = reinterpret_cast<RegExp *>(RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine));
if (!regexp->isValid())
return ctx->throwSyntaxError(QStringLiteral("Invalid regular expression"));
- return Encode(ctx->engine->newRegExpObject(regexp, global));
+ return Encode(ctx->d()->engine->newRegExpObject(regexp, global));
}
ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
@@ -311,15 +314,16 @@ ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
void RegExpCtor::markObjects(Managed *that, ExecutionEngine *e)
{
RegExpCtor *This = static_cast<RegExpCtor*>(that);
- This->lastMatch.mark(e);
- This->lastInput.mark(e);
+ This->lastMatch().mark(e);
+ This->lastInput().mark(e);
FunctionObject::markObjects(that, e);
}
-void RegExpPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
{
Scope scope(engine);
ScopedObject o(scope);
+ ScopedObject ctor(scope, constructor);
ctor->defineReadonlyProperty(engine->id_prototype, (o = this));
ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(2));
@@ -355,7 +359,7 @@ void RegExpPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->callData->thisObject.as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
return ctx->throwTypeError();
@@ -365,17 +369,17 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
return Encode::undefined();
QString s = arg->stringValue()->toQString();
- int offset = r->global ? r->lastIndexProperty(ctx)->value.toInt32() : 0;
+ int offset = r->global() ? r->lastIndexProperty(ctx)->value.toInt32() : 0;
if (offset < 0 || offset > s.length()) {
r->lastIndexProperty(ctx)->value = Primitive::fromInt32(0);
return Encode::null();
}
- uint* matchOffsets = (uint*)alloca(r->value->captureCount() * 2 * sizeof(uint));
- const int result = r->value->match(s, offset, matchOffsets);
+ uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint));
+ const int result = r->value()->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
- regExpCtor->clearLastMatch();
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ regExpCtor->d()->clearLastMatch();
if (result == -1) {
r->lastIndexProperty(ctx)->value = Primitive::fromInt32(0);
@@ -383,26 +387,27 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
}
// fill in result data
- Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass));
- int len = r->value->captureCount();
+ Scoped<ArrayObject> array(scope, ctx->d()->engine->newArrayObject(ctx->d()->engine->regExpExecArrayClass));
+ int len = r->value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- v = (start != -1 && end != -1) ? ctx->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ v = (start != -1 && end != -1) ? ctx->d()->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
- array->memberData[Index_ArrayIndex] = Primitive::fromInt32(result);
- array->memberData[Index_ArrayInput] = arg.asReturnedValue();
+ array->memberData()[Index_ArrayIndex] = Primitive::fromInt32(result);
+ array->memberData()[Index_ArrayInput] = arg.asReturnedValue();
- regExpCtor->lastMatch = array;
- regExpCtor->lastInput = arg->stringValue();
- regExpCtor->lastMatchStart = matchOffsets[0];
- regExpCtor->lastMatchEnd = matchOffsets[1];
+ RegExpCtor::Data *dd = regExpCtor->d();
+ dd->lastMatch = array;
+ dd->lastInput = arg->stringValue();
+ dd->lastMatchStart = matchOffsets[0];
+ dd->lastMatchEnd = matchOffsets[1];
- if (r->global)
+ if (r->global())
r->lastIndexProperty(ctx)->value = Primitive::fromInt32(matchOffsets[1]);
return array.asReturnedValue();
@@ -418,27 +423,27 @@ ReturnedValue RegExpPrototype::method_test(CallContext *ctx)
ReturnedValue RegExpPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->callData->thisObject.as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
return ctx->throwTypeError();
- return ctx->engine->newString(r->toString())->asReturnedValue();
+ return ctx->d()->engine->newString(r->toString())->asReturnedValue();
}
ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->callData->thisObject.as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
return ctx->throwTypeError();
- ScopedCallData callData(scope, ctx->callData->argc);
- memcpy(callData->args, ctx->callData->args, ctx->callData->argc*sizeof(Value));
+ ScopedCallData callData(scope, ctx->d()->callData->argc);
+ memcpy(callData->args, ctx->d()->callData->args, ctx->d()->callData->argc*sizeof(Value));
- Scoped<RegExpObject> re(scope, ctx->engine->regExpCtor.asFunctionObject()->construct(callData));
+ Scoped<RegExpObject> re(scope, ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData));
- r->value = re->value;
- r->global = re->global;
+ r->d()->value = re->value();
+ r->d()->global = re->global();
return Encode::undefined();
}
@@ -446,42 +451,42 @@ template <int index>
ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
{
Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastMatch);
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastMatch());
ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
if (result->isUndefined())
- return ctx->engine->newString(QString())->asReturnedValue();
+ return ctx->d()->engine->newString(QString())->asReturnedValue();
return result.asReturnedValue();
}
ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
{
Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastMatch);
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastMatch());
ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
if (result->isUndefined())
- return ctx->engine->newString(QString())->asReturnedValue();
+ return ctx->d()->engine->newString(QString())->asReturnedValue();
return result.asReturnedValue();
}
ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx)
{
- return static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastInput.asReturnedValue();
+ return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastInput().asReturnedValue();
}
ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
- QString lastInput = regExpCtor->lastInput->toQString();
- return ctx->engine->newString(lastInput.left(regExpCtor->lastMatchStart))->asReturnedValue();
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ QString lastInput = regExpCtor->lastInput()->toQString();
+ return ctx->d()->engine->newString(lastInput.left(regExpCtor->lastMatchStart()))->asReturnedValue();
}
ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
- QString lastInput = regExpCtor->lastInput->toQString();
- return ctx->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd))->asReturnedValue();
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ QString lastInput = regExpCtor->lastInput()->toQString();
+ return ctx->d()->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))->asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 1b408749d3..ac07707b2f 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -63,11 +63,18 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-class RegExp;
-
struct RegExpObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, RegExp *value, bool global);
+ Data(ExecutionEngine *engine, const QRegExp &re);
+ Data(InternalClass *ic);
+
+ RegExp *value;
+ bool global;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(RegExpObject)
+
// needs to be compatible with the flags in qv4jsir_p.h
enum Flags {
RegExp_Global = 0x01,
@@ -80,39 +87,37 @@ struct RegExpObject: Object {
Index_ArrayInput = Index_ArrayIndex + 1
};
- RegExp* value;
- Property *lastIndexProperty(ExecutionContext *ctx);
- bool global;
-
- RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global);
- RegExpObject(ExecutionEngine *engine, const QRegExp &re);
- ~RegExpObject() {}
+ RegExp *value() const { return d()->value; }
+ bool global() const { return d()->global; }
void init(ExecutionEngine *engine);
+ Property *lastIndexProperty(ExecutionContext *ctx);
QRegExp toQRegExp() const;
QString toString() const;
QString source() const;
uint flags() const;
protected:
- RegExpObject(InternalClass *ic);
- static void destroy(Managed *that);
static void markObjects(Managed *that, ExecutionEngine *e);
};
-DEFINE_REF(RegExp, Object);
-
struct RegExpCtor: FunctionObject
{
- V4_OBJECT
- RegExpCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ Value lastMatch;
+ StringValue lastInput;
+ int lastMatchStart;
+ int lastMatchEnd;
+ void clearLastMatch();
+ };
+ V4_OBJECT(FunctionObject)
- Value lastMatch;
- StringValue lastInput;
- int lastMatchStart;
- int lastMatchEnd;
- void clearLastMatch();
+ Value lastMatch() { return d()->lastMatch; }
+ StringValue lastInput() { return d()->lastInput; }
+ int lastMatchStart() { return d()->lastMatchStart; }
+ int lastMatchEnd() { return d()->lastMatchEnd; }
static ReturnedValue construct(Managed *m, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -121,8 +126,16 @@ struct RegExpCtor: FunctionObject
struct RegExpPrototype: RegExpObject
{
- RegExpPrototype(InternalClass *ic): RegExpObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ struct Data : RegExpObject::Data
+ {
+ Data(InternalClass *ic): RegExpObject::Data(ic)
+ {
+ setVTable(staticVTable());
+ }
+ };
+ V4_OBJECT(RegExpObject)
+
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_exec(CallContext *ctx);
static ReturnedValue method_test(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index e44d1a07a6..7ea8dbd0aa 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -265,10 +265,9 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
ReturnedValue Runtime::closure(ExecutionContext *ctx, int functionId)
{
- QV4::Function *clos = ctx->compilationUnit->runtimeFunctions[functionId];
+ QV4::Function *clos = ctx->d()->compilationUnit->runtimeFunctions[functionId];
Q_ASSERT(clos);
- FunctionObject *f = FunctionObject::createScriptFunction(ctx, clos);
- return f->asReturnedValue();
+ return FunctionObject::createScriptFunction(ctx, clos)->asReturnedValue();
}
ReturnedValue Runtime::deleteElement(ExecutionContext *ctx, const ValueRef base, const ValueRef index)
@@ -283,10 +282,10 @@ ReturnedValue Runtime::deleteElement(ExecutionContext *ctx, const ValueRef base,
}
ScopedString name(scope, index->toString(ctx));
- return Runtime::deleteMember(ctx, base, name);
+ return Runtime::deleteMember(ctx, base, name.getPointer());
}
-ReturnedValue Runtime::deleteMember(ExecutionContext *ctx, const ValueRef base, const StringRef name)
+ReturnedValue Runtime::deleteMember(ExecutionContext *ctx, const ValueRef base, String *name)
{
Scope scope(ctx);
ScopedObject obj(scope, base->toObject(ctx));
@@ -295,7 +294,7 @@ ReturnedValue Runtime::deleteMember(ExecutionContext *ctx, const ValueRef base,
return Encode(obj->deleteProperty(name));
}
-ReturnedValue Runtime::deleteName(ExecutionContext *ctx, const StringRef name)
+ReturnedValue Runtime::deleteName(ExecutionContext *ctx, String *name)
{
Scope scope(ctx);
return Encode(ctx->deleteProperty(name));
@@ -310,8 +309,8 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef lef
if (!f)
return ctx->throwTypeError();
- if (f->subtype == FunctionObject::BoundFunction)
- f = static_cast<BoundFunction *>(f)->target;
+ if (f->subtype() == FunctionObject::BoundFunction)
+ f = static_cast<BoundFunction *>(f)->target();
Object *v = left->asObject();
if (!v)
@@ -341,7 +340,7 @@ QV4::ReturnedValue Runtime::in(ExecutionContext *ctx, const ValueRef left, const
ScopedString s(scope, left->toString(ctx));
if (scope.hasException())
return Encode::undefined();
- bool r = right->objectValue()->hasProperty(s);
+ bool r = right->objectValue()->hasProperty(s.getPointer());
return Encode(r);
}
@@ -370,7 +369,7 @@ Returned<String> *RuntimeHelpers::stringFromNumber(ExecutionContext *ctx, double
{
QString qstr;
RuntimeHelpers::numberToString(&qstr, number, 10);
- return ctx->engine->newString(qstr);
+ return ctx->engine()->newString(qstr);
}
ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
@@ -382,7 +381,7 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
typeHint = NUMBER_HINT;
}
- ExecutionEngine *engine = object->internalClass->engine;
+ ExecutionEngine *engine = object->internalClass()->engine;
if (engine->hasException)
return Encode::undefined();
@@ -428,13 +427,13 @@ Returned<Object> *RuntimeHelpers::convertToObject(ExecutionContext *ctx, const V
ctx->throwTypeError();
return 0;
case Value::Boolean_Type:
- return ctx->engine->newBooleanObject(value);
+ return ctx->engine()->newBooleanObject(value);
case Value::Managed_Type:
Q_ASSERT(value->isString());
- return ctx->engine->newStringObject(value);
+ return ctx->engine()->newStringObject(value);
case Value::Integer_Type:
default: // double
- return ctx->engine->newNumberObject(value);
+ return ctx->engine()->newNumberObject(value);
}
}
@@ -444,14 +443,14 @@ Returned<String> *RuntimeHelpers::convertToString(ExecutionContext *ctx, const V
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return ctx->engine->id_undefined.ret();
+ return ctx->engine()->id_undefined.ret();
case Value::Null_Type:
- return ctx->engine->id_null.ret();
+ return ctx->engine()->id_null.ret();
case Value::Boolean_Type:
if (value->booleanValue())
- return ctx->engine->id_true.ret();
+ return ctx->engine()->id_true.ret();
else
- return ctx->engine->id_false.ret();
+ return ctx->engine()->id_false.ret();
case Value::Managed_Type:
if (value->isString())
return value->stringValue()->asReturned<String>();
@@ -475,14 +474,14 @@ static Returned<String> *convert_to_string_add(ExecutionContext *ctx, const Valu
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return ctx->engine->id_undefined.ret();
+ return ctx->engine()->id_undefined.ret();
case Value::Null_Type:
- return ctx->engine->id_null.ret();
+ return ctx->engine()->id_null.ret();
case Value::Boolean_Type:
if (value->booleanValue())
- return ctx->engine->id_true.ret();
+ return ctx->engine()->id_true.ret();
else
- return ctx->engine->id_false.ret();
+ return ctx->engine()->id_false.ret();
case Value::Managed_Type:
if (value->isString())
return value->stringValue()->asReturned<String>();
@@ -511,11 +510,11 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionContext *ctx, const ValueR
pright = convert_to_string_add(ctx, pright);
if (scope.engine->hasException)
return Encode::undefined();
- if (!pleft->stringValue()->length())
+ if (!pleft->stringValue()->d()->length())
return pright->asReturnedValue();
- if (!pright->stringValue()->length())
+ if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
- return (new (ctx->engine->memoryManager) String(ctx->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
+ return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
}
double x = RuntimeHelpers::toNumber(pleft);
double y = RuntimeHelpers::toNumber(pright);
@@ -527,11 +526,11 @@ QV4::ReturnedValue Runtime::addString(QV4::ExecutionContext *ctx, const QV4::Val
Q_ASSERT(left->isString() || right->isString());
if (left->isString() && right->isString()) {
- if (!left->stringValue()->length())
+ if (!left->stringValue()->d()->length())
return right->asReturnedValue();
- if (!right->stringValue()->length())
+ if (!right->stringValue()->d()->length())
return left->asReturnedValue();
- return (new (ctx->engine->memoryManager) String(ctx->engine, left->stringValue(), right->stringValue()))->asReturnedValue();
+ return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, left->stringValue(), right->stringValue()))->asReturnedValue();
}
Scope scope(ctx);
@@ -544,14 +543,14 @@ QV4::ReturnedValue Runtime::addString(QV4::ExecutionContext *ctx, const QV4::Val
pright = convert_to_string_add(ctx, right);
if (scope.engine->hasException)
return Encode::undefined();
- if (!pleft->stringValue()->length())
+ if (!pleft->stringValue()->d()->length())
return pright->asReturnedValue();
- if (!pright->stringValue()->length())
+ if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
- return (new (ctx->engine->memoryManager) String(ctx->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
+ return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
}
-void Runtime::setProperty(ExecutionContext *ctx, const ValueRef object, const StringRef name, const ValueRef value)
+void Runtime::setProperty(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef value)
{
Scope scope(ctx);
ScopedObject o(scope, object->toObject(ctx));
@@ -588,8 +587,8 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
}
if (idx < UINT_MAX) {
- if (!o->arrayData->hasAttributes()) {
- ScopedValue v(scope, o->arrayData->get(idx));
+ if (!o->arrayData()->hasAttributes()) {
+ ScopedValue v(scope, o->arrayData()->get(idx));
if (!v->isEmpty())
return v->asReturnedValue();
}
@@ -600,7 +599,7 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
ScopedString name(scope, index->toString(ctx));
if (scope.hasException())
return Encode::undefined();
- return o->get(name);
+ return o->get(name.getPointer());
}
void Runtime::setElement(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value)
@@ -613,9 +612,9 @@ void Runtime::setElement(ExecutionContext *ctx, const ValueRef object, const Val
uint idx = index->asArrayIndex();
if (idx < UINT_MAX) {
if (o->arrayType() == ArrayData::Simple) {
- SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
- if (s && idx < s->len && !s->data[idx].isEmpty()) {
- s->data[idx] = value;
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData());
+ if (s && idx < s->len() && !s->arrayData()[idx].isEmpty()) {
+ s->arrayData()[idx] = value;
return;
}
}
@@ -624,7 +623,7 @@ void Runtime::setElement(ExecutionContext *ctx, const ValueRef object, const Val
}
ScopedString name(scope, index->toString(ctx));
- o->put(name, value);
+ o->put(name.getPointer(), value);
}
ReturnedValue Runtime::foreachIterator(ExecutionContext *ctx, const ValueRef in)
@@ -633,7 +632,7 @@ ReturnedValue Runtime::foreachIterator(ExecutionContext *ctx, const ValueRef in)
Scoped<Object> o(scope, (Object *)0);
if (!in->isNullOrUndefined())
o = in->toObject(ctx);
- Scoped<Object> it(scope, ctx->engine->newForEachIteratorObject(ctx, o));
+ Scoped<Object> it(scope, ctx->engine()->newForEachIteratorObject(ctx, o));
return it.asReturnedValue();
}
@@ -648,12 +647,12 @@ ReturnedValue Runtime::foreachNextPropertyName(const ValueRef foreach_iterator)
}
-void Runtime::setActivationProperty(ExecutionContext *ctx, const StringRef name, const ValueRef value)
+void Runtime::setActivationProperty(ExecutionContext *ctx, String *name, const ValueRef value)
{
ctx->setProperty(name, value);
}
-ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object, const StringRef name)
+ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object, String *name)
{
Scope scope(ctx);
@@ -672,7 +671,7 @@ ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object,
return o->get(name);
}
-ReturnedValue Runtime::getActivationProperty(ExecutionContext *ctx, const StringRef name)
+ReturnedValue Runtime::getActivationProperty(ExecutionContext *ctx, String *name)
{
return ctx->getProperty(name);
}
@@ -866,31 +865,31 @@ QV4::Bool Runtime::compareLessEqual(const QV4::ValueRef l, const QV4::ValueRef r
}
#ifndef V4_BOOTSTRAP
-ReturnedValue Runtime::callGlobalLookup(ExecutionContext *context, uint index, CallDataRef callData)
+ReturnedValue Runtime::callGlobalLookup(ExecutionContext *context, uint index, CallData *callData)
{
Scope scope(context);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = context->lookups + index;
+ Lookup *l = context->d()->lookups + index;
Scoped<FunctionObject> o(scope, l->globalGetter(l, context));
if (!o)
return context->throwTypeError();
- if (o.getPointer() == context->engine->evalFunction && l->name->equals(context->engine->id_eval))
+ if (o.getPointer() == scope.engine->evalFunction && l->name->equals(scope.engine->id_eval))
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
return o->call(callData);
}
-ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, const StringRef name, CallDataRef callData)
+ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String *name, CallData *callData)
{
Q_ASSERT(callData->thisObject.isUndefined());
Scope scope(context);
ScopedObject base(scope);
- ScopedValue func(scope, context->getPropertyAndBase(name, base));
- if (context->engine->hasException)
+ ScopedValue func(scope, context->getPropertyAndBase(name, base.ptr->o));
+ if (scope.engine->hasException)
return Encode::undefined();
if (base)
@@ -905,14 +904,14 @@ ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, const S
return context->throwTypeError(msg);
}
- if (o == context->engine->evalFunction && name->equals(context->engine->id_eval)) {
+ if (o == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) {
return static_cast<EvalFunction *>(o)->evalCall(callData, true);
}
return o->call(callData);
}
-ReturnedValue Runtime::callProperty(ExecutionContext *context, const StringRef name, CallDataRef callData)
+ReturnedValue Runtime::callProperty(ExecutionContext *context, String *name, CallData *callData)
{
Scope scope(context);
Scoped<Object> baseObject(scope, callData->thisObject);
@@ -938,9 +937,9 @@ ReturnedValue Runtime::callProperty(ExecutionContext *context, const StringRef n
return o->call(callData);
}
-ReturnedValue Runtime::callPropertyLookup(ExecutionContext *context, uint index, CallDataRef callData)
+ReturnedValue Runtime::callPropertyLookup(ExecutionContext *context, uint index, CallData *callData)
{
- Lookup *l = context->lookups + index;
+ Lookup *l = context->d()->lookups + index;
Value v;
v = l->getter(l, callData->thisObject);
if (!v.isObject())
@@ -949,7 +948,7 @@ ReturnedValue Runtime::callPropertyLookup(ExecutionContext *context, uint index,
return v.objectValue()->call(callData);
}
-ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef index, CallDataRef callData)
+ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef index, CallData *callData)
{
Scope scope(context);
ScopedObject baseObject(scope, callData->thisObject.toObject(context));
@@ -959,14 +958,14 @@ ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef ind
return Encode::undefined();
callData->thisObject = baseObject;
- ScopedObject o(scope, baseObject->get(s));
+ ScopedObject o(scope, baseObject->get(s.getPointer()));
if (!o)
return context->throwTypeError();
return o->call(callData);
}
-ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func, CallDataRef callData)
+ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func, CallData *callData)
{
if (!func->isObject())
return context->throwTypeError();
@@ -975,12 +974,12 @@ ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func,
}
-ReturnedValue Runtime::constructGlobalLookup(ExecutionContext *context, uint index, CallDataRef callData)
+ReturnedValue Runtime::constructGlobalLookup(ExecutionContext *context, uint index, CallData *callData)
{
Scope scope(context);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = context->lookups + index;
+ Lookup *l = context->d()->lookups + index;
Scoped<Object> f(scope, l->globalGetter(l, context));
if (!f)
return context->throwTypeError();
@@ -989,11 +988,11 @@ ReturnedValue Runtime::constructGlobalLookup(ExecutionContext *context, uint ind
}
-ReturnedValue Runtime::constructActivationProperty(ExecutionContext *context, const StringRef name, CallDataRef callData)
+ReturnedValue Runtime::constructActivationProperty(ExecutionContext *context, String *name, CallData *callData)
{
Scope scope(context);
ScopedValue func(scope, context->getProperty(name));
- if (context->engine->hasException)
+ if (scope.engine->hasException)
return Encode::undefined();
Object *f = func->asObject();
@@ -1003,7 +1002,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionContext *context, co
return f->construct(callData);
}
-ReturnedValue Runtime::constructValue(ExecutionContext *context, const ValueRef func, CallDataRef callData)
+ReturnedValue Runtime::constructValue(ExecutionContext *context, const ValueRef func, CallData *callData)
{
Object *f = func->asObject();
if (!f)
@@ -1012,7 +1011,7 @@ ReturnedValue Runtime::constructValue(ExecutionContext *context, const ValueRef
return f->construct(callData);
}
-ReturnedValue Runtime::constructProperty(ExecutionContext *context, const StringRef name, CallDataRef callData)
+ReturnedValue Runtime::constructProperty(ExecutionContext *context, String *name, CallData *callData)
{
Scope scope(context);
ScopedObject thisObject(scope, callData->thisObject.toObject(context));
@@ -1026,9 +1025,9 @@ ReturnedValue Runtime::constructProperty(ExecutionContext *context, const String
return f->construct(callData);
}
-ReturnedValue Runtime::constructPropertyLookup(ExecutionContext *context, uint index, CallDataRef callData)
+ReturnedValue Runtime::constructPropertyLookup(ExecutionContext *context, uint index, CallData *callData)
{
- Lookup *l = context->lookups + index;
+ Lookup *l = context->d()->lookups + index;
Value v;
v = l->getter(l, callData->thisObject);
if (!v.isObject())
@@ -1050,39 +1049,39 @@ ReturnedValue Runtime::typeofValue(ExecutionContext *ctx, const ValueRef value)
ScopedString res(scope);
switch (value->type()) {
case Value::Undefined_Type:
- res = ctx->engine->id_undefined;
+ res = ctx->engine()->id_undefined;
break;
case Value::Null_Type:
- res = ctx->engine->id_object;
+ res = ctx->engine()->id_object;
break;
case Value::Boolean_Type:
- res = ctx->engine->id_boolean;
+ res = ctx->engine()->id_boolean;
break;
case Value::Managed_Type:
if (value->isString())
- res = ctx->engine->id_string;
+ res = ctx->engine()->id_string;
else if (value->objectValue()->asFunctionObject())
- res = ctx->engine->id_function;
+ res = ctx->engine()->id_function;
else
- res = ctx->engine->id_object; // ### implementation-defined
+ res = ctx->engine()->id_object; // ### implementation-defined
break;
default:
- res = ctx->engine->id_number;
+ res = ctx->engine()->id_number;
break;
}
return res.asReturnedValue();
}
-QV4::ReturnedValue Runtime::typeofName(ExecutionContext *context, const StringRef name)
+QV4::ReturnedValue Runtime::typeofName(ExecutionContext *context, String *name)
{
Scope scope(context);
ScopedValue prop(scope, context->getProperty(name));
// typeof doesn't throw. clear any possible exception
- context->engine->hasException = false;
+ scope.engine->hasException = false;
return Runtime::typeofValue(context, prop);
}
-QV4::ReturnedValue Runtime::typeofMember(ExecutionContext *context, const ValueRef base, const StringRef name)
+QV4::ReturnedValue Runtime::typeofMember(ExecutionContext *context, const ValueRef base, String *name)
{
Scope scope(context);
ScopedObject obj(scope, base->toObject(context));
@@ -1099,7 +1098,7 @@ QV4::ReturnedValue Runtime::typeofElement(ExecutionContext *context, const Value
ScopedObject obj(scope, base->toObject(context));
if (scope.engine->hasException)
return Encode::undefined();
- ScopedValue prop(scope, obj->get(name));
+ ScopedValue prop(scope, obj->get(name.getPointer()));
return Runtime::typeofValue(context, prop);
}
@@ -1107,29 +1106,29 @@ ExecutionContext *Runtime::pushWithScope(const ValueRef o, ExecutionContext *ctx
{
Scope scope(ctx);
ScopedObject obj(scope, o->toObject(ctx));
- return ctx->newWithContext(obj);
+ return reinterpret_cast<ExecutionContext *>(ctx->newWithContext(obj));
}
ReturnedValue Runtime::unwindException(ExecutionContext *ctx)
{
- if (!ctx->engine->hasException)
+ if (!ctx->engine()->hasException)
return Primitive::emptyValue().asReturnedValue();
- return ctx->engine->catchException(ctx, 0);
+ return ctx->engine()->catchException(ctx, 0);
}
-ExecutionContext *Runtime::pushCatchScope(ExecutionContext *ctx, const StringRef exceptionVarName)
+ExecutionContext *Runtime::pushCatchScope(ExecutionContext *ctx, String *exceptionVarName)
{
Scope scope(ctx);
- ScopedValue v(scope, ctx->engine->catchException(ctx, 0));
- return ctx->newCatchContext(exceptionVarName, v);
+ ScopedValue v(scope, ctx->engine()->catchException(ctx, 0));
+ return reinterpret_cast<ExecutionContext *>(ctx->newCatchContext(exceptionVarName, v));
}
ExecutionContext *Runtime::popScope(ExecutionContext *ctx)
{
- return ctx->engine->popContext();
+ return ctx->engine()->popContext();
}
-void Runtime::declareVar(ExecutionContext *ctx, bool deletable, const StringRef name)
+void Runtime::declareVar(ExecutionContext *ctx, bool deletable, String *name)
{
ctx->createMutableBinding(name, deletable);
}
@@ -1137,7 +1136,7 @@ void Runtime::declareVar(ExecutionContext *ctx, bool deletable, const StringRef
ReturnedValue Runtime::arrayLiteral(ExecutionContext *ctx, Value *values, uint length)
{
Scope scope(ctx);
- Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
+ Scoped<ArrayObject> a(scope, ctx->engine()->newArrayObject());
if (length) {
a->arrayReserve(length);
@@ -1150,8 +1149,8 @@ ReturnedValue Runtime::arrayLiteral(ExecutionContext *ctx, Value *values, uint l
ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
Scope scope(ctx);
- QV4::InternalClass *klass = ctx->compilationUnit->runtimeClasses[classId];
- Scoped<Object> o(scope, ctx->engine->newObject(klass));
+ QV4::InternalClass *klass = ctx->d()->compilationUnit->runtimeClasses[classId];
+ Scoped<Object> o(scope, ctx->engine()->newObject(klass));
{
bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;
@@ -1160,26 +1159,30 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
}
for (uint i = 0; i < klass->size; ++i)
- o->memberData[i] = *args++;
-
- ScopedValue entry(scope);
- for (int i = 0; i < arrayValueCount; ++i) {
- uint idx = args->toUInt32();
- ++args;
- entry = *args++;
- o->arraySet(idx, entry);
+ o->memberData()[i] = *args++;
+
+ if (arrayValueCount > 0) {
+ ScopedValue entry(scope);
+ for (int i = 0; i < arrayValueCount; ++i) {
+ uint idx = args->toUInt32();
+ ++args;
+ entry = *args++;
+ o->arraySet(idx, entry);
+ }
}
- ScopedProperty pd(scope);
uint arrayGetterSetterCount = arrayGetterSetterCountAndFlags & ((1 << 30) - 1);
- for (uint i = 0; i < arrayGetterSetterCount; ++i) {
- uint idx = args->toUInt32();
- ++args;
- pd->value = *args;
- ++args;
- pd->set = *args;
- ++args;
- o->arraySet(idx, pd, Attr_Accessor);
+ if (arrayGetterSetterCount > 0) {
+ ScopedProperty pd(scope);
+ for (uint i = 0; i < arrayGetterSetterCount; ++i) {
+ uint idx = args->toUInt32();
+ ++args;
+ pd->value = *args;
+ ++args;
+ pd->set = *args;
+ ++args;
+ o->arraySet(idx, pd, Attr_Accessor);
+ }
}
return o.asReturnedValue();
@@ -1187,9 +1190,9 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
QV4::ReturnedValue Runtime::setupArgumentsObject(ExecutionContext *ctx)
{
- assert(ctx->type >= ExecutionContext::Type_CallContext);
+ Q_ASSERT(ctx->d()->type >= ExecutionContext::Type_CallContext);
CallContext *c = static_cast<CallContext *>(ctx);
- return (new (c->engine->memoryManager) ArgumentsObject(c))->asReturnedValue();
+ return (c->engine()->memoryManager->alloc<ArgumentsObject>(c))->asReturnedValue();
}
#endif // V4_BOOTSTRAP
@@ -1275,27 +1278,27 @@ unsigned Runtime::doubleToUInt(const double &d)
ReturnedValue Runtime::regexpLiteral(ExecutionContext *ctx, int id)
{
- return ctx->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
+ return ctx->d()->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
ReturnedValue Runtime::getQmlIdArray(NoThrowContext *ctx)
{
- return ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>()->idObjectsArray();
+ return ctx->engine()->qmlContextObject()->getPointer()->as<QmlContextWrapper>()->idObjectsArray();
}
ReturnedValue Runtime::getQmlContextObject(NoThrowContext *ctx)
{
- QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
+ QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine());
if (!context)
return Encode::undefined();
- return QObjectWrapper::wrap(ctx->engine, context->contextObject);
+ return QObjectWrapper::wrap(ctx->d()->engine, context->contextObject);
}
ReturnedValue Runtime::getQmlScopeObject(NoThrowContext *ctx)
{
Scope scope(ctx);
- QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
- return QObjectWrapper::wrap(ctx->engine, c->getScopeObject());
+ QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine()->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
+ return QObjectWrapper::wrap(ctx->d()->engine, c->getScopeObject());
}
ReturnedValue Runtime::getQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, bool captureRequired)
@@ -1312,11 +1315,11 @@ ReturnedValue Runtime::getQmlQObjectProperty(ExecutionContext *ctx, const ValueR
QV4::ReturnedValue Runtime::getQmlAttachedProperty(ExecutionContext *ctx, int attachedPropertiesId, int propertyIndex)
{
Scope scope(ctx);
- QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
+ QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine()->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
QObject *scopeObject = c->getScopeObject();
QObject *attachedObject = qmlAttachedPropertiesObjectById(attachedPropertiesId, scopeObject);
- QQmlEngine *qmlEngine = ctx->engine->v8Engine->engine();
+ QQmlEngine *qmlEngine = ctx->engine()->v8Engine->engine();
QQmlData::ensurePropertyCache(qmlEngine, attachedObject);
return QV4::QObjectWrapper::getProperty(attachedObject, ctx, propertyIndex, /*captureRequired*/true);
}
@@ -1334,24 +1337,24 @@ void Runtime::setQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object
ReturnedValue Runtime::getQmlImportedScripts(NoThrowContext *ctx)
{
- QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
+ QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine());
if (!context)
return Encode::undefined();
return context->importedScripts.value();
}
-QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowContext *ctx, const QV4::StringRef name)
+QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowContext *ctx, String *name)
{
- return ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>()->qmlSingletonWrapper(ctx->engine->v8Engine, name);
+ return ctx->engine()->qmlContextObject()->getPointer()->as<QmlContextWrapper>()->qmlSingletonWrapper(ctx->engine()->v8Engine, name);
}
void Runtime::convertThisToObject(ExecutionContext *ctx)
{
- Value *t = &ctx->callData->thisObject;
+ Value *t = &ctx->d()->callData->thisObject;
if (t->isObject())
return;
if (t->isNullOrUndefined()) {
- *t = ctx->engine->globalObject->asReturnedValue();
+ *t = ctx->engine()->globalObject->asReturnedValue();
} else {
*t = t->toObject(ctx)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 0979105680..992b027379 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -105,51 +105,51 @@ struct NoThrowContext : public ExecutionContext
struct Q_QML_PRIVATE_EXPORT Runtime {
// call
- static ReturnedValue callGlobalLookup(ExecutionContext *context, uint index, CallDataRef callData);
- static ReturnedValue callActivationProperty(ExecutionContext *, const StringRef name, CallDataRef callData);
- static ReturnedValue callProperty(ExecutionContext *context, const StringRef name, CallDataRef callData);
- static ReturnedValue callPropertyLookup(ExecutionContext *context, uint index, CallDataRef callData);
- static ReturnedValue callElement(ExecutionContext *context, const ValueRef index, CallDataRef callData);
- static ReturnedValue callValue(ExecutionContext *context, const ValueRef func, CallDataRef callData);
+ static ReturnedValue callGlobalLookup(ExecutionContext *context, uint index, CallData *callData);
+ static ReturnedValue callActivationProperty(ExecutionContext *, String *name, CallData *callData);
+ static ReturnedValue callProperty(ExecutionContext *context, String *name, CallData *callData);
+ static ReturnedValue callPropertyLookup(ExecutionContext *context, uint index, CallData *callData);
+ static ReturnedValue callElement(ExecutionContext *context, const ValueRef index, CallData *callData);
+ static ReturnedValue callValue(ExecutionContext *context, const ValueRef func, CallData *callData);
// construct
- static ReturnedValue constructGlobalLookup(ExecutionContext *context, uint index, CallDataRef callData);
- static ReturnedValue constructActivationProperty(ExecutionContext *, const StringRef name, CallDataRef callData);
- static ReturnedValue constructProperty(ExecutionContext *context, const StringRef name, CallDataRef callData);
- static ReturnedValue constructPropertyLookup(ExecutionContext *context, uint index, CallDataRef callData);
- static ReturnedValue constructValue(ExecutionContext *context, const ValueRef func, CallDataRef callData);
+ static ReturnedValue constructGlobalLookup(ExecutionContext *context, uint index, CallData *callData);
+ static ReturnedValue constructActivationProperty(ExecutionContext *, String *name, CallData *callData);
+ static ReturnedValue constructProperty(ExecutionContext *context, String *name, CallData *callData);
+ static ReturnedValue constructPropertyLookup(ExecutionContext *context, uint index, CallData *callData);
+ static ReturnedValue constructValue(ExecutionContext *context, const ValueRef func, CallData *callData);
// set & get
- static void setActivationProperty(ExecutionContext *ctx, const StringRef name, const ValueRef value);
- static void setProperty(ExecutionContext *ctx, const ValueRef object, const StringRef name, const ValueRef value);
+ static void setActivationProperty(ExecutionContext *ctx, String *name, const ValueRef value);
+ static void setProperty(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef value);
static void setElement(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value);
- static ReturnedValue getProperty(ExecutionContext *ctx, const ValueRef object, const StringRef name);
- static ReturnedValue getActivationProperty(ExecutionContext *ctx, const StringRef name);
+ static ReturnedValue getProperty(ExecutionContext *ctx, const ValueRef object, String *name);
+ static ReturnedValue getActivationProperty(ExecutionContext *ctx, String *name);
static ReturnedValue getElement(ExecutionContext *ctx, const ValueRef object, const ValueRef index);
// typeof
static ReturnedValue typeofValue(ExecutionContext *ctx, const ValueRef val);
- static ReturnedValue typeofName(ExecutionContext *context, const StringRef name);
- static ReturnedValue typeofMember(ExecutionContext* context, const ValueRef base, const StringRef name);
+ static ReturnedValue typeofName(ExecutionContext *context, String *name);
+ static ReturnedValue typeofMember(ExecutionContext* context, const ValueRef base, String *name);
static ReturnedValue typeofElement(ExecutionContext* context, const ValueRef base, const ValueRef index);
// delete
static ReturnedValue deleteElement(ExecutionContext *ctx, const ValueRef base, const ValueRef index);
- static ReturnedValue deleteMember(ExecutionContext *ctx, const ValueRef base, const StringRef name);
- static ReturnedValue deleteName(ExecutionContext *ctx, const StringRef name);
+ static ReturnedValue deleteMember(ExecutionContext *ctx, const ValueRef base, String *name);
+ static ReturnedValue deleteName(ExecutionContext *ctx, String *name);
// exceptions & scopes
static void throwException(ExecutionContext*, const ValueRef value);
static ReturnedValue unwindException(ExecutionContext *ctx);
static ExecutionContext *pushWithScope(const ValueRef o, ExecutionContext *ctx);
- static ExecutionContext *pushCatchScope(ExecutionContext *ctx, const StringRef exceptionVarName);
+ static ExecutionContext *pushCatchScope(ExecutionContext *ctx, String *exceptionVarName);
static ExecutionContext *popScope(ExecutionContext *ctx);
// closures
static ReturnedValue closure(ExecutionContext *ctx, int functionId);
// function header
- static void declareVar(ExecutionContext *ctx, bool deletable, const StringRef name);
+ static void declareVar(ExecutionContext *ctx, bool deletable, String *name);
static ReturnedValue setupArgumentsObject(ExecutionContext *ctx);
static void convertThisToObject(ExecutionContext *ctx);
@@ -226,7 +226,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
static ReturnedValue getQmlImportedScripts(NoThrowContext *ctx);
static ReturnedValue getQmlContextObject(NoThrowContext *ctx);
static ReturnedValue getQmlScopeObject(NoThrowContext *ctx);
- static ReturnedValue getQmlSingleton(NoThrowContext *ctx, const StringRef name);
+ static ReturnedValue getQmlSingleton(NoThrowContext *ctx, String *name);
static ReturnedValue getQmlAttachedProperty(ExecutionContext *ctx, int attachedPropertiesId, int propertyIndex);
static ReturnedValue getQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, bool captureRequired);
static void setQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 5d471ab4fb..563d097440 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -117,6 +117,18 @@ struct ScopedValue
#endif
}
+ ScopedValue(const Scope &scope, HeapObject *o)
+ {
+ ptr = scope.engine->jsStackTop++;
+ ptr->m = reinterpret_cast<Managed *>(o);
+#if QT_POINTER_SIZE == 4
+ ptr->tag = QV4::Value::Managed_Type;
+#endif
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
ScopedValue(const Scope &scope, Managed *m)
{
ptr = scope.engine->jsStackTop++;
@@ -150,6 +162,14 @@ struct ScopedValue
return *this;
}
+ ScopedValue &operator=(HeapObject *o) {
+ ptr->m = reinterpret_cast<Managed *>(o);
+#if QT_POINTER_SIZE == 4
+ ptr->tag = QV4::Value::Managed_Type;
+#endif
+ return *this;
+ }
+
ScopedValue &operator=(Managed *m) {
ptr->val = m->asReturnedValue();
return *this;
@@ -215,6 +235,19 @@ struct Scoped
++scope.size;
#endif
}
+ Scoped(const Scope &scope, HeapObject *o)
+ {
+ Value v;
+ v.m = reinterpret_cast<Managed *>(o);
+#if QT_POINTER_SIZE == 4
+ v.tag = QV4::Value::Managed_Type;
+#endif
+ ptr = scope.engine->jsStackTop++;
+ setPointer(value_cast<T>(v));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
Scoped(const Scope &scope, const ScopedValue &v)
{
ptr = scope.engine->jsStackTop++;
@@ -280,6 +313,15 @@ struct Scoped
#endif
}
+ Scoped<T> &operator=(HeapObject *o) {
+ Value v;
+ v.m = reinterpret_cast<Managed *>(o);
+#if QT_POINTER_SIZE == 4
+ v.tag = QV4::Value::Managed_Type;
+#endif
+ setPointer(value_cast<T>(v));
+ return *this;
+ }
Scoped<T> &operator=(const Value &v) {
setPointer(value_cast<T>(v));
return *this;
@@ -308,6 +350,9 @@ struct Scoped
return *this;
}
+ operator T *() {
+ return static_cast<T *>(ptr->managed());
+ }
T *operator->() {
return static_cast<T *>(ptr->managed());
@@ -379,10 +424,6 @@ struct ScopedCallData {
};
-struct StringRef;
-struct ObjectRef;
-struct FunctionObjectRef;
-
template<typename T>
inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
{
@@ -400,38 +441,6 @@ inline Scoped<T> &Scoped<T>::operator=(const ValueRef &v)
return *this;
}
-struct CallDataRef {
- CallDataRef(const ScopedCallData &c)
- : ptr(c.ptr) {}
- CallDataRef(CallData *v) { ptr = v; }
- // Important: Do NOT add a copy constructor to this class
- // adding a copy constructor actually changes the calling convention, ie.
- // is not even binary compatible. Adding it would break assumptions made
- // in the jit'ed code.
- CallDataRef &operator=(const ScopedCallData &c)
- { *ptr = *c.ptr; return *this; }
- CallDataRef &operator=(const CallDataRef &o)
- { *ptr = *o.ptr; return *this; }
-
- operator const CallData *() const {
- return ptr;
- }
- const CallData *operator->() const {
- return ptr;
- }
-
- operator CallData *() {
- return ptr;
- }
- CallData *operator->() {
- return ptr;
- }
-
-private:
- CallData *ptr;
-};
-
-
template <typename T>
inline Value &Value::operator=(Returned<T> *t)
{
@@ -467,14 +476,20 @@ inline Returned<T> *Value::as()
template<typename T>
inline TypedValue<T> &TypedValue<T>::operator =(T *t)
{
- val = t->asReturnedValue();
+ m = t;
+#if QT_POINTER_SIZE == 4
+ tag = Managed_Type;
+#endif
return *this;
}
template<typename T>
inline TypedValue<T> &TypedValue<T>::operator =(const Scoped<T> &v)
{
- val = v.ptr->val;
+ m = v.ptr->managed();
+#if QT_POINTER_SIZE == 4
+ tag = Managed_Type;
+#endif
return *this;
}
@@ -517,22 +532,12 @@ PersistentValue::PersistentValue(Returned<T> *obj)
{
}
-inline PersistentValue::PersistentValue(const ManagedRef obj)
- : d(new PersistentValuePrivate(obj.asReturnedValue()))
-{
-}
-
template<typename T>
inline PersistentValue &PersistentValue::operator=(Returned<T> *obj)
{
return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
}
-inline PersistentValue &PersistentValue::operator=(const ManagedRef obj)
-{
- return operator=(obj.asReturnedValue());
-}
-
inline PersistentValue &PersistentValue::operator=(const ScopedValue &other)
{
return operator=(other.asReturnedValue());
@@ -573,18 +578,6 @@ inline ValueRef &ValueRef::operator=(const ScopedValue &o)
return *this;
}
-
-inline Value *extractValuePointer(const ScopedValue &v)
-{
- return v.ptr;
-}
-
-template<typename T>
-Value *extractValuePointer(const Scoped<T> &v)
-{
- return v.ptr;
-}
-
struct ScopedProperty
{
ScopedProperty(Scope &scope)
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 36f61a1df5..e08a63bd1f 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -61,12 +61,11 @@
using namespace QV4;
-QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, Function *f, ObjectRef qml)
- : FunctionObject(scope, scope->engine->id_eval, /*createProto = */ false)
+QmlBindingWrapper::Data::Data(ExecutionContext *scope, Function *f, Object *qml)
+ : FunctionObject::Data(scope, scope->d()->engine->id_eval, /*createProto = */ false)
, qml(qml)
- , qmlContext(0)
{
- Q_ASSERT(scope->inUse);
+ Q_ASSERT(scope->inUse());
setVTable(staticVTable());
function = f;
@@ -75,32 +74,30 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, Function *f, Objec
needsActivation = function ? function->needsActivation() : false;
Scope s(scope);
- ScopedValue protectThis(s, this);
+ Scoped<QmlBindingWrapper> o(s, this);
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(1));
+ o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
- qmlContext = scope->engine->currentContext()->newQmlContext(this, qml);
- scope->engine->popContext();
+ o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml));
+ s.engine->popContext();
}
-QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, ObjectRef qml)
- : FunctionObject(scope, scope->engine->id_eval, /*createProto = */ false)
+QmlBindingWrapper::Data::Data(ExecutionContext *scope, Object *qml)
+ : FunctionObject::Data(scope, scope->d()->engine->id_eval, /*createProto = */ false)
, qml(qml)
- , qmlContext(0)
{
- Q_ASSERT(scope->inUse);
+ Q_ASSERT(scope->inUse());
setVTable(staticVTable());
- function = 0;
needsActivation = false;
Scope s(scope);
- ScopedValue protectThis(s, this);
+ Scoped<QmlBindingWrapper> o(s, this);
- defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(1));
+ o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
- qmlContext = scope->engine->currentContext()->newQmlContext(this, qml);
- scope->engine->popContext();
+ o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml));
+ s.engine->popContext();
}
ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
@@ -110,13 +107,13 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
Scope scope(engine);
QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that);
- if (!This->function)
+ if (!This->function())
return QV4::Encode::undefined();
- CallContext *ctx = This->qmlContext;
- std::fill(ctx->locals, ctx->locals + ctx->function->varCount(), Primitive::undefinedValue());
+ CallContext *ctx = This->d()->qmlContext;
+ std::fill(ctx->d()->locals, ctx->d()->locals + ctx->d()->function->varCount(), Primitive::undefinedValue());
engine->pushContext(ctx);
- ScopedValue result(scope, This->function->code(ctx, This->function->codeData));
+ ScopedValue result(scope, This->function()->code(ctx, This->function()->codeData));
engine->popContext();
return result.asReturnedValue();
@@ -125,16 +122,16 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
void QmlBindingWrapper::markObjects(Managed *m, ExecutionEngine *e)
{
QmlBindingWrapper *wrapper = static_cast<QmlBindingWrapper*>(m);
- if (wrapper->qml)
- wrapper->qml->mark(e);
+ if (wrapper->d()->qml)
+ wrapper->d()->qml->mark(e);
FunctionObject::markObjects(m, e);
- if (wrapper->qmlContext)
- wrapper->qmlContext->mark(e);
+ if (wrapper->d()->qmlContext)
+ wrapper->d()->qmlContext->mark(e);
}
static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
{
- QV4::CallContext *signalEmittingContext = ctx->parent->asCallContext();
+ QV4::CallContext *signalEmittingContext = ctx->d()->parent->asCallContext();
Q_ASSERT(signalEmittingContext);
return signalEmittingContext->argument(parameterIndex);
}
@@ -144,7 +141,7 @@ Returned<FunctionObject> *QmlBindingWrapper::createQmlCallableForFunction(QQmlCo
ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(qmlContext->engine);
QV4::Scope valueScope(engine);
QV4::ScopedObject qmlScopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(engine->v8Engine, qmlContext, scopeObject));
- QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, new (engine->memoryManager) QV4::QmlBindingWrapper(engine->rootContext, qmlScopeObject));
+ QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, engine->memoryManager->alloc<QV4::QmlBindingWrapper>(engine->rootContext, qmlScopeObject));
if (!signalParameters.isEmpty()) {
if (error)
@@ -153,10 +150,11 @@ Returned<FunctionObject> *QmlBindingWrapper::createQmlCallableForFunction(QQmlCo
QV4::ScopedString s(valueScope);
int index = 0;
foreach (const QByteArray &param, signalParameters) {
- p->setGetter(new (engine->memoryManager) QV4::IndexedBuiltinFunction(wrapper->context(), index++, signalParameterGetter));
+ QV4::ScopedFunctionObject g(valueScope, engine->memoryManager->alloc<QV4::IndexedBuiltinFunction>(wrapper->context(), index++, signalParameterGetter));
+ p->setGetter(g);
p->setSetter(0);
s = engine->newString(QString::fromUtf8(param));
- qmlScopeObject->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
+ qmlScopeObject->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
}
}
@@ -166,35 +164,37 @@ Returned<FunctionObject> *QmlBindingWrapper::createQmlCallableForFunction(QQmlCo
DEFINE_OBJECT_VTABLE(QmlBindingWrapper);
-struct CompilationUnitHolder : public QV4::Object
+struct CompilationUnitHolder : public Object
{
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, CompiledData::CompilationUnit *unit)
+ : Object::Data(engine)
+ , unit(unit)
+ {
+ unit->ref();
+ setVTable(staticVTable());
+ }
+ ~Data()
+ {
+ unit->deref();
+ }
+ QV4::CompiledData::CompilationUnit *unit;
+ };
+ V4_OBJECT(Object)
- CompilationUnitHolder(ExecutionEngine *engine, CompiledData::CompilationUnit *unit)
- : Object(engine)
- , unit(unit)
- {
- unit->ref();
- setVTable(staticVTable());
- }
- ~CompilationUnitHolder()
- {
- unit->deref();
- }
static void destroy(Managed *that)
{
- static_cast<CompilationUnitHolder*>(that)->~CompilationUnitHolder();
+ static_cast<CompilationUnitHolder*>(that)->d()->~Data();
}
- QV4::CompiledData::CompilationUnit *unit;
};
DEFINE_OBJECT_VTABLE(CompilationUnitHolder);
-Script::Script(ExecutionEngine *v4, ObjectRef qml, CompiledData::CompilationUnit *compilationUnit)
+Script::Script(ExecutionEngine *v4, Object *qml, CompiledData::CompilationUnit *compilationUnit)
: line(0), column(0), scope(v4->rootContext), strictMode(false), inheritContext(true), parsed(false)
- , qml(qml.asReturnedValue()), vmFunction(0), parseAsBinding(true)
+ , qml(qml->asReturnedValue()), vmFunction(0), parseAsBinding(true)
{
parsed = true;
@@ -202,7 +202,7 @@ Script::Script(ExecutionEngine *v4, ObjectRef qml, CompiledData::CompilationUnit
vmFunction = compilationUnit->linkToEngine(v4);
Q_ASSERT(vmFunction);
Scope valueScope(v4);
- ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
+ ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
compilationUnitHolder = holder.asReturnedValue();
} else
vmFunction = 0;
@@ -221,7 +221,7 @@ void Script::parse()
parsed = true;
- ExecutionEngine *v4 = scope->engine;
+ ExecutionEngine *v4 = scope->d()->engine;
Scope valueScope(v4);
MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
@@ -274,7 +274,7 @@ void Script::parse()
isel->setUseFastLookups(false);
QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
vmFunction = compilationUnit->linkToEngine(v4);
- ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
+ ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
compilationUnitHolder = holder.asReturnedValue();
}
@@ -295,16 +295,16 @@ ReturnedValue Script::run()
ContextStateSaver(ExecutionContext *context)
: savedContext(context)
- , strictMode(context->strictMode)
- , lookups(context->lookups)
- , compilationUnit(context->compilationUnit)
+ , strictMode(context->d()->strictMode)
+ , lookups(context->d()->lookups)
+ , compilationUnit(context->d()->compilationUnit)
{}
~ContextStateSaver()
{
- savedContext->strictMode = strictMode;
- savedContext->lookups = lookups;
- savedContext->compilationUnit = compilationUnit;
+ savedContext->d()->strictMode = strictMode;
+ savedContext->d()->lookups = lookups;
+ savedContext->d()->compilationUnit = compilationUnit;
}
};
@@ -313,7 +313,7 @@ ReturnedValue Script::run()
if (!vmFunction)
return Encode::undefined();
- QV4::ExecutionEngine *engine = scope->engine;
+ QV4::ExecutionEngine *engine = scope->d()->engine;
QV4::Scope valueScope(engine);
if (qml.isUndefined()) {
@@ -321,14 +321,14 @@ ReturnedValue Script::run()
ExecutionContextSaver ctxSaver(scope);
ContextStateSaver stateSaver(scope);
- scope->strictMode = vmFunction->isStrict();
- scope->lookups = vmFunction->compilationUnit->runtimeLookups;
- scope->compilationUnit = vmFunction->compilationUnit;
+ scope->d()->strictMode = vmFunction->isStrict();
+ scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups;
+ scope->d()->compilationUnit = vmFunction->compilationUnit;
return vmFunction->code(scope, vmFunction->codeData);
} else {
ScopedObject qmlObj(valueScope, qml.value());
- FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qmlObj);
+ ScopedFunctionObject f(valueScope, engine->memoryManager->alloc<QmlBindingWrapper>(scope, vmFunction, qmlObj));
ScopedCallData callData(valueScope, 0);
callData->thisObject = Primitive::undefinedValue();
return f->call(callData);
@@ -401,14 +401,14 @@ ReturnedValue Script::qmlBinding()
{
if (!parsed)
parse();
- ExecutionEngine *v4 = scope->engine;
+ ExecutionEngine *v4 = scope->d()->engine;
Scope valueScope(v4);
ScopedObject qmlObj(valueScope, qml.value());
- ScopedObject v(valueScope, new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qmlObj));
+ ScopedObject v(valueScope, v4->memoryManager->alloc<QmlBindingWrapper>(scope, vmFunction, qmlObj));
return v.asReturnedValue();
}
-QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, ObjectRef scopeObject)
+QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
{
QV4::Scope scope(engine);
QV4::Script qmlScript(engine, scopeObject, script, QString());
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index de582f9674..6a749d1438 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -55,23 +55,25 @@ namespace QV4 {
struct ExecutionContext;
-struct QmlBindingWrapper : FunctionObject {
- V4_OBJECT
-
- QmlBindingWrapper(ExecutionContext *scope, Function *f, ObjectRef qml);
- // Constructor for QML functions and signal handlers, resulting binding wrapper is not callable!
- QmlBindingWrapper(ExecutionContext *scope, ObjectRef qml);
+struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject {
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, Function *f, Object *qml);
+ // Constructor for QML functions and signal handlers, resulting binding wrapper is not callable!
+ Data(ExecutionContext *scope, Object *qml);
+ Object *qml;
+ CallContext *qmlContext;
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue call(Managed *that, CallData *);
static void markObjects(Managed *m, ExecutionEngine *e);
- CallContext *context() const { return qmlContext; }
+ CallContext *context() const { return d()->qmlContext; }
- static Returned<FunctionObject> *createQmlCallableForFunction(QQmlContextData *qmlContext, QObject *scopeObject, QV4::Function *runtimeFunction, const QList<QByteArray> &signalParameters = QList<QByteArray>(), QString *error = 0);
+ static Returned<FunctionObject> *createQmlCallableForFunction(QQmlContextData *qmlContext, QObject *scopeObject, QV4::Function *runtimeFunction,
+ const QList<QByteArray> &signalParameters = QList<QByteArray>(), QString *error = 0);
private:
- Object *qml;
- CallContext *qmlContext;
};
struct Q_QML_EXPORT Script {
@@ -79,11 +81,11 @@ struct Q_QML_EXPORT Script {
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
, scope(scope), strictMode(false), inheritContext(false), parsed(false)
, vmFunction(0), parseAsBinding(false) {}
- Script(ExecutionEngine *engine, ObjectRef qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
+ Script(ExecutionEngine *engine, Object *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
, scope(engine->rootContext), strictMode(false), inheritContext(true), parsed(false)
- , qml(qml.asReturnedValue()), vmFunction(0), parseAsBinding(true) {}
- Script(ExecutionEngine *engine, ObjectRef qml, CompiledData::CompilationUnit *compilationUnit);
+ , qml(qml->asReturnedValue()), vmFunction(0), parseAsBinding(true) {}
+ Script(ExecutionEngine *engine, Object *qml, CompiledData::CompilationUnit *compilationUnit);
~Script();
QString sourceFile;
int line;
@@ -106,7 +108,7 @@ struct Q_QML_EXPORT Script {
static QV4::CompiledData::CompilationUnit *precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors = 0);
- static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, ObjectRef scopeObject);
+ static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
};
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 89231cfe5f..b55cd2daad 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -58,13 +58,13 @@ using namespace QV4;
// helper function to generate valid warnings if errors occur during sequence operations.
static void generateWarning(QV4::ExecutionContext *ctx, const QString& description)
{
- QQmlEngine *engine = ctx->engine->v8Engine->engine();
+ QQmlEngine *engine = ctx->d()->engine->v8Engine->engine();
if (!engine)
return;
QQmlError retn;
retn.setDescription(description);
- QV4::StackFrame frame = ctx->engine->currentStackFrame();
+ QV4::StackFrame frame = ctx->d()->engine->currentStackFrame();
retn.setLine(frame.line);
retn.setUrl(QUrl(frame.source));
@@ -163,38 +163,41 @@ template <> bool convertValueToElement(const ValueRef value)
}
template <typename Container>
-class QQmlSequence : public QV4::Object
+struct QQmlSequence : public QV4::Object
{
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(QV4::ExecutionEngine *engine, const Container &container)
+ : Object::Data(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
+ , container(container)
+ , propertyIndex(-1)
+ , isReference(false)
+ {
+ QV4::Scope scope(engine);
+ QV4::Scoped<QQmlSequence<Container> > o(scope, this);
+ o->setArrayType(ArrayData::Custom);
+ o->init();
+ }
+
+ Data(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
+ : Object::Data(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
+ , object(object)
+ , propertyIndex(propertyIndex)
+ , isReference(true)
+ {
+ QV4::Scope scope(engine);
+ QV4::Scoped<QQmlSequence<Container> > o(scope, this);
+ o->setArrayType(ArrayData::Custom);
+ o->loadReference();
+ o->init();
+ }
+ mutable Container container;
+ QPointer<QObject> object;
+ int propertyIndex;
+ bool isReference;
+ };
+ V4_OBJECT(QV4::Object)
Q_MANAGED_TYPE(QmlSequence)
public:
- QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
- : QV4::Object(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
- , m_container(container)
- , m_object(0)
- , m_propertyIndex(-1)
- , m_isReference(false)
- {
- QV4::Scope scope(engine);
- QV4::ScopedObject protectThis(scope, this);
- Q_UNUSED(protectThis);
- setArrayType(ArrayData::Custom);
- init();
- }
-
- QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
- : QV4::Object(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
- , m_object(object)
- , m_propertyIndex(propertyIndex)
- , m_isReference(true)
- {
- QV4::Scope scope(engine);
- QV4::ScopedObject protectThis(scope, this);
- Q_UNUSED(protectThis);
- setArrayType(ArrayData::Custom);
- loadReference();
- init();
- }
void init()
{
@@ -210,8 +213,8 @@ public:
*hasProperty = false;
return Encode::undefined();
}
- if (m_isReference) {
- if (!m_object) {
+ if (d()->isReference) {
+ if (!d()->object) {
if (hasProperty)
*hasProperty = false;
return Encode::undefined();
@@ -219,10 +222,10 @@ public:
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
- if (signedIdx < m_container.count()) {
+ if (signedIdx < d()->container.count()) {
if (hasProperty)
*hasProperty = true;
- return convertElementToValue(engine(), m_container.at(signedIdx));
+ return convertElementToValue(engine(), d()->container.at(signedIdx));
}
if (hasProperty)
*hasProperty = false;
@@ -231,7 +234,7 @@ public:
void containerPutIndexed(uint index, const QV4::ValueRef value)
{
- if (internalClass->engine->hasException)
+ if (internalClass()->engine->hasException)
return;
/* Qt containers have int (rather than uint) allowable indexes. */
@@ -240,33 +243,33 @@ public:
return;
}
- if (m_isReference) {
- if (!m_object)
+ if (d()->isReference) {
+ if (!d()->object)
return;
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
- int count = m_container.count();
+ int count = d()->container.count();
typename Container::value_type element = convertValueToElement<typename Container::value_type>(value);
if (signedIdx == count) {
- m_container.append(element);
+ d()->container.append(element);
} else if (signedIdx < count) {
- m_container[signedIdx] = element;
+ d()->container[signedIdx] = element;
} else {
/* according to ECMA262r3 we need to insert */
/* the value at the given index, increasing length to index+1. */
- m_container.reserve(signedIdx + 1);
+ d()->container.reserve(signedIdx + 1);
while (signedIdx > count++) {
- m_container.append(typename Container::value_type());
+ d()->container.append(typename Container::value_type());
}
- m_container.append(element);
+ d()->container.append(element);
}
- if (m_isReference)
+ if (d()->isReference)
storeReference();
}
@@ -277,33 +280,33 @@ public:
generateWarning(engine()->currentContext(), QLatin1String("Index out of range during indexed query"));
return QV4::Attr_Invalid;
}
- if (m_isReference) {
- if (!m_object)
+ if (d()->isReference) {
+ if (!d()->object)
return QV4::Attr_Invalid;
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
- return (signedIdx < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
+ return (signedIdx < d()->container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
}
- void containerAdvanceIterator(ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
+ void containerAdvanceIterator(ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
{
name = (String *)0;
*index = UINT_MAX;
- if (m_isReference) {
- if (!m_object) {
+ if (d()->isReference) {
+ if (!d()->object) {
QV4::Object::advanceIterator(this, it, name, index, p, attrs);
return;
}
loadReference();
}
- if (it->arrayIndex < static_cast<uint>(m_container.count())) {
+ if (it->arrayIndex < static_cast<uint>(d()->container.count())) {
*index = it->arrayIndex;
++it->arrayIndex;
*attrs = QV4::Attr_Data;
- p->value = convertElementToValue(engine(), m_container.at(*index));
+ p->value = convertElementToValue(engine(), d()->container.at(*index));
return;
}
QV4::Object::advanceIterator(this, it, name, index, p, attrs);
@@ -314,21 +317,21 @@ public:
/* Qt containers have int (rather than uint) allowable indexes. */
if (index > INT_MAX)
return false;
- if (m_isReference) {
- if (!m_object)
+ if (d()->isReference) {
+ if (!d()->object)
return false;
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
- if (signedIdx >= m_container.count())
+ if (signedIdx >= d()->container.count())
return false;
/* according to ECMA262r3 it should be Undefined, */
/* but we cannot, so we insert a default-value instead. */
- m_container.replace(signedIdx, typename Container::value_type());
+ d()->container.replace(signedIdx, typename Container::value_type());
- if (m_isReference)
+ if (d()->isReference)
storeReference();
return true;
@@ -339,9 +342,9 @@ public:
QQmlSequence<Container> *otherSequence = other->as<QQmlSequence<Container> >();
if (!otherSequence)
return false;
- if (m_isReference && otherSequence->m_isReference) {
- return m_object == otherSequence->m_object && m_propertyIndex == otherSequence->m_propertyIndex;
- } else if (!m_isReference && !otherSequence->m_isReference) {
+ if (d()->isReference && otherSequence->d()->isReference) {
+ return d()->object == otherSequence->d()->object && d()->propertyIndex == otherSequence->d()->propertyIndex;
+ } else if (!d()->isReference && !otherSequence->d()->isReference) {
return this == otherSequence;
}
return false;
@@ -366,9 +369,9 @@ public:
QV4::Scope scope(m_ctx);
ScopedObject compare(scope, m_compareFn);
ScopedCallData callData(scope, 2);
- callData->args[0] = convertElementToValue(this->m_ctx->engine, lhs);
- callData->args[1] = convertElementToValue(this->m_ctx->engine, rhs);
- callData->thisObject = this->m_ctx->engine->globalObject;
+ callData->args[0] = convertElementToValue(this->m_ctx->d()->engine, lhs);
+ callData->args[1] = convertElementToValue(this->m_ctx->d()->engine, rhs);
+ callData->thisObject = this->m_ctx->d()->engine->globalObject;
QV4::ScopedValue result(scope, compare->call(callData));
return result->toNumber() < 0;
}
@@ -380,82 +383,82 @@ public:
void sort(QV4::CallContext *ctx)
{
- if (m_isReference) {
- if (!m_object)
+ if (d()->isReference) {
+ if (!d()->object)
return;
loadReference();
}
QV4::Scope scope(ctx);
- if (ctx->callData->argc == 1 && ctx->callData->args[0].asFunctionObject()) {
- CompareFunctor cf(ctx, ctx->callData->args[0]);
- std::sort(m_container.begin(), m_container.end(), cf);
+ if (ctx->d()->callData->argc == 1 && ctx->d()->callData->args[0].asFunctionObject()) {
+ CompareFunctor cf(ctx, ctx->d()->callData->args[0]);
+ std::sort(d()->container.begin(), d()->container.end(), cf);
} else {
DefaultCompareFunctor cf;
- std::sort(m_container.begin(), m_container.end(), cf);
+ std::sort(d()->container.begin(), d()->container.end(), cf);
}
- if (m_isReference)
+ if (d()->isReference)
storeReference();
}
static QV4::ReturnedValue method_get_length(QV4::CallContext *ctx)
{
QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->d()->callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
return ctx->throwTypeError();
- if (This->m_isReference) {
- if (!This->m_object)
+ if (This->d()->isReference) {
+ if (!This->d()->object)
return QV4::Encode(0);
This->loadReference();
}
- return QV4::Encode(This->m_container.count());
+ return QV4::Encode(This->d()->container.count());
}
static QV4::ReturnedValue method_set_length(QV4::CallContext* ctx)
{
QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->d()->callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
return ctx->throwTypeError();
- quint32 newLength = ctx->callData->args[0].toUInt32();
+ quint32 newLength = ctx->d()->callData->args[0].toUInt32();
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(ctx, QLatin1String("Index out of range during length set"));
return QV4::Encode::undefined();
}
/* Read the sequence from the QObject property if we're a reference */
- if (This->m_isReference) {
- if (!This->m_object)
+ if (This->d()->isReference) {
+ if (!This->d()->object)
return QV4::Encode::undefined();
This->loadReference();
}
/* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength);
- qint32 count = This->m_container.count();
+ qint32 count = This->d()->container.count();
if (newCount == count) {
return QV4::Encode::undefined();
} else if (newCount > count) {
/* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */
/* We cannot, so we insert default-values instead. */
- This->m_container.reserve(newCount);
+ This->d()->container.reserve(newCount);
while (newCount > count++) {
- This->m_container.append(typename Container::value_type());
+ This->d()->container.append(typename Container::value_type());
}
} else {
/* according to ECMA262r3 we need to remove */
/* elements until the sequence is the required length. */
while (newCount < count) {
count--;
- This->m_container.removeAt(count);
+ This->d()->container.removeAt(count);
}
}
/* write back if required. */
- if (This->m_isReference) {
+ if (This->d()->isReference) {
/* write back. already checked that object is non-null, so skip that check here. */
This->storeReference();
}
@@ -463,9 +466,9 @@ public:
}
QVariant toVariant() const
- { return QVariant::fromValue<Container>(m_container); }
+ { return QVariant::fromValue<Container>(d()->container); }
- static QVariant toVariant(QV4::ArrayObjectRef array)
+ static QVariant toVariant(QV4::ArrayObject *array)
{
QV4::Scope scope(array->engine());
Container result;
@@ -479,27 +482,22 @@ public:
private:
void loadReference() const
{
- Q_ASSERT(m_object);
- Q_ASSERT(m_isReference);
- void *a[] = { &m_container, 0 };
- QMetaObject::metacall(m_object, QMetaObject::ReadProperty, m_propertyIndex, a);
+ Q_ASSERT(d()->object);
+ Q_ASSERT(d()->isReference);
+ void *a[] = { &d()->container, 0 };
+ QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->propertyIndex, a);
}
void storeReference()
{
- Q_ASSERT(m_object);
- Q_ASSERT(m_isReference);
+ Q_ASSERT(d()->object);
+ Q_ASSERT(d()->isReference);
int status = -1;
QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::DontRemoveBinding;
- void *a[] = { &m_container, 0, &status, &flags };
- QMetaObject::metacall(m_object, QMetaObject::WriteProperty, m_propertyIndex, a);
+ void *a[] = { &d()->container, 0, &status, &flags };
+ QMetaObject::metacall(d()->object, QMetaObject::WriteProperty, d()->propertyIndex, a);
}
- mutable Container m_container;
- QPointer<QObject> m_object;
- int m_propertyIndex;
- bool m_isReference;
-
static QV4::ReturnedValue getIndexed(QV4::Managed *that, uint index, bool *hasProperty)
{ return static_cast<QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
static void putIndexed(Managed *that, uint index, const QV4::ValueRef value)
@@ -510,7 +508,7 @@ private:
{ return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(index); }
static bool isEqualTo(Managed *that, Managed *other)
{ return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
- static void advanceIterator(Managed *that, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
+ static void advanceIterator(Managed *that, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
{ return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, p, attrs); }
static void destroy(Managed *that)
@@ -539,27 +537,22 @@ template<>
DEFINE_OBJECT_VTABLE(QQmlRealList);
#define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>(#SequenceType);
-SequencePrototype::SequencePrototype(InternalClass *ic)
- : QV4::Object(ic)
-{
- FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE)
-}
-#undef REGISTER_QML_SEQUENCE_METATYPE
-
void SequencePrototype::init()
{
+ FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE)
defineDefaultProperty(QStringLiteral("sort"), method_sort, 1);
defineDefaultProperty(engine()->id_valueOf, method_valueOf, 0);
}
+#undef REGISTER_QML_SEQUENCE_METATYPE
QV4::ReturnedValue SequencePrototype::method_sort(QV4::CallContext *ctx)
{
QV4::Scope scope(ctx);
- QV4::ScopedObject o(scope, ctx->callData->thisObject);
+ QV4::ScopedObject o(scope, ctx->d()->callData->thisObject);
if (!o || !o->isListType())
return ctx->throwTypeError();
- if (ctx->callData->argc >= 2)
+ if (ctx->d()->callData->argc >= 2)
return o.asReturnedValue();
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
@@ -587,7 +580,7 @@ bool SequencePrototype::isSequenceType(int sequenceTypeId)
#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::Scoped<QV4::Object> obj(scope, new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex)); \
+ QV4::Scoped<QV4::Object> obj(scope, engine->memoryManager->alloc<QQml##ElementTypeName##List>(engine, object, propertyIndex)); \
return obj.asReturnedValue(); \
} else
@@ -605,7 +598,7 @@ ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int s
#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::Scoped<QV4::Object> obj(scope, new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >())); \
+ QV4::Scoped<QV4::Object> obj(scope, engine->memoryManager->alloc<QQml##ElementTypeName##List>(engine, v.value<SequenceType >())); \
return obj.asReturnedValue(); \
} else
@@ -627,7 +620,7 @@ ReturnedValue SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const
return list->toVariant(); \
else
-QVariant SequencePrototype::toVariant(ObjectRef object)
+QVariant SequencePrototype::toVariant(Object *object)
{
Q_ASSERT(object->isListType());
FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ return QVariant(); }
@@ -660,7 +653,7 @@ QVariant SequencePrototype::toVariant(const QV4::ValueRef array, int typeHint, b
return qMetaTypeId<SequenceType>(); \
} else
-int SequencePrototype::metaTypeForSequence(QV4::ObjectRef object)
+int SequencePrototype::metaTypeForSequence(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 4a5e82b688..727f312930 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -65,13 +65,11 @@ namespace QV4 {
struct SequencePrototype : public QV4::Object
{
- SequencePrototype(QV4::InternalClass *ic);
-
void init();
static ReturnedValue method_valueOf(QV4::CallContext *ctx)
{
- return ctx->callData->thisObject.toString(ctx)->asReturnedValue();
+ return ctx->d()->callData->thisObject.toString(ctx)->asReturnedValue();
}
static ReturnedValue method_sort(QV4::CallContext *ctx);
@@ -79,8 +77,8 @@ 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(ObjectRef object);
- static QVariant toVariant(QV4::ObjectRef object);
+ static int metaTypeForSequence(Object *object);
+ static QVariant toVariant(Object *object);
static QVariant toVariant(const ValueRef array, int typeHint, bool *succeeded);
};
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index 3d754389a2..4e88a331a4 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -208,7 +208,7 @@ void Serialize::serialize(QByteArray &data, const QV4::ValueRef v, QV8Engine *en
} else if (QV4::DateObject *d = v->asDateObject()) {
reserve(data, sizeof(quint32) + sizeof(double));
push(data, valueheader(WorkerDate));
- push(data, d->value.asDouble());
+ push(data, d->date().asDouble());
} else if (v->as<RegExpObject>()) {
Scoped<RegExpObject> re(scope, v);
quint32 flags = re->flags();
@@ -281,7 +281,7 @@ void Serialize::serialize(QByteArray &data, const QV4::ValueRef v, QV8Engine *en
QV4::ExecutionContext *ctx = v4->currentContext();
str = s;
- val = o->get(str);
+ val = o->get(str.getPointer());
if (scope.hasException())
ctx->catchException();
@@ -342,7 +342,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
name = deserialize(data, engine);
value = deserialize(data, engine);
n = name.asReturnedValue();
- o->put(n, value);
+ o->put(n.getPointer(), value);
}
return o.asReturnedValue();
}
@@ -372,7 +372,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
QVariant var = qVariantFromValue(ref);
QV4::ScopedValue v(scope, engine->fromVariant((var)));
QV4::ScopedString s(scope, v4->newString(QStringLiteral("__qml:hidden:ref")));
- rv->asObject()->defineReadonlyProperty(s, v);
+ rv->asObject()->defineReadonlyProperty(s.getPointer(), v);
agent->release();
agent->setV8Engine(engine);
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index d9aa881f21..123d1648c2 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -108,7 +108,7 @@ static uint toArrayIndex(const char *ch, const char *end, bool *ok)
const ObjectVTable String::static_vtbl =
{
- DEFINE_MANAGED_VTABLE_INT(String),
+ DEFINE_MANAGED_VTABLE_INT(String, 0),
0,
0,
get,
@@ -133,13 +133,13 @@ void String::destroy(Managed *that)
void String::markObjects(Managed *that, ExecutionEngine *e)
{
String *s = static_cast<String *>(that);
- if (s->largestSubLength) {
- s->left->mark(e);
- s->right->mark(e);
+ if (s->d()->largestSubLength) {
+ s->d()->left->mark(e);
+ s->d()->right->mark(e);
}
}
-ReturnedValue String::get(Managed *m, const StringRef name, bool *hasProperty)
+ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
{
ExecutionEngine *v4 = m->engine();
Scope scope(v4);
@@ -148,7 +148,7 @@ ReturnedValue String::get(Managed *m, const StringRef name, bool *hasProperty)
if (name->equals(v4->id_length)) {
if (hasProperty)
*hasProperty = true;
- return Primitive::fromInt32(that->_text->size).asReturnedValue();
+ return Primitive::fromInt32(that->d()->text->size).asReturnedValue();
}
PropertyAttributes attrs;
Property *pd = v4->stringObjectClass->prototype->__getPropertyDescriptor__(name, &attrs);
@@ -168,7 +168,7 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
Scope scope(engine);
ScopedString that(scope, static_cast<String *>(m));
- if (index < static_cast<uint>(that->_text->size)) {
+ if (index < static_cast<uint>(that->d()->text->size)) {
if (hasProperty)
*hasProperty = true;
return Encode(engine->newString(that->toQString().mid(index, 1)));
@@ -185,7 +185,7 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
return engine->stringObjectClass->prototype->getValue(that, pd, attrs);
}
-void String::put(Managed *m, const StringRef name, const ValueRef value)
+void String::put(Managed *m, String *name, const ValueRef value)
{
Scope scope(m->engine());
if (scope.hasException())
@@ -206,7 +206,7 @@ void String::putIndexed(Managed *m, uint index, const ValueRef value)
o->putIndexed(index, value);
}
-PropertyAttributes String::query(const Managed *m, StringRef name)
+PropertyAttributes String::query(const Managed *m, String *name)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -217,10 +217,10 @@ PropertyAttributes String::query(const Managed *m, StringRef name)
PropertyAttributes String::queryIndexed(const Managed *m, uint index)
{
const String *that = static_cast<const String *>(m);
- return (index < static_cast<uint>(that->_text->size)) ? Attr_NotConfigurable|Attr_NotWritable : Attr_Invalid;
+ return (index < static_cast<uint>(that->d()->text->size)) ? Attr_NotConfigurable|Attr_NotWritable : Attr_Invalid;
}
-bool String::deleteProperty(Managed *, const StringRef)
+bool String::deleteProperty(Managed *, String *)
{
return false;
}
@@ -235,44 +235,50 @@ bool String::isEqualTo(Managed *t, Managed *o)
if (t == o)
return true;
- if (!o->internalClass->vtable->isString)
+ if (!o->internalClass()->vtable->isString)
return false;
String *that = static_cast<String *>(t);
String *other = static_cast<String *>(o);
if (that->hashValue() != other->hashValue())
return false;
- if (that->identifier && that->identifier == other->identifier)
+ if (that->identifier() && that->identifier() == other->identifier())
return true;
- if (that->subtype >= StringType_UInt && that->subtype == other->subtype)
+ if (that->subtype() >= StringType_UInt && that->subtype() == other->subtype())
return true;
return that->toQString() == other->toQString();
}
-String::String(ExecutionEngine *engine, const QString &text)
- : Managed(engine->stringClass), _text(const_cast<QString &>(text).data_ptr())
- , identifier(0), stringHash(UINT_MAX)
- , largestSubLength(0)
+String::Data::Data(ExecutionEngine *engine, const QString &t)
+ : Managed::Data(engine->stringClass)
{
- _text->ref.ref();
- len = _text->size;
subtype = StringType_Unknown;
+
+ text = const_cast<QString &>(t).data_ptr();
+ text->ref.ref();
+ identifier = 0;
+ stringHash = UINT_MAX;
+ largestSubLength = 0;
+ len = text->size;
}
-String::String(ExecutionEngine *engine, String *l, String *r)
- : Managed(engine->stringClass)
- , left(l), right(r)
- , stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength))
- , len(l->len + r->len)
+String::Data::Data(ExecutionEngine *engine, String *l, String *r)
+ : Managed::Data(engine->stringClass)
{
subtype = StringType_Unknown;
- if (!l->largestSubLength && l->len > largestSubLength)
- largestSubLength = l->len;
- if (!r->largestSubLength && r->len > largestSubLength)
- largestSubLength = r->len;
+ left = l;
+ right = r;
+ stringHash = UINT_MAX;
+ largestSubLength = qMax(l->d()->largestSubLength, r->d()->largestSubLength);
+ len = l->d()->len + r->d()->len;
+
+ if (!l->d()->largestSubLength && l->d()->len > largestSubLength)
+ largestSubLength = l->d()->len;
+ if (!r->d()->largestSubLength && r->d()->len > largestSubLength)
+ largestSubLength = r->d()->len;
// make sure we don't get excessive depth in our strings
if (len > 256 && len >= 2*largestSubLength)
@@ -283,10 +289,10 @@ uint String::toUInt(bool *ok) const
{
*ok = true;
- if (subtype == StringType_Unknown)
+ if (subtype() == StringType_Unknown)
createHashValue();
- if (subtype >= StringType_UInt)
- return stringHash;
+ if (subtype() >= StringType_UInt)
+ return d()->stringHash;
// ### this conversion shouldn't be required
double d = RuntimeHelpers::stringToNumber(toQString());
@@ -297,15 +303,15 @@ uint String::toUInt(bool *ok) const
return UINT_MAX;
}
-bool String::equals(const StringRef other) const
+bool String::equals(String *other) const
{
- if (this == other.getPointer())
+ if (this == other)
return true;
if (hashValue() != other->hashValue())
return false;
- if (identifier && identifier == other->identifier)
+ if (identifier() && identifier() == other->identifier())
return true;
- if (subtype >= StringType_UInt && subtype == other->subtype)
+ if (subtype() >= StringType_UInt && subtype() == other->subtype())
return true;
return toQString() == other->toQString();
@@ -313,13 +319,13 @@ bool String::equals(const StringRef other) const
void String::makeIdentifierImpl() const
{
- if (largestSubLength)
- simplifyString();
- Q_ASSERT(!largestSubLength);
+ if (d()->largestSubLength)
+ d()->simplifyString();
+ Q_ASSERT(!d()->largestSubLength);
engine()->identifierTable->identifier(this);
}
-void String::simplifyString() const
+void String::Data::simplifyString() const
{
Q_ASSERT(largestSubLength);
@@ -327,20 +333,20 @@ void String::simplifyString() const
QString result(l, Qt::Uninitialized);
QChar *ch = const_cast<QChar *>(result.constData());
recursiveAppend(ch);
- _text = result.data_ptr();
- _text->ref.ref();
+ text = result.data_ptr();
+ text->ref.ref();
identifier = 0;
largestSubLength = 0;
}
-QChar *String::recursiveAppend(QChar *ch) const
+QChar *String::Data::recursiveAppend(QChar *ch) const
{
if (largestSubLength) {
- ch = left->recursiveAppend(ch);
- ch = right->recursiveAppend(ch);
+ ch = left->d()->recursiveAppend(ch);
+ ch = right->d()->recursiveAppend(ch);
} else {
- memcpy(ch, _text->data(), _text->size*sizeof(QChar));
- ch += _text->size;
+ memcpy(ch, text->data(), text->size*sizeof(QChar));
+ ch += text->size;
}
return ch;
}
@@ -348,17 +354,17 @@ QChar *String::recursiveAppend(QChar *ch) const
void String::createHashValue() const
{
- if (largestSubLength)
- simplifyString();
- Q_ASSERT(!largestSubLength);
- const QChar *ch = reinterpret_cast<const QChar *>(_text->data());
- const QChar *end = ch + _text->size;
+ if (d()->largestSubLength)
+ d()->simplifyString();
+ Q_ASSERT(!d()->largestSubLength);
+ const QChar *ch = reinterpret_cast<const QChar *>(d()->text->data());
+ const QChar *end = ch + d()->text->size;
// array indices get their number as hash value
bool ok;
- stringHash = ::toArrayIndex(ch, end, &ok);
+ d()->stringHash = ::toArrayIndex(ch, end, &ok);
if (ok) {
- subtype = (stringHash == UINT_MAX) ? StringType_UInt : StringType_ArrayIndex;
+ setSubtype((d()->stringHash == UINT_MAX) ? StringType_UInt : StringType_ArrayIndex);
return;
}
@@ -368,8 +374,8 @@ void String::createHashValue() const
++ch;
}
- stringHash = h;
- subtype = StringType_Regular;
+ d()->stringHash = h;
+ setSubtype(StringType_Regular);
}
uint String::createHashValue(const QChar *ch, int length)
@@ -414,7 +420,7 @@ uint String::createHashValue(const char *ch, int length)
uint String::getLength(const Managed *m)
{
- return static_cast<const String *>(m)->length();
+ return static_cast<const String *>(m)->d()->length();
}
#endif // V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index ed2a4e3646..f9d3cd1cc0 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -53,8 +53,36 @@ struct Identifier;
struct Q_QML_PRIVATE_EXPORT String : public Managed {
#ifndef V4_BOOTSTRAP
+ struct Q_QML_PRIVATE_EXPORT Data : Managed::Data {
+ Data(ExecutionEngine *engine, const QString &text);
+ Data(ExecutionEngine *engine, String *l, String *n);
+ ~Data() {
+ if (!largestSubLength && !text->ref.deref())
+ QStringData::deallocate(text);
+ }
+ void simplifyString() const;
+ int length() const {
+ Q_ASSERT((largestSubLength &&
+ (len == left->d()->len + right->d()->len)) ||
+ len == (uint)text->size);
+ return len;
+ }
+ union {
+ mutable QStringData *text;
+ mutable String *left;
+ };
+ union {
+ mutable Identifier *identifier;
+ mutable String *right;
+ };
+ mutable uint stringHash;
+ mutable uint largestSubLength;
+ uint len;
+ private:
+ QChar *recursiveAppend(QChar *ch) const;
+ };
// ### FIXME: Should this be a V4_OBJECT
- V4_OBJECT
+ V4_OBJECT(QV4::Managed)
Q_MANAGED_TYPE(String)
enum {
IsString = true
@@ -67,24 +95,16 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
StringType_ArrayIndex
};
- String(ExecutionEngine *engine, const QString &text);
- String(ExecutionEngine *engine, String *l, String *n);
- ~String() {
- if (!largestSubLength && !_text->ref.deref())
- QStringData::deallocate(_text);
- _data = 0;
- }
-
- bool equals(const StringRef other) const;
+ bool equals(String *other) const;
inline bool isEqualTo(const String *other) const {
if (this == other)
return true;
if (hashValue() != other->hashValue())
return false;
- Q_ASSERT(!largestSubLength);
- if (identifier && identifier == other->identifier)
+ Q_ASSERT(!d()->largestSubLength);
+ if (d()->identifier && d()->identifier == other->d()->identifier)
return true;
- if (subtype >= StringType_UInt && subtype == other->subtype)
+ if (subtype() >= StringType_UInt && subtype() == other->subtype())
return true;
return toQString() == other->toQString();
@@ -95,34 +115,32 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
}
inline QString toQString() const {
- if (largestSubLength)
- simplifyString();
- QStringDataPtr ptr = { _text };
- _text->ref.ref();
+ if (d()->largestSubLength)
+ d()->simplifyString();
+ QStringDataPtr ptr = { d()->text };
+ d()->text->ref.ref();
return QString(ptr);
}
- void simplifyString() const;
-
inline unsigned hashValue() const {
- if (subtype == StringType_Unknown)
+ if (subtype() == StringType_Unknown)
createHashValue();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(!d()->largestSubLength);
- return stringHash;
+ return d()->stringHash;
}
uint asArrayIndex() const {
- if (subtype == StringType_Unknown)
+ if (subtype() == StringType_Unknown)
createHashValue();
- Q_ASSERT(!largestSubLength);
- if (subtype == StringType_ArrayIndex)
- return stringHash;
+ Q_ASSERT(!d()->largestSubLength);
+ if (subtype() == StringType_ArrayIndex)
+ return d()->stringHash;
return UINT_MAX;
}
uint toUInt(bool *ok) const;
void makeIdentifier() const {
- if (identifier)
+ if (d()->identifier)
return;
makeIdentifierImpl();
}
@@ -135,44 +153,26 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
bool startsWithUpper() const {
const String *l = this;
- while (l->largestSubLength)
- l = l->left;
- return l->_text->size && QChar::isUpper(l->_text->data()[0]);
- }
- int length() const {
- Q_ASSERT((largestSubLength && (len == left->len + right->len)) || len == (uint)_text->size);
- return len;
+ while (l->d()->largestSubLength)
+ l = l->d()->left;
+ return l->d()->text->size && QChar::isUpper(l->d()->text->data()[0]);
}
- union {
- mutable QStringData *_text;
- mutable String *left;
- };
- union {
- mutable Identifier *identifier;
- mutable String *right;
- };
- mutable uint stringHash;
- mutable uint largestSubLength;
- uint len;
-
+ Identifier *identifier() const { return d()->identifier; }
protected:
static void destroy(Managed *);
static void markObjects(Managed *that, ExecutionEngine *e);
- static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, const StringRef name, const ValueRef value);
+ static void put(Managed *m, String *name, const ValueRef value);
static void putIndexed(Managed *m, uint index, const ValueRef value);
- static PropertyAttributes query(const Managed *m, StringRef name);
+ static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static bool deleteProperty(Managed *, const StringRef);
+ static bool deleteProperty(Managed *, String *);
static bool deleteIndexedProperty(Managed *m, uint index);
static bool isEqualTo(Managed *that, Managed *o);
static uint getLength(const Managed *m);
-
-private:
- QChar *recursiveAppend(QChar *ch) const;
#endif
public:
@@ -191,7 +191,6 @@ inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
return v.toString(e)->asReturnedValue();
}
-DEFINE_REF(String, Managed);
#endif
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index f1e51703a8..3f683495cd 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -77,44 +77,38 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(StringObject);
-StringObject::StringObject(InternalClass *ic)
- : Object(ic)
+StringObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
Q_ASSERT(internalClass->vtable == staticVTable());
-
- Scope scope(engine());
- ScopedObject protectThis(scope, this);
-
value = ic->engine->newString(QStringLiteral(""))->asReturnedValue();
-
tmpProperty.value = Primitive::undefinedValue();
- defineReadonlyProperty(ic->engine->id_length, Primitive::fromInt32(0));
+ Scope scope(ic->engine);
+ ScopedObject s(scope, this);
+ s->defineReadonlyProperty(ic->engine->id_length, Primitive::fromInt32(0));
}
-StringObject::StringObject(ExecutionEngine *engine, const ValueRef val)
- : Object(engine->stringObjectClass)
+StringObject::Data::Data(ExecutionEngine *engine, const ValueRef val)
+ : Object::Data(engine->stringObjectClass)
{
+ value = val;
+ Q_ASSERT(value.isString());
+ tmpProperty.value = Primitive::undefinedValue();
setVTable(staticVTable());
Scope scope(engine);
- ScopedObject protectThis(scope, this);
-
- value = *val;
-
- tmpProperty.value = Primitive::undefinedValue();
-
- assert(value.isString());
- defineReadonlyProperty(engine->id_length, Primitive::fromUInt32(value.stringValue()->toQString().length()));
+ ScopedObject s(scope, this);
+ s->defineReadonlyProperty(engine->id_length, Primitive::fromUInt32(value.stringValue()->toQString().length()));
}
Property *StringObject::getIndex(uint index) const
{
- QString str = value.stringValue()->toQString();
+ QString str = d()->value.stringValue()->toQString();
if (index >= (uint)str.length())
return 0;
- tmpProperty.value = Encode(internalClass->engine->newString(str.mid(index, 1)));
- return &tmpProperty;
+ d()->tmpProperty.value = Encode(internalClass()->engine->newString(str.mid(index, 1)));
+ return &d()->tmpProperty;
}
bool StringObject::deleteIndexedProperty(Managed *m, uint index)
@@ -127,19 +121,19 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
return false;
}
- if (index < static_cast<uint>(o->value.stringValue()->toQString().length())) {
- if (v4->currentContext()->strictMode)
+ if (index < static_cast<uint>(o->d()->value.stringValue()->toQString().length())) {
+ if (v4->currentContext()->d()->strictMode)
v4->currentContext()->throwTypeError();
return false;
}
return true;
}
-void StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
+void StringObject::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
{
name = (String *)0;
StringObject *s = static_cast<StringObject *>(m);
- uint slen = s->value.stringValue()->toQString().length();
+ uint slen = s->d()->value.stringValue()->toQString().length();
if (it->arrayIndex <= slen) {
while (it->arrayIndex < slen) {
*index = it->arrayIndex;
@@ -152,7 +146,7 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef nam
return;
}
}
- if (s->arrayData) {
+ if (s->arrayData()) {
it->arrayNode = s->sparseBegin();
// iterate until we're past the end of the string
while (it->arrayNode && it->arrayNode->key() < slen)
@@ -166,15 +160,15 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef nam
void StringObject::markObjects(Managed *that, ExecutionEngine *e)
{
StringObject *o = static_cast<StringObject *>(that);
- o->value.stringValue()->mark(e);
- o->tmpProperty.value.mark(e);
+ o->d()->value.stringValue()->mark(e);
+ o->d()->tmpProperty.value.mark(e);
Object::markObjects(that, e);
}
DEFINE_OBJECT_VTABLE(StringCtor);
-StringCtor::StringCtor(ExecutionContext *scope)
- : FunctionObject(scope, QStringLiteral("String"))
+StringCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("String"))
{
setVTable(staticVTable());
}
@@ -203,7 +197,7 @@ ReturnedValue StringCtor::call(Managed *m, CallData *callData)
return value.asReturnedValue();
}
-void StringPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
+void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
@@ -238,11 +232,11 @@ void StringPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
static QString getThisString(ExecutionContext *ctx)
{
Scope scope(ctx);
- ScopedValue t(scope, ctx->callData->thisObject);
+ ScopedValue t(scope, ctx->d()->callData->thisObject);
if (t->isString())
return t->stringValue()->toQString();
if (StringObject *thisString = t->asStringObject())
- return thisString->value.stringValue()->toQString();
+ return thisString->d()->value.stringValue()->toQString();
if (t->isUndefined() || t->isNull()) {
ctx->throwTypeError();
return QString();
@@ -252,41 +246,41 @@ static QString getThisString(ExecutionContext *ctx)
ReturnedValue StringPrototype::method_toString(CallContext *context)
{
- if (context->callData->thisObject.isString())
- return context->callData->thisObject.asReturnedValue();
+ if (context->d()->callData->thisObject.isString())
+ return context->d()->callData->thisObject.asReturnedValue();
- StringObject *o = context->callData->thisObject.asStringObject();
+ StringObject *o = context->d()->callData->thisObject.asStringObject();
if (!o)
return context->throwTypeError();
- return o->value.asReturnedValue();
+ return o->d()->value.asReturnedValue();
}
ReturnedValue StringPrototype::method_charAt(CallContext *context)
{
const QString str = getThisString(context);
- if (context->engine->hasException)
+ if (context->d()->engine->hasException)
return Encode::undefined();
int pos = 0;
- if (context->callData->argc > 0)
- pos = (int) context->callData->args[0].toInteger();
+ if (context->d()->callData->argc > 0)
+ pos = (int) context->d()->callData->args[0].toInteger();
QString result;
if (pos >= 0 && pos < str.length())
result += str.at(pos);
- return context->engine->newString(result)->asReturnedValue();
+ return context->d()->engine->newString(result)->asReturnedValue();
}
ReturnedValue StringPrototype::method_charCodeAt(CallContext *context)
{
const QString str = getThisString(context);
- if (context->engine->hasException)
+ if (context->d()->engine->hasException)
return Encode::undefined();
int pos = 0;
- if (context->callData->argc > 0)
- pos = (int) context->callData->args[0].toInteger();
+ if (context->d()->callData->argc > 0)
+ pos = (int) context->d()->callData->args[0].toInteger();
if (pos >= 0 && pos < str.length())
@@ -304,30 +298,30 @@ ReturnedValue StringPrototype::method_concat(CallContext *context)
return Encode::undefined();
ScopedValue v(scope);
- for (int i = 0; i < context->callData->argc; ++i) {
- v = RuntimeHelpers::toString(context, ValueRef(&context->callData->args[i]));
+ for (int i = 0; i < context->d()->callData->argc; ++i) {
+ v = RuntimeHelpers::toString(context, ValueRef(&context->d()->callData->args[i]));
if (scope.hasException())
return Encode::undefined();
Q_ASSERT(v->isString());
value += v->stringValue()->toQString();
}
- return context->engine->newString(value)->asReturnedValue();
+ return context->d()->engine->newString(value)->asReturnedValue();
}
ReturnedValue StringPrototype::method_indexOf(CallContext *context)
{
QString value = getThisString(context);
- if (context->engine->hasException)
+ if (context->d()->engine->hasException)
return Encode::undefined();
QString searchString;
- if (context->callData->argc)
- searchString = context->callData->args[0].toString(context)->toQString();
+ if (context->d()->callData->argc)
+ searchString = context->d()->callData->args[0].toString(context)->toQString();
int pos = 0;
- if (context->callData->argc > 1)
- pos = (int) context->callData->args[1].toInteger();
+ if (context->d()->callData->argc > 1)
+ pos = (int) context->d()->callData->args[1].toInteger();
int index = -1;
if (! value.isEmpty())
@@ -345,8 +339,8 @@ ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context)
return Encode::undefined();
QString searchString;
- if (context->callData->argc)
- searchString = context->callData->args[0].toQString();
+ if (context->d()->callData->argc)
+ searchString = context->d()->callData->args[0].toQString();
ScopedValue posArg(scope, context->argument(1));
double position = RuntimeHelpers::toNumber(posArg);
@@ -371,36 +365,36 @@ ReturnedValue StringPrototype::method_localeCompare(CallContext *context)
if (scope.engine->hasException)
return Encode::undefined();
- ScopedValue v(scope, context->callData->argument(0));
+ ScopedValue v(scope, context->d()->callData->argument(0));
const QString that = v->toQString();
return Encode(QString::localeAwareCompare(value, that));
}
ReturnedValue StringPrototype::method_match(CallContext *context)
{
- if (context->callData->thisObject.isUndefined() || context->callData->thisObject.isNull())
+ if (context->d()->callData->thisObject.isUndefined() || context->d()->callData->thisObject.isNull())
return context->throwTypeError();
Scope scope(context);
- ScopedString s(scope, context->callData->thisObject.toString(context));
+ ScopedString s(scope, context->d()->callData->thisObject.toString(context));
- ScopedValue regexp(scope, context->callData->argument(0));
+ ScopedValue regexp(scope, context->d()->callData->argument(0));
Scoped<RegExpObject> rx(scope, regexp);
if (!rx) {
ScopedCallData callData(scope, 1);
callData->args[0] = regexp;
- rx = context->engine->regExpCtor.asFunctionObject()->construct(callData);
+ rx = context->d()->engine->regExpCtor.asFunctionObject()->construct(callData);
}
if (!rx)
// ### CHECK
return context->throwTypeError();
- bool global = rx->global;
+ bool global = rx->global();
// ### use the standard builtin function, not the one that might be redefined in the proto
- ScopedString execString(scope, context->engine->newString(QStringLiteral("exec")));
- Scoped<FunctionObject> exec(scope, context->engine->regExpClass->prototype->get(execString));
+ ScopedString execString(scope, context->d()->engine->newString(QStringLiteral("exec")));
+ Scoped<FunctionObject> exec(scope, context->d()->engine->regExpClass->prototype->get(execString.getPointer()));
ScopedCallData callData(scope, 1);
callData->thisObject = rx;
@@ -408,9 +402,9 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
if (!global)
return exec->call(callData);
- ScopedString lastIndex(scope, context->engine->newString(QStringLiteral("lastIndex")));
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
- Scoped<ArrayObject> a(scope, context->engine->newArrayObject());
+ ScopedString lastIndex(scope, context->d()->engine->newString(QStringLiteral("lastIndex")));
+ rx->put(lastIndex.getPointer(), ScopedValue(scope, Primitive::fromInt32(0)));
+ Scoped<ArrayObject> a(scope, context->d()->engine->newArrayObject());
double previousLastIndex = 0;
uint n = 0;
@@ -422,11 +416,11 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
if (result->isNull())
break;
assert(result->isObject());
- index = rx->get(lastIndex, 0);
+ index = rx->get(lastIndex.getPointer(), 0);
double thisIndex = index->toInteger();
if (previousLastIndex == thisIndex) {
previousLastIndex = thisIndex + 1;
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromDouble(previousLastIndex)));
+ rx->put(lastIndex.getPointer(), ScopedValue(scope, Primitive::fromDouble(previousLastIndex)));
} else {
previousLastIndex = thisIndex;
}
@@ -491,10 +485,10 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
{
Scope scope(ctx);
QString string;
- if (StringObject *thisString = ctx->callData->thisObject.asStringObject())
- string = thisString->value.stringValue()->toQString();
+ if (StringObject *thisString = ctx->d()->callData->thisObject.asStringObject())
+ string = thisString->d()->value.stringValue()->toQString();
else
- string = ctx->callData->thisObject.toString(ctx)->toQString();
+ string = ctx->d()->callData->thisObject.toString(ctx)->toQString();
int numCaptures = 0;
int numStringMatches = 0;
@@ -510,7 +504,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint offset = 0;
// We extract the pointer here to work around a compiler bug on Android.
- Scoped<RegExp> re(scope, regExp->value);
+ Scoped<RegExp> re(scope, regExp->value());
while (true) {
int oldSize = nMatchOffsets;
if (allocatedMatchOffsets < nMatchOffsets + re->captureCount() * 2) {
@@ -526,14 +520,14 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
break;
}
nMatchOffsets += re->captureCount() * 2;
- if (!regExp->global)
+ if (!regExp->d()->global)
break;
offset = qMax(offset + 1, matchOffsets[oldSize + 1]);
}
- if (regExp->global)
+ if (regExp->global())
regExp->lastIndexProperty(ctx)->value = Primitive::fromUInt32(0);
- numStringMatches = nMatchOffsets / (regExp->value->captureCount() * 2);
- numCaptures = regExp->value->captureCount();
+ numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2);
+ numCaptures = regExp->value()->captureCount();
} else {
numCaptures = 1;
QString searchString = searchValue->toString(ctx)->toQString();
@@ -563,14 +557,14 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint end = matchOffsets[idx + 1];
entry = Primitive::undefinedValue();
if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
- entry = ctx->engine->newString(string.mid(start, end - start));
+ entry = ctx->d()->engine->newString(string.mid(start, end - start));
callData->args[k] = entry;
}
uint matchStart = matchOffsets[i * numCaptures * 2];
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = ctx->engine->newString(string);
+ callData->args[numCaptures + 1] = ctx->d()->engine->newString(string);
replacement = searchCallback->call(callData);
result += string.midRef(lastEnd, matchStart - lastEnd);
@@ -600,7 +594,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
if (matchOffsets != _matchOffsets)
free(matchOffsets);
- return ctx->engine->newString(result)->asReturnedValue();
+ return ctx->d()->engine->newString(result)->asReturnedValue();
}
ReturnedValue StringPrototype::method_search(CallContext *ctx)
@@ -614,14 +608,14 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx)
if (!regExp) {
ScopedCallData callData(scope, 1);
callData->args[0] = regExpValue;
- regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(callData);
+ regExpValue = ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData);
if (scope.engine->hasException)
return Encode::undefined();
regExp = regExpValue->as<RegExpObject>();
Q_ASSERT(regExp);
}
- uint* matchOffsets = (uint*)alloca(regExp->value->captureCount() * 2 * sizeof(uint));
- uint result = regExp->value->match(string, /*offset*/0, matchOffsets);
+ uint* matchOffsets = (uint*)alloca(regExp->value()->captureCount() * 2 * sizeof(uint));
+ uint result = regExp->value()->match(string, /*offset*/0, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
return Encode(-1);
return Encode(result);
@@ -630,14 +624,14 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx)
ReturnedValue StringPrototype::method_slice(CallContext *ctx)
{
const QString text = getThisString(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
const double length = text.length();
- double start = ctx->callData->argc ? ctx->callData->args[0].toInteger() : 0;
- double end = (ctx->callData->argc < 2 || ctx->callData->args[1].isUndefined())
- ? length : ctx->callData->args[1].toInteger();
+ double start = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toInteger() : 0;
+ double end = (ctx->d()->callData->argc < 2 || ctx->d()->callData->args[1].isUndefined())
+ ? length : ctx->d()->callData->args[1].toInteger();
if (start < 0)
start = qMax(length + start, 0.);
@@ -653,7 +647,7 @@ ReturnedValue StringPrototype::method_slice(CallContext *ctx)
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- return ctx->engine->newString(text.mid(intStart, count))->asReturnedValue();
+ return ctx->d()->engine->newString(text.mid(intStart, count))->asReturnedValue();
}
ReturnedValue StringPrototype::method_split(CallContext *ctx)
@@ -666,15 +660,15 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
ScopedValue separatorValue(scope, ctx->argument(0));
ScopedValue limitValue(scope, ctx->argument(1));
- ScopedArrayObject array(scope, ctx->engine->newArrayObject());
+ ScopedArrayObject array(scope, ctx->d()->engine->newArrayObject());
if (separatorValue->isUndefined()) {
if (limitValue->isUndefined()) {
- ScopedString s(scope, ctx->engine->newString(text));
+ ScopedString s(scope, ctx->d()->engine->newString(text));
array->push_back(s);
return array.asReturnedValue();
}
- return ctx->engine->newString(text.left(limitValue->toInteger()))->asReturnedValue();
+ return ctx->d()->engine->newString(text.left(limitValue->toInteger()))->asReturnedValue();
}
uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
@@ -684,55 +678,55 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
Scoped<RegExpObject> re(scope, separatorValue);
if (re) {
- if (re->value->pattern().isEmpty()) {
+ if (re->value()->pattern().isEmpty()) {
re = (RegExpObject *)0;
- separatorValue = ctx->engine->newString(QString());
+ separatorValue = ctx->d()->engine->newString(QString());
}
}
ScopedString s(scope);
if (re) {
uint offset = 0;
- uint* matchOffsets = (uint*)alloca(re->value->captureCount() * 2 * sizeof(uint));
+ uint* matchOffsets = (uint*)alloca(re->value()->captureCount() * 2 * sizeof(uint));
while (true) {
- uint result = re->value->match(text, offset, matchOffsets);
+ uint result = re->value()->match(text, offset, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
break;
- array->push_back((s = ctx->engine->newString(text.mid(offset, matchOffsets[0] - offset))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(offset, matchOffsets[0] - offset))));
offset = qMax(offset + 1, matchOffsets[1]);
if (array->getLength() >= limit)
break;
- for (int i = 1; i < re->value->captureCount(); ++i) {
+ for (int i = 1; i < re->value()->captureCount(); ++i) {
uint start = matchOffsets[i * 2];
uint end = matchOffsets[i * 2 + 1];
- array->push_back((s = ctx->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
if (array->getLength() >= limit)
break;
}
}
if (array->getLength() < limit)
- array->push_back((s = ctx->engine->newString(text.mid(offset))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(offset))));
} else {
QString separator = separatorValue->toString(ctx)->toQString();
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
- array->push_back((s = ctx->engine->newString(text.mid(i, 1))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(i, 1))));
return array.asReturnedValue();
}
int start = 0;
int end;
while ((end = text.indexOf(separator, start)) != -1) {
- array->push_back((s = ctx->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
start = end + separator.size();
if (array->getLength() >= limit)
break;
}
if (array->getLength() < limit && start != -1)
- array->push_back((s = ctx->engine->newString(text.mid(start))));
+ array->push_back((s = ctx->d()->engine->newString(text.mid(start))));
}
return array.asReturnedValue();
}
@@ -740,16 +734,16 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
ReturnedValue StringPrototype::method_substr(CallContext *context)
{
const QString value = getThisString(context);
- if (context->engine->hasException)
+ if (context->d()->engine->hasException)
return Encode::undefined();
double start = 0;
- if (context->callData->argc > 0)
- start = context->callData->args[0].toInteger();
+ if (context->d()->callData->argc > 0)
+ start = context->d()->callData->args[0].toInteger();
double length = +qInf();
- if (context->callData->argc > 1)
- length = context->callData->args[1].toInteger();
+ if (context->d()->callData->argc > 1)
+ length = context->d()->callData->args[1].toInteger();
double count = value.length();
if (start < 0)
@@ -759,21 +753,21 @@ ReturnedValue StringPrototype::method_substr(CallContext *context)
qint32 x = Primitive::toInt32(start);
qint32 y = Primitive::toInt32(length);
- return context->engine->newString(value.mid(x, y))->asReturnedValue();
+ return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
}
ReturnedValue StringPrototype::method_substring(CallContext *context)
{
QString value = getThisString(context);
- if (context->engine->hasException)
+ if (context->d()->engine->hasException)
return Encode::undefined();
int length = value.length();
double start = 0;
double end = length;
- if (context->callData->argc > 0)
- start = context->callData->args[0].toInteger();
+ if (context->d()->callData->argc > 0)
+ start = context->d()->callData->args[0].toInteger();
Scope scope(context);
ScopedValue endValue(scope, context->argument(1));
@@ -800,15 +794,15 @@ ReturnedValue StringPrototype::method_substring(CallContext *context)
qint32 x = (int)start;
qint32 y = (int)(end - start);
- return context->engine->newString(value.mid(x, y))->asReturnedValue();
+ return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
}
ReturnedValue StringPrototype::method_toLowerCase(CallContext *ctx)
{
QString value = getThisString(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
- return ctx->engine->newString(value.toLower())->asReturnedValue();
+ return ctx->d()->engine->newString(value.toLower())->asReturnedValue();
}
ReturnedValue StringPrototype::method_toLocaleLowerCase(CallContext *ctx)
@@ -819,9 +813,9 @@ ReturnedValue StringPrototype::method_toLocaleLowerCase(CallContext *ctx)
ReturnedValue StringPrototype::method_toUpperCase(CallContext *ctx)
{
QString value = getThisString(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
- return ctx->engine->newString(value.toUpper())->asReturnedValue();
+ return ctx->d()->engine->newString(value.toUpper())->asReturnedValue();
}
ReturnedValue StringPrototype::method_toLocaleUpperCase(CallContext *ctx)
@@ -831,19 +825,19 @@ ReturnedValue StringPrototype::method_toLocaleUpperCase(CallContext *ctx)
ReturnedValue StringPrototype::method_fromCharCode(CallContext *context)
{
- QString str(context->callData->argc, Qt::Uninitialized);
+ QString str(context->d()->callData->argc, Qt::Uninitialized);
QChar *ch = str.data();
- for (int i = 0; i < context->callData->argc; ++i) {
- *ch = QChar(context->callData->args[i].toUInt16());
+ for (int i = 0; i < context->d()->callData->argc; ++i) {
+ *ch = QChar(context->d()->callData->args[i].toUInt16());
++ch;
}
- return context->engine->newString(str)->asReturnedValue();
+ return context->d()->engine->newString(str)->asReturnedValue();
}
ReturnedValue StringPrototype::method_trim(CallContext *ctx)
{
QString s = getThisString(ctx);
- if (ctx->engine->hasException)
+ if (ctx->d()->engine->hasException)
return Encode::undefined();
const QChar *chars = s.constData();
@@ -857,5 +851,5 @@ ReturnedValue StringPrototype::method_trim(CallContext *ctx)
break;
}
- return ctx->engine->newString(QString(chars + start, end - start + 1))->asReturnedValue();
+ return ctx->d()->engine->newString(QString(chars + start, end - start + 1))->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index c38fd5b75f..0fc556f849 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -50,27 +50,32 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct StringObject: Object {
- V4_OBJECT
+ struct Data : Object::Data {
+ Data(ExecutionEngine *engine, const ValueRef value);
+ Data(InternalClass *ic);
+ Value value;
+ // ### get rid of tmpProperty
+ mutable Property tmpProperty;
+ };
+ V4_OBJECT(Object)
Q_MANAGED_TYPE(StringObject)
- Value value;
- mutable Property tmpProperty;
- StringObject(ExecutionEngine *engine, const ValueRef value);
Property *getIndex(uint index) const;
static bool deleteIndexedProperty(Managed *m, uint index);
protected:
- StringObject(InternalClass *ic);
- static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs);
+ static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs);
static void markObjects(Managed *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
{
- V4_OBJECT
- StringCtor(ExecutionContext *scope);
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+ V4_OBJECT(FunctionObject)
static ReturnedValue construct(Managed *m, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -78,8 +83,7 @@ struct StringCtor: FunctionObject
struct StringPrototype: StringObject
{
- StringPrototype(InternalClass *ic): StringObject(ic) {}
- void init(ExecutionEngine *engine, ObjectRef ctor);
+ void init(ExecutionEngine *engine, Object *ctor);
static ReturnedValue method_toString(CallContext *context);
static ReturnedValue method_charAt(CallContext *context);
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index e9246f7a14..e122b18892 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -95,7 +95,7 @@ double Value::toNumberImpl() const
if (isString())
return RuntimeHelpers::stringToNumber(stringValue()->toQString());
{
- ExecutionContext *ctx = objectValue()->internalClass->engine->currentContext();
+ ExecutionContext *ctx = objectValue()->internalClass()->engine->currentContext();
Scope scope(ctx);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(ValueRef::fromRawValue(this), NUMBER_HINT));
return prim->toNumber();
@@ -129,7 +129,7 @@ QString Value::toQStringNoThrow() const
if (isString())
return stringValue()->toQString();
{
- ExecutionContext *ctx = objectValue()->internalClass->engine->currentContext();
+ ExecutionContext *ctx = objectValue()->internalClass()->engine->currentContext();
Scope scope(ctx);
ScopedValue ex(scope);
bool caughtException = false;
@@ -182,7 +182,7 @@ QString Value::toQString() const
if (isString())
return stringValue()->toQString();
{
- ExecutionContext *ctx = objectValue()->internalClass->engine->currentContext();
+ ExecutionContext *ctx = objectValue()->internalClass()->engine->currentContext();
Scope scope(ctx);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(ValueRef::fromRawValue(this), STRING_HINT));
return prim->toQString();
diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h
index 1fe9e1c165..84a8e1adf2 100644
--- a/src/qml/jsruntime/qv4value_inl_p.h
+++ b/src/qml/jsruntime/qv4value_inl_p.h
@@ -64,13 +64,13 @@ inline bool Value::isString() const
{
if (!isManaged())
return false;
- return managed() && managed()->internalClass->vtable->isString;
+ return managed() && managed()->internalClass()->vtable->isString;
}
inline bool Value::isObject() const
{
if (!isManaged())
return false;
- return managed() && managed()->internalClass->vtable->isObject;
+ return managed() && managed()->internalClass()->vtable->isObject;
}
inline bool Value::isPrimitive() const
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 29cb8b42ed..7b49db74d9 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -64,6 +64,8 @@ struct Returned : private T
using T::asReturnedValue;
};
+struct HeapObject {};
+
struct Q_QML_PRIVATE_EXPORT Value
{
/*
@@ -347,6 +349,10 @@ struct Q_QML_PRIVATE_EXPORT Value
val = Value::fromManaged(t).val;
return *this;
}
+ Value &operator=(HeapObject *o) {
+ m = reinterpret_cast<Managed *>(o);
+ return *this;
+ }
template<typename T>
Value &operator=(const Scoped<T> &t);
@@ -430,7 +436,10 @@ struct TypedValue : public Value
{
template<typename X>
TypedValue &operator =(X *x) {
- val = Value::fromManaged(x).val;
+ m = x;
+#if QT_POINTER_SIZE == 4
+ tag = Managed_Type;
+#endif
}
TypedValue &operator =(T *t);
TypedValue &operator =(const Scoped<T> &v);
@@ -441,6 +450,7 @@ struct TypedValue : public Value
bool operator!() const { return !managed(); }
+ operator T *() { return static_cast<T *>(managed()); }
T *operator->() { return static_cast<T *>(managed()); }
const T *operator->() const { return static_cast<T *>(managed()); }
T *getPointer() const { return static_cast<T *>(managed()); }
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 92cc19d8b9..a5b22a2de8 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -51,18 +51,15 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(VariantObject);
-VariantObject::VariantObject(InternalClass *ic)
- : Object(ic)
- , ExecutionEngine::ScarceResourceData(QVariant())
- , m_vmePropertyReferenceCount(0)
+VariantObject::Data::Data(InternalClass *ic)
+ : Object::Data(ic)
{
}
-VariantObject::VariantObject(ExecutionEngine *engine, const QVariant &value)
- : Object(engine->variantClass)
- , ExecutionEngine::ScarceResourceData(value)
- , m_vmePropertyReferenceCount(0)
+VariantObject::Data::Data(ExecutionEngine *engine, const QVariant &value)
+ : Object::Data(engine->variantClass)
{
+ data = value;
if (isScarce())
engine->scarceResources.insert(this);
}
@@ -89,7 +86,7 @@ QVariant VariantObject::toVariant(const QV4::ValueRef v)
return QVariant();
}
-bool VariantObject::isScarce() const
+bool VariantObject::Data::isScarce() const
{
QVariant::Type t = data.type();
return t == QVariant::Pixmap || t == QVariant::Image;
@@ -98,9 +95,7 @@ bool VariantObject::isScarce() const
void VariantObject::destroy(Managed *that)
{
VariantObject *v = static_cast<VariantObject *>(that);
- if (v->isScarce())
- v->node.remove();
- v->~VariantObject();
+ v->d()->~Data();
}
bool VariantObject::isEqualTo(Managed *m, Managed *other)
@@ -109,40 +104,35 @@ bool VariantObject::isEqualTo(Managed *m, Managed *other)
assert(lv);
if (QV4::VariantObject *rv = other->as<QV4::VariantObject>())
- return lv->data == rv->data;
+ return lv->d()->data == rv->d()->data;
if (QV4::QmlValueTypeWrapper *v = other->as<QmlValueTypeWrapper>())
- return v->isEqual(lv->data);
+ return v->isEqual(lv->d()->data);
return false;
}
void VariantObject::addVmePropertyReference()
{
- if (isScarce() && ++m_vmePropertyReferenceCount == 1) {
+ if (d()->isScarce() && ++d()->vmePropertyReferenceCount == 1) {
// remove from the ep->scarceResources list
// since it is now no longer eligible to be
// released automatically by the engine.
- node.remove();
+ d()->node.remove();
}
}
void VariantObject::removeVmePropertyReference()
{
- if (isScarce() && --m_vmePropertyReferenceCount == 0) {
+ if (d()->isScarce() && --d()->vmePropertyReferenceCount == 0) {
// and add to the ep->scarceResources list
// since it is now eligible to be released
// automatically by the engine.
- internalClass->engine->scarceResources.insert(this);
+ internalClass()->engine->scarceResources.insert(d());
}
}
-VariantPrototype::VariantPrototype(InternalClass *ic)
- : VariantObject(ic)
-{
-}
-
void VariantPrototype::init()
{
defineDefaultProperty(QStringLiteral("preserve"), method_preserve, 0);
@@ -154,20 +144,20 @@ void VariantPrototype::init()
QV4::ReturnedValue VariantPrototype::method_preserve(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->callData->thisObject.as<QV4::VariantObject>());
- if (o && o->isScarce())
- o->node.remove();
+ Scoped<VariantObject> o(scope, ctx->d()->callData->thisObject.as<QV4::VariantObject>());
+ if (o && o->d()->isScarce())
+ o->d()->node.remove();
return Encode::undefined();
}
QV4::ReturnedValue VariantPrototype::method_destroy(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->callData->thisObject.as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, ctx->d()->callData->thisObject.as<QV4::VariantObject>());
if (o) {
- if (o->isScarce())
- o->node.remove();
- o->data = QVariant();
+ if (o->d()->isScarce())
+ o->d()->node.remove();
+ o->d()->data = QVariant();
}
return Encode::undefined();
}
@@ -175,26 +165,26 @@ QV4::ReturnedValue VariantPrototype::method_destroy(CallContext *ctx)
QV4::ReturnedValue VariantPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->callData->thisObject.as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, ctx->d()->callData->thisObject.as<QV4::VariantObject>());
if (!o)
return Encode::undefined();
- QString result = o->data.toString();
- if (result.isEmpty() && !o->data.canConvert(QVariant::String))
- result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(o->data.typeName()));
- return Encode(ctx->engine->newString(result));
+ QString result = o->d()->data.toString();
+ if (result.isEmpty() && !o->d()->data.canConvert(QVariant::String))
+ result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(o->d()->data.typeName()));
+ return Encode(ctx->d()->engine->newString(result));
}
QV4::ReturnedValue VariantPrototype::method_valueOf(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->callData->thisObject.as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, ctx->d()->callData->thisObject.as<QV4::VariantObject>());
if (o) {
- QVariant v = o->data;
+ QVariant v = o->d()->data;
switch (v.type()) {
case QVariant::Invalid:
return Encode::undefined();
case QVariant::String:
- return Encode(ctx->engine->newString(v.toString()));
+ return Encode(ctx->d()->engine->newString(v.toString()));
case QVariant::Int:
return Encode(v.toInt());
case QVariant::Double:
@@ -206,7 +196,7 @@ QV4::ReturnedValue VariantPrototype::method_valueOf(CallContext *ctx)
break;
}
}
- return ctx->callData->thisObject.asReturnedValue();
+ return ctx->d()->callData->thisObject.asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 656608d49b..18e93f6ca7 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -64,31 +64,33 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct VariantObject : Object, public ExecutionEngine::ScarceResourceData
+struct VariantObject : Object
{
- V4_OBJECT
-public:
- VariantObject(InternalClass *ic);
- VariantObject(ExecutionEngine *engine, const QVariant &value);
+ struct Data : Object::Data, public ExecutionEngine::ScarceResourceData
+ {
+ Data(InternalClass *ic);
+ Data(ExecutionEngine *engine, const QVariant &value);
+ ~Data() {
+ if (isScarce())
+ node.remove();
+ }
+ bool isScarce() const;
+ int vmePropertyReferenceCount;
+ };
+ V4_OBJECT(Object)
static QVariant toVariant(const ValueRef v);
void addVmePropertyReference();
void removeVmePropertyReference();
- bool isScarce() const;
- int m_vmePropertyReferenceCount;
static void destroy(Managed *that);
static bool isEqualTo(Managed *m, Managed *other);
};
-DEFINE_REF(VariantObject, Object);
-
struct VariantPrototype : VariantObject
{
public:
- VariantPrototype(InternalClass *ic);
-
void init();
static ReturnedValue method_preserve(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 8e52ed5a96..7f058bf8b7 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -185,14 +185,14 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
const uchar *exceptionHandler = 0;
- context->lineNumber = -1;
- QV4::ExecutionEngine *engine = context->engine;
+ context->d()->lineNumber = -1;
+ QV4::ExecutionEngine *engine = context->d()->engine;
#ifdef DO_TRACE_INSTR
qDebug("Starting VME with context=%p and code=%p", context, code);
#endif // DO_TRACE_INSTR
- QV4::StringValue * const runtimeStrings = context->compilationUnit->runtimeStrings;
+ QV4::StringValue * const runtimeStrings = context->d()->compilationUnit->runtimeStrings;
// setup lookup scopes
int scopeDepth = 0;
@@ -200,28 +200,28 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
QV4::ExecutionContext *scope = context;
while (scope) {
++scopeDepth;
- scope = scope->outer;
+ scope = scope->d()->outer;
}
}
QV4::Value **scopes = static_cast<QV4::Value **>(alloca(sizeof(QV4::Value *)*(2 + 2*scopeDepth)));
{
- scopes[0] = const_cast<QV4::Value *>(context->compilationUnit->data->constants());
+ scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->data->constants());
// stack gets setup in push instruction
scopes[1] = 0;
QV4::ExecutionContext *scope = context;
int i = 0;
while (scope) {
- if (scope->type >= QV4::ExecutionContext::Type_SimpleCallContext) {
+ if (scope->d()->type >= QV4::ExecutionContext::Type_SimpleCallContext) {
QV4::CallContext *cc = static_cast<QV4::CallContext *>(scope);
- scopes[2*i + 2] = cc->callData->args;
- scopes[2*i + 3] = cc->locals;
+ scopes[2*i + 2] = cc->d()->callData->args;
+ scopes[2*i + 3] = cc->d()->locals;
} else {
scopes[2*i + 2] = 0;
scopes[2*i + 3] = 0;
}
++i;
- scope = scope->outer;
+ scope = scope->d()->outer;
}
}
@@ -253,7 +253,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_BEGIN_INSTR(LoadRegExp)
// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- VALUE(instr.result) = context->compilationUnit->runtimeRegularExpressions[instr.regExpId];
+ VALUE(instr.result) = context->d()->compilationUnit->runtimeRegularExpressions[instr.regExpId];
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
@@ -267,7 +267,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_BEGIN_INSTR(GetGlobalLookup)
TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
- QV4::Lookup *l = context->lookups + instr.index;
+ QV4::Lookup *l = context->d()->lookups + instr.index;
STOREVALUE(instr.result, l->globalGetter(l, context));
MOTH_END_INSTR(GetGlobalLookup)
@@ -282,7 +282,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementLookup)
- QV4::Lookup *l = context->lookups + instr.lookup;
+ QV4::Lookup *l = context->d()->lookups + instr.lookup;
STOREVALUE(instr.result, l->indexedGetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(LoadElementLookup)
@@ -292,7 +292,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(StoreElementLookup)
- QV4::Lookup *l = context->lookups + instr.lookup;
+ QV4::Lookup *l = context->d()->lookups + instr.lookup;
l->indexedSetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElementLookup)
@@ -302,7 +302,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(GetLookup)
- QV4::Lookup *l = context->lookups + instr.index;
+ QV4::Lookup *l = context->d()->lookups + instr.index;
STOREVALUE(instr.result, l->getter(l, VALUEPTR(instr.base)));
MOTH_END_INSTR(GetLookup)
@@ -312,7 +312,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
- QV4::Lookup *l = context->lookups + instr.index;
+ QV4::Lookup *l = context->d()->lookups + instr.index;
l->setter(l, VALUEPTR(instr.base), VALUEPTR(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(SetLookup)
@@ -333,7 +333,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_BEGIN_INSTR(Push)
TRACE(inline, "stack size: %u", instr.value);
stackSize = instr.value;
- stack = context->engine->stackPush(stackSize);
+ stack = context->engine()->stackPush(stackSize);
#ifndef QT_NO_DEBUG
memset(stack, 0, stackSize * sizeof(QV4::Value));
#endif
@@ -342,7 +342,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_BEGIN_INSTR(CallValue)
#if 0 //def DO_TRACE_INSTR
- if (Debugging::Debugger *debugger = context->engine->debugger) {
+ if (Debugging::Debugger *debugger = context->engine()->debugger) {
if (QV4::FunctionObject *o = (VALUE(instr.dest)).asFunctionObject()) {
if (Debugging::FunctionDebugInfo *info = debugger->debugInfo(o)) {
QString n = debugger->name(o);
@@ -655,24 +655,24 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(Ret)
- context->engine->stackPop(stackSize);
+ context->engine()->stackPop(stackSize);
// TRACE(Ret, "returning value %s", result.toString(context)->toQString().toUtf8().constData());
return VALUE(instr.result).asReturnedValue();
MOTH_END_INSTR(Ret)
MOTH_BEGIN_INSTR(Debug)
- context->lineNumber = instr.lineNumber;
- QV4::Debugging::Debugger *debugger = context->engine->debugger;
+ context->d()->lineNumber = instr.lineNumber;
+ QV4::Debugging::Debugger *debugger = context->engine()->debugger;
if (debugger && debugger->pauseAtNextOpportunity())
debugger->maybeBreakAtInstruction();
MOTH_END_INSTR(Debug)
MOTH_BEGIN_INSTR(Line)
- context->lineNumber = instr.lineNumber;
+ context->d()->lineNumber = instr.lineNumber;
MOTH_END_INSTR(Debug)
MOTH_BEGIN_INSTR(LoadThis)
- VALUE(instr.result) = context->callData->thisObject;
+ VALUE(instr.result) = context->d()->callData->thisObject;
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(LoadQmlIdArray)
@@ -706,9 +706,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
Q_ASSERT(false);
catchException:
- Q_ASSERT(context->engine->hasException);
+ Q_ASSERT(context->engine()->hasException);
if (!exceptionHandler) {
- context->engine->stackPop(stackSize);
+ context->engine()->stackPop(stackSize);
return QV4::Encode::undefined();
}
code = exceptionHandler;
@@ -732,7 +732,7 @@ void **VME::instructionJumpTable()
QV4::ReturnedValue VME::exec(QV4::ExecutionContext *ctxt, const uchar *code)
{
VME vme;
- QV4::Debugging::Debugger *debugger = ctxt->engine->debugger;
+ QV4::Debugging::Debugger *debugger = ctxt->engine()->debugger;
if (debugger)
debugger->enteringFunction();
QV4::ReturnedValue retVal = vme.run(ctxt, code);