| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index a833119e853aabc9593735ecc5c7af83f72fcd5f..21381f15d5cb578e49c2594d4cfec3749e366471 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -515,10 +515,10 @@ BUILTIN(ArrayShift) {
|
| Object* elms_obj;
|
| { MaybeObject* maybe_elms_obj =
|
| EnsureJSArrayWithWritableFastElements(receiver);
|
| + if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayShift", args);
|
| if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
|
| }
|
| - if (elms_obj == NULL ||
|
| - !IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| + if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| return CallJsBuiltin("ArrayShift", args);
|
| }
|
| FixedArray* elms = FixedArray::cast(elms_obj);
|
| @@ -557,10 +557,10 @@ BUILTIN(ArrayUnshift) {
|
| Object* elms_obj;
|
| { MaybeObject* maybe_elms_obj =
|
| EnsureJSArrayWithWritableFastElements(receiver);
|
| + if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayUnshift", args);
|
| if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
|
| }
|
| - if (elms_obj == NULL ||
|
| - !IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| + if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| return CallJsBuiltin("ArrayUnshift", args);
|
| }
|
| FixedArray* elms = FixedArray::cast(elms_obj);
|
| @@ -611,21 +611,46 @@ BUILTIN(ArrayUnshift) {
|
|
|
| BUILTIN(ArraySlice) {
|
| Object* receiver = *args.receiver();
|
| - Object* elms_obj;
|
| + FixedArray* elms;
|
| + int len = -1;
|
| { MaybeObject* maybe_elms_obj =
|
| EnsureJSArrayWithWritableFastElements(receiver);
|
| - if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
|
| - }
|
| - if (elms_obj == NULL ||
|
| - !IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| - return CallJsBuiltin("ArraySlice", args);
|
| - }
|
| - FixedArray* elms = FixedArray::cast(elms_obj);
|
| - JSArray* array = JSArray::cast(receiver);
|
| - ASSERT(array->HasFastElements());
|
| -
|
| - int len = Smi::cast(array->length())->value();
|
| + Object* elms_obj;
|
| + if (maybe_elms_obj != NULL && maybe_elms_obj->ToObject(&elms_obj)) {
|
| + if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| + return CallJsBuiltin("ArraySlice", args);
|
| + }
|
| + elms = FixedArray::cast(elms_obj);
|
| + JSArray* array = JSArray::cast(receiver);
|
| + ASSERT(array->HasFastElements());
|
|
|
| + len = Smi::cast(array->length())->value();
|
| + } else {
|
| + // Array.slice(arguments, ...) is quite a common idiom (notably more
|
| + // than 50% of invocations in Web apps). Treat it in C++ as well.
|
| + Map* arguments_map =
|
| + Top::context()->global_context()->arguments_boilerplate()->map();
|
| +
|
| + bool is_arguments_object_with_fast_elements =
|
| + receiver->IsJSObject()
|
| + && JSObject::cast(receiver)->map() == arguments_map
|
| + && JSObject::cast(receiver)->HasFastElements();
|
| + if (!is_arguments_object_with_fast_elements) {
|
| + 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());
|
| + }
|
| + }
|
| +#endif
|
| + }
|
| + }
|
| + ASSERT(len >= 0);
|
| int n_arguments = args.length() - 1;
|
|
|
| // Note carefully choosen defaults---if argument is missing,
|
| @@ -693,10 +718,10 @@ BUILTIN(ArraySplice) {
|
| Object* elms_obj;
|
| { MaybeObject* maybe_elms_obj =
|
| EnsureJSArrayWithWritableFastElements(receiver);
|
| + if (maybe_elms_obj == NULL) return CallJsBuiltin("ArraySplice", args);
|
| if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
|
| }
|
| - if (elms_obj == NULL ||
|
| - !IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| + if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
| return CallJsBuiltin("ArraySplice", args);
|
| }
|
| FixedArray* elms = FixedArray::cast(elms_obj);
|
|
|