summaryrefslogtreecommitdiffstats
path: root/src/v4/qv4object.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/v4/qv4object.h')
-rw-r--r--src/v4/qv4object.h142
1 files changed, 75 insertions, 67 deletions
diff --git a/src/v4/qv4object.h b/src/v4/qv4object.h
index 8c35a5a0..9919ce3a 100644
--- a/src/v4/qv4object.h
+++ b/src/v4/qv4object.h
@@ -111,7 +111,7 @@ struct Q_V4_EXPORT Object: Managed {
Object *prototype;
InternalClass *internalClass;
uint memberDataAlloc;
- PropertyDescriptor *memberData;
+ Property *memberData;
union {
uint arrayFreeList;
@@ -119,7 +119,8 @@ struct Q_V4_EXPORT Object: Managed {
};
uint arrayDataLen;
uint arrayAlloc;
- PropertyDescriptor *arrayData;
+ PropertyAttributes *arrayAttributes;
+ Property *arrayData;
SparseArray *sparseArray;
ExternalResource *externalResource;
@@ -127,50 +128,46 @@ struct Q_V4_EXPORT Object: Managed {
Object(ExecutionContext *context);
~Object();
- PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, String *name);
- PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, uint index);
+ Property *__getOwnProperty__(ExecutionContext *ctx, String *name, PropertyAttributes *attrs = 0);
+ Property *__getOwnProperty__(ExecutionContext *ctx, uint index, PropertyAttributes *attrs = 0);
- PropertyDescriptor *__getPropertyDescriptor__(const ExecutionContext *ctx, String *name) const;
- PropertyDescriptor *__getPropertyDescriptor__(const ExecutionContext *ctx, uint index) const;
+ Property *__getPropertyDescriptor__(const ExecutionContext *ctx, String *name, PropertyAttributes *attrs = 0) const;
+ Property *__getPropertyDescriptor__(const ExecutionContext *ctx, uint index, PropertyAttributes *attrs = 0) const;
bool __hasProperty__(const ExecutionContext *ctx, String *name) const {
- PropertyDescriptor *pd = __getPropertyDescriptor__(ctx, name);
- return pd && pd->attrs.type() != PropertyAttributes::Generic;
+ return __getPropertyDescriptor__(ctx, name);
}
bool __hasProperty__(const ExecutionContext *ctx, uint index) const {
- PropertyDescriptor *pd = __getPropertyDescriptor__(ctx, index);
- return pd && pd->attrs.type() != PropertyAttributes::Generic;
+ return __getPropertyDescriptor__(ctx, index);
}
- bool __defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, const PropertyDescriptor *desc);
- bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const PropertyDescriptor *desc);
- bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc);
- bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const PropertyDescriptor *desc);
+ bool __defineOwnProperty__(ExecutionContext *ctx, Property *current, String *member, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs);
//
// helpers
//
void put(ExecutionContext *ctx, const QString &name, const Value &value);
- static Value getValue(const Value &thisObject, ExecutionContext *ctx, const PropertyDescriptor *p);
- Value getValue(ExecutionContext *ctx, const PropertyDescriptor *p) const {
- return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p);
+ static Value getValue(const Value &thisObject, ExecutionContext *ctx, const Property *p, PropertyAttributes attrs);
+ Value getValue(ExecutionContext *ctx, const Property *p, PropertyAttributes attrs) const {
+ return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p, attrs);
}
- Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p) const {
- if (!p || p->attrs.type() == PropertyAttributes::Generic)
+ Value getValueChecked(ExecutionContext *ctx, const Property *p, PropertyAttributes attrs) const {
+ if (!p || attrs.isGeneric())
return Value::undefinedValue();
- return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p);
+ return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p, attrs);
}
- Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, bool *exists) const {
- *exists = p && p->attrs.type() != PropertyAttributes::Generic;
+ Value getValueChecked(ExecutionContext *ctx, const Property *p, PropertyAttributes attrs, bool *exists) const {
+ *exists = p && !attrs.isGeneric();
if (!*exists)
return Value::undefinedValue();
- return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p);
+ return getValue(Value::fromObject(const_cast<Object *>(this)), ctx, p, attrs);
}
-
- void putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value &value);
- void putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value &thisObject, const Value &value);
+ void putValue(ExecutionContext *ctx, Property *pd, PropertyAttributes attrs, const Value &value);
void inplaceBinOp(ExecutionContext *ctx, BinOp op, String *name, const Value &rhs);
void inplaceBinOp(ExecutionContext *ctx, BinOp op, const Value &index, const Value &rhs);
@@ -183,52 +180,48 @@ struct Q_V4_EXPORT Object: Managed {
void defineReadonlyProperty(ExecutionEngine *engine, const QString &name, Value value);
void defineReadonlyProperty(String *name, Value value);
- PropertyDescriptor *insertMember(String *s, PropertyAttributes attributes);
+ Property *insertMember(String *s, PropertyAttributes attributes);
// Array handling
- static void fillDescriptor(PropertyDescriptor *pd, Value v)
- {
- pd->attrs = PropertyAttributes(Attr_Data);
- pd->value = v;
- }
-
uint allocArrayValue() {
uint idx = arrayFreeList;
if (arrayAlloc <= arrayFreeList)
arrayReserve(arrayAlloc + 1);
- arrayFreeList = arrayData[arrayFreeList].value.integerValue();
+ arrayFreeList = arrayData[arrayFreeList].value.uint_32;
+ if (arrayAttributes)
+ arrayAttributes[idx].setType(PropertyAttributes::Data);
return idx;
}
uint allocArrayValue(Value v) {
uint idx = allocArrayValue();
- PropertyDescriptor *pd = &arrayData[idx];
- fillDescriptor(pd, v);
+ Property *pd = &arrayData[idx];
+ pd->value = v;
return idx;
}
void freeArrayValue(int idx) {
- PropertyDescriptor &pd = arrayData[idx];
- pd.attrs.clear();
- pd.value.tag = Value::_Undefined_Type;
+ Property &pd = arrayData[idx];
+ pd.value.tag = Value::_Deleted_Type;
pd.value.int_32 = arrayFreeList;
arrayFreeList = idx;
- }
-
- PropertyDescriptor *arrayDecriptor(uint index) {
- return arrayData + index;
- }
- const PropertyDescriptor *arrayDecriptor(uint index) const {
- return arrayData + index;
+ if (arrayAttributes)
+ arrayAttributes[idx].clear();
}
void getArrayHeadRoom() {
assert(!sparseArray && !arrayOffset);
arrayOffset = qMax(arrayDataLen >> 2, (uint)16);
- PropertyDescriptor *newArray = new PropertyDescriptor[arrayOffset + arrayAlloc];
- memcpy(newArray + arrayOffset, arrayData, arrayDataLen*sizeof(PropertyDescriptor));
+ Property *newArray = new Property[arrayOffset + arrayAlloc];
+ memcpy(newArray + arrayOffset, arrayData, arrayDataLen*sizeof(Property));
delete [] arrayData;
arrayData = newArray + arrayOffset;
+ if (arrayAttributes) {
+ PropertyAttributes *newAttrs = new PropertyAttributes[arrayOffset + arrayAlloc];
+ memcpy(newAttrs + arrayOffset, arrayAttributes, arrayDataLen*sizeof(PropertyAttributes));
+ delete [] arrayAttributes;
+ arrayAttributes = newAttrs + arrayOffset;
+ }
}
public:
@@ -240,54 +233,68 @@ public:
void setArrayLengthUnchecked(uint l);
- PropertyDescriptor *arrayInsert(uint index) {
- PropertyDescriptor *pd;
+ Property *arrayInsert(uint index, PropertyAttributes attributes = Attr_Data) {
+
+ Property *pd;
if (!sparseArray && (index < 0x1000 || index < arrayDataLen + (arrayDataLen >> 2))) {
if (index >= arrayAlloc)
arrayReserve(index + 1);
if (index >= arrayDataLen) {
- for (uint i = arrayDataLen; i < index; ++i) {
- arrayData[i].attrs.clear();
- arrayData[i].value.tag = Value::_Undefined_Type;
- }
+ ensureArrayAttributes();
+ for (uint i = arrayDataLen; i < index; ++i)
+ arrayAttributes[i].clear();
arrayDataLen = index + 1;
}
- pd = arrayDecriptor(index);
+ pd = arrayData + index;
} else {
initSparse();
SparseArrayNode *n = sparseArray->insert(index);
if (n->value == UINT_MAX)
n->value = allocArrayValue();
- pd = arrayDecriptor(n->value);
+ pd = arrayData + n->value;
}
if (index >= arrayLength())
setArrayLengthUnchecked(index + 1);
+ if (arrayAttributes || attributes != Attr_Data) {
+ if (!arrayAttributes)
+ ensureArrayAttributes();
+ attributes.resolve();
+ arrayAttributes[pd - arrayData] = attributes;
+ }
return pd;
}
- void arraySet(uint index, const PropertyDescriptor *pd) {
+ void arraySet(uint index, const Property *pd) {
*arrayInsert(index) = *pd;
}
void arraySet(uint index, Value value) {
- PropertyDescriptor *pd = arrayInsert(index);
- fillDescriptor(pd, value);
+ Property *pd = arrayInsert(index);
+ pd->value = value;
}
- PropertyDescriptor *arrayAt(uint index) const {
+ uint propertyIndexFromArrayIndex(uint index) const
+ {
if (!sparseArray) {
if (index >= arrayDataLen)
- return 0;
- return arrayData + index;
+ return UINT_MAX;
+ return index;
} else {
SparseArrayNode *n = sparseArray->findNode(index);
if (!n)
- return 0;
- return arrayData + n->value;
+ return UINT_MAX;
+ return n->value;
}
}
- PropertyDescriptor *nonSparseArrayAt(uint index) const {
+ Property *arrayAt(uint index) const {
+ uint pidx = propertyIndexFromArrayIndex(index);
+ if (pidx == UINT_MAX)
+ return 0;
+ return arrayData + pidx;
+ }
+
+ Property *nonSparseArrayAt(uint index) const {
if (sparseArray)
return 0;
if (index >= arrayDataLen)
@@ -302,7 +309,7 @@ public:
if (!sparseArray) {
if (idx >= arrayAlloc)
arrayReserve(idx + 1);
- fillDescriptor(arrayData + idx, v);
+ arrayData[idx].value = v;
arrayDataLen = idx + 1;
} else {
uint idx = allocArrayValue(v);
@@ -319,6 +326,7 @@ public:
Value arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o);
void arrayReserve(uint n);
+ void ensureArrayAttributes();
using Managed::get;
using Managed::getIndexed;
@@ -401,7 +409,7 @@ inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject()) {
// length is always the first property of an array
- PropertyDescriptor &lengthProperty = memberData[ArrayObject::LengthPropertyIndex];
+ Property &lengthProperty = memberData[ArrayObject::LengthPropertyIndex];
lengthProperty.value = Value::fromUInt32(l);
}
}