| OLD | NEW |
| 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/builtins.h" | 5 #include "src/builtins.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/api-natives.h" | 9 #include "src/api-natives.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 BUILTIN(ArraySlice) { | 651 BUILTIN(ArraySlice) { |
| 652 HandleScope scope(isolate); | 652 HandleScope scope(isolate); |
| 653 Handle<Object> receiver = args.receiver(); | 653 Handle<Object> receiver = args.receiver(); |
| 654 int len = -1; | 654 int len = -1; |
| 655 int relative_start = 0; | 655 int relative_start = 0; |
| 656 int relative_end = 0; | 656 int relative_end = 0; |
| 657 | 657 |
| 658 if (receiver->IsJSArray()) { | 658 if (receiver->IsJSArray()) { |
| 659 DisallowHeapAllocation no_gc; | 659 DisallowHeapAllocation no_gc; |
| 660 JSArray* array = JSArray::cast(*receiver); | 660 JSArray* array = JSArray::cast(*receiver); |
| 661 if (!array->HasFastElements() || | 661 if (V8_UNLIKELY(!array->HasFastElements() || |
| 662 !IsJSArrayFastElementMovingAllowed(isolate, array) || | 662 !IsJSArrayFastElementMovingAllowed(isolate, array) || |
| 663 !isolate->IsArraySpeciesLookupChainIntact() || | 663 !isolate->IsArraySpeciesLookupChainIntact() || |
| 664 // If this is a subclass of Array, then call out to JS | 664 // If this is a subclass of Array, then call out to JS |
| 665 !array->HasArrayPrototype(isolate)) { | 665 !array->HasArrayPrototype(isolate))) { |
| 666 AllowHeapAllocation allow_allocation; | 666 AllowHeapAllocation allow_allocation; |
| 667 return CallJsIntrinsic(isolate, isolate->array_slice(), args); | 667 return CallJsIntrinsic(isolate, isolate->array_slice(), args); |
| 668 } | 668 } |
| 669 len = Smi::cast(array->length())->value(); | 669 len = Smi::cast(array->length())->value(); |
| 670 } else if (receiver->IsJSObject() && | 670 } else if (receiver->IsJSObject() && |
| 671 GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver), | 671 GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver), |
| 672 &len)) { | 672 &len)) { |
| 673 DCHECK_EQ(FAST_ELEMENTS, JSObject::cast(*receiver)->GetElementsKind()); | 673 DCHECK_EQ(FAST_ELEMENTS, JSObject::cast(*receiver)->GetElementsKind()); |
| 674 // Array.prototype.slice(arguments, ...) is quite a common idiom | 674 // Array.prototype.slice(arguments, ...) is quite a common idiom |
| 675 // (notably more than 50% of invocations in Web apps). | 675 // (notably more than 50% of invocations in Web apps). |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 | 713 |
| 714 Handle<JSObject> object = Handle<JSObject>::cast(receiver); | 714 Handle<JSObject> object = Handle<JSObject>::cast(receiver); |
| 715 ElementsAccessor* accessor = object->GetElementsAccessor(); | 715 ElementsAccessor* accessor = object->GetElementsAccessor(); |
| 716 return *accessor->Slice(object, actual_start, actual_end); | 716 return *accessor->Slice(object, actual_start, actual_end); |
| 717 } | 717 } |
| 718 | 718 |
| 719 | 719 |
| 720 BUILTIN(ArraySplice) { | 720 BUILTIN(ArraySplice) { |
| 721 HandleScope scope(isolate); | 721 HandleScope scope(isolate); |
| 722 Handle<Object> receiver = args.receiver(); | 722 Handle<Object> receiver = args.receiver(); |
| 723 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) || | 723 if (V8_UNLIKELY( |
| 724 // If this is a subclass of Array, then call out to JS. | 724 !EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) || |
| 725 !Handle<JSArray>::cast(receiver)->HasArrayPrototype(isolate) || | 725 // If this is a subclass of Array, then call out to JS. |
| 726 // If anything with @@species has been messed with, call out to JS. | 726 !Handle<JSArray>::cast(receiver)->HasArrayPrototype(isolate) || |
| 727 !isolate->IsArraySpeciesLookupChainIntact()) { | 727 // If anything with @@species has been messed with, call out to JS. |
| 728 !isolate->IsArraySpeciesLookupChainIntact())) { |
| 728 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 729 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
| 729 } | 730 } |
| 730 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 731 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 731 DCHECK(!array->map()->is_observed()); | 732 DCHECK(!array->map()->is_observed()); |
| 732 | 733 |
| 733 int argument_count = args.length() - 1; | 734 int argument_count = args.length() - 1; |
| 734 int relative_start = 0; | 735 int relative_start = 0; |
| 735 if (argument_count > 0) { | 736 if (argument_count > 0) { |
| 736 DisallowHeapAllocation no_gc; | 737 DisallowHeapAllocation no_gc; |
| 737 if (!ClampedToInteger(args[1], &relative_start)) { | 738 if (!ClampedToInteger(args[1], &relative_start)) { |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, | 1585 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, |
| 1585 isolate->factory()->NewStringFromAsciiChecked( | 1586 isolate->factory()->NewStringFromAsciiChecked( |
| 1586 "Array.prototype.concat"))); | 1587 "Array.prototype.concat"))); |
| 1587 } | 1588 } |
| 1588 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1589 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1589 isolate, receiver, Object::ToObject(isolate, args.receiver())); | 1590 isolate, receiver, Object::ToObject(isolate, args.receiver())); |
| 1590 args[0] = *receiver; | 1591 args[0] = *receiver; |
| 1591 | 1592 |
| 1592 Handle<JSArray> result_array; | 1593 Handle<JSArray> result_array; |
| 1593 | 1594 |
| 1595 // Avoid a real species read to avoid extra lookups to the array constructor |
| 1596 if (V8_LIKELY(receiver->IsJSArray() && |
| 1597 Handle<JSArray>::cast(receiver)->HasArrayPrototype(isolate) && |
| 1598 isolate->IsArraySpeciesLookupChainIntact())) { |
| 1599 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { |
| 1600 return *result_array; |
| 1601 } |
| 1602 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
| 1603 } |
| 1594 // Reading @@species happens before anything else with a side effect, so | 1604 // Reading @@species happens before anything else with a side effect, so |
| 1595 // we can do it here to determine whether to take the fast path. | 1605 // we can do it here to determine whether to take the fast path. |
| 1596 Handle<Object> species; | 1606 Handle<Object> species; |
| 1597 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1607 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1598 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); | 1608 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); |
| 1599 if (*species == isolate->context()->native_context()->array_function()) { | 1609 if (*species == *isolate->array_function()) { |
| 1600 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { | 1610 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { |
| 1601 return *result_array; | 1611 return *result_array; |
| 1602 } | 1612 } |
| 1603 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 1613 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
| 1604 } | 1614 } |
| 1605 return Slow_ArrayConcat(&args, species, isolate); | 1615 return Slow_ArrayConcat(&args, species, isolate); |
| 1606 } | 1616 } |
| 1607 | 1617 |
| 1608 | 1618 |
| 1609 // ES6 22.1.2.2 Array.isArray | 1619 // ES6 22.1.2.2 Array.isArray |
| (...skipping 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4858 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 4868 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
| 4859 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4869 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 4860 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4870 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 4861 #undef DEFINE_BUILTIN_ACCESSOR_C | 4871 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 4862 #undef DEFINE_BUILTIN_ACCESSOR_A | 4872 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 4863 #undef DEFINE_BUILTIN_ACCESSOR_T | 4873 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 4864 #undef DEFINE_BUILTIN_ACCESSOR_H | 4874 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 4865 | 4875 |
| 4866 } // namespace internal | 4876 } // namespace internal |
| 4867 } // namespace v8 | 4877 } // namespace v8 |
| OLD | NEW |