| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 if (!info->HasExpectedReceiverType()) return true; | 337 if (!info->HasExpectedReceiverType()) return true; |
| 338 Handle<Map> map = IC::TypeToMap(*type, isolate); | 338 Handle<Map> map = IC::TypeToMap(*type, isolate); |
| 339 if (!map->IsJSObjectMap()) return false; | 339 if (!map->IsJSObjectMap()) return false; |
| 340 return FunctionTemplateInfo::cast(info->expected_receiver_type()) | 340 return FunctionTemplateInfo::cast(info->expected_receiver_type()) |
| 341 ->IsTemplateFor(*map); | 341 ->IsTemplateFor(*map); |
| 342 } | 342 } |
| 343 | 343 |
| 344 | 344 |
| 345 MaybeHandle<Object> Object::SetPropertyWithAccessor( | 345 MaybeHandle<Object> Object::SetPropertyWithAccessor( |
| 346 Handle<Object> receiver, Handle<Name> name, Handle<Object> value, | 346 Handle<Object> receiver, Handle<Name> name, Handle<Object> value, |
| 347 Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) { | 347 Handle<JSObject> holder, Handle<Object> structure, |
| 348 LanguageMode language_mode) { |
| 348 Isolate* isolate = name->GetIsolate(); | 349 Isolate* isolate = name->GetIsolate(); |
| 349 | 350 |
| 350 // We should never get here to initialize a const with the hole | 351 // We should never get here to initialize a const with the hole |
| 351 // value since a const declaration would conflict with the setter. | 352 // value since a const declaration would conflict with the setter. |
| 352 DCHECK(!structure->IsForeign()); | 353 DCHECK(!structure->IsForeign()); |
| 353 if (structure->IsExecutableAccessorInfo()) { | 354 if (structure->IsExecutableAccessorInfo()) { |
| 354 // Don't call executable accessor setters with non-JSObject receivers. | 355 // Don't call executable accessor setters with non-JSObject receivers. |
| 355 if (!receiver->IsJSObject()) return value; | 356 if (!receiver->IsJSObject()) return value; |
| 356 // api style callbacks | 357 // api style callbacks |
| 357 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); | 358 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 375 return value; | 376 return value; |
| 376 } | 377 } |
| 377 | 378 |
| 378 if (structure->IsAccessorPair()) { | 379 if (structure->IsAccessorPair()) { |
| 379 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 380 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 380 if (setter->IsSpecFunction()) { | 381 if (setter->IsSpecFunction()) { |
| 381 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 382 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 382 return SetPropertyWithDefinedSetter( | 383 return SetPropertyWithDefinedSetter( |
| 383 receiver, Handle<JSReceiver>::cast(setter), value); | 384 receiver, Handle<JSReceiver>::cast(setter), value); |
| 384 } else { | 385 } else { |
| 385 if (strict_mode == SLOPPY) return value; | 386 if (is_sloppy(language_mode)) return value; |
| 386 Handle<Object> args[2] = { name, holder }; | 387 Handle<Object> args[2] = { name, holder }; |
| 387 THROW_NEW_ERROR( | 388 THROW_NEW_ERROR( |
| 388 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), | 389 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), |
| 389 Object); | 390 Object); |
| 390 } | 391 } |
| 391 } | 392 } |
| 392 | 393 |
| 393 UNREACHABLE(); | 394 UNREACHABLE(); |
| 394 return MaybeHandle<Object>(); | 395 return MaybeHandle<Object>(); |
| 395 } | 396 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 if (accessors->IsAccessorInfo()) { | 478 if (accessors->IsAccessorInfo()) { |
| 478 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 479 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
| 479 } | 480 } |
| 480 } | 481 } |
| 481 } | 482 } |
| 482 return false; | 483 return false; |
| 483 } | 484 } |
| 484 | 485 |
| 485 | 486 |
| 486 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( | 487 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( |
| 487 LookupIterator* it, Handle<Object> value, StrictMode strict_mode) { | 488 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { |
| 488 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 489 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 489 if (FindAllCanWriteHolder(it)) { | 490 if (FindAllCanWriteHolder(it)) { |
| 490 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, | 491 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, |
| 491 it->GetHolder<JSObject>(), | 492 it->GetHolder<JSObject>(), |
| 492 it->GetAccessors(), strict_mode); | 493 it->GetAccessors(), language_mode); |
| 493 } | 494 } |
| 494 | 495 |
| 495 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); | 496 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); |
| 496 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 497 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
| 497 return value; | 498 return value; |
| 498 } | 499 } |
| 499 | 500 |
| 500 | 501 |
| 501 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 502 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 502 Handle<Name> name, | 503 Handle<Name> name, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 if (!result->IsTheHole()) return result; | 601 if (!result->IsTheHole()) return result; |
| 601 } | 602 } |
| 602 } | 603 } |
| 603 | 604 |
| 604 return isolate->factory()->undefined_value(); | 605 return isolate->factory()->undefined_value(); |
| 605 } | 606 } |
| 606 | 607 |
| 607 | 608 |
| 608 MaybeHandle<Object> Object::SetElementWithReceiver( | 609 MaybeHandle<Object> Object::SetElementWithReceiver( |
| 609 Isolate* isolate, Handle<Object> object, Handle<Object> receiver, | 610 Isolate* isolate, Handle<Object> object, Handle<Object> receiver, |
| 610 uint32_t index, Handle<Object> value, StrictMode strict_mode) { | 611 uint32_t index, Handle<Object> value, LanguageMode language_mode) { |
| 611 // Iterate up the prototype chain until an element is found or the null | 612 // Iterate up the prototype chain until an element is found or the null |
| 612 // prototype is encountered. | 613 // prototype is encountered. |
| 613 bool done = false; | 614 bool done = false; |
| 614 for (PrototypeIterator iter(isolate, object, | 615 for (PrototypeIterator iter(isolate, object, |
| 615 object->IsJSProxy() || object->IsJSObject() | 616 object->IsJSProxy() || object->IsJSObject() |
| 616 ? PrototypeIterator::START_AT_RECEIVER | 617 ? PrototypeIterator::START_AT_RECEIVER |
| 617 : PrototypeIterator::START_AT_PROTOTYPE); | 618 : PrototypeIterator::START_AT_PROTOTYPE); |
| 618 !iter.IsAtEnd() && !done; iter.Advance()) { | 619 !iter.IsAtEnd() && !done; iter.Advance()) { |
| 619 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 620 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 620 // TODO(dslomov): implement. | 621 // TODO(dslomov): implement. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 634 } | 635 } |
| 635 } | 636 } |
| 636 | 637 |
| 637 if (js_object->HasIndexedInterceptor()) { | 638 if (js_object->HasIndexedInterceptor()) { |
| 638 Maybe<PropertyAttributes> from_interceptor = | 639 Maybe<PropertyAttributes> from_interceptor = |
| 639 JSObject::GetElementAttributeFromInterceptor(js_object, receiver, | 640 JSObject::GetElementAttributeFromInterceptor(js_object, receiver, |
| 640 index); | 641 index); |
| 641 if (!from_interceptor.has_value) return MaybeHandle<Object>(); | 642 if (!from_interceptor.has_value) return MaybeHandle<Object>(); |
| 642 if ((from_interceptor.value & READ_ONLY) != 0) { | 643 if ((from_interceptor.value & READ_ONLY) != 0) { |
| 643 return WriteToReadOnlyElement(isolate, receiver, index, value, | 644 return WriteToReadOnlyElement(isolate, receiver, index, value, |
| 644 strict_mode); | 645 language_mode); |
| 645 } | 646 } |
| 646 done = from_interceptor.value != ABSENT; | 647 done = from_interceptor.value != ABSENT; |
| 647 } | 648 } |
| 648 | 649 |
| 649 if (!done && | 650 if (!done && |
| 650 js_object->elements() != isolate->heap()->empty_fixed_array()) { | 651 js_object->elements() != isolate->heap()->empty_fixed_array()) { |
| 651 ElementsAccessor* accessor = js_object->GetElementsAccessor(); | 652 ElementsAccessor* accessor = js_object->GetElementsAccessor(); |
| 652 PropertyAttributes attrs = | 653 PropertyAttributes attrs = |
| 653 accessor->GetAttributes(receiver, js_object, index); | 654 accessor->GetAttributes(receiver, js_object, index); |
| 654 if ((attrs & READ_ONLY) != 0) { | 655 if ((attrs & READ_ONLY) != 0) { |
| 655 return WriteToReadOnlyElement(isolate, receiver, index, value, | 656 return WriteToReadOnlyElement(isolate, receiver, index, value, |
| 656 strict_mode); | 657 language_mode); |
| 657 } | 658 } |
| 658 Handle<AccessorPair> accessor_pair; | 659 Handle<AccessorPair> accessor_pair; |
| 659 if (accessor->GetAccessorPair(receiver, js_object, index) | 660 if (accessor->GetAccessorPair(receiver, js_object, index) |
| 660 .ToHandle(&accessor_pair)) { | 661 .ToHandle(&accessor_pair)) { |
| 661 return JSObject::SetElementWithCallback(receiver, accessor_pair, index, | 662 return JSObject::SetElementWithCallback( |
| 662 value, js_object, strict_mode); | 663 receiver, accessor_pair, index, value, js_object, language_mode); |
| 663 } else { | 664 } else { |
| 664 done = attrs != ABSENT; | 665 done = attrs != ABSENT; |
| 665 } | 666 } |
| 666 } | 667 } |
| 667 } | 668 } |
| 668 | 669 |
| 669 if (!receiver->IsJSObject()) { | 670 if (!receiver->IsJSObject()) { |
| 670 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode); | 671 return WriteToReadOnlyElement(isolate, receiver, index, value, |
| 672 language_mode); |
| 671 } | 673 } |
| 672 Handle<JSObject> target = Handle<JSObject>::cast(receiver); | 674 Handle<JSObject> target = Handle<JSObject>::cast(receiver); |
| 673 ElementsAccessor* accessor = target->GetElementsAccessor(); | 675 ElementsAccessor* accessor = target->GetElementsAccessor(); |
| 674 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index); | 676 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index); |
| 675 if ((attrs & READ_ONLY) != 0) { | 677 if ((attrs & READ_ONLY) != 0) { |
| 676 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode); | 678 return WriteToReadOnlyElement(isolate, receiver, index, value, |
| 679 language_mode); |
| 677 } | 680 } |
| 678 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE; | 681 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE; |
| 679 return JSObject::SetElement(target, index, value, new_attrs, strict_mode, | 682 return JSObject::SetElement(target, index, value, new_attrs, language_mode, |
| 680 false); | 683 false); |
| 681 } | 684 } |
| 682 | 685 |
| 683 | 686 |
| 684 Map* Object::GetRootMap(Isolate* isolate) { | 687 Map* Object::GetRootMap(Isolate* isolate) { |
| 685 DisallowHeapAllocation no_alloc; | 688 DisallowHeapAllocation no_alloc; |
| 686 if (IsSmi()) { | 689 if (IsSmi()) { |
| 687 Context* context = isolate->context()->native_context(); | 690 Context* context = isolate->context()->native_context(); |
| 688 return context->number_function()->initial_map(); | 691 return context->number_function()->initial_map(); |
| 689 } | 692 } |
| (...skipping 2059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); | 2752 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); |
| 2750 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 2753 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
| 2751 if (!result.IsEmpty()) return value; | 2754 if (!result.IsEmpty()) return value; |
| 2752 | 2755 |
| 2753 return MaybeHandle<Object>(); | 2756 return MaybeHandle<Object>(); |
| 2754 } | 2757 } |
| 2755 | 2758 |
| 2756 | 2759 |
| 2757 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 2760 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 2758 Handle<Name> name, Handle<Object> value, | 2761 Handle<Name> name, Handle<Object> value, |
| 2759 StrictMode strict_mode, | 2762 LanguageMode language_mode, |
| 2760 StoreFromKeyed store_mode) { | 2763 StoreFromKeyed store_mode) { |
| 2761 LookupIterator it(object, name); | 2764 LookupIterator it(object, name); |
| 2762 return SetProperty(&it, value, strict_mode, store_mode); | 2765 return SetProperty(&it, value, language_mode, store_mode); |
| 2763 } | 2766 } |
| 2764 | 2767 |
| 2765 | 2768 |
| 2766 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, | 2769 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, |
| 2767 Handle<Object> value, | 2770 Handle<Object> value, |
| 2768 StrictMode strict_mode, | 2771 LanguageMode language_mode, |
| 2769 StoreFromKeyed store_mode, | 2772 StoreFromKeyed store_mode, |
| 2770 StorePropertyMode data_store_mode) { | 2773 StorePropertyMode data_store_mode) { |
| 2771 // Make sure that the top context does not change when doing callbacks or | 2774 // Make sure that the top context does not change when doing callbacks or |
| 2772 // interceptor calls. | 2775 // interceptor calls. |
| 2773 AssertNoContextChange ncc(it->isolate()); | 2776 AssertNoContextChange ncc(it->isolate()); |
| 2774 | 2777 |
| 2775 bool done = false; | 2778 bool done = false; |
| 2776 for (; it->IsFound(); it->Next()) { | 2779 for (; it->IsFound(); it->Next()) { |
| 2777 switch (it->state()) { | 2780 switch (it->state()) { |
| 2778 case LookupIterator::NOT_FOUND: | 2781 case LookupIterator::NOT_FOUND: |
| 2779 UNREACHABLE(); | 2782 UNREACHABLE(); |
| 2780 | 2783 |
| 2781 case LookupIterator::ACCESS_CHECK: | 2784 case LookupIterator::ACCESS_CHECK: |
| 2782 // TODO(verwaest): Remove the distinction. This is mostly bogus since we | 2785 // TODO(verwaest): Remove the distinction. This is mostly bogus since we |
| 2783 // don't know whether we'll want to fetch attributes or call a setter | 2786 // don't know whether we'll want to fetch attributes or call a setter |
| 2784 // until we find the property. | 2787 // until we find the property. |
| 2785 if (it->HasAccess(v8::ACCESS_SET)) break; | 2788 if (it->HasAccess(v8::ACCESS_SET)) break; |
| 2786 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 2789 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 2787 strict_mode); | 2790 language_mode); |
| 2788 | 2791 |
| 2789 case LookupIterator::JSPROXY: | 2792 case LookupIterator::JSPROXY: |
| 2790 if (it->HolderIsReceiverOrHiddenPrototype()) { | 2793 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 2791 return JSProxy::SetPropertyWithHandler(it->GetHolder<JSProxy>(), | 2794 return JSProxy::SetPropertyWithHandler(it->GetHolder<JSProxy>(), |
| 2792 it->GetReceiver(), it->name(), | 2795 it->GetReceiver(), it->name(), |
| 2793 value, strict_mode); | 2796 value, language_mode); |
| 2794 } else { | 2797 } else { |
| 2795 // TODO(verwaest): Use the MaybeHandle to indicate result. | 2798 // TODO(verwaest): Use the MaybeHandle to indicate result. |
| 2796 bool has_result = false; | 2799 bool has_result = false; |
| 2797 MaybeHandle<Object> maybe_result = | 2800 MaybeHandle<Object> maybe_result = |
| 2798 JSProxy::SetPropertyViaPrototypesWithHandler( | 2801 JSProxy::SetPropertyViaPrototypesWithHandler( |
| 2799 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name(), | 2802 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name(), |
| 2800 value, strict_mode, &has_result); | 2803 value, language_mode, &has_result); |
| 2801 if (has_result) return maybe_result; | 2804 if (has_result) return maybe_result; |
| 2802 done = true; | 2805 done = true; |
| 2803 } | 2806 } |
| 2804 break; | 2807 break; |
| 2805 | 2808 |
| 2806 case LookupIterator::INTERCEPTOR: | 2809 case LookupIterator::INTERCEPTOR: |
| 2807 if (it->HolderIsReceiverOrHiddenPrototype()) { | 2810 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 2808 MaybeHandle<Object> maybe_result = | 2811 MaybeHandle<Object> maybe_result = |
| 2809 JSObject::SetPropertyWithInterceptor(it, value); | 2812 JSObject::SetPropertyWithInterceptor(it, value); |
| 2810 if (!maybe_result.is_null()) return maybe_result; | 2813 if (!maybe_result.is_null()) return maybe_result; |
| 2811 if (it->isolate()->has_pending_exception()) return maybe_result; | 2814 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 2812 } else { | 2815 } else { |
| 2813 Maybe<PropertyAttributes> maybe_attributes = | 2816 Maybe<PropertyAttributes> maybe_attributes = |
| 2814 JSObject::GetPropertyAttributesWithInterceptor( | 2817 JSObject::GetPropertyAttributesWithInterceptor( |
| 2815 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 2818 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 2816 if (!maybe_attributes.has_value) return MaybeHandle<Object>(); | 2819 if (!maybe_attributes.has_value) return MaybeHandle<Object>(); |
| 2817 done = maybe_attributes.value != ABSENT; | 2820 done = maybe_attributes.value != ABSENT; |
| 2818 if (done && (maybe_attributes.value & READ_ONLY) != 0) { | 2821 if (done && (maybe_attributes.value & READ_ONLY) != 0) { |
| 2819 return WriteToReadOnlyProperty(it, value, strict_mode); | 2822 return WriteToReadOnlyProperty(it, value, language_mode); |
| 2820 } | 2823 } |
| 2821 } | 2824 } |
| 2822 break; | 2825 break; |
| 2823 | 2826 |
| 2824 case LookupIterator::ACCESSOR: | 2827 case LookupIterator::ACCESSOR: |
| 2825 if (it->property_details().IsReadOnly()) { | 2828 if (it->property_details().IsReadOnly()) { |
| 2826 return WriteToReadOnlyProperty(it, value, strict_mode); | 2829 return WriteToReadOnlyProperty(it, value, language_mode); |
| 2827 } | 2830 } |
| 2828 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, | 2831 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, |
| 2829 it->GetHolder<JSObject>(), | 2832 it->GetHolder<JSObject>(), |
| 2830 it->GetAccessors(), strict_mode); | 2833 it->GetAccessors(), language_mode); |
| 2831 | 2834 |
| 2832 case LookupIterator::DATA: | 2835 case LookupIterator::DATA: |
| 2833 if (it->property_details().IsReadOnly()) { | 2836 if (it->property_details().IsReadOnly()) { |
| 2834 return WriteToReadOnlyProperty(it, value, strict_mode); | 2837 return WriteToReadOnlyProperty(it, value, language_mode); |
| 2835 } | 2838 } |
| 2836 if (it->HolderIsReceiverOrHiddenPrototype()) { | 2839 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 2837 return SetDataProperty(it, value); | 2840 return SetDataProperty(it, value); |
| 2838 } | 2841 } |
| 2839 done = true; | 2842 done = true; |
| 2840 break; | 2843 break; |
| 2841 | 2844 |
| 2842 case LookupIterator::TRANSITION: | 2845 case LookupIterator::TRANSITION: |
| 2843 done = true; | 2846 done = true; |
| 2844 break; | 2847 break; |
| 2845 } | 2848 } |
| 2846 | 2849 |
| 2847 if (done) break; | 2850 if (done) break; |
| 2848 } | 2851 } |
| 2849 | 2852 |
| 2850 // If the receiver is the JSGlobalObject, the store was contextual. In case | 2853 // If the receiver is the JSGlobalObject, the store was contextual. In case |
| 2851 // the property did not exist yet on the global object itself, we have to | 2854 // the property did not exist yet on the global object itself, we have to |
| 2852 // throw a reference error in strict mode. | 2855 // throw a reference error in strict mode. |
| 2853 if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) { | 2856 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { |
| 2854 Handle<Object> args[1] = {it->name()}; | 2857 Handle<Object> args[1] = {it->name()}; |
| 2855 THROW_NEW_ERROR(it->isolate(), | 2858 THROW_NEW_ERROR(it->isolate(), |
| 2856 NewReferenceError("not_defined", HandleVector(args, 1)), | 2859 NewReferenceError("not_defined", HandleVector(args, 1)), |
| 2857 Object); | 2860 Object); |
| 2858 } | 2861 } |
| 2859 | 2862 |
| 2860 if (data_store_mode == SUPER_PROPERTY) { | 2863 if (data_store_mode == SUPER_PROPERTY) { |
| 2861 LookupIterator own_lookup(it->GetReceiver(), it->name(), | 2864 LookupIterator own_lookup(it->GetReceiver(), it->name(), |
| 2862 LookupIterator::OWN); | 2865 LookupIterator::OWN); |
| 2863 | 2866 |
| 2864 return JSObject::SetProperty(&own_lookup, value, strict_mode, store_mode, | 2867 return JSObject::SetProperty(&own_lookup, value, language_mode, store_mode, |
| 2865 NORMAL_PROPERTY); | 2868 NORMAL_PROPERTY); |
| 2866 } | 2869 } |
| 2867 | 2870 |
| 2868 return AddDataProperty(it, value, NONE, strict_mode, store_mode); | 2871 return AddDataProperty(it, value, NONE, language_mode, store_mode); |
| 2869 } | 2872 } |
| 2870 | 2873 |
| 2871 | 2874 |
| 2872 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, | 2875 MaybeHandle<Object> Object::WriteToReadOnlyProperty( |
| 2873 Handle<Object> value, | 2876 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { |
| 2874 StrictMode strict_mode) { | 2877 if (is_sloppy(language_mode)) return value; |
| 2875 if (strict_mode != STRICT) return value; | |
| 2876 | 2878 |
| 2877 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 2879 Handle<Object> args[] = {it->name(), it->GetReceiver()}; |
| 2878 THROW_NEW_ERROR(it->isolate(), | 2880 THROW_NEW_ERROR(it->isolate(), |
| 2879 NewTypeError("strict_read_only_property", | 2881 NewTypeError("strict_read_only_property", |
| 2880 HandleVector(args, arraysize(args))), | 2882 HandleVector(args, arraysize(args))), |
| 2881 Object); | 2883 Object); |
| 2882 } | 2884 } |
| 2883 | 2885 |
| 2884 | 2886 |
| 2885 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, | 2887 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, |
| 2886 Handle<Object> receiver, | 2888 Handle<Object> receiver, |
| 2887 uint32_t index, | 2889 uint32_t index, |
| 2888 Handle<Object> value, | 2890 Handle<Object> value, |
| 2889 StrictMode strict_mode) { | 2891 LanguageMode language_mode) { |
| 2890 if (strict_mode != STRICT) return value; | 2892 if (is_sloppy(language_mode)) return value; |
| 2891 | 2893 |
| 2892 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), | 2894 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), |
| 2893 receiver}; | 2895 receiver}; |
| 2894 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 2896 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 2895 HandleVector(args, arraysize(args))), | 2897 HandleVector(args, arraysize(args))), |
| 2896 Object); | 2898 Object); |
| 2897 } | 2899 } |
| 2898 | 2900 |
| 2899 | 2901 |
| 2900 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, | 2902 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2929 Object); | 2931 Object); |
| 2930 } | 2932 } |
| 2931 | 2933 |
| 2932 return value; | 2934 return value; |
| 2933 } | 2935 } |
| 2934 | 2936 |
| 2935 | 2937 |
| 2936 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 2938 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
| 2937 Handle<Object> value, | 2939 Handle<Object> value, |
| 2938 PropertyAttributes attributes, | 2940 PropertyAttributes attributes, |
| 2939 StrictMode strict_mode, | 2941 LanguageMode language_mode, |
| 2940 StoreFromKeyed store_mode) { | 2942 StoreFromKeyed store_mode) { |
| 2941 DCHECK(!it->GetReceiver()->IsJSProxy()); | 2943 DCHECK(!it->GetReceiver()->IsJSProxy()); |
| 2942 if (!it->GetReceiver()->IsJSObject()) { | 2944 if (!it->GetReceiver()->IsJSObject()) { |
| 2943 // TODO(verwaest): Throw a TypeError with a more specific message. | 2945 // TODO(verwaest): Throw a TypeError with a more specific message. |
| 2944 return WriteToReadOnlyProperty(it, value, strict_mode); | 2946 return WriteToReadOnlyProperty(it, value, language_mode); |
| 2945 } | 2947 } |
| 2946 | 2948 |
| 2947 Handle<JSObject> receiver = it->GetStoreTarget(); | 2949 Handle<JSObject> receiver = it->GetStoreTarget(); |
| 2948 | 2950 |
| 2949 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) | 2951 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) |
| 2950 // instead. If the prototype is Null, the proxy is detached. | 2952 // instead. If the prototype is Null, the proxy is detached. |
| 2951 if (receiver->IsJSGlobalProxy()) return value; | 2953 if (receiver->IsJSGlobalProxy()) return value; |
| 2952 | 2954 |
| 2953 // If the receiver is Indexed Exotic object (currently only typed arrays), | 2955 // If the receiver is Indexed Exotic object (currently only typed arrays), |
| 2954 // disallow adding properties with numeric names. | 2956 // disallow adding properties with numeric names. |
| 2955 if (it->IsSpecialNumericIndex()) return value; | 2957 if (it->IsSpecialNumericIndex()) return value; |
| 2956 | 2958 |
| 2957 // Possibly migrate to the most up-to-date map that will be able to store | 2959 // Possibly migrate to the most up-to-date map that will be able to store |
| 2958 // |value| under it->name() with |attributes|. | 2960 // |value| under it->name() with |attributes|. |
| 2959 it->PrepareTransitionToDataProperty(value, attributes, store_mode); | 2961 it->PrepareTransitionToDataProperty(value, attributes, store_mode); |
| 2960 if (it->state() != LookupIterator::TRANSITION) { | 2962 if (it->state() != LookupIterator::TRANSITION) { |
| 2961 if (strict_mode == SLOPPY) return value; | 2963 if (is_sloppy(language_mode)) return value; |
| 2962 | 2964 |
| 2963 Handle<Object> args[1] = {it->name()}; | 2965 Handle<Object> args[1] = {it->name()}; |
| 2964 THROW_NEW_ERROR(it->isolate(), | 2966 THROW_NEW_ERROR(it->isolate(), |
| 2965 NewTypeError("object_not_extensible", | 2967 NewTypeError("object_not_extensible", |
| 2966 HandleVector(args, arraysize(args))), | 2968 HandleVector(args, arraysize(args))), |
| 2967 Object); | 2969 Object); |
| 2968 } | 2970 } |
| 2969 it->ApplyTransitionToDataProperty(); | 2971 it->ApplyTransitionToDataProperty(); |
| 2970 | 2972 |
| 2971 // TODO(verwaest): Encapsulate dictionary handling better. | 2973 // TODO(verwaest): Encapsulate dictionary handling better. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2985 receiver, "add", it->name(), | 2987 receiver, "add", it->name(), |
| 2986 it->factory()->the_hole_value()), | 2988 it->factory()->the_hole_value()), |
| 2987 Object); | 2989 Object); |
| 2988 } | 2990 } |
| 2989 | 2991 |
| 2990 return value; | 2992 return value; |
| 2991 } | 2993 } |
| 2992 | 2994 |
| 2993 | 2995 |
| 2994 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 2996 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 2995 Handle<JSObject> object, | 2997 Handle<JSObject> object, uint32_t index, Handle<Object> value, bool* found, |
| 2996 uint32_t index, | 2998 LanguageMode language_mode) { |
| 2997 Handle<Object> value, | |
| 2998 bool* found, | |
| 2999 StrictMode strict_mode) { | |
| 3000 Isolate* isolate = object->GetIsolate(); | 2999 Isolate* isolate = object->GetIsolate(); |
| 3001 for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd(); | 3000 for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd(); |
| 3002 iter.Advance()) { | 3001 iter.Advance()) { |
| 3003 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 3002 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 3004 return JSProxy::SetPropertyViaPrototypesWithHandler( | 3003 return JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3005 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object, | 3004 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object, |
| 3006 isolate->factory()->Uint32ToString(index), // name | 3005 isolate->factory()->Uint32ToString(index), // name |
| 3007 value, strict_mode, found); | 3006 value, language_mode, found); |
| 3008 } | 3007 } |
| 3009 Handle<JSObject> js_proto = | 3008 Handle<JSObject> js_proto = |
| 3010 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 3009 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 3011 | 3010 |
| 3012 if (js_proto->IsAccessCheckNeeded()) { | 3011 if (js_proto->IsAccessCheckNeeded()) { |
| 3013 if (!isolate->MayIndexedAccess(js_proto, index, v8::ACCESS_SET)) { | 3012 if (!isolate->MayIndexedAccess(js_proto, index, v8::ACCESS_SET)) { |
| 3014 *found = true; | 3013 *found = true; |
| 3015 isolate->ReportFailedAccessCheck(js_proto, v8::ACCESS_SET); | 3014 isolate->ReportFailedAccessCheck(js_proto, v8::ACCESS_SET); |
| 3016 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 3015 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 3017 return MaybeHandle<Object>(); | 3016 return MaybeHandle<Object>(); |
| 3018 } | 3017 } |
| 3019 } | 3018 } |
| 3020 | 3019 |
| 3021 if (!js_proto->HasDictionaryElements()) { | 3020 if (!js_proto->HasDictionaryElements()) { |
| 3022 continue; | 3021 continue; |
| 3023 } | 3022 } |
| 3024 | 3023 |
| 3025 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); | 3024 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
| 3026 int entry = dictionary->FindEntry(index); | 3025 int entry = dictionary->FindEntry(index); |
| 3027 if (entry != SeededNumberDictionary::kNotFound) { | 3026 if (entry != SeededNumberDictionary::kNotFound) { |
| 3028 PropertyDetails details = dictionary->DetailsAt(entry); | 3027 PropertyDetails details = dictionary->DetailsAt(entry); |
| 3029 if (details.type() == ACCESSOR_CONSTANT) { | 3028 if (details.type() == ACCESSOR_CONSTANT) { |
| 3030 *found = true; | 3029 *found = true; |
| 3031 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 3030 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
| 3032 return SetElementWithCallback(object, structure, index, value, js_proto, | 3031 return SetElementWithCallback(object, structure, index, value, js_proto, |
| 3033 strict_mode); | 3032 language_mode); |
| 3034 } | 3033 } |
| 3035 } | 3034 } |
| 3036 } | 3035 } |
| 3037 *found = false; | 3036 *found = false; |
| 3038 return isolate->factory()->the_hole_value(); | 3037 return isolate->factory()->the_hole_value(); |
| 3039 } | 3038 } |
| 3040 | 3039 |
| 3041 | 3040 |
| 3042 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { | 3041 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { |
| 3043 // Only supports adding slack to owned descriptors. | 3042 // Only supports adding slack to owned descriptors. |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3406 Handle<Object> result; | 3405 Handle<Object> result; |
| 3407 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 3406 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3408 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), | 3407 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), |
| 3409 arraysize(args), args), | 3408 arraysize(args), args), |
| 3410 Maybe<bool>()); | 3409 Maybe<bool>()); |
| 3411 | 3410 |
| 3412 return maybe(result->BooleanValue()); | 3411 return maybe(result->BooleanValue()); |
| 3413 } | 3412 } |
| 3414 | 3413 |
| 3415 | 3414 |
| 3416 MaybeHandle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, | 3415 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( |
| 3417 Handle<Object> receiver, | 3416 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, |
| 3418 Handle<Name> name, | 3417 Handle<Object> value, LanguageMode language_mode) { |
| 3419 Handle<Object> value, | |
| 3420 StrictMode strict_mode) { | |
| 3421 Isolate* isolate = proxy->GetIsolate(); | 3418 Isolate* isolate = proxy->GetIsolate(); |
| 3422 | 3419 |
| 3423 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3420 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3424 if (name->IsSymbol()) return value; | 3421 if (name->IsSymbol()) return value; |
| 3425 | 3422 |
| 3426 Handle<Object> args[] = { receiver, name, value }; | 3423 Handle<Object> args[] = { receiver, name, value }; |
| 3427 RETURN_ON_EXCEPTION( | 3424 RETURN_ON_EXCEPTION( |
| 3428 isolate, | 3425 isolate, |
| 3429 CallTrap(proxy, | 3426 CallTrap(proxy, |
| 3430 "set", | 3427 "set", |
| 3431 isolate->derived_set_trap(), | 3428 isolate->derived_set_trap(), |
| 3432 arraysize(args), | 3429 arraysize(args), |
| 3433 args), | 3430 args), |
| 3434 Object); | 3431 Object); |
| 3435 | 3432 |
| 3436 return value; | 3433 return value; |
| 3437 } | 3434 } |
| 3438 | 3435 |
| 3439 | 3436 |
| 3440 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( | 3437 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3441 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, | 3438 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, |
| 3442 Handle<Object> value, StrictMode strict_mode, bool* done) { | 3439 Handle<Object> value, LanguageMode language_mode, bool* done) { |
| 3443 Isolate* isolate = proxy->GetIsolate(); | 3440 Isolate* isolate = proxy->GetIsolate(); |
| 3444 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | 3441 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. |
| 3445 | 3442 |
| 3446 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3443 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3447 if (name->IsSymbol()) { | 3444 if (name->IsSymbol()) { |
| 3448 *done = false; | 3445 *done = false; |
| 3449 return isolate->factory()->the_hole_value(); | 3446 return isolate->factory()->the_hole_value(); |
| 3450 } | 3447 } |
| 3451 | 3448 |
| 3452 *done = true; // except where redefined... | 3449 *done = true; // except where redefined... |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3503 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | 3500 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
| 3504 DCHECK(hasWritable->IsBoolean()); | 3501 DCHECK(hasWritable->IsBoolean()); |
| 3505 if (hasWritable->IsTrue()) { | 3502 if (hasWritable->IsTrue()) { |
| 3506 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( | 3503 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( |
| 3507 STATIC_CHAR_VECTOR("writable_")); | 3504 STATIC_CHAR_VECTOR("writable_")); |
| 3508 Handle<Object> writable = | 3505 Handle<Object> writable = |
| 3509 Object::GetProperty(desc, writable_name).ToHandleChecked(); | 3506 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
| 3510 DCHECK(writable->IsBoolean()); | 3507 DCHECK(writable->IsBoolean()); |
| 3511 *done = writable->IsFalse(); | 3508 *done = writable->IsFalse(); |
| 3512 if (!*done) return isolate->factory()->the_hole_value(); | 3509 if (!*done) return isolate->factory()->the_hole_value(); |
| 3513 if (strict_mode == SLOPPY) return value; | 3510 if (is_sloppy(language_mode)) return value; |
| 3514 Handle<Object> args[] = { name, receiver }; | 3511 Handle<Object> args[] = { name, receiver }; |
| 3515 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 3512 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 3516 HandleVector(args, arraysize(args))), | 3513 HandleVector(args, arraysize(args))), |
| 3517 Object); | 3514 Object); |
| 3518 } | 3515 } |
| 3519 | 3516 |
| 3520 // We have an AccessorDescriptor. | 3517 // We have an AccessorDescriptor. |
| 3521 Handle<String> set_name = | 3518 Handle<String> set_name = |
| 3522 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); | 3519 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); |
| 3523 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | 3520 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
| 3524 if (!setter->IsUndefined()) { | 3521 if (!setter->IsUndefined()) { |
| 3525 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3522 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 3526 return SetPropertyWithDefinedSetter( | 3523 return SetPropertyWithDefinedSetter( |
| 3527 receiver, Handle<JSReceiver>::cast(setter), value); | 3524 receiver, Handle<JSReceiver>::cast(setter), value); |
| 3528 } | 3525 } |
| 3529 | 3526 |
| 3530 if (strict_mode == SLOPPY) return value; | 3527 if (is_sloppy(language_mode)) return value; |
| 3531 Handle<Object> args2[] = { name, proxy }; | 3528 Handle<Object> args2[] = { name, proxy }; |
| 3532 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", | 3529 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", |
| 3533 HandleVector(args2, arraysize(args2))), | 3530 HandleVector(args2, arraysize(args2))), |
| 3534 Object); | 3531 Object); |
| 3535 } | 3532 } |
| 3536 | 3533 |
| 3537 | 3534 |
| 3538 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(Handle<JSProxy> proxy, | 3535 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( |
| 3539 Handle<Name> name, | 3536 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) { |
| 3540 StrictMode strict_mode) { | |
| 3541 Isolate* isolate = proxy->GetIsolate(); | 3537 Isolate* isolate = proxy->GetIsolate(); |
| 3542 | 3538 |
| 3543 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3539 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3544 if (name->IsSymbol()) return isolate->factory()->false_value(); | 3540 if (name->IsSymbol()) return isolate->factory()->false_value(); |
| 3545 | 3541 |
| 3546 Handle<Object> args[] = { name }; | 3542 Handle<Object> args[] = { name }; |
| 3547 Handle<Object> result; | 3543 Handle<Object> result; |
| 3548 ASSIGN_RETURN_ON_EXCEPTION( | 3544 ASSIGN_RETURN_ON_EXCEPTION( |
| 3549 isolate, result, | 3545 isolate, result, |
| 3550 CallTrap(proxy, | 3546 CallTrap(proxy, |
| 3551 "delete", | 3547 "delete", |
| 3552 Handle<Object>(), | 3548 Handle<Object>(), |
| 3553 arraysize(args), | 3549 arraysize(args), |
| 3554 args), | 3550 args), |
| 3555 Object); | 3551 Object); |
| 3556 | 3552 |
| 3557 bool result_bool = result->BooleanValue(); | 3553 bool result_bool = result->BooleanValue(); |
| 3558 if (strict_mode == STRICT && !result_bool) { | 3554 if (is_strict(language_mode) && !result_bool) { |
| 3559 Handle<Object> handler(proxy->handler(), isolate); | 3555 Handle<Object> handler(proxy->handler(), isolate); |
| 3560 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 3556 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
| 3561 STATIC_CHAR_VECTOR("delete")); | 3557 STATIC_CHAR_VECTOR("delete")); |
| 3562 Handle<Object> args[] = { handler, trap_name }; | 3558 Handle<Object> args[] = { handler, trap_name }; |
| 3563 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", | 3559 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", |
| 3564 HandleVector(args, arraysize(args))), | 3560 HandleVector(args, arraysize(args))), |
| 3565 Object); | 3561 Object); |
| 3566 } | 3562 } |
| 3567 return isolate->factory()->ToBoolean(result_bool); | 3563 return isolate->factory()->ToBoolean(result_bool); |
| 3568 } | 3564 } |
| 3569 | 3565 |
| 3570 | 3566 |
| 3571 MaybeHandle<Object> JSProxy::DeleteElementWithHandler(Handle<JSProxy> proxy, | 3567 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( |
| 3572 uint32_t index, | 3568 Handle<JSProxy> proxy, uint32_t index, LanguageMode language_mode) { |
| 3573 StrictMode strict_mode) { | |
| 3574 Isolate* isolate = proxy->GetIsolate(); | 3569 Isolate* isolate = proxy->GetIsolate(); |
| 3575 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3570 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 3576 return JSProxy::DeletePropertyWithHandler(proxy, name, strict_mode); | 3571 return JSProxy::DeletePropertyWithHandler(proxy, name, language_mode); |
| 3577 } | 3572 } |
| 3578 | 3573 |
| 3579 | 3574 |
| 3580 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( | 3575 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( |
| 3581 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { | 3576 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { |
| 3582 Isolate* isolate = proxy->GetIsolate(); | 3577 Isolate* isolate = proxy->GetIsolate(); |
| 3583 HandleScope scope(isolate); | 3578 HandleScope scope(isolate); |
| 3584 | 3579 |
| 3585 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3580 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3586 if (name->IsSymbol()) return maybe(ABSENT); | 3581 if (name->IsSymbol()) return maybe(ABSENT); |
| (...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4855 } | 4850 } |
| 4856 // TODO(verwaest): Shouldn't this be the mode that was passed in? | 4851 // TODO(verwaest): Shouldn't this be the mode that was passed in? |
| 4857 MaybeHandle<Object> delete_result = | 4852 MaybeHandle<Object> delete_result = |
| 4858 object->GetElementsAccessor()->Delete(object, index, SLOPPY); | 4853 object->GetElementsAccessor()->Delete(object, index, SLOPPY); |
| 4859 return delete_result; | 4854 return delete_result; |
| 4860 } | 4855 } |
| 4861 | 4856 |
| 4862 | 4857 |
| 4863 MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 4858 MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
| 4864 uint32_t index, | 4859 uint32_t index, |
| 4865 StrictMode strict_mode) { | 4860 LanguageMode language_mode) { |
| 4866 Isolate* isolate = object->GetIsolate(); | 4861 Isolate* isolate = object->GetIsolate(); |
| 4867 Factory* factory = isolate->factory(); | 4862 Factory* factory = isolate->factory(); |
| 4868 | 4863 |
| 4869 // Check access rights if needed. | 4864 // Check access rights if needed. |
| 4870 if (object->IsAccessCheckNeeded() && | 4865 if (object->IsAccessCheckNeeded() && |
| 4871 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { | 4866 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { |
| 4872 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 4867 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
| 4873 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 4868 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 4874 return factory->false_value(); | 4869 return factory->false_value(); |
| 4875 } | 4870 } |
| 4876 | 4871 |
| 4877 if (object->IsStringObjectWithCharacterAt(index)) { | 4872 if (object->IsStringObjectWithCharacterAt(index)) { |
| 4878 if (strict_mode == STRICT) { | 4873 if (is_strict(language_mode)) { |
| 4879 // Deleting a non-configurable property in strict mode. | 4874 // Deleting a non-configurable property in strict mode. |
| 4880 Handle<Object> name = factory->NewNumberFromUint(index); | 4875 Handle<Object> name = factory->NewNumberFromUint(index); |
| 4881 Handle<Object> args[2] = { name, object }; | 4876 Handle<Object> args[2] = { name, object }; |
| 4882 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", | 4877 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", |
| 4883 HandleVector(args, 2)), | 4878 HandleVector(args, 2)), |
| 4884 Object); | 4879 Object); |
| 4885 } | 4880 } |
| 4886 return factory->false_value(); | 4881 return factory->false_value(); |
| 4887 } | 4882 } |
| 4888 | 4883 |
| 4889 if (object->IsJSGlobalProxy()) { | 4884 if (object->IsJSGlobalProxy()) { |
| 4890 PrototypeIterator iter(isolate, object); | 4885 PrototypeIterator iter(isolate, object); |
| 4891 if (iter.IsAtEnd()) return factory->false_value(); | 4886 if (iter.IsAtEnd()) return factory->false_value(); |
| 4892 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4887 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 4893 return DeleteElement( | 4888 return DeleteElement( |
| 4894 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 4889 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
| 4895 strict_mode); | 4890 language_mode); |
| 4896 } | 4891 } |
| 4897 | 4892 |
| 4898 Handle<Object> old_value; | 4893 Handle<Object> old_value; |
| 4899 bool should_enqueue_change_record = false; | 4894 bool should_enqueue_change_record = false; |
| 4900 if (object->map()->is_observed()) { | 4895 if (object->map()->is_observed()) { |
| 4901 Maybe<bool> maybe = HasOwnElement(object, index); | 4896 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4902 if (!maybe.has_value) return MaybeHandle<Object>(); | 4897 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4903 should_enqueue_change_record = maybe.value; | 4898 should_enqueue_change_record = maybe.value; |
| 4904 if (should_enqueue_change_record) { | 4899 if (should_enqueue_change_record) { |
| 4905 if (!GetOwnElementAccessorPair(object, index).is_null()) { | 4900 if (!GetOwnElementAccessorPair(object, index).is_null()) { |
| 4906 old_value = Handle<Object>::cast(factory->the_hole_value()); | 4901 old_value = Handle<Object>::cast(factory->the_hole_value()); |
| 4907 } else { | 4902 } else { |
| 4908 old_value = Object::GetElement( | 4903 old_value = Object::GetElement( |
| 4909 isolate, object, index).ToHandleChecked(); | 4904 isolate, object, index).ToHandleChecked(); |
| 4910 } | 4905 } |
| 4911 } | 4906 } |
| 4912 } | 4907 } |
| 4913 | 4908 |
| 4914 // Skip interceptor if forcing deletion. | 4909 // Skip interceptor if forcing deletion. |
| 4915 MaybeHandle<Object> maybe_result; | 4910 MaybeHandle<Object> maybe_result; |
| 4916 if (object->HasIndexedInterceptor()) { | 4911 if (object->HasIndexedInterceptor()) { |
| 4917 maybe_result = DeleteElementWithInterceptor(object, index); | 4912 maybe_result = DeleteElementWithInterceptor(object, index); |
| 4918 } else { | 4913 } else { |
| 4919 maybe_result = | 4914 maybe_result = |
| 4920 object->GetElementsAccessor()->Delete(object, index, strict_mode); | 4915 object->GetElementsAccessor()->Delete(object, index, language_mode); |
| 4921 } | 4916 } |
| 4922 Handle<Object> result; | 4917 Handle<Object> result; |
| 4923 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 4918 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
| 4924 | 4919 |
| 4925 if (should_enqueue_change_record) { | 4920 if (should_enqueue_change_record) { |
| 4926 Maybe<bool> maybe = HasOwnElement(object, index); | 4921 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4927 if (!maybe.has_value) return MaybeHandle<Object>(); | 4922 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4928 if (!maybe.value) { | 4923 if (!maybe.value) { |
| 4929 Handle<String> name = factory->Uint32ToString(index); | 4924 Handle<String> name = factory->Uint32ToString(index); |
| 4930 RETURN_ON_EXCEPTION( | 4925 RETURN_ON_EXCEPTION( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4958 | 4953 |
| 4959 NameDictionary::DeleteProperty(dictionary, entry); | 4954 NameDictionary::DeleteProperty(dictionary, entry); |
| 4960 Handle<NameDictionary> new_properties = | 4955 Handle<NameDictionary> new_properties = |
| 4961 NameDictionary::Shrink(dictionary, name); | 4956 NameDictionary::Shrink(dictionary, name); |
| 4962 object->set_properties(*new_properties); | 4957 object->set_properties(*new_properties); |
| 4963 } | 4958 } |
| 4964 | 4959 |
| 4965 | 4960 |
| 4966 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 4961 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
| 4967 Handle<Name> name, | 4962 Handle<Name> name, |
| 4968 StrictMode strict_mode) { | 4963 LanguageMode language_mode) { |
| 4969 // ECMA-262, 3rd, 8.6.2.5 | 4964 // ECMA-262, 3rd, 8.6.2.5 |
| 4970 DCHECK(name->IsName()); | 4965 DCHECK(name->IsName()); |
| 4971 | 4966 |
| 4972 uint32_t index = 0; | 4967 uint32_t index = 0; |
| 4973 if (name->AsArrayIndex(&index)) { | 4968 if (name->AsArrayIndex(&index)) { |
| 4974 return DeleteElement(object, index, strict_mode); | 4969 return DeleteElement(object, index, language_mode); |
| 4975 } | 4970 } |
| 4976 | 4971 |
| 4977 LookupIterator it(object, name, LookupIterator::HIDDEN); | 4972 LookupIterator it(object, name, LookupIterator::HIDDEN); |
| 4978 | 4973 |
| 4979 bool is_observed = object->map()->is_observed() && | 4974 bool is_observed = object->map()->is_observed() && |
| 4980 !it.isolate()->IsInternallyUsedPropertyName(name); | 4975 !it.isolate()->IsInternallyUsedPropertyName(name); |
| 4981 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 4976 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 4982 | 4977 |
| 4983 for (; it.IsFound(); it.Next()) { | 4978 for (; it.IsFound(); it.Next()) { |
| 4984 switch (it.state()) { | 4979 switch (it.state()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5003 break; | 4998 break; |
| 5004 } | 4999 } |
| 5005 case LookupIterator::DATA: | 5000 case LookupIterator::DATA: |
| 5006 if (is_observed) { | 5001 if (is_observed) { |
| 5007 old_value = it.GetDataValue(); | 5002 old_value = it.GetDataValue(); |
| 5008 } | 5003 } |
| 5009 // Fall through. | 5004 // Fall through. |
| 5010 case LookupIterator::ACCESSOR: { | 5005 case LookupIterator::ACCESSOR: { |
| 5011 if (!it.IsConfigurable()) { | 5006 if (!it.IsConfigurable()) { |
| 5012 // Fail if the property is not configurable. | 5007 // Fail if the property is not configurable. |
| 5013 if (strict_mode == STRICT) { | 5008 if (is_strict(language_mode)) { |
| 5014 Handle<Object> args[2] = {name, object}; | 5009 Handle<Object> args[2] = {name, object}; |
| 5015 THROW_NEW_ERROR(it.isolate(), | 5010 THROW_NEW_ERROR(it.isolate(), |
| 5016 NewTypeError("strict_delete_property", | 5011 NewTypeError("strict_delete_property", |
| 5017 HandleVector(args, arraysize(args))), | 5012 HandleVector(args, arraysize(args))), |
| 5018 Object); | 5013 Object); |
| 5019 } | 5014 } |
| 5020 return it.isolate()->factory()->false_value(); | 5015 return it.isolate()->factory()->false_value(); |
| 5021 } | 5016 } |
| 5022 | 5017 |
| 5023 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5018 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5045 } | 5040 } |
| 5046 } | 5041 } |
| 5047 } | 5042 } |
| 5048 | 5043 |
| 5049 return it.isolate()->factory()->true_value(); | 5044 return it.isolate()->factory()->true_value(); |
| 5050 } | 5045 } |
| 5051 | 5046 |
| 5052 | 5047 |
| 5053 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 5048 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
| 5054 uint32_t index, | 5049 uint32_t index, |
| 5055 StrictMode strict_mode) { | 5050 LanguageMode language_mode) { |
| 5056 if (object->IsJSProxy()) { | 5051 if (object->IsJSProxy()) { |
| 5057 return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), | 5052 return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), |
| 5058 index, strict_mode); | 5053 index, language_mode); |
| 5059 } | 5054 } |
| 5060 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, | 5055 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, |
| 5061 strict_mode); | 5056 language_mode); |
| 5062 } | 5057 } |
| 5063 | 5058 |
| 5064 | 5059 |
| 5065 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, | 5060 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
| 5066 Handle<Name> name, | 5061 Handle<Name> name, |
| 5067 StrictMode strict_mode) { | 5062 LanguageMode language_mode) { |
| 5068 if (object->IsJSProxy()) { | 5063 if (object->IsJSProxy()) { |
| 5069 return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), | 5064 return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), |
| 5070 name, strict_mode); | 5065 name, language_mode); |
| 5071 } | 5066 } |
| 5072 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, | 5067 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, |
| 5073 strict_mode); | 5068 language_mode); |
| 5074 } | 5069 } |
| 5075 | 5070 |
| 5076 | 5071 |
| 5077 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5072 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 5078 ElementsKind kind, | 5073 ElementsKind kind, |
| 5079 Object* object) { | 5074 Object* object) { |
| 5080 DCHECK(IsFastObjectElementsKind(kind) || | 5075 DCHECK(IsFastObjectElementsKind(kind) || |
| 5081 kind == DICTIONARY_ELEMENTS); | 5076 kind == DICTIONARY_ELEMENTS); |
| 5082 if (IsFastObjectElementsKind(kind)) { | 5077 if (IsFastObjectElementsKind(kind)) { |
| 5083 int length = IsJSArray() | 5078 int length = IsJSArray() |
| (...skipping 4804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9888 } else { | 9883 } else { |
| 9889 function->map()->set_non_instance_prototype(false); | 9884 function->map()->set_non_instance_prototype(false); |
| 9890 } | 9885 } |
| 9891 | 9886 |
| 9892 return SetInstancePrototype(function, construct_prototype); | 9887 return SetInstancePrototype(function, construct_prototype); |
| 9893 } | 9888 } |
| 9894 | 9889 |
| 9895 | 9890 |
| 9896 bool JSFunction::RemovePrototype() { | 9891 bool JSFunction::RemovePrototype() { |
| 9897 Context* native_context = context()->native_context(); | 9892 Context* native_context = context()->native_context(); |
| 9898 Map* no_prototype_map = shared()->strict_mode() == SLOPPY | 9893 Map* no_prototype_map = |
| 9899 ? native_context->sloppy_function_without_prototype_map() | 9894 is_strict(shared()->language_mode()) |
| 9900 : native_context->strict_function_without_prototype_map(); | 9895 ? native_context->strict_function_without_prototype_map() |
| 9896 : native_context->sloppy_function_without_prototype_map(); |
| 9901 | 9897 |
| 9902 if (map() == no_prototype_map) return true; | 9898 if (map() == no_prototype_map) return true; |
| 9903 | 9899 |
| 9904 #ifdef DEBUG | 9900 #ifdef DEBUG |
| 9905 if (map() != (shared()->strict_mode() == SLOPPY | 9901 if (map() != (is_strict(shared()->language_mode()) |
| 9906 ? native_context->sloppy_function_map() | 9902 ? native_context->strict_function_map() |
| 9907 : native_context->strict_function_map())) { | 9903 : native_context->sloppy_function_map())) { |
| 9908 return false; | 9904 return false; |
| 9909 } | 9905 } |
| 9910 #endif | 9906 #endif |
| 9911 | 9907 |
| 9912 set_map(no_prototype_map); | 9908 set_map(no_prototype_map); |
| 9913 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); | 9909 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); |
| 9914 return true; | 9910 return true; |
| 9915 } | 9911 } |
| 9916 | 9912 |
| 9917 | 9913 |
| (...skipping 1366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11284 case FAST: return "FAST"; | 11280 case FAST: return "FAST"; |
| 11285 } | 11281 } |
| 11286 UNREACHABLE(); // keep the compiler happy | 11282 UNREACHABLE(); // keep the compiler happy |
| 11287 return NULL; | 11283 return NULL; |
| 11288 } | 11284 } |
| 11289 | 11285 |
| 11290 | 11286 |
| 11291 void Code::PrintExtraICState(std::ostream& os, // NOLINT | 11287 void Code::PrintExtraICState(std::ostream& os, // NOLINT |
| 11292 Kind kind, ExtraICState extra) { | 11288 Kind kind, ExtraICState extra) { |
| 11293 os << "extra_ic_state = "; | 11289 os << "extra_ic_state = "; |
| 11294 if ((kind == STORE_IC || kind == KEYED_STORE_IC) && (extra == STRICT)) { | 11290 if ((kind == STORE_IC || kind == KEYED_STORE_IC) && |
| 11291 is_strict(static_cast<LanguageMode>(extra))) { |
| 11295 os << "STRICT\n"; | 11292 os << "STRICT\n"; |
| 11296 } else { | 11293 } else { |
| 11297 os << extra << "\n"; | 11294 os << extra << "\n"; |
| 11298 } | 11295 } |
| 11299 } | 11296 } |
| 11300 | 11297 |
| 11301 | 11298 |
| 11302 void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT | 11299 void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT |
| 11303 os << "kind = " << Kind2String(kind()) << "\n"; | 11300 os << "kind = " << Kind2String(kind()) << "\n"; |
| 11304 if (IsCodeStubOrIC()) { | 11301 if (IsCodeStubOrIC()) { |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12178 } | 12175 } |
| 12179 | 12176 |
| 12180 // Check for lookup interceptor. | 12177 // Check for lookup interceptor. |
| 12181 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); | 12178 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); |
| 12182 | 12179 |
| 12183 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); | 12180 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); |
| 12184 } | 12181 } |
| 12185 | 12182 |
| 12186 | 12183 |
| 12187 MaybeHandle<Object> JSObject::SetElementWithInterceptor( | 12184 MaybeHandle<Object> JSObject::SetElementWithInterceptor( |
| 12188 Handle<JSObject> object, | 12185 Handle<JSObject> object, uint32_t index, Handle<Object> value, |
| 12189 uint32_t index, | 12186 PropertyAttributes attributes, LanguageMode language_mode, |
| 12190 Handle<Object> value, | 12187 bool check_prototype, SetPropertyMode set_mode) { |
| 12191 PropertyAttributes attributes, | |
| 12192 StrictMode strict_mode, | |
| 12193 bool check_prototype, | |
| 12194 SetPropertyMode set_mode) { | |
| 12195 Isolate* isolate = object->GetIsolate(); | 12188 Isolate* isolate = object->GetIsolate(); |
| 12196 | 12189 |
| 12197 // Make sure that the top context does not change when doing | 12190 // Make sure that the top context does not change when doing |
| 12198 // callbacks or interceptor calls. | 12191 // callbacks or interceptor calls. |
| 12199 AssertNoContextChange ncc(isolate); | 12192 AssertNoContextChange ncc(isolate); |
| 12200 | 12193 |
| 12201 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | 12194 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
| 12202 if (!interceptor->setter()->IsUndefined()) { | 12195 if (!interceptor->setter()->IsUndefined()) { |
| 12203 v8::IndexedPropertySetterCallback setter = | 12196 v8::IndexedPropertySetterCallback setter = |
| 12204 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 12197 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 12205 LOG(isolate, | 12198 LOG(isolate, |
| 12206 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); | 12199 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); |
| 12207 PropertyCallbackArguments args(isolate, interceptor->data(), *object, | 12200 PropertyCallbackArguments args(isolate, interceptor->data(), *object, |
| 12208 *object); | 12201 *object); |
| 12209 v8::Handle<v8::Value> result = | 12202 v8::Handle<v8::Value> result = |
| 12210 args.Call(setter, index, v8::Utils::ToLocal(value)); | 12203 args.Call(setter, index, v8::Utils::ToLocal(value)); |
| 12211 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12204 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12212 if (!result.IsEmpty()) return value; | 12205 if (!result.IsEmpty()) return value; |
| 12213 } | 12206 } |
| 12214 | 12207 |
| 12215 return SetElementWithoutInterceptor(object, index, value, attributes, | 12208 return SetElementWithoutInterceptor(object, index, value, attributes, |
| 12216 strict_mode, | 12209 language_mode, check_prototype, set_mode); |
| 12217 check_prototype, | |
| 12218 set_mode); | |
| 12219 } | 12210 } |
| 12220 | 12211 |
| 12221 | 12212 |
| 12222 MaybeHandle<Object> JSObject::GetElementWithCallback( | 12213 MaybeHandle<Object> JSObject::GetElementWithCallback( |
| 12223 Handle<JSObject> object, | 12214 Handle<JSObject> object, |
| 12224 Handle<Object> receiver, | 12215 Handle<Object> receiver, |
| 12225 Handle<Object> structure, | 12216 Handle<Object> structure, |
| 12226 uint32_t index, | 12217 uint32_t index, |
| 12227 Handle<Object> holder) { | 12218 Handle<Object> holder) { |
| 12228 Isolate* isolate = object->GetIsolate(); | 12219 Isolate* isolate = object->GetIsolate(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12263 return isolate->factory()->undefined_value(); | 12254 return isolate->factory()->undefined_value(); |
| 12264 } | 12255 } |
| 12265 | 12256 |
| 12266 UNREACHABLE(); | 12257 UNREACHABLE(); |
| 12267 return MaybeHandle<Object>(); | 12258 return MaybeHandle<Object>(); |
| 12268 } | 12259 } |
| 12269 | 12260 |
| 12270 | 12261 |
| 12271 MaybeHandle<Object> JSObject::SetElementWithCallback( | 12262 MaybeHandle<Object> JSObject::SetElementWithCallback( |
| 12272 Handle<Object> object, Handle<Object> structure, uint32_t index, | 12263 Handle<Object> object, Handle<Object> structure, uint32_t index, |
| 12273 Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode) { | 12264 Handle<Object> value, Handle<JSObject> holder, LanguageMode language_mode) { |
| 12274 Isolate* isolate = holder->GetIsolate(); | 12265 Isolate* isolate = holder->GetIsolate(); |
| 12275 | 12266 |
| 12276 // We should never get here to initialize a const with the hole | 12267 // We should never get here to initialize a const with the hole |
| 12277 // value since a const declaration would conflict with the setter. | 12268 // value since a const declaration would conflict with the setter. |
| 12278 DCHECK(!value->IsTheHole()); | 12269 DCHECK(!value->IsTheHole()); |
| 12279 DCHECK(!structure->IsForeign()); | 12270 DCHECK(!structure->IsForeign()); |
| 12280 if (structure->IsExecutableAccessorInfo()) { | 12271 if (structure->IsExecutableAccessorInfo()) { |
| 12281 // api style callbacks | 12272 // api style callbacks |
| 12282 Handle<ExecutableAccessorInfo> data = | 12273 Handle<ExecutableAccessorInfo> data = |
| 12283 Handle<ExecutableAccessorInfo>::cast(structure); | 12274 Handle<ExecutableAccessorInfo>::cast(structure); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 12297 return value; | 12288 return value; |
| 12298 } | 12289 } |
| 12299 | 12290 |
| 12300 if (structure->IsAccessorPair()) { | 12291 if (structure->IsAccessorPair()) { |
| 12301 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 12292 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 12302 if (setter->IsSpecFunction()) { | 12293 if (setter->IsSpecFunction()) { |
| 12303 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12294 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 12304 return SetPropertyWithDefinedSetter( | 12295 return SetPropertyWithDefinedSetter( |
| 12305 object, Handle<JSReceiver>::cast(setter), value); | 12296 object, Handle<JSReceiver>::cast(setter), value); |
| 12306 } else { | 12297 } else { |
| 12307 if (strict_mode == SLOPPY) return value; | 12298 if (is_sloppy(language_mode)) return value; |
| 12308 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 12299 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
| 12309 Handle<Object> args[2] = { key, holder }; | 12300 Handle<Object> args[2] = { key, holder }; |
| 12310 THROW_NEW_ERROR( | 12301 THROW_NEW_ERROR( |
| 12311 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), | 12302 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), |
| 12312 Object); | 12303 Object); |
| 12313 } | 12304 } |
| 12314 } | 12305 } |
| 12315 | 12306 |
| 12316 UNREACHABLE(); | 12307 UNREACHABLE(); |
| 12317 return MaybeHandle<Object>(); | 12308 return MaybeHandle<Object>(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 12341 return arguments->IsDictionary(); | 12332 return arguments->IsDictionary(); |
| 12342 } | 12333 } |
| 12343 | 12334 |
| 12344 | 12335 |
| 12345 // Adding n elements in fast case is O(n*n). | 12336 // Adding n elements in fast case is O(n*n). |
| 12346 // Note: revisit design to have dual undefined values to capture absent | 12337 // Note: revisit design to have dual undefined values to capture absent |
| 12347 // elements. | 12338 // elements. |
| 12348 MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object, | 12339 MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
| 12349 uint32_t index, | 12340 uint32_t index, |
| 12350 Handle<Object> value, | 12341 Handle<Object> value, |
| 12351 StrictMode strict_mode, | 12342 LanguageMode language_mode, |
| 12352 bool check_prototype) { | 12343 bool check_prototype) { |
| 12353 DCHECK(object->HasFastSmiOrObjectElements() || | 12344 DCHECK(object->HasFastSmiOrObjectElements() || |
| 12354 object->HasFastArgumentsElements()); | 12345 object->HasFastArgumentsElements()); |
| 12355 | 12346 |
| 12356 Isolate* isolate = object->GetIsolate(); | 12347 Isolate* isolate = object->GetIsolate(); |
| 12357 | 12348 |
| 12358 // Array optimizations rely on the prototype lookups of Array objects always | 12349 // Array optimizations rely on the prototype lookups of Array objects always |
| 12359 // returning undefined. If there is a store to the initial prototype object, | 12350 // returning undefined. If there is a store to the initial prototype object, |
| 12360 // make sure all of these optimizations are invalidated. | 12351 // make sure all of these optimizations are invalidated. |
| 12361 if (isolate->is_initial_object_prototype(*object) || | 12352 if (isolate->is_initial_object_prototype(*object) || |
| 12362 isolate->is_initial_array_prototype(*object)) { | 12353 isolate->is_initial_array_prototype(*object)) { |
| 12363 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, | 12354 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
| 12364 DependentCode::kElementsCantBeAddedGroup); | 12355 DependentCode::kElementsCantBeAddedGroup); |
| 12365 } | 12356 } |
| 12366 | 12357 |
| 12367 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); | 12358 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
| 12368 if (backing_store->map() == | 12359 if (backing_store->map() == |
| 12369 isolate->heap()->sloppy_arguments_elements_map()) { | 12360 isolate->heap()->sloppy_arguments_elements_map()) { |
| 12370 backing_store = handle(FixedArray::cast(backing_store->get(1))); | 12361 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
| 12371 } else { | 12362 } else { |
| 12372 backing_store = EnsureWritableFastElements(object); | 12363 backing_store = EnsureWritableFastElements(object); |
| 12373 } | 12364 } |
| 12374 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12365 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 12375 | 12366 |
| 12376 if (check_prototype && | 12367 if (check_prototype && |
| 12377 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12368 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
| 12378 bool found; | 12369 bool found; |
| 12379 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( | 12370 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12380 object, index, value, &found, strict_mode); | 12371 object, index, value, &found, language_mode); |
| 12381 if (found) return result; | 12372 if (found) return result; |
| 12382 } | 12373 } |
| 12383 | 12374 |
| 12384 uint32_t new_capacity = capacity; | 12375 uint32_t new_capacity = capacity; |
| 12385 // Check if the length property of this object needs to be updated. | 12376 // Check if the length property of this object needs to be updated. |
| 12386 uint32_t array_length = 0; | 12377 uint32_t array_length = 0; |
| 12387 bool must_update_array_length = false; | 12378 bool must_update_array_length = false; |
| 12388 bool introduces_holes = true; | 12379 bool introduces_holes = true; |
| 12389 if (object->IsJSArray()) { | 12380 if (object->IsJSArray()) { |
| 12390 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); | 12381 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 12413 bool convert_to_slow = true; | 12404 bool convert_to_slow = true; |
| 12414 if ((index - capacity) < kMaxGap) { | 12405 if ((index - capacity) < kMaxGap) { |
| 12415 new_capacity = NewElementsCapacity(index + 1); | 12406 new_capacity = NewElementsCapacity(index + 1); |
| 12416 DCHECK(new_capacity > index); | 12407 DCHECK(new_capacity > index); |
| 12417 if (!object->ShouldConvertToSlowElements(new_capacity)) { | 12408 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
| 12418 convert_to_slow = false; | 12409 convert_to_slow = false; |
| 12419 } | 12410 } |
| 12420 } | 12411 } |
| 12421 if (convert_to_slow) { | 12412 if (convert_to_slow) { |
| 12422 NormalizeElements(object); | 12413 NormalizeElements(object); |
| 12423 return SetDictionaryElement(object, index, value, NONE, strict_mode, | 12414 return SetDictionaryElement(object, index, value, NONE, language_mode, |
| 12424 check_prototype); | 12415 check_prototype); |
| 12425 } | 12416 } |
| 12426 } | 12417 } |
| 12427 // Convert to fast double elements if appropriate. | 12418 // Convert to fast double elements if appropriate. |
| 12428 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 12419 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
| 12429 // Consider fixing the boilerplate as well if we have one. | 12420 // Consider fixing the boilerplate as well if we have one. |
| 12430 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 12421 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
| 12431 ? FAST_HOLEY_DOUBLE_ELEMENTS | 12422 ? FAST_HOLEY_DOUBLE_ELEMENTS |
| 12432 : FAST_DOUBLE_ELEMENTS; | 12423 : FAST_DOUBLE_ELEMENTS; |
| 12433 | 12424 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12467 DCHECK(object->elements()->IsFixedArray()); | 12458 DCHECK(object->elements()->IsFixedArray()); |
| 12468 backing_store->set(index, *value); | 12459 backing_store->set(index, *value); |
| 12469 if (must_update_array_length) { | 12460 if (must_update_array_length) { |
| 12470 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | 12461 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
| 12471 } | 12462 } |
| 12472 return value; | 12463 return value; |
| 12473 } | 12464 } |
| 12474 | 12465 |
| 12475 | 12466 |
| 12476 MaybeHandle<Object> JSObject::SetDictionaryElement( | 12467 MaybeHandle<Object> JSObject::SetDictionaryElement( |
| 12477 Handle<JSObject> object, | 12468 Handle<JSObject> object, uint32_t index, Handle<Object> value, |
| 12478 uint32_t index, | 12469 PropertyAttributes attributes, LanguageMode language_mode, |
| 12479 Handle<Object> value, | 12470 bool check_prototype, SetPropertyMode set_mode) { |
| 12480 PropertyAttributes attributes, | |
| 12481 StrictMode strict_mode, | |
| 12482 bool check_prototype, | |
| 12483 SetPropertyMode set_mode) { | |
| 12484 DCHECK(object->HasDictionaryElements() || | 12471 DCHECK(object->HasDictionaryElements() || |
| 12485 object->HasDictionaryArgumentsElements()); | 12472 object->HasDictionaryArgumentsElements()); |
| 12486 Isolate* isolate = object->GetIsolate(); | 12473 Isolate* isolate = object->GetIsolate(); |
| 12487 | 12474 |
| 12488 // Insert element in the dictionary. | 12475 // Insert element in the dictionary. |
| 12489 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12476 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 12490 bool is_arguments = | 12477 bool is_arguments = |
| 12491 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12478 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 12492 Handle<SeededNumberDictionary> dictionary(is_arguments | 12479 Handle<SeededNumberDictionary> dictionary(is_arguments |
| 12493 ? SeededNumberDictionary::cast(elements->get(1)) | 12480 ? SeededNumberDictionary::cast(elements->get(1)) |
| 12494 : SeededNumberDictionary::cast(*elements)); | 12481 : SeededNumberDictionary::cast(*elements)); |
| 12495 | 12482 |
| 12496 int entry = dictionary->FindEntry(index); | 12483 int entry = dictionary->FindEntry(index); |
| 12497 if (entry != SeededNumberDictionary::kNotFound) { | 12484 if (entry != SeededNumberDictionary::kNotFound) { |
| 12498 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12485 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
| 12499 PropertyDetails details = dictionary->DetailsAt(entry); | 12486 PropertyDetails details = dictionary->DetailsAt(entry); |
| 12500 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { | 12487 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { |
| 12501 return SetElementWithCallback(object, element, index, value, object, | 12488 return SetElementWithCallback(object, element, index, value, object, |
| 12502 strict_mode); | 12489 language_mode); |
| 12503 } else { | 12490 } else { |
| 12504 dictionary->UpdateMaxNumberKey(index); | 12491 dictionary->UpdateMaxNumberKey(index); |
| 12505 // If a value has not been initialized we allow writing to it even if it | 12492 // If a value has not been initialized we allow writing to it even if it |
| 12506 // is read-only (a declared const that has not been initialized). If a | 12493 // is read-only (a declared const that has not been initialized). If a |
| 12507 // value is being defined we skip attribute checks completely. | 12494 // value is being defined we skip attribute checks completely. |
| 12508 if (set_mode == DEFINE_PROPERTY) { | 12495 if (set_mode == DEFINE_PROPERTY) { |
| 12509 details = PropertyDetails(attributes, DATA, details.dictionary_index()); | 12496 details = PropertyDetails(attributes, DATA, details.dictionary_index()); |
| 12510 dictionary->DetailsAtPut(entry, details); | 12497 dictionary->DetailsAtPut(entry, details); |
| 12511 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12498 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
| 12512 if (strict_mode == SLOPPY) { | 12499 if (is_sloppy(language_mode)) { |
| 12513 return isolate->factory()->undefined_value(); | 12500 return isolate->factory()->undefined_value(); |
| 12514 } else { | 12501 } else { |
| 12515 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12502 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12516 Handle<Object> args[2] = { number, object }; | 12503 Handle<Object> args[2] = { number, object }; |
| 12517 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 12504 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 12518 HandleVector(args, 2)), | 12505 HandleVector(args, 2)), |
| 12519 Object); | 12506 Object); |
| 12520 } | 12507 } |
| 12521 } | 12508 } |
| 12522 // Elements of the arguments object in slow mode might be slow aliases. | 12509 // Elements of the arguments object in slow mode might be slow aliases. |
| 12523 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12510 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 12524 Handle<AliasedArgumentsEntry> entry = | 12511 Handle<AliasedArgumentsEntry> entry = |
| 12525 Handle<AliasedArgumentsEntry>::cast(element); | 12512 Handle<AliasedArgumentsEntry>::cast(element); |
| 12526 Handle<Context> context(Context::cast(elements->get(0))); | 12513 Handle<Context> context(Context::cast(elements->get(0))); |
| 12527 int context_index = entry->aliased_context_slot(); | 12514 int context_index = entry->aliased_context_slot(); |
| 12528 DCHECK(!context->get(context_index)->IsTheHole()); | 12515 DCHECK(!context->get(context_index)->IsTheHole()); |
| 12529 context->set(context_index, *value); | 12516 context->set(context_index, *value); |
| 12530 // For elements that are still writable we keep slow aliasing. | 12517 // For elements that are still writable we keep slow aliasing. |
| 12531 if (!details.IsReadOnly()) value = element; | 12518 if (!details.IsReadOnly()) value = element; |
| 12532 } | 12519 } |
| 12533 dictionary->ValueAtPut(entry, *value); | 12520 dictionary->ValueAtPut(entry, *value); |
| 12534 } | 12521 } |
| 12535 } else { | 12522 } else { |
| 12536 // Index not already used. Look for an accessor in the prototype chain. | 12523 // Index not already used. Look for an accessor in the prototype chain. |
| 12537 // Can cause GC! | 12524 // Can cause GC! |
| 12538 if (check_prototype) { | 12525 if (check_prototype) { |
| 12539 bool found; | 12526 bool found; |
| 12540 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( | 12527 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12541 object, index, value, &found, strict_mode); | 12528 object, index, value, &found, language_mode); |
| 12542 if (found) return result; | 12529 if (found) return result; |
| 12543 } | 12530 } |
| 12544 | 12531 |
| 12545 // When we set the is_extensible flag to false we always force the | 12532 // When we set the is_extensible flag to false we always force the |
| 12546 // element into dictionary mode (and force them to stay there). | 12533 // element into dictionary mode (and force them to stay there). |
| 12547 if (!object->map()->is_extensible()) { | 12534 if (!object->map()->is_extensible()) { |
| 12548 if (strict_mode == SLOPPY) { | 12535 if (is_sloppy(language_mode)) { |
| 12549 return isolate->factory()->undefined_value(); | 12536 return isolate->factory()->undefined_value(); |
| 12550 } else { | 12537 } else { |
| 12551 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12538 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12552 Handle<String> name = isolate->factory()->NumberToString(number); | 12539 Handle<String> name = isolate->factory()->NumberToString(number); |
| 12553 Handle<Object> args[1] = { name }; | 12540 Handle<Object> args[1] = { name }; |
| 12554 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", | 12541 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", |
| 12555 HandleVector(args, 1)), | 12542 HandleVector(args, 1)), |
| 12556 Object); | 12543 Object); |
| 12557 } | 12544 } |
| 12558 } | 12545 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12602 if (FLAG_trace_normalization) { | 12589 if (FLAG_trace_normalization) { |
| 12603 OFStream os(stdout); | 12590 OFStream os(stdout); |
| 12604 os << "Object elements are fast case again:\n"; | 12591 os << "Object elements are fast case again:\n"; |
| 12605 object->Print(os); | 12592 object->Print(os); |
| 12606 } | 12593 } |
| 12607 #endif | 12594 #endif |
| 12608 } | 12595 } |
| 12609 return value; | 12596 return value; |
| 12610 } | 12597 } |
| 12611 | 12598 |
| 12612 MaybeHandle<Object> JSObject::SetFastDoubleElement( | 12599 MaybeHandle<Object> JSObject::SetFastDoubleElement(Handle<JSObject> object, |
| 12613 Handle<JSObject> object, | 12600 uint32_t index, |
| 12614 uint32_t index, | 12601 Handle<Object> value, |
| 12615 Handle<Object> value, | 12602 LanguageMode language_mode, |
| 12616 StrictMode strict_mode, | 12603 bool check_prototype) { |
| 12617 bool check_prototype) { | |
| 12618 DCHECK(object->HasFastDoubleElements()); | 12604 DCHECK(object->HasFastDoubleElements()); |
| 12619 | 12605 |
| 12620 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); | 12606 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
| 12621 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12607 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
| 12622 | 12608 |
| 12623 // If storing to an element that isn't in the array, pass the store request | 12609 // If storing to an element that isn't in the array, pass the store request |
| 12624 // up the prototype chain before storing in the receiver's elements. | 12610 // up the prototype chain before storing in the receiver's elements. |
| 12625 if (check_prototype && | 12611 if (check_prototype && |
| 12626 (index >= elms_length || | 12612 (index >= elms_length || |
| 12627 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { | 12613 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
| 12628 bool found; | 12614 bool found; |
| 12629 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( | 12615 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12630 object, index, value, &found, strict_mode); | 12616 object, index, value, &found, language_mode); |
| 12631 if (found) return result; | 12617 if (found) return result; |
| 12632 } | 12618 } |
| 12633 | 12619 |
| 12634 // If the value object is not a heap number, switch to fast elements and try | 12620 // If the value object is not a heap number, switch to fast elements and try |
| 12635 // again. | 12621 // again. |
| 12636 bool value_is_smi = value->IsSmi(); | 12622 bool value_is_smi = value->IsSmi(); |
| 12637 bool introduces_holes = true; | 12623 bool introduces_holes = true; |
| 12638 uint32_t length = elms_length; | 12624 uint32_t length = elms_length; |
| 12639 if (object->IsJSArray()) { | 12625 if (object->IsJSArray()) { |
| 12640 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); | 12626 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); |
| 12641 introduces_holes = index > length; | 12627 introduces_holes = index > length; |
| 12642 } else { | 12628 } else { |
| 12643 introduces_holes = index >= elms_length; | 12629 introduces_holes = index >= elms_length; |
| 12644 } | 12630 } |
| 12645 | 12631 |
| 12646 if (!value->IsNumber()) { | 12632 if (!value->IsNumber()) { |
| 12647 SetFastElementsCapacityAndLength(object, elms_length, length, | 12633 SetFastElementsCapacityAndLength(object, elms_length, length, |
| 12648 kDontAllowSmiElements); | 12634 kDontAllowSmiElements); |
| 12649 Handle<Object> result; | 12635 Handle<Object> result; |
| 12650 ASSIGN_RETURN_ON_EXCEPTION( | 12636 ASSIGN_RETURN_ON_EXCEPTION( |
| 12651 object->GetIsolate(), result, | 12637 object->GetIsolate(), result, |
| 12652 SetFastElement(object, index, value, strict_mode, check_prototype), | 12638 SetFastElement(object, index, value, language_mode, check_prototype), |
| 12653 Object); | 12639 Object); |
| 12654 JSObject::ValidateElements(object); | 12640 JSObject::ValidateElements(object); |
| 12655 return result; | 12641 return result; |
| 12656 } | 12642 } |
| 12657 | 12643 |
| 12658 double double_value = value_is_smi | 12644 double double_value = value_is_smi |
| 12659 ? static_cast<double>(Handle<Smi>::cast(value)->value()) | 12645 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
| 12660 : Handle<HeapNumber>::cast(value)->value(); | 12646 : Handle<HeapNumber>::cast(value)->value(); |
| 12661 | 12647 |
| 12662 // If the array is growing, and it's not growth by a single element at the | 12648 // If the array is growing, and it's not growth by a single element at the |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12697 } | 12683 } |
| 12698 | 12684 |
| 12699 // Otherwise default to slow case. | 12685 // Otherwise default to slow case. |
| 12700 DCHECK(object->HasFastDoubleElements()); | 12686 DCHECK(object->HasFastDoubleElements()); |
| 12701 DCHECK(object->map()->has_fast_double_elements()); | 12687 DCHECK(object->map()->has_fast_double_elements()); |
| 12702 DCHECK(object->elements()->IsFixedDoubleArray() || | 12688 DCHECK(object->elements()->IsFixedDoubleArray() || |
| 12703 object->elements()->length() == 0); | 12689 object->elements()->length() == 0); |
| 12704 | 12690 |
| 12705 NormalizeElements(object); | 12691 NormalizeElements(object); |
| 12706 DCHECK(object->HasDictionaryElements()); | 12692 DCHECK(object->HasDictionaryElements()); |
| 12707 return SetElement(object, index, value, NONE, strict_mode, check_prototype); | 12693 return SetElement(object, index, value, NONE, language_mode, check_prototype); |
| 12708 } | 12694 } |
| 12709 | 12695 |
| 12710 | 12696 |
| 12711 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12697 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
| 12712 uint32_t index, | 12698 uint32_t index, Handle<Object> value, |
| 12713 Handle<Object> value, | |
| 12714 PropertyAttributes attributes, | 12699 PropertyAttributes attributes, |
| 12715 StrictMode strict_mode) { | 12700 LanguageMode language_mode) { |
| 12716 if (object->IsJSProxy()) { | 12701 if (object->IsJSProxy()) { |
| 12717 return JSProxy::SetElementWithHandler( | 12702 return JSProxy::SetElementWithHandler(Handle<JSProxy>::cast(object), object, |
| 12718 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12703 index, value, language_mode); |
| 12719 } | 12704 } |
| 12720 return JSObject::SetElement( | 12705 return JSObject::SetElement(Handle<JSObject>::cast(object), index, value, |
| 12721 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12706 attributes, language_mode); |
| 12722 } | 12707 } |
| 12723 | 12708 |
| 12724 | 12709 |
| 12725 MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12710 MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
| 12726 uint32_t index, | 12711 uint32_t index, |
| 12727 Handle<Object> value, | 12712 Handle<Object> value, |
| 12728 StrictMode strict_mode) { | 12713 LanguageMode language_mode) { |
| 12729 DCHECK(!object->HasExternalArrayElements()); | 12714 DCHECK(!object->HasExternalArrayElements()); |
| 12730 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); | 12715 return JSObject::SetElement(object, index, value, NONE, language_mode, false); |
| 12731 } | 12716 } |
| 12732 | 12717 |
| 12733 | 12718 |
| 12734 MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, | 12719 MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, |
| 12735 uint32_t index, | 12720 uint32_t index, Handle<Object> value, |
| 12736 Handle<Object> value, | |
| 12737 PropertyAttributes attributes, | 12721 PropertyAttributes attributes, |
| 12738 StrictMode strict_mode, | 12722 LanguageMode language_mode, |
| 12739 bool check_prototype, | 12723 bool check_prototype, |
| 12740 SetPropertyMode set_mode) { | 12724 SetPropertyMode set_mode) { |
| 12741 Isolate* isolate = object->GetIsolate(); | 12725 Isolate* isolate = object->GetIsolate(); |
| 12742 | 12726 |
| 12743 if (object->HasExternalArrayElements() || | 12727 if (object->HasExternalArrayElements() || |
| 12744 object->HasFixedTypedArrayElements()) { | 12728 object->HasFixedTypedArrayElements()) { |
| 12745 if (!value->IsNumber() && !value->IsUndefined()) { | 12729 if (!value->IsNumber() && !value->IsUndefined()) { |
| 12746 ASSIGN_RETURN_ON_EXCEPTION( | 12730 ASSIGN_RETURN_ON_EXCEPTION( |
| 12747 isolate, value, | 12731 isolate, value, |
| 12748 Execution::ToNumber(isolate, value), Object); | 12732 Execution::ToNumber(isolate, value), Object); |
| 12749 } | 12733 } |
| 12750 } | 12734 } |
| 12751 | 12735 |
| 12752 // Check access rights if needed. | 12736 // Check access rights if needed. |
| 12753 if (object->IsAccessCheckNeeded()) { | 12737 if (object->IsAccessCheckNeeded()) { |
| 12754 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { | 12738 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { |
| 12755 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 12739 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 12756 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12740 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12757 return value; | 12741 return value; |
| 12758 } | 12742 } |
| 12759 } | 12743 } |
| 12760 | 12744 |
| 12761 if (object->IsJSGlobalProxy()) { | 12745 if (object->IsJSGlobalProxy()) { |
| 12762 PrototypeIterator iter(isolate, object); | 12746 PrototypeIterator iter(isolate, object); |
| 12763 if (iter.IsAtEnd()) return value; | 12747 if (iter.IsAtEnd()) return value; |
| 12764 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 12748 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 12765 return SetElement( | 12749 return SetElement( |
| 12766 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 12750 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
| 12767 value, attributes, strict_mode, check_prototype, set_mode); | 12751 value, attributes, language_mode, check_prototype, set_mode); |
| 12768 } | 12752 } |
| 12769 | 12753 |
| 12770 // Don't allow element properties to be redefined for external arrays. | 12754 // Don't allow element properties to be redefined for external arrays. |
| 12771 if ((object->HasExternalArrayElements() || | 12755 if ((object->HasExternalArrayElements() || |
| 12772 object->HasFixedTypedArrayElements()) && | 12756 object->HasFixedTypedArrayElements()) && |
| 12773 set_mode == DEFINE_PROPERTY) { | 12757 set_mode == DEFINE_PROPERTY) { |
| 12774 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12758 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12775 Handle<Object> args[] = { object, number }; | 12759 Handle<Object> args[] = { object, number }; |
| 12776 THROW_NEW_ERROR(isolate, NewTypeError("redef_external_array_element", | 12760 THROW_NEW_ERROR(isolate, NewTypeError("redef_external_array_element", |
| 12777 HandleVector(args, arraysize(args))), | 12761 HandleVector(args, arraysize(args))), |
| 12778 Object); | 12762 Object); |
| 12779 } | 12763 } |
| 12780 | 12764 |
| 12781 // Normalize the elements to enable attributes on the property. | 12765 // Normalize the elements to enable attributes on the property. |
| 12782 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12766 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 12783 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 12767 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 12784 // Make sure that we never go back to fast case. | 12768 // Make sure that we never go back to fast case. |
| 12785 dictionary->set_requires_slow_elements(); | 12769 dictionary->set_requires_slow_elements(); |
| 12786 } | 12770 } |
| 12787 | 12771 |
| 12788 if (!object->map()->is_observed()) { | 12772 if (!object->map()->is_observed()) { |
| 12789 return object->HasIndexedInterceptor() | 12773 return object->HasIndexedInterceptor() |
| 12790 ? SetElementWithInterceptor(object, index, value, attributes, | 12774 ? SetElementWithInterceptor(object, index, value, attributes, |
| 12791 strict_mode, check_prototype, set_mode) | 12775 language_mode, check_prototype, |
| 12792 : SetElementWithoutInterceptor(object, index, value, attributes, | 12776 set_mode) |
| 12793 strict_mode, check_prototype, set_mode); | 12777 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12778 language_mode, check_prototype, |
| 12779 set_mode); |
| 12794 } | 12780 } |
| 12795 | 12781 |
| 12796 Maybe<PropertyAttributes> maybe = | 12782 Maybe<PropertyAttributes> maybe = |
| 12797 JSReceiver::GetOwnElementAttribute(object, index); | 12783 JSReceiver::GetOwnElementAttribute(object, index); |
| 12798 if (!maybe.has_value) return MaybeHandle<Object>(); | 12784 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 12799 PropertyAttributes old_attributes = maybe.value; | 12785 PropertyAttributes old_attributes = maybe.value; |
| 12800 | 12786 |
| 12801 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12787 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 12802 Handle<Object> old_length_handle; | 12788 Handle<Object> old_length_handle; |
| 12803 Handle<Object> new_length_handle; | 12789 Handle<Object> new_length_handle; |
| 12804 | 12790 |
| 12805 if (old_attributes != ABSENT) { | 12791 if (old_attributes != ABSENT) { |
| 12806 if (GetOwnElementAccessorPair(object, index).is_null()) { | 12792 if (GetOwnElementAccessorPair(object, index).is_null()) { |
| 12807 old_value = Object::GetElement(isolate, object, index).ToHandleChecked(); | 12793 old_value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 12808 } | 12794 } |
| 12809 } else if (object->IsJSArray()) { | 12795 } else if (object->IsJSArray()) { |
| 12810 // Store old array length in case adding an element grows the array. | 12796 // Store old array length in case adding an element grows the array. |
| 12811 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12797 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12812 isolate); | 12798 isolate); |
| 12813 } | 12799 } |
| 12814 | 12800 |
| 12815 // Check for lookup interceptor | 12801 // Check for lookup interceptor |
| 12816 Handle<Object> result; | 12802 Handle<Object> result; |
| 12817 ASSIGN_RETURN_ON_EXCEPTION( | 12803 ASSIGN_RETURN_ON_EXCEPTION( |
| 12818 isolate, result, | 12804 isolate, result, |
| 12819 object->HasIndexedInterceptor() | 12805 object->HasIndexedInterceptor() |
| 12820 ? SetElementWithInterceptor( | 12806 ? SetElementWithInterceptor(object, index, value, attributes, |
| 12821 object, index, value, attributes, | 12807 language_mode, check_prototype, set_mode) |
| 12822 strict_mode, check_prototype, set_mode) | 12808 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12823 : SetElementWithoutInterceptor( | 12809 language_mode, check_prototype, |
| 12824 object, index, value, attributes, | 12810 set_mode), |
| 12825 strict_mode, check_prototype, set_mode), | |
| 12826 Object); | 12811 Object); |
| 12827 | 12812 |
| 12828 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12813 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 12829 maybe = GetOwnElementAttribute(object, index); | 12814 maybe = GetOwnElementAttribute(object, index); |
| 12830 if (!maybe.has_value) return MaybeHandle<Object>(); | 12815 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 12831 PropertyAttributes new_attributes = maybe.value; | 12816 PropertyAttributes new_attributes = maybe.value; |
| 12832 | 12817 |
| 12833 if (old_attributes == ABSENT) { | 12818 if (old_attributes == ABSENT) { |
| 12834 if (object->IsJSArray() && | 12819 if (object->IsJSArray() && |
| 12835 !old_length_handle->SameValue( | 12820 !old_length_handle->SameValue( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12880 isolate, EnqueueChangeRecord(object, "update", name, old_value), | 12865 isolate, EnqueueChangeRecord(object, "update", name, old_value), |
| 12881 Object); | 12866 Object); |
| 12882 } | 12867 } |
| 12883 } | 12868 } |
| 12884 | 12869 |
| 12885 return result; | 12870 return result; |
| 12886 } | 12871 } |
| 12887 | 12872 |
| 12888 | 12873 |
| 12889 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( | 12874 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( |
| 12890 Handle<JSObject> object, | 12875 Handle<JSObject> object, uint32_t index, Handle<Object> value, |
| 12891 uint32_t index, | 12876 PropertyAttributes attributes, LanguageMode language_mode, |
| 12892 Handle<Object> value, | 12877 bool check_prototype, SetPropertyMode set_mode) { |
| 12893 PropertyAttributes attributes, | |
| 12894 StrictMode strict_mode, | |
| 12895 bool check_prototype, | |
| 12896 SetPropertyMode set_mode) { | |
| 12897 DCHECK(object->HasDictionaryElements() || | 12878 DCHECK(object->HasDictionaryElements() || |
| 12898 object->HasDictionaryArgumentsElements() || | 12879 object->HasDictionaryArgumentsElements() || |
| 12899 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12880 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
| 12900 Isolate* isolate = object->GetIsolate(); | 12881 Isolate* isolate = object->GetIsolate(); |
| 12901 if (FLAG_trace_external_array_abuse && | 12882 if (FLAG_trace_external_array_abuse && |
| 12902 IsExternalArrayElementsKind(object->GetElementsKind())) { | 12883 IsExternalArrayElementsKind(object->GetElementsKind())) { |
| 12903 CheckArrayAbuse(object, "external elements write", index); | 12884 CheckArrayAbuse(object, "external elements write", index); |
| 12904 } | 12885 } |
| 12905 if (FLAG_trace_js_array_abuse && | 12886 if (FLAG_trace_js_array_abuse && |
| 12906 !IsExternalArrayElementsKind(object->GetElementsKind())) { | 12887 !IsExternalArrayElementsKind(object->GetElementsKind())) { |
| 12907 if (object->IsJSArray()) { | 12888 if (object->IsJSArray()) { |
| 12908 CheckArrayAbuse(object, "elements write", index, true); | 12889 CheckArrayAbuse(object, "elements write", index, true); |
| 12909 } | 12890 } |
| 12910 } | 12891 } |
| 12911 if (object->IsJSArray() && JSArray::WouldChangeReadOnlyLength( | 12892 if (object->IsJSArray() && JSArray::WouldChangeReadOnlyLength( |
| 12912 Handle<JSArray>::cast(object), index)) { | 12893 Handle<JSArray>::cast(object), index)) { |
| 12913 if (strict_mode == SLOPPY) { | 12894 if (is_sloppy(language_mode)) { |
| 12914 return value; | 12895 return value; |
| 12915 } else { | 12896 } else { |
| 12916 return JSArray::ReadOnlyLengthError(Handle<JSArray>::cast(object)); | 12897 return JSArray::ReadOnlyLengthError(Handle<JSArray>::cast(object)); |
| 12917 } | 12898 } |
| 12918 } | 12899 } |
| 12919 switch (object->GetElementsKind()) { | 12900 switch (object->GetElementsKind()) { |
| 12920 case FAST_SMI_ELEMENTS: | 12901 case FAST_SMI_ELEMENTS: |
| 12921 case FAST_ELEMENTS: | 12902 case FAST_ELEMENTS: |
| 12922 case FAST_HOLEY_SMI_ELEMENTS: | 12903 case FAST_HOLEY_SMI_ELEMENTS: |
| 12923 case FAST_HOLEY_ELEMENTS: | 12904 case FAST_HOLEY_ELEMENTS: |
| 12924 return SetFastElement(object, index, value, strict_mode, check_prototype); | 12905 return SetFastElement(object, index, value, language_mode, |
| 12906 check_prototype); |
| 12925 case FAST_DOUBLE_ELEMENTS: | 12907 case FAST_DOUBLE_ELEMENTS: |
| 12926 case FAST_HOLEY_DOUBLE_ELEMENTS: | 12908 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 12927 return SetFastDoubleElement(object, index, value, strict_mode, | 12909 return SetFastDoubleElement(object, index, value, language_mode, |
| 12928 check_prototype); | 12910 check_prototype); |
| 12929 | 12911 |
| 12930 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 12912 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 12931 case EXTERNAL_##TYPE##_ELEMENTS: { \ | 12913 case EXTERNAL_##TYPE##_ELEMENTS: { \ |
| 12932 Handle<External##Type##Array> array( \ | 12914 Handle<External##Type##Array> array( \ |
| 12933 External##Type##Array::cast(object->elements())); \ | 12915 External##Type##Array::cast(object->elements())); \ |
| 12934 return External##Type##Array::SetValue(array, index, value); \ | 12916 return External##Type##Array::SetValue(array, index, value); \ |
| 12935 } \ | 12917 } \ |
| 12936 case TYPE##_ELEMENTS: { \ | 12918 case TYPE##_ELEMENTS: { \ |
| 12937 Handle<Fixed##Type##Array> array( \ | 12919 Handle<Fixed##Type##Array> array( \ |
| 12938 Fixed##Type##Array::cast(object->elements())); \ | 12920 Fixed##Type##Array::cast(object->elements())); \ |
| 12939 return Fixed##Type##Array::SetValue(array, index, value); \ | 12921 return Fixed##Type##Array::SetValue(array, index, value); \ |
| 12940 } | 12922 } |
| 12941 | 12923 |
| 12942 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 12924 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 12943 | 12925 |
| 12944 #undef TYPED_ARRAY_CASE | 12926 #undef TYPED_ARRAY_CASE |
| 12945 | 12927 |
| 12946 case DICTIONARY_ELEMENTS: | 12928 case DICTIONARY_ELEMENTS: |
| 12947 return SetDictionaryElement(object, index, value, attributes, strict_mode, | 12929 return SetDictionaryElement(object, index, value, attributes, |
| 12948 check_prototype, | 12930 language_mode, check_prototype, set_mode); |
| 12949 set_mode); | |
| 12950 case SLOPPY_ARGUMENTS_ELEMENTS: { | 12931 case SLOPPY_ARGUMENTS_ELEMENTS: { |
| 12951 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 12932 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| 12952 uint32_t length = parameter_map->length(); | 12933 uint32_t length = parameter_map->length(); |
| 12953 Handle<Object> probe = index < length - 2 ? | 12934 Handle<Object> probe = index < length - 2 ? |
| 12954 Handle<Object>(parameter_map->get(index + 2), isolate) : | 12935 Handle<Object>(parameter_map->get(index + 2), isolate) : |
| 12955 Handle<Object>(); | 12936 Handle<Object>(); |
| 12956 if (!probe.is_null() && !probe->IsTheHole()) { | 12937 if (!probe.is_null() && !probe->IsTheHole()) { |
| 12957 Handle<Context> context(Context::cast(parameter_map->get(0))); | 12938 Handle<Context> context(Context::cast(parameter_map->get(0))); |
| 12958 int context_index = Handle<Smi>::cast(probe)->value(); | 12939 int context_index = Handle<Smi>::cast(probe)->value(); |
| 12959 DCHECK(!context->get(context_index)->IsTheHole()); | 12940 DCHECK(!context->get(context_index)->IsTheHole()); |
| 12960 context->set(context_index, *value); | 12941 context->set(context_index, *value); |
| 12961 // Redefining attributes of an aliased element destroys fast aliasing. | 12942 // Redefining attributes of an aliased element destroys fast aliasing. |
| 12962 if (set_mode == SET_PROPERTY || attributes == NONE) return value; | 12943 if (set_mode == SET_PROPERTY || attributes == NONE) return value; |
| 12963 parameter_map->set_the_hole(index + 2); | 12944 parameter_map->set_the_hole(index + 2); |
| 12964 // For elements that are still writable we re-establish slow aliasing. | 12945 // For elements that are still writable we re-establish slow aliasing. |
| 12965 if ((attributes & READ_ONLY) == 0) { | 12946 if ((attributes & READ_ONLY) == 0) { |
| 12966 value = Handle<Object>::cast( | 12947 value = Handle<Object>::cast( |
| 12967 isolate->factory()->NewAliasedArgumentsEntry(context_index)); | 12948 isolate->factory()->NewAliasedArgumentsEntry(context_index)); |
| 12968 } | 12949 } |
| 12969 } | 12950 } |
| 12970 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 12951 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 12971 if (arguments->IsDictionary()) { | 12952 if (arguments->IsDictionary()) { |
| 12972 return SetDictionaryElement(object, index, value, attributes, | 12953 return SetDictionaryElement(object, index, value, attributes, |
| 12973 strict_mode, | 12954 language_mode, check_prototype, set_mode); |
| 12974 check_prototype, | |
| 12975 set_mode); | |
| 12976 } else { | 12955 } else { |
| 12977 return SetFastElement(object, index, value, strict_mode, | 12956 return SetFastElement(object, index, value, language_mode, |
| 12978 check_prototype); | 12957 check_prototype); |
| 12979 } | 12958 } |
| 12980 } | 12959 } |
| 12981 } | 12960 } |
| 12982 // All possible cases have been handled above. Add a return to avoid the | 12961 // All possible cases have been handled above. Add a return to avoid the |
| 12983 // complaints from the compiler. | 12962 // complaints from the compiler. |
| 12984 UNREACHABLE(); | 12963 UNREACHABLE(); |
| 12985 return isolate->factory()->null_value(); | 12964 return isolate->factory()->null_value(); |
| 12986 } | 12965 } |
| 12987 | 12966 |
| (...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14004 } else { | 13983 } else { |
| 14005 os << " (" << PrivateSymbolToName() << ")"; | 13984 os << " (" << PrivateSymbolToName() << ")"; |
| 14006 } | 13985 } |
| 14007 os << ">"; | 13986 os << ">"; |
| 14008 } | 13987 } |
| 14009 | 13988 |
| 14010 | 13989 |
| 14011 // StringSharedKeys are used as keys in the eval cache. | 13990 // StringSharedKeys are used as keys in the eval cache. |
| 14012 class StringSharedKey : public HashTableKey { | 13991 class StringSharedKey : public HashTableKey { |
| 14013 public: | 13992 public: |
| 14014 StringSharedKey(Handle<String> source, | 13993 StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared, |
| 14015 Handle<SharedFunctionInfo> shared, | 13994 LanguageMode language_mode, int scope_position) |
| 14016 StrictMode strict_mode, | |
| 14017 int scope_position) | |
| 14018 : source_(source), | 13995 : source_(source), |
| 14019 shared_(shared), | 13996 shared_(shared), |
| 14020 strict_mode_(strict_mode), | 13997 language_mode_(language_mode), |
| 14021 scope_position_(scope_position) { } | 13998 scope_position_(scope_position) {} |
| 14022 | 13999 |
| 14023 bool IsMatch(Object* other) OVERRIDE { | 14000 bool IsMatch(Object* other) OVERRIDE { |
| 14024 DisallowHeapAllocation no_allocation; | 14001 DisallowHeapAllocation no_allocation; |
| 14025 if (!other->IsFixedArray()) { | 14002 if (!other->IsFixedArray()) { |
| 14026 if (!other->IsNumber()) return false; | 14003 if (!other->IsNumber()) return false; |
| 14027 uint32_t other_hash = static_cast<uint32_t>(other->Number()); | 14004 uint32_t other_hash = static_cast<uint32_t>(other->Number()); |
| 14028 return Hash() == other_hash; | 14005 return Hash() == other_hash; |
| 14029 } | 14006 } |
| 14030 FixedArray* other_array = FixedArray::cast(other); | 14007 FixedArray* other_array = FixedArray::cast(other); |
| 14031 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14008 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
| 14032 if (shared != *shared_) return false; | 14009 if (shared != *shared_) return false; |
| 14033 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14010 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
| 14034 DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14011 DCHECK(is_valid_language_mode(language_unchecked)); |
| 14035 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14012 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
| 14036 if (strict_mode != strict_mode_) return false; | 14013 if (language_mode != language_mode_) return false; |
| 14037 int scope_position = Smi::cast(other_array->get(3))->value(); | 14014 int scope_position = Smi::cast(other_array->get(3))->value(); |
| 14038 if (scope_position != scope_position_) return false; | 14015 if (scope_position != scope_position_) return false; |
| 14039 String* source = String::cast(other_array->get(1)); | 14016 String* source = String::cast(other_array->get(1)); |
| 14040 return source->Equals(*source_); | 14017 return source->Equals(*source_); |
| 14041 } | 14018 } |
| 14042 | 14019 |
| 14043 static uint32_t StringSharedHashHelper(String* source, | 14020 static uint32_t StringSharedHashHelper(String* source, |
| 14044 SharedFunctionInfo* shared, | 14021 SharedFunctionInfo* shared, |
| 14045 StrictMode strict_mode, | 14022 LanguageMode language_mode, |
| 14046 int scope_position) { | 14023 int scope_position) { |
| 14047 uint32_t hash = source->Hash(); | 14024 uint32_t hash = source->Hash(); |
| 14048 if (shared->HasSourceCode()) { | 14025 if (shared->HasSourceCode()) { |
| 14049 // Instead of using the SharedFunctionInfo pointer in the hash | 14026 // Instead of using the SharedFunctionInfo pointer in the hash |
| 14050 // code computation, we use a combination of the hash of the | 14027 // code computation, we use a combination of the hash of the |
| 14051 // script source code and the start position of the calling scope. | 14028 // script source code and the start position of the calling scope. |
| 14052 // We do this to ensure that the cache entries can survive garbage | 14029 // We do this to ensure that the cache entries can survive garbage |
| 14053 // collection. | 14030 // collection. |
| 14054 Script* script(Script::cast(shared->script())); | 14031 Script* script(Script::cast(shared->script())); |
| 14055 hash ^= String::cast(script->source())->Hash(); | 14032 hash ^= String::cast(script->source())->Hash(); |
| 14056 if (strict_mode == STRICT) hash ^= 0x8000; | 14033 STATIC_ASSERT(LANGUAGE_END == 2); |
| 14034 if (is_strict(language_mode)) hash ^= 0x8000; |
| 14057 hash += scope_position; | 14035 hash += scope_position; |
| 14058 } | 14036 } |
| 14059 return hash; | 14037 return hash; |
| 14060 } | 14038 } |
| 14061 | 14039 |
| 14062 uint32_t Hash() OVERRIDE { | 14040 uint32_t Hash() OVERRIDE { |
| 14063 return StringSharedHashHelper(*source_, *shared_, strict_mode_, | 14041 return StringSharedHashHelper(*source_, *shared_, language_mode_, |
| 14064 scope_position_); | 14042 scope_position_); |
| 14065 } | 14043 } |
| 14066 | 14044 |
| 14067 uint32_t HashForObject(Object* obj) OVERRIDE { | 14045 uint32_t HashForObject(Object* obj) OVERRIDE { |
| 14068 DisallowHeapAllocation no_allocation; | 14046 DisallowHeapAllocation no_allocation; |
| 14069 if (obj->IsNumber()) { | 14047 if (obj->IsNumber()) { |
| 14070 return static_cast<uint32_t>(obj->Number()); | 14048 return static_cast<uint32_t>(obj->Number()); |
| 14071 } | 14049 } |
| 14072 FixedArray* other_array = FixedArray::cast(obj); | 14050 FixedArray* other_array = FixedArray::cast(obj); |
| 14073 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14051 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
| 14074 String* source = String::cast(other_array->get(1)); | 14052 String* source = String::cast(other_array->get(1)); |
| 14075 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14053 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
| 14076 DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14054 DCHECK(is_valid_language_mode(language_unchecked)); |
| 14077 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14055 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
| 14078 int scope_position = Smi::cast(other_array->get(3))->value(); | 14056 int scope_position = Smi::cast(other_array->get(3))->value(); |
| 14079 return StringSharedHashHelper( | 14057 return StringSharedHashHelper(source, shared, language_mode, |
| 14080 source, shared, strict_mode, scope_position); | 14058 scope_position); |
| 14081 } | 14059 } |
| 14082 | 14060 |
| 14083 | 14061 |
| 14084 Handle<Object> AsHandle(Isolate* isolate) OVERRIDE { | 14062 Handle<Object> AsHandle(Isolate* isolate) OVERRIDE { |
| 14085 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); | 14063 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); |
| 14086 array->set(0, *shared_); | 14064 array->set(0, *shared_); |
| 14087 array->set(1, *source_); | 14065 array->set(1, *source_); |
| 14088 array->set(2, Smi::FromInt(strict_mode_)); | 14066 array->set(2, Smi::FromInt(language_mode_)); |
| 14089 array->set(3, Smi::FromInt(scope_position_)); | 14067 array->set(3, Smi::FromInt(scope_position_)); |
| 14090 return array; | 14068 return array; |
| 14091 } | 14069 } |
| 14092 | 14070 |
| 14093 private: | 14071 private: |
| 14094 Handle<String> source_; | 14072 Handle<String> source_; |
| 14095 Handle<SharedFunctionInfo> shared_; | 14073 Handle<SharedFunctionInfo> shared_; |
| 14096 StrictMode strict_mode_; | 14074 LanguageMode language_mode_; |
| 14097 int scope_position_; | 14075 int scope_position_; |
| 14098 }; | 14076 }; |
| 14099 | 14077 |
| 14100 | 14078 |
| 14101 // RegExpKey carries the source and flags of a regular expression as key. | 14079 // RegExpKey carries the source and flags of a regular expression as key. |
| 14102 class RegExpKey : public HashTableKey { | 14080 class RegExpKey : public HashTableKey { |
| 14103 public: | 14081 public: |
| 14104 RegExpKey(Handle<String> string, JSRegExp::Flags flags) | 14082 RegExpKey(Handle<String> string, JSRegExp::Flags flags) |
| 14105 : string_(string), | 14083 : string_(string), |
| 14106 flags_(Smi::FromInt(flags.value())) { } | 14084 flags_(Smi::FromInt(flags.value())) { } |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15245 int entry = FindEntry(&key); | 15223 int entry = FindEntry(&key); |
| 15246 if (entry == kNotFound) return isolate->factory()->undefined_value(); | 15224 if (entry == kNotFound) return isolate->factory()->undefined_value(); |
| 15247 int index = EntryToIndex(entry); | 15225 int index = EntryToIndex(entry); |
| 15248 if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value(); | 15226 if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value(); |
| 15249 return Handle<Object>(get(index + 1), isolate); | 15227 return Handle<Object>(get(index + 1), isolate); |
| 15250 } | 15228 } |
| 15251 | 15229 |
| 15252 | 15230 |
| 15253 Handle<Object> CompilationCacheTable::LookupEval( | 15231 Handle<Object> CompilationCacheTable::LookupEval( |
| 15254 Handle<String> src, Handle<SharedFunctionInfo> outer_info, | 15232 Handle<String> src, Handle<SharedFunctionInfo> outer_info, |
| 15255 StrictMode strict_mode, int scope_position) { | 15233 LanguageMode language_mode, int scope_position) { |
| 15256 Isolate* isolate = GetIsolate(); | 15234 Isolate* isolate = GetIsolate(); |
| 15257 // Cache key is the tuple (source, outer shared function info, scope position) | 15235 // Cache key is the tuple (source, outer shared function info, scope position) |
| 15258 // to unambiguously identify the context chain the cached eval code assumes. | 15236 // to unambiguously identify the context chain the cached eval code assumes. |
| 15259 StringSharedKey key(src, outer_info, strict_mode, scope_position); | 15237 StringSharedKey key(src, outer_info, language_mode, scope_position); |
| 15260 int entry = FindEntry(&key); | 15238 int entry = FindEntry(&key); |
| 15261 if (entry == kNotFound) return isolate->factory()->undefined_value(); | 15239 if (entry == kNotFound) return isolate->factory()->undefined_value(); |
| 15262 int index = EntryToIndex(entry); | 15240 int index = EntryToIndex(entry); |
| 15263 if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value(); | 15241 if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value(); |
| 15264 return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); | 15242 return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); |
| 15265 } | 15243 } |
| 15266 | 15244 |
| 15267 | 15245 |
| 15268 Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src, | 15246 Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src, |
| 15269 JSRegExp::Flags flags) { | 15247 JSRegExp::Flags flags) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15303 cache->ElementAdded(); | 15281 cache->ElementAdded(); |
| 15304 return cache; | 15282 return cache; |
| 15305 } | 15283 } |
| 15306 | 15284 |
| 15307 | 15285 |
| 15308 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( | 15286 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
| 15309 Handle<CompilationCacheTable> cache, Handle<String> src, | 15287 Handle<CompilationCacheTable> cache, Handle<String> src, |
| 15310 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, | 15288 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, |
| 15311 int scope_position) { | 15289 int scope_position) { |
| 15312 Isolate* isolate = cache->GetIsolate(); | 15290 Isolate* isolate = cache->GetIsolate(); |
| 15313 StringSharedKey key(src, outer_info, value->strict_mode(), scope_position); | 15291 StringSharedKey key(src, outer_info, value->language_mode(), scope_position); |
| 15314 { | 15292 { |
| 15315 Handle<Object> k = key.AsHandle(isolate); | 15293 Handle<Object> k = key.AsHandle(isolate); |
| 15316 DisallowHeapAllocation no_allocation_scope; | 15294 DisallowHeapAllocation no_allocation_scope; |
| 15317 int entry = cache->FindEntry(&key); | 15295 int entry = cache->FindEntry(&key); |
| 15318 if (entry != kNotFound) { | 15296 if (entry != kNotFound) { |
| 15319 cache->set(EntryToIndex(entry), *k); | 15297 cache->set(EntryToIndex(entry), *k); |
| 15320 cache->set(EntryToIndex(entry) + 1, *value); | 15298 cache->set(EntryToIndex(entry) + 1, *value); |
| 15321 return cache; | 15299 return cache; |
| 15322 } | 15300 } |
| 15323 } | 15301 } |
| (...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16888 Handle<DependentCode> codes = | 16866 Handle<DependentCode> codes = |
| 16889 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16867 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16890 DependentCode::kPropertyCellChangedGroup, | 16868 DependentCode::kPropertyCellChangedGroup, |
| 16891 info->object_wrapper()); | 16869 info->object_wrapper()); |
| 16892 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16870 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16893 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16871 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16894 cell, info->zone()); | 16872 cell, info->zone()); |
| 16895 } | 16873 } |
| 16896 | 16874 |
| 16897 } } // namespace v8::internal | 16875 } } // namespace v8::internal |
| OLD | NEW |