| 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-arguments.h" | 7 #include "src/api-arguments.h" |
| 8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 // Returns |false| if not applicable. | 270 // Returns |false| if not applicable. |
| 271 MUST_USE_RESULT | 271 MUST_USE_RESULT |
| 272 inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate, | 272 inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate, |
| 273 Handle<Object> receiver, | 273 Handle<Object> receiver, |
| 274 Arguments* args, | 274 Arguments* args, |
| 275 int first_added_arg) { | 275 int first_added_arg) { |
| 276 if (!receiver->IsJSArray()) return false; | 276 if (!receiver->IsJSArray()) return false; |
| 277 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 277 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 278 ElementsKind origin_kind = array->GetElementsKind(); | 278 ElementsKind origin_kind = array->GetElementsKind(); |
| 279 if (IsDictionaryElementsKind(origin_kind)) return false; | 279 if (IsDictionaryElementsKind(origin_kind)) return false; |
| 280 if (array->map()->is_observed()) return false; | |
| 281 if (!array->map()->is_extensible()) return false; | 280 if (!array->map()->is_extensible()) return false; |
| 282 if (args == nullptr) return true; | 281 if (args == nullptr) return true; |
| 283 | 282 |
| 284 // If there may be elements accessors in the prototype chain, the fast path | 283 // If there may be elements accessors in the prototype chain, the fast path |
| 285 // cannot be used if there arguments to add to the array. | 284 // cannot be used if there arguments to add to the array. |
| 286 if (!IsJSArrayFastElementMovingAllowed(isolate, *array)) return false; | 285 if (!IsJSArrayFastElementMovingAllowed(isolate, *array)) return false; |
| 287 | 286 |
| 288 // Adding elements to the array prototype would break code that makes sure | 287 // Adding elements to the array prototype would break code that makes sure |
| 289 // it has no elements. Handle that elsewhere. | 288 // it has no elements. Handle that elsewhere. |
| 290 if (isolate->IsAnyInitialArrayPrototype(array)) return false; | 289 if (isolate->IsAnyInitialArrayPrototype(array)) return false; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 } | 576 } |
| 578 | 577 |
| 579 BUILTIN(ArrayPop) { | 578 BUILTIN(ArrayPop) { |
| 580 HandleScope scope(isolate); | 579 HandleScope scope(isolate); |
| 581 Handle<Object> receiver = args.receiver(); | 580 Handle<Object> receiver = args.receiver(); |
| 582 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { | 581 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { |
| 583 return CallJsIntrinsic(isolate, isolate->array_pop(), args); | 582 return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
| 584 } | 583 } |
| 585 | 584 |
| 586 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 585 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 587 DCHECK(!array->map()->is_observed()); | |
| 588 | 586 |
| 589 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value()); | 587 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value()); |
| 590 if (len == 0) return isolate->heap()->undefined_value(); | 588 if (len == 0) return isolate->heap()->undefined_value(); |
| 591 | 589 |
| 592 if (JSArray::HasReadOnlyLength(array)) { | 590 if (JSArray::HasReadOnlyLength(array)) { |
| 593 return CallJsIntrinsic(isolate, isolate->array_pop(), args); | 591 return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
| 594 } | 592 } |
| 595 | 593 |
| 596 Handle<Object> result; | 594 Handle<Object> result; |
| 597 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { | 595 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 610 | 608 |
| 611 BUILTIN(ArrayShift) { | 609 BUILTIN(ArrayShift) { |
| 612 HandleScope scope(isolate); | 610 HandleScope scope(isolate); |
| 613 Heap* heap = isolate->heap(); | 611 Heap* heap = isolate->heap(); |
| 614 Handle<Object> receiver = args.receiver(); | 612 Handle<Object> receiver = args.receiver(); |
| 615 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0) || | 613 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0) || |
| 616 !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { | 614 !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
| 617 return CallJsIntrinsic(isolate, isolate->array_shift(), args); | 615 return CallJsIntrinsic(isolate, isolate->array_shift(), args); |
| 618 } | 616 } |
| 619 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 617 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 620 DCHECK(!array->map()->is_observed()); | |
| 621 | 618 |
| 622 int len = Smi::cast(array->length())->value(); | 619 int len = Smi::cast(array->length())->value(); |
| 623 if (len == 0) return heap->undefined_value(); | 620 if (len == 0) return heap->undefined_value(); |
| 624 | 621 |
| 625 if (JSArray::HasReadOnlyLength(array)) { | 622 if (JSArray::HasReadOnlyLength(array)) { |
| 626 return CallJsIntrinsic(isolate, isolate->array_shift(), args); | 623 return CallJsIntrinsic(isolate, isolate->array_shift(), args); |
| 627 } | 624 } |
| 628 | 625 |
| 629 Handle<Object> first = array->GetElementsAccessor()->Shift(array); | 626 Handle<Object> first = array->GetElementsAccessor()->Shift(array); |
| 630 return *first; | 627 return *first; |
| 631 } | 628 } |
| 632 | 629 |
| 633 | 630 |
| 634 BUILTIN(ArrayUnshift) { | 631 BUILTIN(ArrayUnshift) { |
| 635 HandleScope scope(isolate); | 632 HandleScope scope(isolate); |
| 636 Handle<Object> receiver = args.receiver(); | 633 Handle<Object> receiver = args.receiver(); |
| 637 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { | 634 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { |
| 638 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); | 635 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); |
| 639 } | 636 } |
| 640 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 637 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 641 DCHECK(!array->map()->is_observed()); | |
| 642 int to_add = args.length() - 1; | 638 int to_add = args.length() - 1; |
| 643 if (to_add == 0) return array->length(); | 639 if (to_add == 0) return array->length(); |
| 644 | 640 |
| 645 // Currently fixed arrays cannot grow too big, so we should never hit this. | 641 // Currently fixed arrays cannot grow too big, so we should never hit this. |
| 646 DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value()); | 642 DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value()); |
| 647 | 643 |
| 648 if (JSArray::HasReadOnlyLength(array)) { | 644 if (JSArray::HasReadOnlyLength(array)) { |
| 649 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); | 645 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); |
| 650 } | 646 } |
| 651 | 647 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 HandleScope scope(isolate); | 725 HandleScope scope(isolate); |
| 730 Handle<Object> receiver = args.receiver(); | 726 Handle<Object> receiver = args.receiver(); |
| 731 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) || | 727 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) || |
| 732 // If this is a subclass of Array, then call out to JS. | 728 // If this is a subclass of Array, then call out to JS. |
| 733 !JSArray::cast(*receiver)->map()->new_target_is_base() || | 729 !JSArray::cast(*receiver)->map()->new_target_is_base() || |
| 734 // If anything with @@species has been messed with, call out to JS. | 730 // If anything with @@species has been messed with, call out to JS. |
| 735 !isolate->IsArraySpeciesLookupChainIntact()) { | 731 !isolate->IsArraySpeciesLookupChainIntact()) { |
| 736 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 732 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
| 737 } | 733 } |
| 738 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 734 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 739 DCHECK(!array->map()->is_observed()); | |
| 740 | 735 |
| 741 int argument_count = args.length() - 1; | 736 int argument_count = args.length() - 1; |
| 742 int relative_start = 0; | 737 int relative_start = 0; |
| 743 if (argument_count > 0) { | 738 if (argument_count > 0) { |
| 744 DisallowHeapAllocation no_gc; | 739 DisallowHeapAllocation no_gc; |
| 745 if (!ClampedToInteger(args[1], &relative_start)) { | 740 if (!ClampedToInteger(args[1], &relative_start)) { |
| 746 AllowHeapAllocation allow_allocation; | 741 AllowHeapAllocation allow_allocation; |
| 747 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 742 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
| 748 } | 743 } |
| 749 } | 744 } |
| (...skipping 4601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5351 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5346 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
| 5352 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5347 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 5353 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5348 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 5354 #undef DEFINE_BUILTIN_ACCESSOR_C | 5349 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 5355 #undef DEFINE_BUILTIN_ACCESSOR_A | 5350 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 5356 #undef DEFINE_BUILTIN_ACCESSOR_T | 5351 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 5357 #undef DEFINE_BUILTIN_ACCESSOR_H | 5352 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 5358 | 5353 |
| 5359 } // namespace internal | 5354 } // namespace internal |
| 5360 } // namespace v8 | 5355 } // namespace v8 |
| OLD | NEW |