Move functionality from PropertyDescriptor to Property
authorLars Knoll <lars.knoll@digia.com>
Tue, 9 Apr 2013 12:28:20 +0000 (14:28 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 12 Apr 2013 12:32:13 +0000 (14:32 +0200)
Change-Id: I37177b5287ec323f54826cce1cb307ee7f678930
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/v4/qv4argumentsobject.cpp
src/v4/qv4global.h
src/v4/qv4object.cpp
src/v4/qv4objectiterator.cpp
src/v4/qv4objectproto.cpp
src/v4/qv4propertydescriptor.h
src/v4/qv4runtime.cpp

index e2fb9d6..0378112 100644 (file)
@@ -96,7 +96,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
     PropertyDescriptor map;
     bool isMapped = false;
     if (pd && index < (uint)mappedArguments.size())
-        isMapped = pd->isAccessor() && pd->get == context->engine->argumentsAccessors.at(index).get;
+        isMapped = pd->attrs.isAccessor() && pd->get == context->engine->argumentsAccessors.at(index).get;
 
     if (isMapped) {
         map = *pd;
@@ -111,12 +111,12 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
     ctx->strictMode = strict;
     isNonStrictArgumentsObject = true;
 
-    if (isMapped && desc->isData()) {
+    if (isMapped && desc->attrs.isData()) {
         if (desc->attrs.type() != PropertyAttributes::Generic) {
             Value arg = desc->value;
             map.set->call(ctx, Value::fromObject(this), &arg, 1);
         }
-        if (desc->attrs.writable())
+        if (desc->attrs.isWritable())
             *pd = map;
     }
 
index 3ffa29b..0e0a4f0 100644 (file)
@@ -136,9 +136,9 @@ struct PropertyAttributes
     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; }
+    bool isWritable() const { return m_writable; }
+    bool isEnumerable() const { return m_enumerable; }
+    bool isConfigurable() const { return m_configurable; }
 
     void clearType() { m_type = Data; type_set = false; }
     void clearWritable() { m_writable = false; writable_set = false; }
index aa4a596..68f7c9a 100644 (file)
@@ -110,7 +110,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->attrs.type() != PropertyAttributes::Generic);
-    if (p->isData())
+    if (p->attrs.isData())
         return p->value;
     if (!p->get)
         return Value::undefinedValue();
@@ -120,7 +120,7 @@ Value Object::getValue(const Value &thisObject, ExecutionContext *ctx, const Pro
 
 void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value &value)
 {
-    if (pd->isAccessor()) {
+    if (pd->attrs.isAccessor()) {
             if (pd->set) {
                 Value args[1];
                 args[0] = value;
@@ -130,7 +130,7 @@ void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value
             goto reject;
     }
 
-    if (!pd->isWritable())
+    if (!pd->attrs.isWritable())
         goto reject;
 
     pd->value = value;
@@ -144,7 +144,7 @@ void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value
 
 void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value &thisObject, const Value &value)
 {
-    if (pd->isAccessor()) {
+    if (pd->attrs.isAccessor()) {
             if (pd->set) {
                 Value args[1];
                 args[0] = value;
@@ -154,7 +154,7 @@ void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value
             goto reject;
     }
 
-    if (!pd->isWritable())
+    if (!pd->attrs.isWritable())
         goto reject;
 
     pd->value = value;
@@ -231,10 +231,10 @@ void Object::markObjects(Managed *that)
 
     for (int i = 0; i < o->internalClass->size; ++i) {
         const PropertyDescriptor &pd = o->memberData[i];
-        if (pd.isData()) {
+        if (pd.attrs.isData()) {
             if (Managed *m = pd.value.asManaged())
                 m->mark();
-         } else if (pd.isAccessor()) {
+         } else if (pd.attrs.isAccessor()) {
             if (pd.get)
                 pd.get->mark();
             if (pd.set)
@@ -346,7 +346,7 @@ PropertyAttributes Object::query(Managed *m, ExecutionContext *ctx, String *name
     PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, name);
     if (!pd || pd->attrs.type() == PropertyAttributes::Generic)
         return Attr_Invalid;
-    return pd->toPropertyAttributes();
+    return pd->attrs;
 }
 
 PropertyAttributes Object::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
@@ -355,7 +355,7 @@ PropertyAttributes Object::queryIndexed(Managed *m, ExecutionContext *ctx, uint
     PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, index);
     if (!pd || pd->attrs.type() == PropertyAttributes::Generic)
         return Attr_Invalid;
-    return pd->toPropertyAttributes();
+    return pd->attrs;
 }
 
 bool Object::deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
@@ -447,11 +447,11 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value
 
     // clause 1
     if (pd) {
-        if (pd->isAccessor()) {
+        if (pd->attrs.isAccessor()) {
                 if (pd->set)
                     goto cont;
                 goto reject;
-        } else if (!pd->isWritable())
+        } else if (!pd->attrs.isWritable())
             goto reject;
         else if (isArrayObject() && name->isEqualTo(ctx->engine->id_length)) {
             bool ok;
@@ -470,14 +470,14 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value
             goto reject;
     } else {
         if (PropertyDescriptor *p = prototype->__getPropertyDescriptor__(ctx, name)) {
-            if (p->isAccessor()) {
+            if (p->attrs.isAccessor()) {
                 if (p->set)
                     goto cont;
                 goto reject;
             }
             if (!extensible)
                 goto reject;
-            if (!p->isWritable())
+            if (!p->attrs.isWritable())
                 goto reject;
         } else {
             if (!extensible)
@@ -493,7 +493,7 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value
         pd = prototype->__getPropertyDescriptor__(ctx, name);
 
     // Clause 5
-    if (pd && pd->isAccessor()) {
+    if (pd && pd->attrs.isAccessor()) {
         assert(pd->set != 0);
 
         Value args[1];
@@ -524,11 +524,11 @@ void Object::internalPutIndexed(ExecutionContext *ctx, uint index, const Value &
 
     // clause 1
     if (pd) {
-        if (pd->isAccessor()) {
+        if (pd->attrs.isAccessor()) {
                 if (pd->set)
                     goto cont;
                 goto reject;
-        } else if (!pd->isWritable())
+        } else if (!pd->attrs.isWritable())
             goto reject;
         else
             pd->value = value;
@@ -538,14 +538,14 @@ void Object::internalPutIndexed(ExecutionContext *ctx, uint index, const Value &
             goto reject;
     } else {
         if (PropertyDescriptor *p = prototype->__getPropertyDescriptor__(ctx, index)) {
-            if (p->isAccessor()) {
+            if (p->attrs.isAccessor()) {
                 if (p->set)
                     goto cont;
                 goto reject;
             }
             if (!extensible)
                 goto reject;
-            if (!p->isWritable())
+            if (!p->attrs.isWritable())
                 goto reject;
         } else {
             if (!extensible)
@@ -560,7 +560,7 @@ void Object::internalPutIndexed(ExecutionContext *ctx, uint index, const Value &
         pd = prototype->__getPropertyDescriptor__(ctx, index);
 
     // Clause 5
-    if (pd && pd->isAccessor()) {
+    if (pd && pd->attrs.isAccessor()) {
         assert(pd->set != 0);
 
         Value args[1];
@@ -589,7 +589,7 @@ bool Object::internalDeleteProperty(ExecutionContext *ctx, String *name)
     uint memberIdx = internalClass->find(name);
     if (memberIdx != UINT_MAX) {
         PropertyDescriptor &pd = memberData[memberIdx];
-        if (pd.isConfigurable()) {
+        if (pd.attrs.isConfigurable()) {
             internalClass->removeMember(this, name->identifier);
             memmove(memberData + memberIdx, memberData + memberIdx + 1, (internalClass->size - memberIdx)*sizeof(PropertyDescriptor));
             return true;
@@ -617,7 +617,7 @@ bool Object::internalDeleteIndexedProperty(ExecutionContext *ctx, uint index)
     if (!pd || pd->attrs.type() == PropertyAttributes::Generic)
         return true;
 
-    if (pd->isConfigurable()) {
+    if (pd->attrs.isConfigurable()) {
         pd->attrs.clear();
         pd->value = Value::undefinedValue();
         if (sparseArray) {
@@ -646,9 +646,9 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
     if (isArrayObject() && name->isEqualTo(ctx->engine->id_length)) {
         PropertyDescriptor *lp = memberData + ArrayObject::LengthPropertyIndex;
         assert(0 == internalClass->find(ctx->engine->id_length));
-        if (desc->isEmpty() || desc->isSubset(lp))
+        if (desc->attrs.isEmpty() || desc->isSubset(desc->attrs, lp))
             return true;
-        if (!lp->isWritable() || desc->attrs.type() == PropertyAttributes::Accessor || desc->isConfigurable() || desc->isEnumerable())
+        if (!lp->attrs.isWritable() || desc->attrs.type() == PropertyAttributes::Accessor || desc->attrs.isConfigurable() || desc->attrs.isEnumerable())
             goto reject;
         bool succeeded = true;
         if (desc->attrs.type() == PropertyAttributes::Data) {
@@ -659,7 +659,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
             succeeded = setArrayLength(l);
         }
         if (desc->attrs.hasWritable())
-            lp->attrs.setWritable(desc->attrs.writable());
+            lp->attrs.setWritable(desc->attrs.isWritable());
         if (!succeeded)
             goto reject;
         return true;
@@ -676,9 +676,9 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
         if (!extensible)
             goto reject;
         // clause 4
-        PropertyDescriptor *pd = insertMember(name, desc->toPropertyAttributes());
+        PropertyDescriptor *pd = insertMember(name, desc->attrs);
         *pd = *desc;
-        pd->fullyPopulated();
+        pd->fullyPopulated(&pd->attrs);
         return true;
     }
 
@@ -694,7 +694,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
     PropertyDescriptor *current;
 
     // 15.4.5.1, 4b
-    if (isArrayObject() && index >= arrayLength() && !memberData[ArrayObject::LengthPropertyIndex].isWritable())
+    if (isArrayObject() && index >= arrayLength() && !memberData[ArrayObject::LengthPropertyIndex].attrs.isWritable())
         goto reject;
 
     if (isNonStrictArgumentsObject)
@@ -714,7 +714,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
         // clause 4
         PropertyDescriptor *pd = arrayInsert(index);
         *pd = *desc;
-        pd->fullyPopulated();
+        pd->fullyPopulated(&pd->attrs);
         return true;
     }
 
@@ -728,31 +728,31 @@ reject:
 bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, const PropertyDescriptor *desc)
 {
     // clause 5
-    if (desc->isEmpty())
+    if (desc->attrs.isEmpty())
         return true;
 
     // clause 6
-    if (desc->isSubset(current))
+    if (desc->isSubset(desc->attrs, current))
         return true;
 
     // clause 7
-    if (!current->isConfigurable()) {
-        if (desc->isConfigurable())
+    if (!current->attrs.isConfigurable()) {
+        if (desc->attrs.isConfigurable())
             goto reject;
-        if (desc->attrs.hasEnumerable() && desc->attrs.enumerable() != current->attrs.enumerable())
+        if (desc->attrs.hasEnumerable() && desc->attrs.isEnumerable() != current->attrs.isEnumerable())
             goto reject;
     }
 
     // clause 8
-    if (desc->isGeneric())
+    if (desc->attrs.isGeneric())
         goto accept;
 
     // clause 9
-    if (current->isData() != desc->isData()) {
+    if (current->attrs.isData() != desc->attrs.isData()) {
         // 9a
-        if (!current->isConfigurable())
+        if (!current->attrs.isConfigurable())
             goto reject;
-        if (current->isData()) {
+        if (current->attrs.isData()) {
             // 9b
             current->attrs.setType(PropertyAttributes::Accessor);
             current->attrs.clearWritable();
@@ -764,14 +764,14 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *cu
             current->attrs.setWritable(false);
             current->value = Value::undefinedValue();
         }
-    } else if (current->isData() && desc->isData()) { // clause 10
-        if (!current->isConfigurable() && !current->isWritable()) {
-            if (desc->isWritable() || !current->value.sameValue(desc->value))
+    } else if (current->attrs.isData() && desc->attrs.isData()) { // clause 10
+        if (!current->attrs.isConfigurable() && !current->attrs.isWritable()) {
+            if (desc->attrs.isWritable() || !current->value.sameValue(desc->value))
                 goto reject;
         }
     } else { // clause 10
-        assert(current->isAccessor() && desc->isAccessor());
-        if (!current->isConfigurable()) {
+        assert(current->attrs.isAccessor() && desc->attrs.isAccessor());
+        if (!current->attrs.isConfigurable()) {
             if (desc->get && !(current->get == desc->get || (!current->get && (quintptr)desc->get == 0x1)))
                 goto reject;
             if (desc->set && !(current->set == desc->set || (!current->set && (quintptr)desc->set == 0x1)))
@@ -781,7 +781,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *cu
 
   accept:
 
-    *current += *desc;
+    current->merge(current->attrs, *desc);
     return true;
   reject:
     if (ctx->strictMode)
@@ -973,7 +973,7 @@ void Object::arrayReserve(uint n)
 bool Object::setArrayLength(uint newLen) {
     assert(isArrayObject());
     const PropertyDescriptor *lengthProperty = memberData + ArrayObject::LengthPropertyIndex;
-    if (lengthProperty && !lengthProperty->isWritable())
+    if (lengthProperty && !lengthProperty->attrs.isWritable())
         return false;
     uint oldLen = arrayLength();
     bool ok = true;
@@ -984,7 +984,7 @@ bool Object::setArrayLength(uint newLen) {
                 SparseArrayNode *it = sparseArray->end()->previousNode();
                 while (1) {
                     PropertyDescriptor &pd = arrayData[it->value];
-                    if (pd.attrs.type() != PropertyAttributes::Generic && !pd.isConfigurable()) {
+                    if (pd.attrs.type() != PropertyAttributes::Generic && !pd.attrs.isConfigurable()) {
                         ok = false;
                         newLen = it->key() + 1;
                         break;
@@ -1005,7 +1005,7 @@ bool Object::setArrayLength(uint newLen) {
             PropertyDescriptor *it = arrayData + arrayDataLen;
             const PropertyDescriptor *begin = arrayData + newLen;
             while (--it >= begin) {
-                if (it->attrs.type() != PropertyAttributes::Generic && !it->isConfigurable()) {
+                if (it->attrs.type() != PropertyAttributes::Generic && !it->attrs.isConfigurable()) {
                     ok = false;
                     newLen = it - arrayData + 1;
                     break;
@@ -1025,10 +1025,10 @@ void Object::markArrayObjects() const
 {
     for (uint i = 0; i < arrayDataLen; ++i) {
         const PropertyDescriptor &pd = arrayData[i];
-        if (pd.isData()) {
+        if (pd.attrs.isData()) {
             if (Managed *m = pd.value.asManaged())
                 m->mark();
-         } else if (pd.isAccessor()) {
+         } else if (pd.attrs.isAccessor()) {
             if (pd.get)
                 pd.get->mark();
             if (pd.set)
index a0cd1a6..29b0c96 100644 (file)
@@ -96,7 +96,7 @@ PropertyDescriptor *ObjectIterator::next(String **name, uint *index)
                 int k = arrayNode->key();
                 p = current->arrayAt(k);
                 arrayNode = arrayNode->nextNode();
-                if (p && (!(flags & EnumberableOnly) || p->isEnumerable())) {
+                if (p && (!(flags & EnumberableOnly) || p->attrs.isEnumerable())) {
                     arrayIndex = k + 1;
                     *index = k;
                     return p;
@@ -109,7 +109,7 @@ PropertyDescriptor *ObjectIterator::next(String **name, uint *index)
         while (arrayIndex < current->arrayDataLen) {
             p = current->arrayAt(arrayIndex);
             ++arrayIndex;
-            if (p && p->attrs.type() != PropertyAttributes::Generic && (!(flags & EnumberableOnly) || p->isEnumerable())) {
+            if (p && p->attrs.type() != PropertyAttributes::Generic && (!(flags & EnumberableOnly) || p->attrs.isEnumerable())) {
                 *index = arrayIndex - 1;
                 return p;
             }
@@ -138,7 +138,7 @@ PropertyDescriptor *ObjectIterator::next(String **name, uint *index)
 
         p = current->memberData + memberIndex;
         ++memberIndex;
-        if (!(flags & EnumberableOnly) || p->isEnumerable()) {
+        if (!(flags & EnumberableOnly) || p->attrs.isEnumerable()) {
             *name = n;
             return p;
         }
index 3e02d2c..0721aa1 100644 (file)
@@ -299,7 +299,7 @@ Value ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
         PropertyDescriptor *pd = it.next(&name, &index);
         if (!pd)
             break;
-        if (pd->attrs.configurable())
+        if (pd->attrs.isConfigurable())
             return Value::fromBoolean(false);
     }
     return Value::fromBoolean(true);
@@ -321,7 +321,7 @@ Value ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
         PropertyDescriptor *pd = it.next(&name, &index);
         if (!pd)
             break;
-            if (pd->isWritable() || pd->isConfigurable())
+            if (pd->attrs.isWritable() || pd->attrs.isConfigurable())
             return Value::fromBoolean(false);
     }
     return Value::fromBoolean(true);
@@ -423,7 +423,7 @@ Value ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
 
     Object *o = ctx->thisObject.toObject(ctx);
     PropertyDescriptor *pd = o->__getOwnProperty__(ctx, p);
-    return Value::fromBoolean(pd && pd->isEnumerable());
+    return Value::fromBoolean(pd && pd->attrs.isEnumerable());
 }
 
 Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
@@ -508,7 +508,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
     }
 
     if (o->__hasProperty__(ctx, ctx->engine->id_writable)) {
-        if (desc->isAccessor())
+        if (desc->attrs.isAccessor())
             ctx->throwTypeError();
         desc->attrs.setWritable(o->get(ctx, ctx->engine->id_writable).toBoolean());
         // writable forces it to be a data descriptor
@@ -516,7 +516,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
     }
 
     if (o->__hasProperty__(ctx, ctx->engine->id_value)) {
-        if (desc->isAccessor())
+        if (desc->attrs.isAccessor())
             ctx->throwTypeError();
         desc->value = o->get(ctx, ctx->engine->id_value);
         desc->attrs.setType(PropertyAttributes::Data);
@@ -537,10 +537,10 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope
     PropertyDescriptor pd;
     pd.attrs = Attr_Data;
 
-    if (desc->isData()) {
+    if (desc->attrs.isData()) {
         pd.value = desc->value;
         o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("value")), &pd);
-        pd.value = Value::fromBoolean(desc->attrs.writable());
+        pd.value = Value::fromBoolean(desc->attrs.isWritable());
         o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("writable")), &pd);
     } else {
         pd.value = desc->get ? Value::fromObject(desc->get) : Value::undefinedValue();
@@ -548,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->attrs.enumerable());
+    pd.value = Value::fromBoolean(desc->attrs.isEnumerable());
     o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("enumerable")), &pd);
-    pd.value = Value::fromBoolean(desc->attrs.configurable());
+    pd.value = Value::fromBoolean(desc->attrs.isConfigurable());
     o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), &pd);
 
     return Value::fromObject(o);
index 252d486..0d77067 100644 (file)
@@ -51,6 +51,7 @@ namespace QQmlJS {
 namespace VM {
 
 struct FunctionObject;
+struct PropertyDescriptor;
 
 struct Property {
     union {
@@ -60,6 +61,28 @@ struct Property {
             FunctionObject *set;
         };
     };
+
+    // Section 8.10
+    inline void fullyPopulated(PropertyAttributes *attrs) {
+        if (!attrs->hasType()) {
+            attrs->setType(PropertyAttributes::Data);
+            value = Value::undefinedValue();
+        }
+        if (attrs->type() == PropertyAttributes::Data) {
+            attrs->resolveWritable();
+        } else {
+            attrs->clearWritable();
+            if ((quintptr)get == 0x1)
+                get = 0;
+            if ((quintptr)set == 0x1)
+                set = 0;
+        }
+        attrs->resolveEnumerable();
+        attrs->resolveConfigurable();
+    }
+
+    inline bool isSubset(const PropertyAttributes &attrs, PropertyDescriptor *other) const;
+    inline void merge(PropertyAttributes &attrs, const PropertyDescriptor &other);
 };
 
 struct PropertyDescriptor : public Property
@@ -79,79 +102,49 @@ struct PropertyDescriptor : public Property
         pd.attrs.setType(PropertyAttributes::Accessor);
         return pd;
     }
+};
 
-    PropertyAttributes toPropertyAttributes() const {
-        return attrs;
-    }
-
-    // Section 8.10
-    inline void fullyPopulated() {
-        if (!attrs.hasType()) {
-            attrs.setType(PropertyAttributes::Data);
-            value = Value::undefinedValue();
-        }
-        if (attrs.type() == PropertyAttributes::Data) {
-            attrs.resolveWritable();
-        } else {
-            attrs.clearWritable();
-            if ((quintptr)get == 0x1)
-                get = 0;
-            if ((quintptr)set == 0x1)
-                set = 0;
-        }
-        attrs.resolveEnumerable();
-        attrs.resolveConfigurable();
-    }
-
-    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 attrs.writable(); }
-    inline bool isEnumerable() const { return attrs.enumerable(); }
-    inline bool isConfigurable() const { return attrs.configurable(); }
-
-    inline bool isEmpty() const {
-        return attrs.isEmpty();
-    }
-    inline bool isSubset(PropertyDescriptor *other) const {
-        if (attrs.type() != PropertyAttributes::Generic && attrs.type() != other->attrs.type())
-            return false;
-        if (attrs.hasEnumerable() && attrs.enumerable() != other->attrs.enumerable())
-            return false;
-        if (attrs.hasConfigurable() && attrs.configurable() != other->attrs.configurable())
-            return false;
-        if (attrs.hasWritable() && attrs.writable() != other->attrs.writable())
+inline bool Property::isSubset(const PropertyAttributes &attrs, PropertyDescriptor *other) const
+{
+    if (attrs.type() != PropertyAttributes::Generic && attrs.type() != other->attrs.type())
+        return false;
+    if (attrs.hasEnumerable() && attrs.isEnumerable() != other->attrs.isEnumerable())
+        return false;
+    if (attrs.hasConfigurable() && attrs.isConfigurable() != other->attrs.isConfigurable())
+        return false;
+    if (attrs.hasWritable() && attrs.isWritable() != other->attrs.isWritable())
+        return false;
+    if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other->value))
+        return false;
+    if (attrs.type() == PropertyAttributes::Accessor) {
+        if (get != other->get)
             return false;
-        if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other->value))
+        if (set != other->set)
             return false;
-        if (attrs.type() == PropertyAttributes::Accessor) {
-            if (get != other->get)
-                return false;
-            if (set != other->set)
-                return false;
-        }
-        return true;
     }
-    inline void operator+=(const PropertyDescriptor &other) {
-        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.attrs.type() == PropertyAttributes::Data){
-            attrs.setType(PropertyAttributes::Data);
-            value = other.value;
-        }
+    return true;
+}
+
+inline void Property::merge(PropertyAttributes &attrs, const PropertyDescriptor &other)
+{
+    if (other.attrs.hasEnumerable())
+        attrs.setEnumerable(other.attrs.isEnumerable());
+    if (other.attrs.hasConfigurable())
+        attrs.setConfigurable(other.attrs.isConfigurable());
+    if (other.attrs.hasWritable())
+        attrs.setWritable(other.attrs.isWritable());
+    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.attrs.type() == PropertyAttributes::Data){
+        attrs.setType(PropertyAttributes::Data);
+        value = other.value;
     }
-};
+}
+
 
 } // namespace VM
 } // namespace QQmlJS
index 7fc078d..083bfea 100644 (file)
@@ -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->attrs.type() == PropertyAttributes::Data && p->isWritable()) {
+        if (p && p->attrs.type() == PropertyAttributes::Data && p->attrs.isWritable()) {
             p->value = value;
             return;
         }