From 380a486ae72457a0684d5d85c8bab79579509dcc Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 9 Apr 2013 13:37:31 +0200 Subject: [PATCH] Use PropertyAttributes in PropertyDescriptor This further encapsulates the property attribute handling, and will allow to separate the attributes from the proprety data. Change-Id: I140a6c9349cd1e871cd9fdcef51abac7ae78e517 Reviewed-by: Simon Hausmann --- src/v4/qv4argumentsobject.cpp | 17 +++----- src/v4/qv4arrayobject.cpp | 7 +--- src/v4/qv4context.cpp | 13 +++--- src/v4/qv4engine.cpp | 4 +- src/v4/qv4functionobject.cpp | 11 ++--- src/v4/qv4global.h | 32 +++++++++++++-- src/v4/qv4internalclass.cpp | 2 +- src/v4/qv4jsonobject.cpp | 7 +--- src/v4/qv4object.cpp | 81 +++++++++++++++--------------------- src/v4/qv4object.h | 18 ++++---- src/v4/qv4objectiterator.cpp | 2 +- src/v4/qv4objectproto.cpp | 50 ++++++++++------------- src/v4/qv4propertydescriptor.h | 93 +++++++++++++++--------------------------- src/v4/qv4regexpobject.cpp | 5 +-- src/v4/qv4runtime.cpp | 30 ++++---------- src/v4/qv4sparsearray.cpp | 4 +- src/v4/qv4string.cpp | 4 +- src/v4/qv4stringobject.cpp | 5 +-- src/v4/qv4v8.cpp | 22 ++++------ 19 files changed, 168 insertions(+), 239 deletions(-) diff --git a/src/v4/qv4argumentsobject.cpp b/src/v4/qv4argumentsobject.cpp index ac67c36..e2fb9d6 100644 --- a/src/v4/qv4argumentsobject.cpp +++ b/src/v4/qv4argumentsobject.cpp @@ -64,8 +64,7 @@ ArgumentsObject::ArgumentsObject(CallContext *context, int formalParameterCount, Object::put(context, QString::number(i), context->arguments[i]); FunctionObject *thrower = context->engine->newBuiltinFunction(context, 0, throwTypeError); PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower); - pd.configurable = PropertyDescriptor::Disabled; - pd.enumerable = PropertyDescriptor::Disabled; + pd.attrs = Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable; __defineOwnProperty__(context, QStringLiteral("callee"), &pd); __defineOwnProperty__(context, QStringLiteral("caller"), &pd); } else { @@ -76,10 +75,7 @@ ArgumentsObject::ArgumentsObject(CallContext *context, int formalParameterCount, __defineOwnProperty__(context, i, &context->engine->argumentsAccessors.at(i)); } PropertyDescriptor pd; - pd.type = PropertyDescriptor::Data; - pd.writable = PropertyDescriptor::Enabled; - pd.configurable = PropertyDescriptor::Enabled; - pd.enumerable = PropertyDescriptor::Enabled; + pd.attrs = Attr_Data; for (uint i = numAccessors; i < qMin((uint)actualParameterCount, context->argumentCount); ++i) { pd.value = context->argument(i); __defineOwnProperty__(context, i, &pd); @@ -104,10 +100,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const if (isMapped) { map = *pd; - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Enabled; + pd->attrs = Attr_Data; pd->value = mappedArguments.at(index); } @@ -119,11 +112,11 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const isNonStrictArgumentsObject = true; if (isMapped && desc->isData()) { - if (desc->type != PropertyDescriptor::Generic) { + if (desc->attrs.type() != PropertyAttributes::Generic) { Value arg = desc->value; map.set->call(ctx, Value::fromObject(this), &arg, 1); } - if (desc->writable != PropertyDescriptor::Disabled) + if (desc->attrs.writable()) *pd = map; } diff --git a/src/v4/qv4arrayobject.cpp b/src/v4/qv4arrayobject.cpp index 9b5f2d4..1ca9cf9 100644 --- a/src/v4/qv4arrayobject.cpp +++ b/src/v4/qv4arrayobject.cpp @@ -337,7 +337,7 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx) if (n) front = instance->arrayDecriptor(n->value); } - if (front && front->type == PropertyDescriptor::Generic) + if (front && front->attrs.type() == PropertyAttributes::Generic) front = 0; Value result = instance->getValueChecked(ctx, front); @@ -447,10 +447,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx) newArray->arrayReserve(deleteCount); PropertyDescriptor *pd = newArray->arrayData; for (uint i = 0; i < deleteCount; ++i) { - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; + pd->attrs = Attr_Data; pd->value = instance->getIndexed(ctx, start + i); ++pd; } diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index baddb81..9703809 100644 --- a/src/v4/qv4context.cpp +++ b/src/v4/qv4context.cpp @@ -100,10 +100,10 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) return; PropertyDescriptor desc; desc.value = Value::undefinedValue(); - desc.type = PropertyDescriptor::Data; - desc.configurable = deletable ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled; - desc.writable = PropertyDescriptor::Enabled; - desc.enumerable = PropertyDescriptor::Enabled; + desc.attrs.setType(PropertyAttributes::Data); + desc.attrs.setConfigurable(deletable); + desc.attrs.setWritable(true); + desc.attrs.setEnumerable(true); activation->__defineOwnProperty__(this, name, &desc); } @@ -207,10 +207,7 @@ void CallContext::initCallContext(ExecutionEngine *engine) activation = engine->newObject(); PropertyDescriptor desc; desc.value = Value::fromObject(args); - desc.type = PropertyDescriptor::Data; - desc.configurable = PropertyDescriptor::Disabled; - desc.writable = PropertyDescriptor::Enabled; - desc.enumerable = PropertyDescriptor::Enabled; + desc.attrs = PropertyAttributes(Attr_NotConfigurable); activation->__defineOwnProperty__(this, engine->id_arguments, &desc); } } diff --git a/src/v4/qv4engine.cpp b/src/v4/qv4engine.cpp index 24770d2..54ddf43 100644 --- a/src/v4/qv4engine.cpp +++ b/src/v4/qv4engine.cpp @@ -483,8 +483,8 @@ void ExecutionEngine::requireArgumentsAccessors(int n) FunctionObject *set = new (memoryManager) ArgumentsSetterFunction(rootContext, i); set->prototype = functionPrototype; PropertyDescriptor pd = PropertyDescriptor::fromAccessor(get, set); - pd.configurable = PropertyDescriptor::Enabled; - pd.enumerable = PropertyDescriptor::Enabled; + pd.attrs.setConfigurable(true); + pd.attrs.setEnumerable(true); argumentsAccessors[i] = pd; } } diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index 4deb318..8393ec9 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -342,17 +342,13 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function) Object *proto = scope->engine->newObject(); proto->defineDefaultProperty(scope->engine->id_constructor, Value::fromObject(this)); PropertyDescriptor *pd = insertMember(scope->engine->id_prototype, Attr_NotEnumerable|Attr_NotConfigurable); - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Disabled; - pd->configurable = PropertyDescriptor::Disabled; + pd->attrs = Attr_Data|Attr_NotEnumerable|Attr_NotConfigurable; pd->value = Value::fromObject(proto); if (scope->strictMode) { FunctionObject *thrower = scope->engine->newBuiltinFunction(scope, 0, throwTypeError); PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower); - pd.configurable = PropertyDescriptor::Disabled; - pd.enumerable = PropertyDescriptor::Disabled; + pd.attrs = Attr_Accessor|Attr_NotEnumerable|Attr_NotConfigurable; __defineOwnProperty__(scope, QStringLiteral("caller"), &pd); __defineOwnProperty__(scope, QStringLiteral("arguments"), &pd); } @@ -480,8 +476,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va FunctionObject *thrower = scope->engine->newBuiltinFunction(scope, 0, throwTypeError); PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower); - pd.configurable = PropertyDescriptor::Disabled; - pd.enumerable = PropertyDescriptor::Disabled; + pd.attrs = Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable; *insertMember(scope->engine->id_arguments, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd; *insertMember(scope->engine->id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd; } diff --git a/src/v4/qv4global.h b/src/v4/qv4global.h index 11a74bb..3ffa29b 100644 --- a/src/v4/qv4global.h +++ b/src/v4/qv4global.h @@ -61,7 +61,7 @@ namespace VM { enum PropertyFlag { - Attr_Default = 0, + Attr_Data = 0, Attr_Accessor = 0x1, Attr_NotWritable = 0x2, Attr_NotEnumerable = 0x4, @@ -103,13 +103,13 @@ struct PropertyAttributes PropertyAttributes(PropertyFlag f) : m_all(0) { setType(f & Attr_Accessor ? Accessor : Data); setWritable(!(f & Attr_NotWritable)); - setEnumberable(!(f & Attr_NotEnumerable)); + setEnumerable(!(f & Attr_NotEnumerable)); setConfigurable(!(f & Attr_NotConfigurable)); } PropertyAttributes(PropertyFlags f) : m_all(0) { setType(f & Attr_Accessor ? Accessor : Data); setWritable(!(f & Attr_NotWritable)); - setEnumberable(!(f & Attr_NotEnumerable)); + setEnumerable(!(f & Attr_NotEnumerable)); setConfigurable(!(f & Attr_NotConfigurable)); } PropertyAttributes(const PropertyAttributes &other) : m_all(other.m_all) {} @@ -118,13 +118,37 @@ struct PropertyAttributes void setType(Type t) { m_type = t; type_set = true; } Type type() const { return type_set ? (Type)m_type : Generic; } + bool isData() const { return type() == PropertyAttributes::Data || writable_set; } + bool isAccessor() const { return type() == PropertyAttributes::Accessor; } + bool isGeneric() const { return type() == PropertyAttributes::Generic && !writable_set; } + + bool hasType() const { return type_set; } + bool hasWritable() const { return writable_set; } + bool hasConfigurable() const { return configurable_set; } + bool hasEnumerable() const { return enumerable_set; } + void setWritable(bool b) { m_writable = b; writable_set = true; } void setConfigurable(bool b) { m_configurable = b; configurable_set = true; } - void setEnumberable(bool b) { m_enumerable = b; enumerable_set = true; } + void setEnumerable(bool b) { m_enumerable = b; enumerable_set = true; } + + void resolveType() { type_set = true; } + void resolveWritable() { writable_set = true; } + void resolveConfigurable() { configurable_set = true; } + void resolveEnumerable() { enumerable_set = true; } bool writable() const { return m_writable; } bool enumerable() const { return m_enumerable; } bool configurable() const { return m_configurable; } + + void clearType() { m_type = Data; type_set = false; } + void clearWritable() { m_writable = false; writable_set = false; } + void clearEnumerable() { m_enumerable = false; enumerable_set = false; } + void clearConfigurable() { m_configurable = false; configurable_set = false; } + + void clear() { m_all = 0; } + bool isEmpty() const { return !m_all; } + + uint flags() const { return m_flags; } }; } diff --git a/src/v4/qv4internalclass.cpp b/src/v4/qv4internalclass.cpp index b040aba..00e891b 100644 --- a/src/v4/qv4internalclass.cpp +++ b/src/v4/qv4internalclass.cpp @@ -61,7 +61,7 @@ InternalClass::InternalClass(const QQmlJS::VM::InternalClass &other) InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, uint *index) { engine->identifierCache->toIdentifier(string); - uint id = string->identifier | ((uint)data.m_flags << 23); + uint id = string->identifier | (data.flags() << 24); assert(propertyTable.constFind(id) == propertyTable.constEnd()); diff --git a/src/v4/qv4jsonobject.cpp b/src/v4/qv4jsonobject.cpp index 64f5a6c..d3a71ac 100644 --- a/src/v4/qv4jsonobject.cpp +++ b/src/v4/qv4jsonobject.cpp @@ -281,11 +281,8 @@ bool Parser::parseMember(Object *o) if (!parseValue(&val)) return false; - PropertyDescriptor *p = o->insertMember(context->engine->newIdentifier(key), Attr_Default); - p->type = PropertyDescriptor::Data; - p->writable = PropertyDescriptor::Enabled; - p->enumerable = PropertyDescriptor::Enabled; - p->configurable = PropertyDescriptor::Enabled; + PropertyDescriptor *p = o->insertMember(context->engine->newIdentifier(key), Attr_Data); + p->attrs = Attr_Data; p->value = val; END; diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp index a48a74a..aa4a596 100644 --- a/src/v4/qv4object.cpp +++ b/src/v4/qv4object.cpp @@ -109,7 +109,7 @@ void Object::put(ExecutionContext *ctx, const QString &name, const Value &value) Value Object::getValue(const Value &thisObject, ExecutionContext *ctx, const PropertyDescriptor *p) { - assert(p->type != PropertyDescriptor::Generic); + assert(p->attrs.type() != PropertyAttributes::Generic); if (p->isData()) return p->value; if (!p->get) @@ -192,11 +192,8 @@ void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, const Value &index, c void Object::defineDefaultProperty(String *name, Value value) { - PropertyDescriptor *pd = insertMember(name, Attr_Default); - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Disabled; - pd->configurable = PropertyDescriptor::Enabled; + PropertyDescriptor *pd = insertMember(name, Attr_Data); + pd->attrs = Attr_Data|Attr_NotEnumerable; pd->value = value; } @@ -222,10 +219,7 @@ void Object::defineReadonlyProperty(ExecutionEngine *engine, const QString &name void Object::defineReadonlyProperty(String *name, Value value) { PropertyDescriptor *pd = insertMember(name, Attr_ReadOnly); - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Disabled; - pd->enumerable = PropertyDescriptor::Disabled; - pd->configurable = PropertyDescriptor::Disabled; + pd->attrs = Attr_ReadOnly; pd->value = value; } @@ -282,7 +276,7 @@ PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, String *na PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, uint index) { PropertyDescriptor *p = arrayAt(index); - if(p && p->type != PropertyDescriptor::Generic) + if (p && p->attrs.type() != PropertyAttributes::Generic) return p; if (isStringObject()) return static_cast(this)->getIndex(ctx, index); @@ -314,7 +308,7 @@ PropertyDescriptor *Object::__getPropertyDescriptor__(const ExecutionContext *ct const Object *o = this; while (o) { PropertyDescriptor *p = o->arrayAt(index); - if(p && p->type != PropertyDescriptor::Generic) + if (p && p->attrs.type() != PropertyAttributes::Generic) return p; if (o->isStringObject()) { p = static_cast(o)->getIndex(ctx, index); @@ -350,7 +344,7 @@ PropertyAttributes Object::query(Managed *m, ExecutionContext *ctx, String *name { Object *that = static_cast(m); PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, name); - if (!pd || pd->type == PropertyDescriptor::Generic) + if (!pd || pd->attrs.type() == PropertyAttributes::Generic) return Attr_Invalid; return pd->toPropertyAttributes(); } @@ -359,7 +353,7 @@ PropertyAttributes Object::queryIndexed(Managed *m, ExecutionContext *ctx, uint { Object *that = static_cast(m); PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, index); - if (!pd || pd->type == PropertyDescriptor::Generic) + if (!pd || pd->attrs.type() == PropertyAttributes::Generic) return Attr_Invalid; return pd->toPropertyAttributes(); } @@ -413,7 +407,7 @@ Value Object::internalGetIndexed(ExecutionContext *ctx, uint index, bool *hasPro Object *o = this; while (o) { PropertyDescriptor *p = o->arrayAt(index); - if (p && p->type != PropertyDescriptor::Generic) { + if (p && p->attrs.type() != PropertyAttributes::Generic) { pd = p; break; } @@ -509,12 +503,9 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value } { - PropertyDescriptor *p = insertMember(name, Attr_Default); - p->type = PropertyDescriptor::Data; + PropertyDescriptor *p = insertMember(name, Attr_Data); + p->attrs = Attr_Data; p->value = value; - p->configurable = PropertyDescriptor::Enabled; - p->enumerable = PropertyDescriptor::Enabled; - p->writable = PropertyDescriptor::Enabled; return; } @@ -526,7 +517,7 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value void Object::internalPutIndexed(ExecutionContext *ctx, uint index, const Value &value) { PropertyDescriptor *pd = arrayAt(index); - if (pd && pd->type == PropertyDescriptor::Generic) + if (pd && pd->attrs.type() == PropertyAttributes::Generic) pd = 0; if (!pd && isStringObject()) pd = static_cast(this)->getIndex(ctx, index); @@ -623,11 +614,11 @@ bool Object::internalDeleteIndexedProperty(ExecutionContext *ctx, uint index) if (n) pd = arrayDecriptor(n->value); } - if (!pd || pd->type == PropertyDescriptor::Generic) + if (!pd || pd->attrs.type() == PropertyAttributes::Generic) return true; if (pd->isConfigurable()) { - pd->type = PropertyDescriptor::Generic; + pd->attrs.clear(); pd->value = Value::undefinedValue(); if (sparseArray) { pd->value.int_32 = arrayFreeList; @@ -657,18 +648,18 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr assert(0 == internalClass->find(ctx->engine->id_length)); if (desc->isEmpty() || desc->isSubset(lp)) return true; - if (!lp->isWritable() || desc->type == PropertyDescriptor::Accessor || desc->isConfigurable() || desc->isEnumerable()) + if (!lp->isWritable() || desc->attrs.type() == PropertyAttributes::Accessor || desc->isConfigurable() || desc->isEnumerable()) goto reject; bool succeeded = true; - if (desc->type == PropertyDescriptor::Data) { + if (desc->attrs.type() == PropertyAttributes::Data) { bool ok; uint l = desc->value.asArrayLength(ctx, &ok); if (!ok) ctx->throwRangeError(desc->value); succeeded = setArrayLength(l); } - if (desc->writable == PropertyDescriptor::Disabled) - lp->writable = PropertyDescriptor::Disabled; + if (desc->attrs.hasWritable()) + lp->attrs.setWritable(desc->attrs.writable()); if (!succeeded) goto reject; return true; @@ -711,7 +702,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop // Clause 1 current = arrayAt(index); - if (current && current->type == PropertyDescriptor::Generic) + if (current && current->attrs.type() == PropertyAttributes::Generic) current = 0; if (!current && isStringObject()) current = static_cast(this)->getIndex(ctx, index); @@ -748,7 +739,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *cu if (!current->isConfigurable()) { if (desc->isConfigurable()) goto reject; - if (desc->enumerable != PropertyDescriptor::Undefined && desc->enumerable != current->enumerable) + if (desc->attrs.hasEnumerable() && desc->attrs.enumerable() != current->attrs.enumerable()) goto reject; } @@ -763,14 +754,14 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *cu goto reject; if (current->isData()) { // 9b - current->type = PropertyDescriptor::Accessor; - current->writable = PropertyDescriptor::Undefined; + current->attrs.setType(PropertyAttributes::Accessor); + current->attrs.clearWritable(); current->get = 0; current->set = 0; } else { // 9c - current->type = PropertyDescriptor::Data; - current->writable = PropertyDescriptor::Disabled; + current->attrs.setType(PropertyAttributes::Data); + current->attrs.setWritable(false); current->value = Value::undefinedValue(); } } else if (current->isData() && desc->isData()) { // clause 10 @@ -883,8 +874,7 @@ void Object::arrayConcat(const ArrayObject *other) arrayReserve(oldSize + other->arrayDataLen); if (oldSize > arrayDataLen) { PropertyDescriptor generic; - generic.type = PropertyDescriptor::Generic; - generic.writable = PropertyDescriptor::Undefined; + generic.attrs.clear(); generic.value = Value::undefinedValue(); std::fill(arrayData + arrayDataLen, arrayData + oldSize, generic); } @@ -919,7 +909,7 @@ void Object::initSparse() if (!sparseArray) { sparseArray = new SparseArray; for (int i = 0; i < arrayDataLen; ++i) { - if (arrayData[i].type != PropertyDescriptor::Generic) { + if (arrayData[i].attrs.type() != PropertyAttributes::Generic) { SparseArrayNode *n = sparseArray->insert(i); n->value = i + arrayOffset; } @@ -934,14 +924,14 @@ void Object::initSparse() arrayAlloc += off; int o = off; for (int i = 0; i < o - 1; ++i) { - arrayData[i].type = PropertyDescriptor::Generic; + arrayData[i].attrs.clear(); arrayData[i].value = Value::fromInt32(i + 1); } - arrayData[o - 1].type = PropertyDescriptor::Generic; + arrayData[o - 1].attrs.clear(); arrayData[o - 1].value = Value::fromInt32(arrayDataLen + off); } for (int i = arrayDataLen + off; i < arrayAlloc; ++i) { - arrayData[i].type = PropertyDescriptor::Generic; + arrayData[i].attrs.clear(); arrayData[i].value = Value::fromInt32(i + 1); } } @@ -970,7 +960,7 @@ void Object::arrayReserve(uint n) arrayData = newArrayData; if (sparseArray) { for (uint i = arrayFreeList; i < arrayAlloc; ++i) { - arrayData[i].type = PropertyDescriptor::Generic; + arrayData[i].attrs.clear(); arrayData[i].value = Value::fromInt32(i + 1); } } else { @@ -994,12 +984,12 @@ bool Object::setArrayLength(uint newLen) { SparseArrayNode *it = sparseArray->end()->previousNode(); while (1) { PropertyDescriptor &pd = arrayData[it->value]; - if (pd.type != PropertyDescriptor::Generic && !pd.isConfigurable()) { + if (pd.attrs.type() != PropertyAttributes::Generic && !pd.isConfigurable()) { ok = false; newLen = it->key() + 1; break; } - pd.type = PropertyDescriptor::Generic; + pd.attrs.clear(); pd.value.tag = Value::_Undefined_Type; pd.value.int_32 = arrayFreeList; arrayFreeList = it->value; @@ -1015,7 +1005,7 @@ bool Object::setArrayLength(uint newLen) { PropertyDescriptor *it = arrayData + arrayDataLen; const PropertyDescriptor *begin = arrayData + newLen; while (--it >= begin) { - if (it->type != PropertyDescriptor::Generic && !it->isConfigurable()) { + if (it->attrs.type() != PropertyAttributes::Generic && !it->isConfigurable()) { ok = false; newLen = it - arrayData + 1; break; @@ -1054,10 +1044,7 @@ void ArrayObject::init(ExecutionContext *context) memberData = new PropertyDescriptor[4]; PropertyDescriptor *pd = memberData + LengthPropertyIndex; - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Disabled; - pd->configurable = PropertyDescriptor::Disabled; + pd->attrs = Attr_NotEnumerable|Attr_NotConfigurable; pd->value = Value::fromInt32(0); } diff --git a/src/v4/qv4object.h b/src/v4/qv4object.h index 004b537..8c35a5a 100644 --- a/src/v4/qv4object.h +++ b/src/v4/qv4object.h @@ -135,11 +135,11 @@ struct Q_V4_EXPORT Object: Managed { bool __hasProperty__(const ExecutionContext *ctx, String *name) const { PropertyDescriptor *pd = __getPropertyDescriptor__(ctx, name); - return pd && pd->type != PropertyDescriptor::Generic; + return pd && pd->attrs.type() != PropertyAttributes::Generic; } bool __hasProperty__(const ExecutionContext *ctx, uint index) const { PropertyDescriptor *pd = __getPropertyDescriptor__(ctx, index); - return pd && pd->type != PropertyDescriptor::Generic; + return pd && pd->attrs.type() != PropertyAttributes::Generic; } bool __defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, const PropertyDescriptor *desc); @@ -157,12 +157,12 @@ struct Q_V4_EXPORT Object: Managed { return getValue(Value::fromObject(const_cast(this)), ctx, p); } Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p) const { - if (!p || p->type == PropertyDescriptor::Generic) + if (!p || p->attrs.type() == PropertyAttributes::Generic) return Value::undefinedValue(); return getValue(Value::fromObject(const_cast(this)), ctx, p); } Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, bool *exists) const { - *exists = p && p->type != PropertyDescriptor::Generic; + *exists = p && p->attrs.type() != PropertyAttributes::Generic; if (!*exists) return Value::undefinedValue(); return getValue(Value::fromObject(const_cast(this)), ctx, p); @@ -189,10 +189,7 @@ struct Q_V4_EXPORT Object: Managed { static void fillDescriptor(PropertyDescriptor *pd, Value v) { - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; + pd->attrs = PropertyAttributes(Attr_Data); pd->value = v; } @@ -212,7 +209,7 @@ struct Q_V4_EXPORT Object: Managed { } void freeArrayValue(int idx) { PropertyDescriptor &pd = arrayData[idx]; - pd.type = PropertyDescriptor::Generic; + pd.attrs.clear(); pd.value.tag = Value::_Undefined_Type; pd.value.int_32 = arrayFreeList; arrayFreeList = idx; @@ -250,8 +247,7 @@ public: arrayReserve(index + 1); if (index >= arrayDataLen) { for (uint i = arrayDataLen; i < index; ++i) { - arrayData[i].type = PropertyDescriptor::Generic; - arrayData[i].writable = PropertyDescriptor::Undefined; + arrayData[i].attrs.clear(); arrayData[i].value.tag = Value::_Undefined_Type; } arrayDataLen = index + 1; diff --git a/src/v4/qv4objectiterator.cpp b/src/v4/qv4objectiterator.cpp index d7c1a19..a0cd1a6 100644 --- a/src/v4/qv4objectiterator.cpp +++ b/src/v4/qv4objectiterator.cpp @@ -109,7 +109,7 @@ PropertyDescriptor *ObjectIterator::next(String **name, uint *index) while (arrayIndex < current->arrayDataLen) { p = current->arrayAt(arrayIndex); ++arrayIndex; - if (p && p->type != PropertyDescriptor::Generic && (!(flags & EnumberableOnly) || p->isEnumerable())) { + if (p && p->attrs.type() != PropertyAttributes::Generic && (!(flags & EnumberableOnly) || p->isEnumerable())) { *index = arrayIndex - 1; return p; } diff --git a/src/v4/qv4objectproto.cpp b/src/v4/qv4objectproto.cpp index 907b6fe..3e02d2c 100644 --- a/src/v4/qv4objectproto.cpp +++ b/src/v4/qv4objectproto.cpp @@ -246,7 +246,7 @@ Value ObjectPrototype::method_seal(SimpleCallContext *ctx) PropertyDescriptor *pd = it.next(&name, &index); if (!pd) break; - pd->configurable = PropertyDescriptor::Disabled; + pd->attrs.setConfigurable(false); } return ctx->argument(0); } @@ -266,9 +266,9 @@ Value ObjectPrototype::method_freeze(SimpleCallContext *ctx) PropertyDescriptor *pd = it.next(&name, &index); if (!pd) break; - if (pd->type == PropertyDescriptor::Data) - pd->writable = PropertyDescriptor::Disabled; - pd->configurable = PropertyDescriptor::Disabled; + if (pd->attrs.type() == PropertyAttributes::Data) + pd->attrs.setWritable(false); + pd->attrs.setConfigurable(false); } return ctx->argument(0); } @@ -299,7 +299,7 @@ Value ObjectPrototype::method_isSealed(SimpleCallContext *ctx) PropertyDescriptor *pd = it.next(&name, &index); if (!pd) break; - if (pd->configurable != PropertyDescriptor::Disabled) + if (pd->attrs.configurable()) return Value::fromBoolean(false); } return Value::fromBoolean(true); @@ -439,8 +439,8 @@ Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx) Object *o = ctx->thisObject.toObject(ctx); PropertyDescriptor pd = PropertyDescriptor::fromAccessor(f, 0); - pd.configurable = PropertyDescriptor::Enabled; - pd.enumerable = PropertyDescriptor::Enabled; + pd.attrs.setConfigurable(true); + pd.attrs.setEnumerable(true); o->__defineOwnProperty__(ctx, prop, &pd); return Value::undefinedValue(); } @@ -458,8 +458,8 @@ Value ObjectPrototype::method_defineSetter(SimpleCallContext *ctx) Object *o = ctx->thisObject.toObject(ctx); PropertyDescriptor pd = PropertyDescriptor::fromAccessor(0, f); - pd.configurable = PropertyDescriptor::Enabled; - pd.enumerable = PropertyDescriptor::Enabled; + pd.attrs.setConfigurable(true); + pd.attrs.setEnumerable(true); o->__defineOwnProperty__(ctx, prop, &pd); return Value::undefinedValue(); } @@ -471,17 +471,16 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope Object *o = v.objectValue(); - desc->type = PropertyDescriptor::Generic; + desc->attrs.clear(); + desc->get = 0; + desc->set = 0; - desc->enumerable = PropertyDescriptor::Undefined; if (o->__hasProperty__(ctx, ctx->engine->id_enumerable)) - desc->enumerable = o->get(ctx, ctx->engine->id_enumerable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled; + desc->attrs.setEnumerable(o->get(ctx, ctx->engine->id_enumerable).toBoolean()); - desc->configurable = PropertyDescriptor::Undefined; if (o->__hasProperty__(ctx, ctx->engine->id_configurable)) - desc->configurable = o->get(ctx, ctx->engine->id_configurable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled; + desc->attrs.setConfigurable(o->get(ctx, ctx->engine->id_configurable).toBoolean()); - desc->get = 0; if (o->__hasProperty__(ctx, ctx->engine->id_get)) { Value get = o->get(ctx, ctx->engine->id_get); FunctionObject *f = get.asFunctionObject(); @@ -492,10 +491,9 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope } else { ctx->throwTypeError(); } - desc->type = PropertyDescriptor::Accessor; + desc->attrs.setType(PropertyAttributes::Accessor); } - desc->set = 0; if (o->__hasProperty__(ctx, ctx->engine->id_set)) { Value set = o->get(ctx, ctx->engine->id_set); FunctionObject *f = set.asFunctionObject(); @@ -506,14 +504,13 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope } else { ctx->throwTypeError(); } - desc->type = PropertyDescriptor::Accessor; + desc->attrs.setType(PropertyAttributes::Accessor); } - desc->writable = PropertyDescriptor::Undefined; if (o->__hasProperty__(ctx, ctx->engine->id_writable)) { if (desc->isAccessor()) ctx->throwTypeError(); - desc->writable = o->get(ctx, ctx->engine->id_writable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled; + desc->attrs.setWritable(o->get(ctx, ctx->engine->id_writable).toBoolean()); // writable forces it to be a data descriptor desc->value = Value::undefinedValue(); } @@ -522,7 +519,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope if (desc->isAccessor()) ctx->throwTypeError(); desc->value = o->get(ctx, ctx->engine->id_value); - desc->type = PropertyDescriptor::Data; + desc->attrs.setType(PropertyAttributes::Data); } } @@ -538,15 +535,12 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope Object *o = engine->newObject(); PropertyDescriptor pd; - pd.type = PropertyDescriptor::Data; - pd.writable = PropertyDescriptor::Enabled; - pd.enumerable = PropertyDescriptor::Enabled; - pd.configurable = PropertyDescriptor::Enabled; + pd.attrs = Attr_Data; if (desc->isData()) { pd.value = desc->value; o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("value")), &pd); - pd.value = Value::fromBoolean(desc->writable == PropertyDescriptor::Enabled ? true : false); + pd.value = Value::fromBoolean(desc->attrs.writable()); o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("writable")), &pd); } else { pd.value = desc->get ? Value::fromObject(desc->get) : Value::undefinedValue(); @@ -554,9 +548,9 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope pd.value = desc->set ? Value::fromObject(desc->set) : Value::undefinedValue(); o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("set")), &pd); } - pd.value = Value::fromBoolean(desc->enumerable == PropertyDescriptor::Enabled ? true : false); + pd.value = Value::fromBoolean(desc->attrs.enumerable()); o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("enumerable")), &pd); - pd.value = Value::fromBoolean(desc->configurable == PropertyDescriptor::Enabled ? true : false); + pd.value = Value::fromBoolean(desc->attrs.configurable()); o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), &pd); return Value::fromObject(o); diff --git a/src/v4/qv4propertydescriptor.h b/src/v4/qv4propertydescriptor.h index 56f6301..252d486 100644 --- a/src/v4/qv4propertydescriptor.h +++ b/src/v4/qv4propertydescriptor.h @@ -64,95 +64,68 @@ struct Property { struct PropertyDescriptor : public Property { - enum Type { - Generic, - Data, - Accessor - }; - enum State { - Undefined, - Disabled, - Enabled - }; - uint type : 8; - uint writable : 8; - uint enumerable : 8; - uint configurable : 8; + PropertyAttributes attrs; static inline PropertyDescriptor fromValue(Value v) { PropertyDescriptor pd; pd.value = v; - pd.type = Data; - pd.writable = Undefined; - pd.enumerable = Undefined; - pd.configurable = Undefined; + pd.attrs.setType(PropertyAttributes::Data); return pd; } static inline PropertyDescriptor fromAccessor(FunctionObject *getter, FunctionObject *setter) { PropertyDescriptor pd; pd.get = getter; pd.set = setter; - pd.type = Accessor; - pd.writable = Undefined; - pd.enumerable = Undefined; - pd.configurable = Undefined; + pd.attrs.setType(PropertyAttributes::Accessor); return pd; } PropertyAttributes toPropertyAttributes() const { - PropertyAttributes attrs; - attrs.setType(type == Accessor ? PropertyAttributes::Accessor : PropertyAttributes::Data); - attrs.setWritable(writable == Enabled); - attrs.setEnumberable(enumerable == Enabled); - attrs.setConfigurable(configurable == Enabled); return attrs; } // Section 8.10 inline void fullyPopulated() { - if (type == Generic) { - type = Data; + if (!attrs.hasType()) { + attrs.setType(PropertyAttributes::Data); value = Value::undefinedValue(); } - if (type == Data) { - if (writable == Undefined) - writable = Disabled; + if (attrs.type() == PropertyAttributes::Data) { + attrs.resolveWritable(); } else { - writable = Undefined; + attrs.clearWritable(); if ((quintptr)get == 0x1) get = 0; if ((quintptr)set == 0x1) set = 0; } - if (enumerable == Undefined) - enumerable = Disabled; - if (configurable == Undefined) - configurable = Disabled; + attrs.resolveEnumerable(); + attrs.resolveConfigurable(); } - inline bool isData() const { return type == Data || writable != Undefined; } - inline bool isAccessor() const { return type == Accessor; } - inline bool isGeneric() const { return type == Generic && writable == Undefined; } + inline bool isData() const { return attrs.isData(); } + inline bool isAccessor() const { return attrs.isAccessor(); } + inline bool isGeneric() const { return attrs.isGeneric(); } - inline bool isWritable() const { return writable == Enabled; } - inline bool isEnumerable() const { return enumerable == Enabled; } - inline bool isConfigurable() const { return configurable == Enabled; } + inline bool isWritable() const { return attrs.writable(); } + inline bool isEnumerable() const { return attrs.enumerable(); } + inline bool isConfigurable() const { return attrs.configurable(); } inline bool isEmpty() const { - return type == Generic && writable == Undefined && enumerable == Undefined && configurable == Undefined; + return attrs.isEmpty(); } inline bool isSubset(PropertyDescriptor *other) const { - if (type != Generic && type != other->type) + if (attrs.type() != PropertyAttributes::Generic && attrs.type() != other->attrs.type()) return false; - if (enumerable != Undefined && enumerable != other->enumerable) + if (attrs.hasEnumerable() && attrs.enumerable() != other->attrs.enumerable()) return false; - if (configurable != Undefined && configurable != other->configurable) + if (attrs.hasConfigurable() && attrs.configurable() != other->attrs.configurable()) return false; - if (writable != Undefined && writable != other->writable) + if (attrs.hasWritable() && attrs.writable() != other->attrs.writable()) return false; - if (type == Data && !value.sameValue(other->value)) + if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other->value)) return false; - if (type == Accessor) { + if (attrs.type() == PropertyAttributes::Accessor) { if (get != other->get) return false; if (set != other->set) @@ -161,20 +134,20 @@ struct PropertyDescriptor : public Property return true; } inline void operator+=(const PropertyDescriptor &other) { - if (other.enumerable != Undefined) - enumerable = other.enumerable; - if (other.configurable != Undefined) - configurable = other.configurable; - if (other.writable != Undefined) - writable = other.writable; - if (other.type == Accessor) { - type = Accessor; + if (other.attrs.hasEnumerable()) + attrs.setEnumerable(other.attrs.enumerable()); + if (other.attrs.hasConfigurable()) + attrs.setConfigurable(other.attrs.configurable()); + if (other.attrs.hasWritable()) + attrs.setWritable(other.attrs.writable()); + if (other.attrs.type() == PropertyAttributes::Accessor) { + attrs.setType(PropertyAttributes::Accessor); if (other.get) get = ((quintptr)other.get == 0x1) ? 0 : other.get; if (other.set) set = ((quintptr)other.set == 0x1) ? 0 : other.set; - } else if (other.type == Data){ - type = Data; + } else if (other.attrs.type() == PropertyAttributes::Data){ + attrs.setType(PropertyAttributes::Data); value = other.value; } } diff --git a/src/v4/qv4regexpobject.cpp b/src/v4/qv4regexpobject.cpp index 32db30b..3717da6 100644 --- a/src/v4/qv4regexpobject.cpp +++ b/src/v4/qv4regexpobject.cpp @@ -75,10 +75,7 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, RegExp* value, bool global) PropertyDescriptor *lastIndexProperty = insertMember(engine->newIdentifier(QStringLiteral("lastIndex")), Attr_NotEnumerable|Attr_NotConfigurable); - lastIndexProperty->type = PropertyDescriptor::Data; - lastIndexProperty->writable = PropertyDescriptor::Enabled; - lastIndexProperty->enumerable = PropertyDescriptor::Disabled; - lastIndexProperty->configurable = PropertyDescriptor::Disabled; + lastIndexProperty->attrs = Attr_NotEnumerable|Attr_NotConfigurable; lastIndexProperty->value = Value::fromInt32(0); if (!this->value) return; diff --git a/src/v4/qv4runtime.cpp b/src/v4/qv4runtime.cpp index f85fc51..7fc078d 100644 --- a/src/v4/qv4runtime.cpp +++ b/src/v4/qv4runtime.cpp @@ -614,7 +614,7 @@ void __qmljs_get_element(ExecutionContext *ctx, Value *result, const Value &obje if (idx < UINT_MAX) { const PropertyDescriptor *p = o->nonSparseArrayAt(idx); - if (p && p->type == PropertyDescriptor::Data) { + if (p && p->attrs.type() == PropertyAttributes::Data) { if (result) *result = p->value; return; @@ -639,7 +639,7 @@ void __qmljs_set_element(ExecutionContext *ctx, const Value &object, const Value uint idx = index.asArrayIndex(); if (idx < UINT_MAX) { PropertyDescriptor *p = o->nonSparseArrayAt(idx); - if (p && p->type == PropertyDescriptor::Data && p->isWritable()) { + if (p && p->attrs.type() == PropertyAttributes::Data && p->isWritable()) { p->value = value; return; } @@ -702,7 +702,7 @@ void __qmljs_get_property_lookup(ExecutionContext *ctx, Value *result, const Val if (Object *o = object.asObject()) { PropertyDescriptor *p = l->lookup(o); if (p) - res = p->type == PropertyDescriptor::Data ? p->value : o->getValue(ctx, p); + res = p->attrs.type() == PropertyAttributes::Data ? p->value : o->getValue(ctx, p); else res = Value::undefinedValue(); } else { @@ -864,7 +864,7 @@ void __qmljs_call_property_lookup(ExecutionContext *context, Value *result, cons PropertyDescriptor *p = l->lookup(baseObject); if (!p) context->throwTypeError(); - Value func = p->type == PropertyDescriptor::Data ? p->value : baseObject->getValue(context, p); + Value func = p->attrs.type() == PropertyAttributes::Data ? p->value : baseObject->getValue(context, p); FunctionObject *o = func.asFunctionObject(); if (!o) context->throwTypeError(); @@ -1210,12 +1210,9 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const Value &object, assert(o); uint idx = name->asArrayIndex(); - PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Default); + PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Data); pd->value = val ? *val : Value::undefinedValue(); - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; + pd->attrs = PropertyAttributes(Attr_Data); } void __qmljs_builtin_define_array(ExecutionContext *ctx, Value *array, Value *values, uint length) @@ -1230,16 +1227,10 @@ void __qmljs_builtin_define_array(ExecutionContext *ctx, Value *array, Value *va for (uint i = 0; i < length; ++i) { if (values[i].isUndefined() && values[i].uint_32 == UINT_MAX) { pd->value = Value::undefinedValue(); - pd->type = PropertyDescriptor::Generic; - pd->writable = PropertyDescriptor::Undefined; - pd->enumerable = PropertyDescriptor::Undefined; - pd->configurable = PropertyDescriptor::Undefined; + pd->attrs.clear(); } else { pd->value = values[i]; - pd->type = PropertyDescriptor::Data; - pd->writable = PropertyDescriptor::Enabled; - pd->enumerable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; + pd->attrs = PropertyAttributes(Attr_Data); } ++pd; } @@ -1258,10 +1249,7 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const Value &ob PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Accessor); pd->get = getter ? getter->asFunctionObject() : 0; pd->set = setter ? setter->asFunctionObject() : 0; - pd->type = PropertyDescriptor::Accessor; - pd->writable = PropertyDescriptor::Undefined; - pd->enumerable = PropertyDescriptor::Enabled; - pd->configurable = PropertyDescriptor::Enabled; + pd->attrs = Attr_Accessor; } void __qmljs_increment(ExecutionContext *ctx, Value *result, const Value &value) diff --git a/src/v4/qv4sparsearray.cpp b/src/v4/qv4sparsearray.cpp index 9429994..33aab75 100644 --- a/src/v4/qv4sparsearray.cpp +++ b/src/v4/qv4sparsearray.cpp @@ -55,9 +55,9 @@ namespace VM { bool ArrayElementLessThan::operator()(const PropertyDescriptor &p1, const PropertyDescriptor &p2) const { - if (p1.type == PropertyDescriptor::Generic) + if (p1.attrs.type() == PropertyAttributes::Generic) return false; - if (p2.type == PropertyDescriptor::Generic) + if (p2.attrs.type() == PropertyAttributes::Generic) return true; Value v1 = thisObject->getValue(m_context, &p1); Value v2 = thisObject->getValue(m_context, &p2); diff --git a/src/v4/qv4string.cpp b/src/v4/qv4string.cpp index c16be93..382359f 100644 --- a/src/v4/qv4string.cpp +++ b/src/v4/qv4string.cpp @@ -107,7 +107,7 @@ Value String::get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProp return Value::fromInt32(that->_text.length()); } PropertyDescriptor *pd = ctx->engine->stringPrototype->__getPropertyDescriptor__(ctx, name); - if (!pd || pd->type == PropertyDescriptor::Generic) { + if (!pd || pd->attrs.type() == PropertyAttributes::Generic) { if (hasProperty) *hasProperty = false; return Value::undefinedValue(); @@ -126,7 +126,7 @@ Value String::getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *ha return Value::fromString(ctx, that->toQString().mid(index, 1)); } PropertyDescriptor *pd = ctx->engine->stringPrototype->__getPropertyDescriptor__(ctx, index); - if (!pd || pd->type == PropertyDescriptor::Generic) { + if (!pd || pd->attrs.type() == PropertyAttributes::Generic) { if (hasProperty) *hasProperty = false; return Value::undefinedValue(); diff --git a/src/v4/qv4stringobject.cpp b/src/v4/qv4stringobject.cpp index 28537dd..129c806 100644 --- a/src/v4/qv4stringobject.cpp +++ b/src/v4/qv4stringobject.cpp @@ -83,10 +83,7 @@ StringObject::StringObject(ExecutionContext *ctx, const Value &value) vtbl = &static_vtbl; type = Type_StringObject; - tmpProperty.type = PropertyDescriptor::Data; - tmpProperty.enumerable = PropertyDescriptor::Enabled; - tmpProperty.writable = PropertyDescriptor::Disabled; - tmpProperty.configurable = PropertyDescriptor::Disabled; + tmpProperty.attrs = Attr_NotWritable|Attr_NotConfigurable; tmpProperty.value = Value::undefinedValue(); assert(value.isString()); diff --git a/src/v4/qv4v8.cpp b/src/v4/qv4v8.cpp index 337a385..e4ed24a 100644 --- a/src/v4/qv4v8.cpp +++ b/src/v4/qv4v8.cpp @@ -922,12 +922,10 @@ bool Object::SetAccessor(Handle name, AccessorGetter getter, AccessorSet assert(o); PropertyAttributes attrs = Attr_Accessor; attrs.setConfigurable(!(attribute & DontDelete)); - attrs.setEnumberable(!(attribute & DontEnum)); + attrs.setEnumerable(!(attribute & DontEnum)); VM::PropertyDescriptor *pd = o->insertMember(name->asVMString(), attrs); *pd = VM::PropertyDescriptor::fromAccessor(wrappedGetter, wrappedSetter); - pd->writable = VM::PropertyDescriptor::Undefined; - pd->configurable = attribute & DontDelete ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; - pd->enumerable = attribute & DontEnum ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; + pd->attrs = attrs; return true; } @@ -1429,13 +1427,11 @@ public: foreach (const ObjectTemplate::Accessor &acc, m_template->m_accessors) { PropertyAttributes attrs = Attr_Accessor; attrs.setConfigurable(!(acc.attribute & DontDelete)); - attrs.setEnumberable(!(acc.attribute & DontEnum)); + attrs.setEnumerable(!(acc.attribute & DontEnum)); VM::PropertyDescriptor *pd = this->insertMember(acc.name->asVMString(), attrs); *pd = VM::PropertyDescriptor::fromAccessor(acc.getter->vmValue().asFunctionObject(), acc.setter->vmValue().asFunctionObject()); - pd->writable = VM::PropertyDescriptor::Undefined; - pd->configurable = acc.attribute & DontDelete ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; - pd->enumerable = acc.attribute & DontEnum ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; + pd->attrs = attrs; } initProperties(m_template.get()); @@ -1444,15 +1440,13 @@ public: void initProperties(Template *tmpl) { foreach (const Template::Property &p, tmpl->m_properties) { - PropertyAttributes attrs = Attr_Default; + PropertyAttributes attrs = Attr_Data; attrs.setConfigurable(!(p.attributes & DontDelete)); - attrs.setEnumberable(!(p.attributes & DontEnum)); + attrs.setEnumerable(!(p.attributes & DontEnum)); attrs.setWritable(!(p.attributes & ReadOnly)); VM::PropertyDescriptor *pd = this->insertMember(p.name->asVMString(), attrs); *pd = VM::PropertyDescriptor::fromValue(p.value->vmValue()); - pd->writable = p.attributes & ReadOnly ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; - pd->configurable = p.attributes & DontDelete ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; - pd->enumerable = p.attributes & DontEnum ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled; + pd->attrs = attrs; } } @@ -1554,7 +1548,7 @@ protected: PropertyAttributes flags; int intAttr = attr->ToInt32()->Value(); flags.setWritable(!(intAttr & ReadOnly)); - flags.setEnumberable(!(intAttr & DontEnum)); + flags.setEnumerable(!(intAttr & DontEnum)); flags.setConfigurable(!(intAttr & DontDelete)); return flags; } -- 2.7.4