aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-04-09 14:28:20 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-04-12 14:32:13 +0200
commitf6d5079a44ca0dcb02cdc9c7adf9d3ab71df232d (patch)
tree7001a2c1a392f6e2d1a756720eb0b889b77eda6a /src
parent380a486ae72457a0684d5d85c8bab79579509dcc (diff)
Move functionality from PropertyDescriptor to Property
Change-Id: I37177b5287ec323f54826cce1cb307ee7f678930 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/v4/qv4argumentsobject.cpp6
-rw-r--r--src/v4/qv4global.h6
-rw-r--r--src/v4/qv4object.cpp96
-rw-r--r--src/v4/qv4objectiterator.cpp6
-rw-r--r--src/v4/qv4objectproto.cpp18
-rw-r--r--src/v4/qv4propertydescriptor.h129
-rw-r--r--src/v4/qv4runtime.cpp2
7 files changed, 128 insertions, 135 deletions
diff --git a/src/v4/qv4argumentsobject.cpp b/src/v4/qv4argumentsobject.cpp
index e2fb9d6b07..0378112356 100644
--- a/src/v4/qv4argumentsobject.cpp
+++ b/src/v4/qv4argumentsobject.cpp
@@ -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;
}
diff --git a/src/v4/qv4global.h b/src/v4/qv4global.h
index 3ffa29b396..0e0a4f0f26 100644
--- a/src/v4/qv4global.h
+++ b/src/v4/qv4global.h
@@ -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; }
diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp
index aa4a596c75..68f7c9ac0e 100644
--- a/src/v4/qv4object.cpp
+++ b/src/v4/qv4object.cpp
@@ -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)
diff --git a/src/v4/qv4objectiterator.cpp b/src/v4/qv4objectiterator.cpp
index a0cd1a69ca..29b0c96482 100644
--- a/src/v4/qv4objectiterator.cpp
+++ b/src/v4/qv4objectiterator.cpp
@@ -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;
}
diff --git a/src/v4/qv4objectproto.cpp b/src/v4/qv4objectproto.cpp
index 3e02d2c586..0721aa1b4a 100644
--- a/src/v4/qv4objectproto.cpp
+++ b/src/v4/qv4objectproto.cpp
@@ -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);
diff --git a/src/v4/qv4propertydescriptor.h b/src/v4/qv4propertydescriptor.h
index 252d486c1d..0d77067743 100644
--- a/src/v4/qv4propertydescriptor.h
+++ b/src/v4/qv4propertydescriptor.h
@@ -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
diff --git a/src/v4/qv4runtime.cpp b/src/v4/qv4runtime.cpp
index 7fc078dd81..083bfea206 100644
--- a/src/v4/qv4runtime.cpp
+++ b/src/v4/qv4runtime.cpp
@@ -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;
}