Index: src/runtime.cc |
=================================================================== |
--- src/runtime.cc (revision 627) |
+++ src/runtime.cc (working copy) |
@@ -3994,15 +3994,22 @@ |
* of FixedArray, the class can be used by both fast and slow cases. |
* The second parameter of the constructor, fast_elements, specifies |
* whether the storage is a FixedArray or Dictionary. |
+ * |
+ * An index limit is used to deal with the situation that a result array |
+ * length overflows 32-bit non-negative integer. |
*/ |
class ArrayConcatVisitor { |
public: |
- ArrayConcatVisitor(Handle<FixedArray> storage, bool fast_elements) |
- : storage_(storage), fast_elements_(fast_elements), index_offset_(0) { } |
+ ArrayConcatVisitor(Handle<FixedArray> storage, |
+ uint32_t index_limit, |
+ bool fast_elements) : |
+ storage_(storage), index_limit_(index_limit), |
+ fast_elements_(fast_elements), index_offset_(0) { } |
void visit(uint32_t i, Handle<Object> elm) { |
uint32_t index = i + index_offset_; |
- |
+ if (index >= index_limit_) return; |
+ |
if (fast_elements_) { |
ASSERT(index < static_cast<uint32_t>(storage_->length())); |
storage_->set(index, *elm); |
@@ -4022,6 +4029,7 @@ |
private: |
Handle<FixedArray> storage_; |
+ uint32_t index_limit_; |
bool fast_elements_; |
uint32_t index_offset_; |
}; |
@@ -4126,6 +4134,10 @@ |
* If an argument is an Array object, the function visits array elements. |
* If an argument is not an Array object, the function visits the object |
* as if it is an one-element array. |
+ * |
+ * If the result array index overflows 32-bit integer, the rounded non-negative |
+ * number is used as new length. For example, if one array length is 2^32 - 1, |
+ * second array length is 1, the concatenated array length is 0. |
*/ |
static uint32_t IterateArguments(Handle<JSArray> arguments, |
ArrayConcatVisitor* visitor) { |
@@ -4207,7 +4219,7 @@ |
Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); |
- ArrayConcatVisitor visitor(storage, fast_case); |
+ ArrayConcatVisitor visitor(storage, result_length, fast_case); |
IterateArguments(arguments, &visitor); |