Revision: 6256
Author: [email protected]
Date: Tue Jan 11 03:23:40 2011
Log: Add more bailouts for Array.slice over arguments.
Unfortunately, arguments is pretty much the normal JS object. For now
I am adding more sanity checks (in hope that typically arguments
list is rather short.) However it probably requires more systematic
treatment, for example, we could optimistically copy elements until
we meet first hole and in this case resort to JS builtin.
Review URL: http://codereview.chromium.org/6062006
http://code.google.com/p/v8/source/detail?r=6256
Modified:
/branches/bleeding_edge/src/builtins.cc
/branches/bleeding_edge/test/mjsunit/array-slice.js
=======================================
--- /branches/bleeding_edge/src/builtins.cc Wed Dec 22 07:45:48 2010
+++ /branches/bleeding_edge/src/builtins.cc Tue Jan 11 03:23:40 2011
@@ -636,15 +636,20 @@
return CallJsBuiltin("ArraySlice", args);
}
elms = FixedArray::cast(JSObject::cast(receiver)->elements());
- len = elms->length();
-#ifdef DEBUG
- // Arguments object by construction should have no holes, check it.
- if (FLAG_enable_slow_asserts) {
- for (int i = 0; i < len; i++) {
- ASSERT(elms->get(i) != Heap::the_hole_value());
+ Object* len_obj = JSObject::cast(receiver)
+ ->InObjectPropertyAt(Heap::arguments_length_index);
+ if (!len_obj->IsSmi()) {
+ return CallJsBuiltin("ArraySlice", args);
+ }
+ len = Smi::cast(len_obj)->value();
+ if (len > elms->length()) {
+ return CallJsBuiltin("ArraySlice", args);
+ }
+ for (int i = 0; i < len; i++) {
+ if (elms->get(i) == Heap::the_hole_value()) {
+ return CallJsBuiltin("ArraySlice", args);
}
}
-#endif
}
ASSERT(len >= 0);
int n_arguments = args.length() - 1;
=======================================
--- /branches/bleeding_edge/test/mjsunit/array-slice.js Mon Dec 20 06:41:41
2010
+++ /branches/bleeding_edge/test/mjsunit/array-slice.js Tue Jan 11 03:23:40
2011
@@ -231,3 +231,62 @@
func(['a', 1, undefined], 'a', 1, undefined);
func(['a', 1, undefined, void(0)], 'a', 1, undefined, void(0));
})();
+
+// Check slicing on arguments object when missing arguments get assigined.
+(function() {
+ function func(x, y) {
+ assertEquals(1, arguments.length);
+ assertEquals(undefined, y);
+ y = 239;
+ assertEquals(1, arguments.length); // arguments length is the same.
+ assertEquals([x], Array.prototype.slice.call(arguments, 0));
+ }
+
+ func('a');
+})();
+
+// Check slicing on arguments object when length property has been set.
+(function() {
+ function func(x, y) {
+ assertEquals(1, arguments.length);
+ arguments.length = 7;
+ assertEquals([x,,,,,,,], Array.prototype.slice.call(arguments, 0));
+ }
+
+ func('a');
+})();
+
+// Check slicing on arguments object when length property has been set to
+// some strange value.
+(function() {
+ function func(x, y) {
+ assertEquals(1, arguments.length);
+ arguments.length = 'foobar';
+ assertEquals([], Array.prototype.slice.call(arguments, 0));
+ }
+
+ func('a');
+})();
+
+// Check slicing on arguments object when extra argument has been added
+// via indexed assignment.
+(function() {
+ function func(x, y) {
+ assertEquals(1, arguments.length);
+ arguments[3] = 239;
+ assertEquals([x], Array.prototype.slice.call(arguments, 0));
+ }
+
+ func('a');
+})();
+
+// Check slicing on arguments object when argument has been deleted by
index.
+(function() {
+ function func(x, y, z) {
+ assertEquals(3, arguments.length);
+ delete arguments[1];
+ assertEquals([x,,z], Array.prototype.slice.call(arguments, 0));
+ }
+
+ func('a', 'b', 'c');
+})();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev