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 |