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