From a3466441219e9747d1312639a4a798eacb76abf7 Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Wed, 17 Feb 2010 13:04:30 +0000 Subject: [PATCH] Adding checks for the cases when array grows too big. Review URL: http://codereview.chromium.org/601092 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3887 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/builtins.cc | 11 +++++++++++ test/mjsunit/array-splice.js | 19 +++++++++++++++++++ test/mjsunit/array-unshift.js | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/builtins.cc b/src/builtins.cc index 7ded532..ee98769 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -251,6 +251,9 @@ BUILTIN(ArrayPush) { if (to_add == 0) { return Smi::FromInt(len); } + // Currently fixed arrays cannot grow too big, so + // we should never hit this case. + ASSERT(to_add <= (Smi::kMaxValue - len)); int new_length = len + to_add; FixedArray* elms = FixedArray::cast(array->elements()); @@ -370,6 +373,10 @@ BUILTIN(ArrayUnshift) { // the array. int new_length = len + to_add; + // Currently fixed arrays cannot grow too big, so + // we should never hit this case. + ASSERT(to_add <= (Smi::kMaxValue - len)); + FixedArray* elms = FixedArray::cast(array->elements()); // Fetch the prototype. @@ -614,6 +621,10 @@ BUILTIN(ArraySplice) { elms->set(k - 1, Heap::the_hole_value()); } } else if (itemCount > actualDeleteCount) { + // Currently fixed arrays cannot grow too big, so + // we should never hit this case. + ASSERT((itemCount - actualDeleteCount) <= (Smi::kMaxValue - len)); + FixedArray* source_elms = elms; // Check if array need to grow. diff --git a/test/mjsunit/array-splice.js b/test/mjsunit/array-splice.js index 2eaf6f0..18f81fe 100644 --- a/test/mjsunit/array-splice.js +++ b/test/mjsunit/array-splice.js @@ -268,3 +268,22 @@ assertFalse(array.hasOwnProperty(2 << 32 - 1)); } })(); + + +// Check the behaviour when approaching maximal values for length. +(function() { + for (var i = 0; i < 7; i++) { + try { + new Array((1 << 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5); + throw 'Should have thrown RangeError'; + } catch (e) { + assertTrue(e instanceof RangeError); + } + + // Check smi boundary + var bigNum = (1 << 30) - 3; + var array = new Array(bigNum); + array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7); + assertEquals(bigNum + 7, array.length); + } +})(); diff --git a/test/mjsunit/array-unshift.js b/test/mjsunit/array-unshift.js index 8b35796..06a78a7 100644 --- a/test/mjsunit/array-unshift.js +++ b/test/mjsunit/array-unshift.js @@ -114,3 +114,19 @@ assertTrue(delete Array.prototype[5]); assertTrue(delete Array.prototype[7]); })(); + +// Check the behaviour when approaching maximal values for length. +(function() { + for (var i = 0; i < 7; i++) { + try { + new Array((1 << 32) - 3).unshift(1, 2, 3, 4, 5); + throw 'Should have thrown RangeError'; + } catch (e) { + assertTrue(e instanceof RangeError); + } + + // Check smi boundary + var bigNum = (1 << 30) - 3; + assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7)); + } +})(); -- 2.7.4