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