ArraySplice builtin should return empty array and not alter receiver if invoked with...
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 31 Jan 2011 14:54:53 +0000 (14:54 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 31 Jan 2011 14:54:53 +0000 (14:54 +0000)
Review URL: http://codereview.chromium.org/6357025

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/array.js
src/builtins.cc
test/mjsunit/array-splice.js

index 0d7a7cbc85e1f89a490d229fa759d047b3966fa6..28142bb1600327dc935b60262f60e50e3fac34e8 100644 (file)
@@ -603,16 +603,17 @@ function ArraySplice(start, delete_count) {
   }
 
   // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
-  // given differently from when an undefined delete count is given.
+  // given as a request to delete all the elements from the start.
+  // And it differs from the case of undefined delete count.
   // This does not follow ECMA-262, but we do the same for
   // compatibility.
   var del_count = 0;
-  if (num_arguments > 1) {
+  if (num_arguments == 1) {
+    del_count = len - start_i;
+  } else {
     del_count = TO_INTEGER(delete_count);
     if (del_count < 0) del_count = 0;
     if (del_count > len - start_i) del_count = len - start_i;
-  } else {
-    del_count = len - start_i;
   }
 
   var deleted_elements = [];
index 58dd439d250435055057650af19246246cc56bd4..759ef1d5ade48f8c1539731c56787db9cb90760a 100644 (file)
@@ -750,19 +750,26 @@ BUILTIN(ArraySplice) {
                                           : Min(relative_start, len);
 
   // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
-  // given differently from when an undefined delete count is given.
+  // given as a request to delete all the elements from the start.
+  // And it differs from the case of undefined delete count.
   // This does not follow ECMA-262, but we do the same for
   // compatibility.
-  int delete_count = len;
-  if (n_arguments > 1) {
-    Object* arg2 = args[2];
-    if (arg2->IsSmi()) {
-      delete_count = Smi::cast(arg2)->value();
-    } else {
-      return CallJsBuiltin("ArraySplice", args);
+  int actual_delete_count;
+  if (n_arguments == 1) {
+    ASSERT(len - actual_start >= 0);
+    actual_delete_count = len - actual_start;
+  } else {
+    int value = 0;  // ToInteger(undefined) == 0
+    if (n_arguments > 1) {
+      Object* arg2 = args[2];
+      if (arg2->IsSmi()) {
+        value = Smi::cast(arg2)->value();
+      } else {
+        return CallJsBuiltin("ArraySplice", args);
+      }
     }
+    actual_delete_count = Min(Max(value, 0), len - actual_start);
   }
-  int actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
 
   JSArray* result_array = NULL;
   if (actual_delete_count == 0) {
index 68dd9b2baff02029217610be99ac62e9c4f2463c..0e307b5d3d8a28b4055a76ec49b9d1f4ac71ecae 100644 (file)
 })();
 
 
+// Check the case of JS builtin .splice()
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var array = [1, 2, 3, 4];
+    Array.prototype[3] = 'foo';  // To force JS builtin.
+
+    var spliced = array.splice();
+
+    assertEquals([], spliced);
+    assertEquals([1, 2, 3, 4], array);
+  }
+})();
+
+
 // Check the behaviour when approaching maximal values for length.
 (function() {
   for (var i = 0; i < 7; i++) {