Current custom call generators cannot cope with the case when receiver is not a JSArray.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Apr 2010 15:08:07 +0000 (15:08 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Apr 2010 15:08:07 +0000 (15:08 +0000)
Add a support for bailout from custom call generators (just return undefined).

BUG=684

Review URL: http://codereview.chromium.org/1699005

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

src/ia32/stub-cache-ia32.cc
test/mjsunit/array-pop.js
test/mjsunit/array-push.js

index 11c4ac7..eba4e1f 100644 (file)
@@ -1241,6 +1241,11 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
   // -----------------------------------
   ASSERT(check == RECEIVER_MAP_CHECK);
 
+  // If object is not an array, bail out to regular call.
+  if (!object->IsJSArray()) {
+    return Heap::undefined_value();
+  }
+
   Label miss;
 
   // Get the receiver from the stack.
@@ -1389,6 +1394,11 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object,
   // -----------------------------------
   ASSERT(check == RECEIVER_MAP_CHECK);
 
+  // If object is not an array, bail out to regular call.
+  if (!object->IsJSArray()) {
+    return Heap::undefined_value();
+  }
+
   Label miss, empty_array, call_builtin;
 
   // Get the receiver from the stack.
@@ -1476,7 +1486,11 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
   if (function_info->HasCustomCallGenerator()) {
     CustomCallGenerator generator =
         ToCData<CustomCallGenerator>(function_info->function_data());
-    return generator(this, object, holder, function, name, check);
+    Object* result = generator(this, object, holder, function, name, check);
+    // undefined means bail out to regular compiler.
+    if (!result->IsUndefined()) {
+      return result;
+    }
   }
 
   Label miss_in_smi_check;
index 4edd026..9608cd4 100644 (file)
     assertEquals(0, a.length, "length 9th pop");
   }
 })();
+
+// Test the case of not JSArray receiver.
+// Regression test for custom call generators, see issue 684.
+(function() {
+  var a = [];
+  for (var i = 0; i < 100; i++) a.push(i);
+  var x = {__proto__: a};
+  for (var i = 0; i < 100; i++) {
+    assertEquals(99 - i, x.pop(), i + 'th iteration');
+  }
+})();
index baccf00..2a25a9c 100644 (file)
     assertEquals(29, a.push(29));
   }
 })();
+
+// Test the case of not JSArray receiver.
+// Regression test for custom call generators, see issue 684.
+(function() {
+  var x = {__proto__: []};
+  for (var i = 0; i < 100; i++) {
+    x.push("a");
+    assertEquals(i + 1, x.length, i + 'th iteration');
+  }
+})();