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 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
699 storage_(isolate->global_handles()->Create(*storage)), | 699 storage_(isolate->global_handles()->Create(*storage)), |
700 index_offset_(0u), | 700 index_offset_(0u), |
701 bit_field_(FastElementsField::encode(fast_elements) | | 701 bit_field_(FastElementsField::encode(fast_elements) | |
702 ExceedsLimitField::encode(false) | | 702 ExceedsLimitField::encode(false) | |
703 IsFixedArrayField::encode(storage->IsFixedArray())) { | 703 IsFixedArrayField::encode(storage->IsFixedArray())) { |
704 DCHECK(!(this->fast_elements() && !is_fixed_array())); | 704 DCHECK(!(this->fast_elements() && !is_fixed_array())); |
705 } | 705 } |
706 | 706 |
707 ~ArrayConcatVisitor() { clear_storage(); } | 707 ~ArrayConcatVisitor() { clear_storage(); } |
708 | 708 |
709 bool visit(uint32_t i, Handle<Object> elm) { | 709 bool visit(uint32_t i, Handle<Object> elm) { |
adamk
2016/03/17 21:31:31
Can you add a MUST_USE_RESULT on the front of this
Dan Ehrenberg
2016/03/17 22:11:01
Done
| |
710 uint32_t index = index_offset_ + i; | 710 uint32_t index = index_offset_ + i; |
711 | 711 |
712 if (i >= JSObject::kMaxElementCount - index_offset_) { | 712 if (i >= JSObject::kMaxElementCount - index_offset_) { |
713 set_exceeds_array_limit(true); | 713 set_exceeds_array_limit(true); |
714 // Exception hasn't been thrown at this point. Return true to | 714 // Exception hasn't been thrown at this point. Return true to |
715 // break out, and caller will throw. !visit would imply that | 715 // break out, and caller will throw. !visit would imply that |
716 // there is already a pending exception. | 716 // there is already a pending exception. |
717 return true; | 717 return true; |
718 } | 718 } |
719 | 719 |
720 if (!is_fixed_array()) { | 720 if (!is_fixed_array()) { |
721 Handle<Object> element_value; | 721 LookupIterator it(isolate_, storage_, index, LookupIterator::OWN); |
722 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 722 Maybe<bool> success = |
723 isolate_, element_value, | 723 JSReceiver::CreateDataProperty(&it, elm, Object::THROW_ON_ERROR); |
724 Object::SetElement(isolate_, storage_, index, elm, STRICT), false); | 724 if (!success.IsJust()) return false; |
adamk
2016/03/17 21:31:31
The usual way of writing this is:
MAYBE_RETURN(JS
Dan Ehrenberg
2016/03/17 22:11:01
Done (I'm sad about the lost DCHECK though)
| |
725 DCHECK(success.FromJust()); | |
725 return true; | 726 return true; |
726 } | 727 } |
727 | 728 |
728 if (fast_elements()) { | 729 if (fast_elements()) { |
729 if (index < static_cast<uint32_t>(storage_fixed_array()->length())) { | 730 if (index < static_cast<uint32_t>(storage_fixed_array()->length())) { |
730 storage_fixed_array()->set(index, *elm); | 731 storage_fixed_array()->set(index, *elm); |
731 return true; | 732 return true; |
732 } | 733 } |
733 // Our initial estimate of length was foiled, possibly by | 734 // Our initial estimate of length was foiled, possibly by |
734 // getters on the arrays increasing the length of later arrays | 735 // getters on the arrays increasing the length of later arrays |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
816 if (!new_storage.is_identical_to(slow_storage)) { | 817 if (!new_storage.is_identical_to(slow_storage)) { |
817 slow_storage = loop_scope.CloseAndEscape(new_storage); | 818 slow_storage = loop_scope.CloseAndEscape(new_storage); |
818 } | 819 } |
819 } | 820 } |
820 } | 821 } |
821 clear_storage(); | 822 clear_storage(); |
822 set_storage(*slow_storage); | 823 set_storage(*slow_storage); |
823 set_fast_elements(false); | 824 set_fast_elements(false); |
824 } | 825 } |
825 | 826 |
826 inline void clear_storage() { | 827 inline void clear_storage() { GlobalHandles::Destroy(storage_.location()); } |
827 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); | |
828 } | |
829 | 828 |
830 inline void set_storage(FixedArray* storage) { | 829 inline void set_storage(FixedArray* storage) { |
831 DCHECK(is_fixed_array()); | 830 DCHECK(is_fixed_array()); |
832 storage_ = isolate_->global_handles()->Create(storage); | 831 storage_ = isolate_->global_handles()->Create(storage); |
833 } | 832 } |
834 | 833 |
835 class FastElementsField : public BitField<bool, 0, 1> {}; | 834 class FastElementsField : public BitField<bool, 0, 1> {}; |
836 class ExceedsLimitField : public BitField<bool, 1, 1> {}; | 835 class ExceedsLimitField : public BitField<bool, 1, 1> {}; |
837 class IsFixedArrayField : public BitField<bool, 2, 1> {}; | 836 class IsFixedArrayField : public BitField<bool, 2, 1> {}; |
838 | 837 |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1402 for (int i = 0; i < argument_count; i++) { | 1401 for (int i = 0; i < argument_count; i++) { |
1403 Handle<Object> obj((*args)[i], isolate); | 1402 Handle<Object> obj((*args)[i], isolate); |
1404 Maybe<bool> spreadable = IsConcatSpreadable(isolate, obj); | 1403 Maybe<bool> spreadable = IsConcatSpreadable(isolate, obj); |
1405 MAYBE_RETURN(spreadable, isolate->heap()->exception()); | 1404 MAYBE_RETURN(spreadable, isolate->heap()->exception()); |
1406 if (spreadable.FromJust()) { | 1405 if (spreadable.FromJust()) { |
1407 Handle<JSReceiver> object = Handle<JSReceiver>::cast(obj); | 1406 Handle<JSReceiver> object = Handle<JSReceiver>::cast(obj); |
1408 if (!IterateElements(isolate, object, &visitor)) { | 1407 if (!IterateElements(isolate, object, &visitor)) { |
1409 return isolate->heap()->exception(); | 1408 return isolate->heap()->exception(); |
1410 } | 1409 } |
1411 } else { | 1410 } else { |
1412 visitor.visit(0, obj); | 1411 bool success = visitor.visit(0, obj); |
1412 DCHECK_EQ(success, !isolate->has_pending_exception()); | |
1413 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
adamk
2016/03/17 21:31:31
The pattern elsewhere in this file is:
if (!Somet
Dan Ehrenberg
2016/03/17 22:11:01
Done (but I'm also sad about this DCHECK)
adamk
2016/03/17 22:16:25
Not sure what's really to be done here, this patte
| |
1413 visitor.increase_index_offset(1); | 1414 visitor.increase_index_offset(1); |
1414 } | 1415 } |
1415 } | 1416 } |
1416 | 1417 |
1417 if (visitor.exceeds_array_limit()) { | 1418 if (visitor.exceeds_array_limit()) { |
1418 THROW_NEW_ERROR_RETURN_FAILURE( | 1419 THROW_NEW_ERROR_RETURN_FAILURE( |
1419 isolate, NewRangeError(MessageTemplate::kInvalidArrayLength)); | 1420 isolate, NewRangeError(MessageTemplate::kInvalidArrayLength)); |
1420 } | 1421 } |
1421 | 1422 |
1422 if (is_array_species) { | 1423 if (is_array_species) { |
(...skipping 3123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4546 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 4547 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
4547 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 4548 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
4548 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4549 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
4549 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4550 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
4550 #undef DEFINE_BUILTIN_ACCESSOR_C | 4551 #undef DEFINE_BUILTIN_ACCESSOR_C |
4551 #undef DEFINE_BUILTIN_ACCESSOR_A | 4552 #undef DEFINE_BUILTIN_ACCESSOR_A |
4552 | 4553 |
4553 | 4554 |
4554 } // namespace internal | 4555 } // namespace internal |
4555 } // namespace v8 | 4556 } // namespace v8 |
OLD | NEW |