aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2014-11-01 21:44:57 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-11-07 02:00:05 +0100
commitb340caa0d3ebf7f76c0445b2cdd4032d8e3bf8d5 (patch)
treee475eae0dc4a6c68ca3ee41132b573fc76d2dc10 /src/qml/jsruntime
parente22fc141c3fc5362f9b906c43a1b7c0dbc1f85a3 (diff)
Get rid of Members and directly store MemberData::Data pointers
And do the same change for ArrayData. Change-Id: Ia1ae56bd0ff586c9b987e15af7a53f395a37054a Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp17
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp57
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h11
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp6
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp56
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp27
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h21
-rw-r--r--src/qml/jsruntime/qv4object.cpp21
-rw-r--r--src/qml/jsruntime/qv4object_p.h24
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4value.cpp2
14 files changed, 135 insertions, 118 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index e8cb788b74..c020e99cbb 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -65,10 +65,10 @@ ArgumentsObject::Data::Data(CallContext *context)
} else {
args->setHasAccessorProperty();
Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee));
- args->memberData()[CalleePropertyIndex] = context->d()->function->asReturnedValue();
+ args->memberData()->data()[CalleePropertyIndex] = context->d()->function->asReturnedValue();
}
Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(context->d()->engine->id_length));
- args->memberData()[LengthPropertyIndex] = Primitive::fromInt32(context->d()->realArgumentCount);
+ args->memberData()->data()[LengthPropertyIndex] = Primitive::fromInt32(context->d()->realArgumentCount);
}
void ArgumentsObject::fullyCreate()
@@ -80,9 +80,13 @@ void ArgumentsObject::fullyCreate()
uint argCount = qMin(context()->d()->realArgumentCount, context()->d()->callData->argc);
ArrayData::realloc(this, ArrayData::Sparse, argCount, true);
context()->d()->engine->requireArgumentsAccessors(numAccessors);
- mappedArguments().ensureIndex(engine(), numAccessors);
+
+ Scope scope(engine());
+ Scoped<MemberData> md(scope, d()->mappedArguments);
+ if (md)
+ d()->mappedArguments = md->reallocate(engine(), d()->mappedArguments, numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
- mappedArguments()[i] = context()->d()->callData->args[i];
+ mappedArguments()->data[i] = context()->d()->callData->args[i];
arraySet(i, context()->d()->engine->argumentsAccessors[i], Attr_Accessor);
}
arrayPut(numAccessors, context()->d()->callData->args + numAccessors, argCount - numAccessors);
@@ -111,7 +115,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
map.copy(*pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
pd = arrayData()->getProperty(index);
- pd->value = mappedArguments()[index];
+ pd->value = mappedArguments()->data[index];
}
bool strict = ctx->d()->strictMode;
@@ -227,7 +231,8 @@ void ArgumentsObject::markObjects(HeapObject *that, ExecutionEngine *e)
ArgumentsObject::Data *o = static_cast<ArgumentsObject::Data *>(that);
if (o->context)
o->context->mark(e);
- o->mappedArguments.mark(e);
+ if (o->mappedArguments)
+ 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 73c6bb26f3..d961d0881f 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -82,14 +82,14 @@ struct ArgumentsObject: Object {
Data(CallContext *context);
CallContext *context;
bool fullyCreated;
- Members mappedArguments;
+ MemberData::Data *mappedArguments;
};
V4_OBJECT(Object)
Q_MANAGED_TYPE(ArgumentsObject)
CallContext *context() const { return d()->context; }
bool fullyCreated() const { return d()->fullyCreated; }
- Members &mappedArguments() { return d()->mappedArguments; }
+ MemberData::Data *mappedArguments() { return d()->mappedArguments; }
static bool isNonStrictArgumentsObject(Managed *m) {
return m->internalClass()->vtable->type == Type_ArgumentsObject &&
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 1da54b1129..ff9d2cc181 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -77,7 +77,6 @@ struct SyntaxErrorObject;
struct ArgumentsObject;
struct ExecutionContext;
struct ExecutionEngine;
-struct Members;
class MemoryManager;
class ExecutableAllocator;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index deb9e62591..7c93cab0ca 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -96,8 +96,10 @@ FunctionObject::Data::Data(InternalClass *ic)
: Object::Data(ic)
, scope(ic->engine->rootContext)
{
- memberData.ensureIndex(ic->engine, Index_Prototype);
- memberData[Index_Prototype] = Encode::undefined();
+ Scope scope(ic->engine);
+ ScopedObject o(scope, this);
+ o->ensureMemberIndex(ic->engine, Index_Prototype);
+ memberData->data[Index_Prototype] = Encode::undefined();
}
@@ -115,13 +117,14 @@ void FunctionObject::init(String *n, bool createProto)
d()->needsActivation = true;
d()->strictMode = false;
- memberData().ensureIndex(s.engine, Index_Prototype);
+ ensureMemberIndex(s.engine, Index_Prototype);
if (createProto) {
Scoped<Object> proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass));
- proto->memberData()[Index_ProtoConstructor] = this->asReturnedValue();
- memberData()[Index_Prototype] = proto.asReturnedValue();
+ proto->ensureMemberIndex(s.engine, Index_ProtoConstructor);
+ proto->memberData()->data()[Index_ProtoConstructor] = this->asReturnedValue();
+ memberData()->data()[Index_Prototype] = proto.asReturnedValue();
} else {
- memberData()[Index_Prototype] = Encode::undefined();
+ memberData()->data()[Index_Prototype] = Encode::undefined();
}
ScopedValue v(s, n);
@@ -333,14 +336,12 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
return ctx->engine()->throwTypeError();
ScopedValue boundThis(scope, ctx->argument(0));
- Members boundArgs;
- boundArgs.reset();
+ Scoped<MemberData> boundArgs(scope);
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));
+ boundArgs = MemberData::reallocate(scope.engine, 0, ctx->d()->callData->argc - 1);
+ boundArgs->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 BoundFunction::create(ctx->d()->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
}
@@ -584,10 +585,10 @@ DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
DEFINE_OBJECT_VTABLE(BoundFunction);
-BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs)
+BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, MemberData *boundArgs)
: FunctionObject::Data(scope, QStringLiteral("__bound function__"))
, target(target)
- , boundArgs(boundArgs)
+ , boundArgs(boundArgs ? boundArgs->d() : 0)
{
this->boundThis = boundThis;
setVTable(staticVTable());
@@ -598,7 +599,8 @@ BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const
ScopedValue l(s, target->get(s.engine->id_length));
int len = l->toUInt32();
- len -= boundArgs.size();
+ if (boundArgs)
+ len -= boundArgs->size();
if (len < 0)
len = 0;
f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(len));
@@ -617,10 +619,15 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
if (scope.hasException())
return Encode::undefined();
- ScopedCallData callData(scope, f->boundArgs().size() + dd->argc);
+ Scoped<MemberData> boundArgs(scope, f->boundArgs());
+ ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + 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));
+ Value *argp = callData->args;
+ if (boundArgs) {
+ memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
+ argp += boundArgs->size();
+ }
+ memcpy(argp, dd->args, dd->argc*sizeof(Value));
return f->target()->call(callData);
}
@@ -631,9 +638,14 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
if (scope.hasException())
return Encode::undefined();
- 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));
+ Scoped<MemberData> boundArgs(scope, f->boundArgs());
+ ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
+ Value *argp = callData->args;
+ if (boundArgs) {
+ memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
+ argp += boundArgs->size();
+ }
+ memcpy(argp, dd->args, dd->argc*sizeof(Value));
return f->target()->construct(callData);
}
@@ -642,6 +654,7 @@ void BoundFunction::markObjects(HeapObject *that, ExecutionEngine *e)
BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that);
o->target->mark(e);
o->boundThis.mark(e);
- o->boundArgs.mark(e);
+ if (o->boundArgs)
+ 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 1ff8124e6a..07a8c45aed 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -96,7 +96,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
static Returned<FunctionObject> *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
- ReturnedValue protoProperty() { return memberData()[Index_Prototype].asReturnedValue(); }
+ ReturnedValue protoProperty() { return memberData()->data()[Index_Prototype].asReturnedValue(); }
bool needsActivation() const { return d()->needsActivation; }
bool strictMode() const { return d()->strictMode; }
@@ -202,21 +202,22 @@ struct ScriptFunction: SimpleScriptFunction {
struct BoundFunction: FunctionObject {
struct Data : FunctionObject::Data {
- Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs);
+ Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, MemberData *boundArgs);
FunctionObject *target;
Value boundThis;
- Members boundArgs;
+ MemberData::Data *boundArgs;
};
V4_OBJECT(FunctionObject)
- static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs)
+ static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, QV4::MemberData *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; }
+ // ### GC
+ MemberData::Data *boundArgs() const { return d()->boundArgs; }
static ReturnedValue construct(Managed *, CallData *d);
static ReturnedValue call(Managed *that, CallData *dd);
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index a59c3892a1..0f8eb2bfff 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -153,10 +153,10 @@ void InternalClass::changeMember(Object *object, String *string, PropertyAttribu
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));
+ 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));
+ memmove(object->memberData()->data() + idx + 1, object->memberData()->data() + idx + 2, (object->internalClass()->size - idx - 2)*sizeof(Value));
}
object->setInternalClass(newClass);
}
@@ -351,7 +351,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
}
// remove the entry in memberdata
- memmove(object->memberData().data() + propIdx, object->memberData().data() + propIdx + 1, (object->internalClass()->size - propIdx)*sizeof(Value));
+ memmove(object->memberData()->data() + propIdx, object->memberData()->data() + propIdx + 1, (object->internalClass()->size - propIdx)*sizeof(Value));
oldClass->transitions.insert(t, object->internalClass());
}
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index f7ebb62b8d..9d4649b287 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -49,7 +49,7 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
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);
+ return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -61,7 +61,7 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
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);
+ return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -80,7 +80,7 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
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);
+ return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -92,7 +92,7 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
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);
+ return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@@ -334,7 +334,7 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass())
- return o->memberData()[l->index].asReturnedValue();
+ return o->memberData()->data()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@@ -347,7 +347,7 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object)
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()[l->index].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@@ -363,7 +363,7 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object)
if (l->classList[1] == o->internalClass()) {
o = o->prototype();
if (l->classList[2] == o->internalClass())
- return o->memberData()[l->index].asReturnedValue();
+ return o->memberData()->data()[l->index].asReturnedValue();
}
}
}
@@ -378,9 +378,9 @@ ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object)
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass())
- return o->memberData()[l->index].asReturnedValue();
+ return o->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass())
- return o->memberData()[l->index2].asReturnedValue();
+ return o->memberData()->data()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@@ -393,10 +393,10 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object)
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass())
- return o->memberData()[l->index].asReturnedValue();
+ return o->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
l->classList[3] == o->prototype()->internalClass())
- return o->prototype()->memberData()[l->index2].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@@ -410,10 +410,10 @@ ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object)
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()[l->index].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
l->classList[3] == o->prototype()->internalClass())
- return o->prototype()->memberData()[l->index2].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
return getterFallback(l, object);
}
l->getter = getterFallback;
@@ -496,7 +496,7 @@ 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();
+ return o->memberData()->data()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -508,7 +508,7 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object)
Object *o = l->proto;
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()[l->index].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -565,7 +565,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()->data()[ArrayObject::LengthPropertyIndex].asReturnedValue();
l->getter = getterGeneric;
return getterGeneric(l, object);
@@ -605,7 +605,7 @@ ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->d()->engine->globalObject;
if (l->classList[0] == o->internalClass())
- return o->memberData()[l->index].asReturnedValue();
+ return o->memberData()->data()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@@ -616,7 +616,7 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
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();
+ return o->prototype()->memberData()->data()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@@ -630,7 +630,7 @@ ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx)
if (l->classList[1] == o->internalClass()) {
o = o->prototype();
if (l->classList[2] == o->internalClass()) {
- return o->prototype()->memberData()[l->index].asReturnedValue();
+ return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
}
}
@@ -744,7 +744,7 @@ 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;
+ o->memberData()->data()[l->index] = *value;
return;
}
@@ -756,9 +756,9 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu
Object *o = static_cast<Object *>(object->asManaged());
if (o && o->internalClass() == l->classList[0]) {
if (!o->prototype()) {
- if (l->index >= o->memberData().size())
+ if (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
- o->memberData()[l->index] = *value;
+ o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@@ -774,9 +774,9 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu
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 (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
- o->memberData()[l->index] = *value;
+ o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@@ -794,9 +794,9 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu
if (p && p->internalClass() == l->classList[1]) {
p = p->prototype();
if (p && p->internalClass() == l->classList[2]) {
- if (l->index >= o->memberData().size())
+ if (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
- o->memberData()[l->index] = *value;
+ o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@@ -812,11 +812,11 @@ 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;
+ o->memberData()->data()[l->index] = *value;
return;
}
if (o->internalClass() == l->classList[1]) {
- o->memberData()[l->index2] = *value;
+ o->memberData()->data()[l->index2] = *value;
return;
}
}
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index de226305f1..bf07a74b96 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -45,18 +45,19 @@ void MemberData::markObjects(HeapObject *that, ExecutionEngine *e)
m->data[i].mark(e);
}
-void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
+MemberData::Data *MemberData::reallocate(ExecutionEngine *e, Data *old, uint idx)
{
- uint s = size();
- if (idx >= s) {
- int newAlloc = qMax((uint)4, 2*idx);
- uint alloc = sizeof(MemberData::Data) + (newAlloc)*sizeof(Value);
- MemberData *newMemberData = static_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
- if (d())
- memcpy(newMemberData, d(), sizeof(MemberData::Data) + s*sizeof(Value));
- else
- new (newMemberData) MemberData(e->memberDataClass);
- newMemberData->d()->size = newAlloc;
- m = &newMemberData->data;
- }
+ uint s = old ? old->size : 0;
+ if (idx < s)
+ return old;
+
+ int newAlloc = qMax((uint)4, 2*idx);
+ uint alloc = sizeof(Data) + (newAlloc)*sizeof(Value);
+ MemberData *newMemberData = static_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
+ if (old)
+ memcpy(newMemberData, old, sizeof(MemberData::Data) + s*sizeof(Value));
+ else
+ new (newMemberData) MemberData(e->memberDataClass);
+ newMemberData->d()->size = newAlloc;
+ return newMemberData->d();
}
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index cc7b10ff81..0177601b9f 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -53,24 +53,13 @@ struct MemberData : Managed
MemberData(QV4::InternalClass *ic) : Managed(ic) {}
Value &operator[] (uint idx) { return d()->data[idx]; }
+ const Value *data() const { return d()->data; }
+ Value *data() { return d()->data; }
+ inline uint size() const { return d()->size; }
- static void markObjects(HeapObject *that, ExecutionEngine *e);
-};
+ static MemberData::Data *reallocate(QV4::ExecutionEngine *e, MemberData::Data *old, uint idx);
-struct Members : Value
-{
- void reset() { m = 0; }
- void ensureIndex(QV4::ExecutionEngine *e, uint idx);
- 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())->d()->data; }
-
- void mark(ExecutionEngine *e) const {
- MemberData *m = d();
- if (m)
- m->mark(e);
- }
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 576537dcef..f8b0c9f0a0 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -55,7 +55,7 @@ Object::Data::Data(InternalClass *internalClass)
if (internalClass->size) {
Scope scope(internalClass->engine);
ScopedObject o(scope, this);
- o->memberData().ensureIndex(internalClass->engine, internalClass->size);
+ o->ensureMemberIndex(internalClass->engine, internalClass->size);
}
}
@@ -182,14 +182,15 @@ void Object::markObjects(HeapObject *that, ExecutionEngine *e)
{
Object::Data *o = static_cast<Object::Data *>(that);
- o->memberData.mark(e);
+ if (o->memberData)
+ o->memberData->mark(e);
if (o->arrayData)
o->arrayData->mark(e);
}
void Object::ensureMemberIndex(uint idx)
{
- memberData().ensureIndex(engine(), idx);
+ d()->memberData = MemberData::reallocate(engine(), d()->memberData, idx);
}
void Object::insertMember(String *s, const Property &p, PropertyAttributes attributes)
@@ -206,7 +207,7 @@ void Object::insertMember(String *s, const Property &p, PropertyAttributes attri
pp->value = p.value;
pp->set = p.set;
} else {
- memberData()[idx] = p.value;
+ d()->memberData->data[idx] = p.value;
}
}
@@ -262,7 +263,7 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
if (idx < UINT_MAX) {
if (attrs)
*attrs = o->internalClass()->propertyData[idx];
- return o->propertyAt(idx);
+ return const_cast<Property *>(o->propertyAt(idx));
}
o = o->prototype();
@@ -465,7 +466,7 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
l->classList[0] = o->internalClass();
l->index = idx;
l->setter = Lookup::setter0;
- o->memberData()[idx] = *value;
+ o->memberData()->data()[idx] = *value;
return;
}
@@ -1153,7 +1154,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()->data()[ArrayObject::LengthPropertyIndex].asReturnedValue();
}
return Object::getLookup(m, l);
}
@@ -1161,9 +1162,9 @@ 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()->data()[ArrayObject::LengthPropertyIndex].isInteger())
+ return a->memberData()->data()[ArrayObject::LengthPropertyIndex].integerValue();
+ return Primitive::toUInt32(a->memberData()->data()[ArrayObject::LengthPropertyIndex].doubleValue());
}
QStringList ArrayObject::toQStringList() const
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index f11220f55c..7347232857 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -49,8 +49,8 @@ struct Q_QML_EXPORT Object: Managed {
}
Data(InternalClass *internal = 0);
- Members memberData;
- ArrayData *arrayData;
+ MemberData::Data *memberData;
+ ArrayData::Data *arrayData;
};
V4_OBJECT(Object)
Q_MANAGED_TYPE(Object)
@@ -59,12 +59,14 @@ struct Q_QML_EXPORT Object: Managed {
IsObject = true
};
- Members &memberData() { return d()->memberData; }
- const Members &memberData() const { return d()->memberData; }
- ArrayData *arrayData() const { return d()->arrayData; }
- void setArrayData(ArrayData *a) { d()->arrayData = a; }
+ // ### GC
+ MemberData *memberData() { return reinterpret_cast<MemberData *>(d()->memberData); }
+ const MemberData *memberData() const { return reinterpret_cast<const MemberData *>(d()->memberData); }
+ ArrayData *arrayData() const { return reinterpret_cast<ArrayData *>(d()->arrayData); }
+ void setArrayData(ArrayData *a) { d()->arrayData = a->d(); }
- Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData().data() + index); }
+ const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData()->data() + index); }
+ Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData()->data() + index); }
const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
Object *prototype() const { return internalClass()->prototype; }
@@ -115,6 +117,10 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyProperty(const QString &name, ValueRef value);
void defineReadonlyProperty(String *name, ValueRef value);
+ void ensureMemberIndex(QV4::ExecutionEngine *e, uint idx) {
+ d()->memberData = MemberData::reallocate(e, d()->memberData, idx);
+ }
+
void insertMember(String *s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
Property p(*v);
insertMember(s, p, attributes);
@@ -300,7 +306,7 @@ struct ArrayObject: Object {
Data(ExecutionEngine *engine, const QStringList &list);
Data(InternalClass *ic) : Object::Data(ic) { init(); }
void init()
- { memberData[LengthPropertyIndex] = Primitive::fromInt32(0); }
+ { memberData->data[LengthPropertyIndex] = Primitive::fromInt32(0); }
};
V4_OBJECT(Object)
@@ -321,7 +327,7 @@ struct ArrayObject: Object {
inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject())
- memberData()[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
+ memberData()->data()[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
}
inline void Object::push_back(const ValueRef v)
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 23b46c8492..2fd91a0675 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -390,8 +390,8 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
- array->memberData()[Index_ArrayIndex] = Primitive::fromInt32(result);
- array->memberData()[Index_ArrayInput] = arg.asReturnedValue();
+ array->memberData()->data()[Index_ArrayIndex] = Primitive::fromInt32(result);
+ array->memberData()->data()[Index_ArrayInput] = arg.asReturnedValue();
RegExpCtor::Data *dd = regExpCtor->d();
dd->lastMatch = array;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index b817bc594b..fe9d07e772 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1172,7 +1172,7 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
}
for (uint i = 0; i < klass->size; ++i)
- o->memberData()[i] = *args++;
+ o->memberData()->data()[i] = *args++;
if (arrayValueCount > 0) {
ScopedValue entry(scope);
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index a80cc40add..e4f84b22fb 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -91,6 +91,8 @@ double Value::toNumberImpl() const
ExecutionContext *ctx = objectValue()->internalClass()->engine->currentContext();
Scope scope(ctx);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(ValueRef::fromRawValue(this), NUMBER_HINT));
+ if (scope.engine->hasException)
+ return 0;
return prim->toNumber();
}
#endif