Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1232)

Side by Side Diff: src/builtins.cc

Issue 772533003: Support strict and aliased arguments in Array.prototype.slice Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/elements.cc » ('j') | src/elements.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/base/once.h" 9 #include "src/base/once.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 567
568 if (!array->HasFastElements()) { 568 if (!array->HasFastElements()) {
569 AllowHeapAllocation allow_allocation; 569 AllowHeapAllocation allow_allocation;
570 return CallJsBuiltin(isolate, "ArraySlice", args); 570 return CallJsBuiltin(isolate, "ArraySlice", args);
571 } 571 }
572 572
573 len = Smi::cast(array->length())->value(); 573 len = Smi::cast(array->length())->value();
574 } else { 574 } else {
575 // Array.slice(arguments, ...) is quite a common idiom (notably more 575 // Array.slice(arguments, ...) is quite a common idiom (notably more
576 // than 50% of invocations in Web apps). Treat it in C++ as well. 576 // than 50% of invocations in Web apps). Treat it in C++ as well.
577 Map* arguments_map = 577 Map* sloppy_arguments_map =
578 isolate->context()->native_context()->sloppy_arguments_map(); 578 isolate->context()->native_context()->sloppy_arguments_map();
579 Map* strict_arguments_map =
580 isolate->context()->native_context()->strict_arguments_map();
581 Map* aliased_arguments_map =
582 isolate->context()->native_context()->aliased_arguments_map();
579 583
580 bool is_arguments_object_with_fast_elements = 584 bool is_arguments_object_with_fast_elements =
581 receiver->IsJSObject() && 585 receiver->IsJSObject() &&
582 JSObject::cast(*receiver)->map() == arguments_map; 586 (JSObject::cast(*receiver)->map() == sloppy_arguments_map ||
587 JSObject::cast(*receiver)->map() == strict_arguments_map ||
588 JSObject::cast(*receiver)->map() == aliased_arguments_map);
583 if (!is_arguments_object_with_fast_elements) { 589 if (!is_arguments_object_with_fast_elements) {
584 AllowHeapAllocation allow_allocation; 590 AllowHeapAllocation allow_allocation;
585 return CallJsBuiltin(isolate, "ArraySlice", args); 591 return CallJsBuiltin(isolate, "ArraySlice", args);
586 } 592 }
587 JSObject* object = JSObject::cast(*receiver); 593 JSObject* object = JSObject::cast(*receiver);
588 594
589 if (!object->HasFastElements()) { 595 if (!object->HasFastElements() && !object->HasSloppyArgumentsElements()) {
590 AllowHeapAllocation allow_allocation; 596 AllowHeapAllocation allow_allocation;
591 return CallJsBuiltin(isolate, "ArraySlice", args); 597 return CallJsBuiltin(isolate, "ArraySlice", args);
592 } 598 }
593 599
594 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); 600 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
595 if (!len_obj->IsSmi()) { 601 if (!len_obj->IsSmi()) {
596 AllowHeapAllocation allow_allocation; 602 AllowHeapAllocation allow_allocation;
597 return CallJsBuiltin(isolate, "ArraySlice", args); 603 return CallJsBuiltin(isolate, "ArraySlice", args);
598 } 604 }
599 len = Smi::cast(len_obj)->value(); 605 len = Smi::cast(len_obj)->value();
600 if (len > object->elements()->length()) { 606 if (object->map() == sloppy_arguments_map &&
Igor Sheludko 2015/01/30 14:13:29 Ok, elements of the |aliased_arguments_map| is a s
607 len > object->elements()->length()) {
601 AllowHeapAllocation allow_allocation; 608 AllowHeapAllocation allow_allocation;
602 return CallJsBuiltin(isolate, "ArraySlice", args); 609 return CallJsBuiltin(isolate, "ArraySlice", args);
603 } 610 }
604 } 611 }
605 612
606 DCHECK(len >= 0); 613 DCHECK(len >= 0);
607 int n_arguments = args.length() - 1; 614 int n_arguments = args.length() - 1;
608 615
609 // Note carefully choosen defaults---if argument is missing, 616 // Note carefully choosen defaults---if argument is missing,
610 // it's undefined which gets converted to 0 for relative_start 617 // it's undefined which gets converted to 0 for relative_start
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 int final = (relative_end < 0) ? Max(len + relative_end, 0) 660 int final = (relative_end < 0) ? Max(len + relative_end, 0)
654 : Min(relative_end, len); 661 : Min(relative_end, len);
655 662
656 // Calculate the length of result array. 663 // Calculate the length of result array.
657 int result_len = Max(final - k, 0); 664 int result_len = Max(final - k, 0);
658 665
659 Handle<JSObject> object = Handle<JSObject>::cast(receiver); 666 Handle<JSObject> object = Handle<JSObject>::cast(receiver);
660 Handle<FixedArrayBase> elms(object->elements(), isolate); 667 Handle<FixedArrayBase> elms(object->elements(), isolate);
661 668
662 ElementsKind kind = object->GetElementsKind(); 669 ElementsKind kind = object->GetElementsKind();
670 if (kind == SLOPPY_ARGUMENTS_ELEMENTS) {
671 Handle<FixedArray> arguments(
672 FixedArray::cast(FixedArray::cast(*elms)->get(1)));
673 if (arguments->IsDictionary()) {
674 AllowHeapAllocation allow_allocation;
675 return CallJsBuiltin(isolate, "ArraySlice", args);
676 }
677 kind = FAST_HOLEY_ELEMENTS;
678 }
679
663 if (IsHoleyElementsKind(kind)) { 680 if (IsHoleyElementsKind(kind)) {
664 DisallowHeapAllocation no_gc; 681 DisallowHeapAllocation no_gc;
665 bool packed = true; 682 bool packed = true;
666 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind); 683 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
667 for (int i = k; i < final; i++) { 684 for (int i = k; i < final; i++) {
668 if (!accessor->HasElement(object, object, i, elms)) { 685 if (!accessor->HasElement(object, object, i, elms)) {
669 packed = false; 686 packed = false;
670 break; 687 break;
671 } 688 }
672 } 689 }
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 } 1661 }
1645 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1662 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1646 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1663 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1647 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1664 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1648 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1665 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1649 #undef DEFINE_BUILTIN_ACCESSOR_C 1666 #undef DEFINE_BUILTIN_ACCESSOR_C
1650 #undef DEFINE_BUILTIN_ACCESSOR_A 1667 #undef DEFINE_BUILTIN_ACCESSOR_A
1651 1668
1652 1669
1653 } } // namespace v8::internal 1670 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/elements.cc » ('j') | src/elements.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698