PropertyDescriptor *lp = array.getLengthProperty();
if (!lp->isWritable() || desc->type == PropertyDescriptor::Accessor || desc->isConfigurable() || desc->isEnumerable())
goto reject;
+ bool succeeded = false;
if (desc->type == PropertyDescriptor::Data) {
bool ok;
uint l = desc->value.asArrayLength(ctx, &ok);
if (!ok)
ctx->throwRangeError(desc->value);
- if (!array.setLength(l))
- goto reject;
+ succeeded = array.setLength(l);
}
if (desc->writable == PropertyDescriptor::Disabled)
lp->writable = PropertyDescriptor::Disabled;
+ if (!succeeded)
+ goto reject;
return true;
}
}
}
+bool Array::setLength(uint newLen) {
+ if (lengthProperty && !lengthProperty->isWritable())
+ return false;
+ uint oldLen = length();
+ bool ok = true;
+ if (newLen < oldLen) {
+ if (sparse) {
+ SparseArrayNode *begin = sparse->lowerBound(newLen);
+ SparseArrayNode *it = sparse->end()->previousNode();
+ while (1) {
+ PropertyDescriptor &pd = values[it->value];
+ if (pd.type != PropertyDescriptor::Generic && !pd.isConfigurable()) {
+ ok = false;
+ newLen = it->key() + 1;
+ break;
+ }
+ pd.type = PropertyDescriptor::Generic;
+ pd.value.tag = Value::_Undefined_Type;
+ pd.value.int_32 = freeList;
+ freeList = it->value;
+ bool brk = (it == begin);
+ SparseArrayNode *prev = it->previousNode();
+ sparse->erase(it);
+ if (brk)
+ break;
+ it = prev;
+ }
+ } else {
+ PropertyDescriptor *it = values.data() + offset + values.size();
+ const PropertyDescriptor *begin = values.constData() + offset + newLen;
+ while (--it >= begin) {
+ if (it->type != PropertyDescriptor::Generic && !it->isConfigurable()) {
+ ok = false;
+ newLen = it - values.data() + offset + 1;
+ break;
+ }
+ }
+ values.resize(newLen);
+ }
+ } else {
+ if (newLen >= 0x100000)
+ initSparse();
+ }
+ setLengthUnchecked(newLen);
+ return ok;
+}
}
}
void initSparse();
uint length() const { return len; }
- bool setLength(uint l) {
- if (lengthProperty && !lengthProperty->isWritable())
- return false;
- setLengthUnchecked(l);
- if (len >= 0x100000)
- initSparse();
- if (sparse) {
- SparseArrayNode *it = sparse->lowerBound(l);
- while (it != sparse->end()) {
- PropertyDescriptor &pd = values[it->value];
- pd.type = PropertyDescriptor::Generic;
- pd.value.tag = Value::_Undefined_Type;
- pd.value.int_32 = freeList;
- freeList = it->value;
- it = sparse->erase(it);
- }
- } else if (values.size() > (int)len){
- values.resize(len);
- }
- return true;
- }
+ bool setLength(uint newLen);
void setLengthProperty(PropertyDescriptor *pd) { lengthProperty = pd; }
PropertyDescriptor *getLengthProperty() { return lengthProperty; }
setLengthUnchecked(len - 1);
}
+ SparseArrayNode *sparseLowerBound(uint idx) { return sparse ? sparse->lowerBound(idx) : 0; }
SparseArrayNode *sparseBegin() { return sparse ? sparse->begin() : 0; }
SparseArrayNode *sparseEnd() { return sparse ? sparse->end() : 0; }
15.2.3.6-3-94 failing
15.2.3.6-4-108 failing
15.2.3.6-4-111 failing
-15.2.3.6-4-116 failing
-15.2.3.6-4-117 failing
15.2.3.6-4-163 failing
-15.2.3.6-4-168 failing
-15.2.3.6-4-169 failing
-15.2.3.6-4-170 failing
-15.2.3.6-4-172 failing
-15.2.3.6-4-173 failing
-15.2.3.6-4-174 failing
-15.2.3.6-4-176 failing
-15.2.3.6-4-177 failing
15.2.3.6-4-188 failing
15.2.3.6-4-189 failing
15.2.3.6-4-20 failing
15.4.4.20-9-c-i-6 failing
15.4.4.21-8-b-iii-1-6 failing
15.4.4.22-8-b-iii-1-6 failing
-
-15.4.4.16-7-b-16 failing
-15.4.4.17-7-b-16 failing
-15.4.4.18-7-b-16 failing
-15.4.4.19-8-b-16 failing
-15.4.4.20-9-b-16 failing
-15.4.4.21-9-b-29 failing
-15.4.4.22-9-b-16 failing
\ No newline at end of file