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>
This commit is contained in:
parent
e22fc141c3
commit
b340caa0d3
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -77,7 +77,6 @@ struct SyntaxErrorObject;
|
|||
struct ArgumentsObject;
|
||||
struct ExecutionContext;
|
||||
struct ExecutionEngine;
|
||||
struct Members;
|
||||
class MemoryManager;
|
||||
class ExecutableAllocator;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -53,26 +53,15 @@ 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 MemberData::Data *reallocate(QV4::ExecutionEngine *e, MemberData::Data *old, uint idx);
|
||||
|
||||
static void markObjects(HeapObject *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())->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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue