Reviewers: ulan,
Description:
Fix ElementsKind handling of prototypes in Array.concat
Double elements, typed elements, and sloppy arguments elements were all
erroneously marked UNREACHABLE.
BUG=chromium:412203
LOG=n
Please review this at https://codereview.chromium.org/560463002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+62, -19 lines):
M src/runtime.cc
A test/mjsunit/regress/regress-crbug-412203.js
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
ce2d51c82a77cc9c2f37bad70764bdadb0aa7b21..e559f94fb8f732b2074e4a5c8bf09c1953ca01c4
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -10282,8 +10282,19 @@ static void CollectElementIndices(Handle<JSObject>
object,
}
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS: {
- // TODO(1810): Decide if it's worthwhile to implement this.
- UNREACHABLE();
+ if (object->elements()->IsFixedArray()) {
+ DCHECK(object->elements()->length() == 0);
+ break;
+ }
+ Handle<FixedDoubleArray> elements(
+ FixedDoubleArray::cast(object->elements()));
+ uint32_t length = static_cast<uint32_t>(elements->length());
+ if (range < length) length = range;
+ for (uint32_t i = 0; i < length; i++) {
+ if (!elements->is_the_hole(i)) {
+ indices->Add(i);
+ }
+ }
break;
}
case DICTIONARY_ELEMENTS: {
@@ -10303,25 +10314,15 @@ static void
CollectElementIndices(Handle<JSObject> object,
}
break;
}
- default: {
- int dense_elements_length;
- switch (kind) {
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype,
size) \
- case EXTERNAL_##TYPE##_ELEMENTS:
{ \
- dense_elements_length
= \
-
External##Type##Array::cast(object->elements())->length(); \
-
break; \
- }
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ case EXTERNAL_##TYPE##_ELEMENTS:
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
-
- default:
- UNREACHABLE();
- dense_elements_length = 0;
- break;
- }
- uint32_t length = static_cast<uint32_t>(dense_elements_length);
+ {
+ uint32_t length = static_cast<uint32_t>(
+ FixedArrayBase::cast(object->elements())->length());
if (range <= length) {
length = range;
// We will add all indices, so we might as well clear it first
@@ -10334,6 +10335,17 @@ static void CollectElementIndices(Handle<JSObject>
object,
if (length == range) return; // All indices accounted for already.
break;
}
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
+ uint32_t length = static_cast<uint32_t>(
+ Handle<JSArray>::cast(object)->length()->Number());
+ ElementsAccessor* accessor = object->GetElementsAccessor();
+ for (uint32_t i = 0; i < length; i++) {
+ if (accessor->HasElement(object, object, i)) {
+ indices->Add(i);
+ }
+ }
+ break;
+ }
}
PrototypeIterator iter(isolate, object);
Index: test/mjsunit/regress/regress-crbug-412203.js
diff --git a/test/mjsunit/regress/regress-crbug-412203.js
b/test/mjsunit/regress/regress-crbug-412203.js
new file mode 100644
index
0000000000000000000000000000000000000000..6a781308f75b2932ffb606f754f65911228728b9
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-412203.js
@@ -0,0 +1,31 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var b = [];
+b[10000] = 1;
+// Required to reproduce the bug.
+assertTrue(%HasDictionaryElements(b));
+
+var a1 = [1.5];
+b.__proto__ = a1;
+assertEquals(1.5, ([].concat(b))[0]);
+
+var a2 = new Int32Array(2);
+a2[0] = 3;
+b.__proto__ = a2
+assertEquals(3, ([].concat(b))[0]);
+
+function foo(x, y) {
+ var a = [];
+ a[10000] = 1;
+ assertTrue(%HasDictionaryElements(a));
+
+ a.__proto__ = arguments;
+ var c = [].concat(a);
+ assertEquals(2, c[0]);
+ assertEquals(undefined, c[1]);
+}
+foo(2);
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.