if (ArrayObject *instance = ctx->thisObject.asArrayObject()) {
result->copyArrayData(instance);
- } else {
+ } else if (ctx->thisObject.asStringObject()) {
QString v = ctx->thisObject.toString(ctx)->toQString();
result->arraySet(0, Value::fromString(ctx, v));
+ } else {
+ Object *instance = ctx->thisObject.asObject();
+ result->arraySet(0, ctx->thisObject);
}
for (uint i = 0; i < ctx->argumentCount; ++i) {
void Object::copyArrayData(Object *other)
{
- arrayReserve(other->arrayDataLen);
- arrayDataLen = other->arrayDataLen;
- memcpy(arrayData, other->arrayData, arrayDataLen*sizeof(Property));
+ Q_ASSERT(isArrayObject());
+
+ bool protoHasArray = false;
+ Object *p = other;
+ while ((p = p->prototype))
+ if (p->arrayDataLen)
+ protoHasArray = true;
+
+ bool arrayHasGetter = false;
+ if (!protoHasArray && other->arrayAttributes) {
+ for (uint i = 0; i < other->arrayDataLen; ++i) {
+ if (other->arrayAttributes[i].isAccessor()) {
+ const Property &pd = other->arrayData[i];
+ FunctionObject *getter = pd.getter();
+ if (getter) {
+ arrayHasGetter = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (protoHasArray || arrayHasGetter) {
+ uint len = other->arrayLength();
+ Q_ASSERT(len);
+
+ for (uint i = 0; i < len; ++i) {
+ arraySet(i, other->getIndexed(i));
+ }
+ } else {
+ arrayReserve(other->arrayDataLen);
+ arrayDataLen = other->arrayDataLen;
+ memcpy(arrayData, other->arrayData, arrayDataLen*sizeof(Property));
+ }
+
arrayOffset = 0;
+
if (other->sparseArray) {
sparseArray = new SparseArray(*other->sparseArray);
arrayFreeList = other->arrayFreeList;
}
- if (isArrayObject())
- setArrayLengthUnchecked(other->arrayLength());
+
+ setArrayLengthUnchecked(other->arrayLength());
}