| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 return fun->IsJSFunction() || | 101 return fun->IsJSFunction() || |
| 102 (fun->IsHeapObject() && | 102 (fun->IsHeapObject() && |
| 103 HeapObject::cast(fun)->map()->has_instance_call_handler()); | 103 HeapObject::cast(fun)->map()->has_instance_call_handler()); |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { | 107 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
| 108 for (; it->IsFound(); it->Next()) { | 108 for (; it->IsFound(); it->Next()) { |
| 109 switch (it->state()) { | 109 switch (it->state()) { |
| 110 case LookupIterator::NOT_FOUND: | 110 case LookupIterator::NOT_FOUND: |
| 111 case LookupIterator::TRANSITION: |
| 111 UNREACHABLE(); | 112 UNREACHABLE(); |
| 112 case LookupIterator::JSPROXY: | 113 case LookupIterator::JSPROXY: |
| 113 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), | 114 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), |
| 114 it->GetReceiver(), it->name()); | 115 it->GetReceiver(), it->name()); |
| 115 case LookupIterator::INTERCEPTOR: { | 116 case LookupIterator::INTERCEPTOR: { |
| 116 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( | 117 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( |
| 117 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 118 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 118 if (!maybe_result.is_null()) return maybe_result; | 119 if (!maybe_result.is_null()) return maybe_result; |
| 119 if (it->isolate()->has_pending_exception()) return maybe_result; | 120 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 120 break; | 121 break; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 143 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, | 144 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, |
| 144 Handle<Name> key) { | 145 Handle<Name> key) { |
| 145 LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY); | 146 LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY); |
| 146 return GetDataProperty(&it); | 147 return GetDataProperty(&it); |
| 147 } | 148 } |
| 148 | 149 |
| 149 | 150 |
| 150 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) { | 151 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) { |
| 151 for (; it->IsFound(); it->Next()) { | 152 for (; it->IsFound(); it->Next()) { |
| 152 switch (it->state()) { | 153 switch (it->state()) { |
| 153 case LookupIterator::NOT_FOUND: | |
| 154 case LookupIterator::ACCESS_CHECK: | 154 case LookupIterator::ACCESS_CHECK: |
| 155 case LookupIterator::INTERCEPTOR: | 155 case LookupIterator::INTERCEPTOR: |
| 156 case LookupIterator::NOT_FOUND: |
| 157 case LookupIterator::TRANSITION: |
| 156 UNREACHABLE(); | 158 UNREACHABLE(); |
| 157 case LookupIterator::JSPROXY: | 159 case LookupIterator::JSPROXY: |
| 158 it->NotFound(); | 160 it->NotFound(); |
| 159 return it->isolate()->factory()->undefined_value(); | 161 return it->isolate()->factory()->undefined_value(); |
| 160 case LookupIterator::PROPERTY: | 162 case LookupIterator::PROPERTY: |
| 161 if (!it->HasProperty()) continue; | 163 if (!it->HasProperty()) continue; |
| 162 switch (it->property_kind()) { | 164 switch (it->property_kind()) { |
| 163 case LookupIterator::DATA: | 165 case LookupIterator::DATA: |
| 164 return it->GetDataValue(); | 166 return it->GetDataValue(); |
| 165 case LookupIterator::ACCESSOR: | 167 case LookupIterator::ACCESSOR: |
| (...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { | 2709 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { |
| 2708 proto_map = Handle<Map>(holder->map()); | 2710 proto_map = Handle<Map>(holder->map()); |
| 2709 } | 2711 } |
| 2710 } | 2712 } |
| 2711 return TryUpdateInternal(map); | 2713 return TryUpdateInternal(map); |
| 2712 } | 2714 } |
| 2713 | 2715 |
| 2714 | 2716 |
| 2715 // static | 2717 // static |
| 2716 Handle<Map> Map::Update(Handle<Map> map) { | 2718 Handle<Map> Map::Update(Handle<Map> map) { |
| 2719 if (!map->is_deprecated()) return map; |
| 2717 return GeneralizeRepresentation(map, 0, Representation::None(), | 2720 return GeneralizeRepresentation(map, 0, Representation::None(), |
| 2718 HeapType::None(map->GetIsolate()), | 2721 HeapType::None(map->GetIsolate()), |
| 2719 ALLOW_AS_CONSTANT); | 2722 ALLOW_AS_CONSTANT); |
| 2720 } | 2723 } |
| 2721 | 2724 |
| 2722 | 2725 |
| 2723 // static | 2726 // static |
| 2724 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { | 2727 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { |
| 2725 DisallowHeapAllocation no_allocation; | 2728 DisallowHeapAllocation no_allocation; |
| 2726 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); | 2729 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2887 it->GetAccessors(), strict_mode); | 2890 it->GetAccessors(), strict_mode); |
| 2888 } | 2891 } |
| 2889 break; | 2892 break; |
| 2890 case LookupIterator::DATA: | 2893 case LookupIterator::DATA: |
| 2891 if (it->HolderIsReceiverOrHiddenPrototype()) { | 2894 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 2892 return SetDataProperty(it, value); | 2895 return SetDataProperty(it, value); |
| 2893 } | 2896 } |
| 2894 } | 2897 } |
| 2895 done = true; | 2898 done = true; |
| 2896 break; | 2899 break; |
| 2900 |
| 2901 case LookupIterator::TRANSITION: |
| 2902 done = true; |
| 2903 break; |
| 2897 } | 2904 } |
| 2898 | 2905 |
| 2899 if (done) break; | 2906 if (done) break; |
| 2900 } | 2907 } |
| 2901 | 2908 |
| 2902 return AddDataProperty(it, value, NONE, strict_mode, store_mode); | 2909 return AddDataProperty(it, value, NONE, strict_mode, store_mode); |
| 2903 } | 2910 } |
| 2904 | 2911 |
| 2905 | 2912 |
| 2906 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, | 2913 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2953 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 2960 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
| 2954 Handle<Object> value, | 2961 Handle<Object> value, |
| 2955 PropertyAttributes attributes, | 2962 PropertyAttributes attributes, |
| 2956 StrictMode strict_mode, | 2963 StrictMode strict_mode, |
| 2957 StoreFromKeyed store_mode) { | 2964 StoreFromKeyed store_mode) { |
| 2958 DCHECK(!it->GetReceiver()->IsJSProxy()); | 2965 DCHECK(!it->GetReceiver()->IsJSProxy()); |
| 2959 if (!it->GetReceiver()->IsJSObject()) { | 2966 if (!it->GetReceiver()->IsJSObject()) { |
| 2960 // TODO(verwaest): Throw a TypeError with a more specific message. | 2967 // TODO(verwaest): Throw a TypeError with a more specific message. |
| 2961 return WriteToReadOnlyProperty(it, value, strict_mode); | 2968 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 2962 } | 2969 } |
| 2963 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 2970 Handle<JSObject> receiver = it->GetStoreTarget(); |
| 2964 | 2971 |
| 2965 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) | 2972 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) |
| 2966 // instead. If the prototype is Null, the proxy is detached. | 2973 // instead. If the prototype is Null, the proxy is detached. |
| 2967 if (receiver->IsJSGlobalProxy()) { | 2974 if (receiver->IsJSGlobalProxy()) return value; |
| 2968 // Trying to assign to a detached proxy. | |
| 2969 PrototypeIterator iter(it->isolate(), receiver); | |
| 2970 if (iter.IsAtEnd()) return value; | |
| 2971 receiver = | |
| 2972 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
| 2973 } | |
| 2974 | 2975 |
| 2975 if (!it->name().is_identical_to(it->isolate()->factory()->hidden_string()) && | 2976 // Possibly migrate to the most up-to-date map that will be able to store |
| 2976 !receiver->map()->is_extensible()) { | 2977 // |value| under it->name() with |attributes|. |
| 2978 it->PrepareTransitionToDataProperty(value, attributes, store_mode); |
| 2979 if (it->state() != LookupIterator::TRANSITION) { |
| 2977 if (strict_mode == SLOPPY) return value; | 2980 if (strict_mode == SLOPPY) return value; |
| 2978 | 2981 |
| 2979 Handle<Object> args[1] = {it->name()}; | 2982 Handle<Object> args[1] = {it->name()}; |
| 2980 Handle<Object> error = it->factory()->NewTypeError( | 2983 Handle<Object> error = it->factory()->NewTypeError( |
| 2981 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 2984 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
| 2982 return it->isolate()->Throw<Object>(error); | 2985 return it->isolate()->Throw<Object>(error); |
| 2983 } | 2986 } |
| 2984 | 2987 it->ApplyTransitionToDataProperty(); |
| 2985 // Possibly migrate to the most up-to-date map that will be able to store | |
| 2986 // |value| under it->name() with |attributes|. | |
| 2987 it->TransitionToDataProperty(value, attributes, store_mode); | |
| 2988 | 2988 |
| 2989 // TODO(verwaest): Encapsulate dictionary handling better. | 2989 // TODO(verwaest): Encapsulate dictionary handling better. |
| 2990 if (receiver->map()->is_dictionary_map()) { | 2990 if (receiver->map()->is_dictionary_map()) { |
| 2991 // TODO(verwaest): Probably should ensure this is done beforehand. | 2991 // TODO(verwaest): Probably should ensure this is done beforehand. |
| 2992 it->InternalizeName(); | 2992 it->InternalizeName(); |
| 2993 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); | 2993 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); |
| 2994 } else { | 2994 } else { |
| 2995 // Write the property value. | 2995 // Write the property value. |
| 2996 it->WriteDataValue(value); | 2996 it->WriteDataValue(value); |
| 2997 } | 2997 } |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3372 } | 3372 } |
| 3373 | 3373 |
| 3374 | 3374 |
| 3375 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, | 3375 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, |
| 3376 ElementsKind to_kind) { | 3376 ElementsKind to_kind) { |
| 3377 Handle<Map> map(object->map()); | 3377 Handle<Map> map(object->map()); |
| 3378 return Map::TransitionElementsTo(map, to_kind); | 3378 return Map::TransitionElementsTo(map, to_kind); |
| 3379 } | 3379 } |
| 3380 | 3380 |
| 3381 | 3381 |
| 3382 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, | |
| 3383 LookupResult* result) { | |
| 3384 DisallowHeapAllocation no_gc; | |
| 3385 if (IsJSGlobalProxy()) { | |
| 3386 PrototypeIterator iter(GetIsolate(), this); | |
| 3387 if (iter.IsAtEnd()) return result->NotFound(); | |
| 3388 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | |
| 3389 return JSObject::cast(iter.GetCurrent()) | |
| 3390 ->LookupOwnRealNamedProperty(name, result); | |
| 3391 } | |
| 3392 | |
| 3393 if (HasFastProperties()) { | |
| 3394 map()->LookupDescriptor(this, *name, result); | |
| 3395 // A property or a map transition was found. We return all of these result | |
| 3396 // types because LookupOwnRealNamedProperty is used when setting | |
| 3397 // properties where map transitions are handled. | |
| 3398 DCHECK(!result->IsFound() || | |
| 3399 (result->holder() == this && result->IsFastPropertyType())); | |
| 3400 return; | |
| 3401 } | |
| 3402 | |
| 3403 int entry = property_dictionary()->FindEntry(name); | |
| 3404 if (entry != NameDictionary::kNotFound) { | |
| 3405 Object* value = property_dictionary()->ValueAt(entry); | |
| 3406 if (IsGlobalObject()) { | |
| 3407 PropertyDetails d = property_dictionary()->DetailsAt(entry); | |
| 3408 if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) { | |
| 3409 result->NotFound(); | |
| 3410 return; | |
| 3411 } | |
| 3412 value = PropertyCell::cast(value)->value(); | |
| 3413 } | |
| 3414 result->DictionaryResult(this, entry); | |
| 3415 return; | |
| 3416 } | |
| 3417 | |
| 3418 result->NotFound(); | |
| 3419 } | |
| 3420 | |
| 3421 | |
| 3422 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, | 3382 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, |
| 3423 Handle<Name> name) { | 3383 Handle<Name> name) { |
| 3424 Isolate* isolate = proxy->GetIsolate(); | 3384 Isolate* isolate = proxy->GetIsolate(); |
| 3425 | 3385 |
| 3426 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3386 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3427 if (name->IsSymbol()) return maybe(false); | 3387 if (name->IsSymbol()) return maybe(false); |
| 3428 | 3388 |
| 3429 Handle<Object> args[] = { name }; | 3389 Handle<Object> args[] = { name }; |
| 3430 Handle<Object> result; | 3390 Handle<Object> result; |
| 3431 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 3391 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3840 Handle<Object> value, | 3800 Handle<Object> value, |
| 3841 PropertyAttributes attributes, | 3801 PropertyAttributes attributes, |
| 3842 ExecutableAccessorInfoHandling handling) { | 3802 ExecutableAccessorInfoHandling handling) { |
| 3843 DCHECK(!value->IsTheHole()); | 3803 DCHECK(!value->IsTheHole()); |
| 3844 LookupIterator it(object, name, | 3804 LookupIterator it(object, name, |
| 3845 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR); | 3805 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR); |
| 3846 bool is_observed = object->map()->is_observed() && | 3806 bool is_observed = object->map()->is_observed() && |
| 3847 *name != it.isolate()->heap()->hidden_string(); | 3807 *name != it.isolate()->heap()->hidden_string(); |
| 3848 for (; it.IsFound(); it.Next()) { | 3808 for (; it.IsFound(); it.Next()) { |
| 3849 switch (it.state()) { | 3809 switch (it.state()) { |
| 3810 case LookupIterator::INTERCEPTOR: |
| 3811 case LookupIterator::JSPROXY: |
| 3850 case LookupIterator::NOT_FOUND: | 3812 case LookupIterator::NOT_FOUND: |
| 3851 case LookupIterator::JSPROXY: | 3813 case LookupIterator::TRANSITION: |
| 3852 case LookupIterator::INTERCEPTOR: | |
| 3853 UNREACHABLE(); | 3814 UNREACHABLE(); |
| 3854 | 3815 |
| 3855 case LookupIterator::ACCESS_CHECK: | 3816 case LookupIterator::ACCESS_CHECK: |
| 3856 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 3817 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 3857 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | 3818 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
| 3858 } | 3819 } |
| 3859 break; | 3820 break; |
| 3860 | 3821 |
| 3861 case LookupIterator::PROPERTY: { | 3822 case LookupIterator::PROPERTY: { |
| 3862 if (!it.HasProperty()) break; | 3823 if (!it.HasProperty()) break; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4015 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN); | 3976 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN); |
| 4016 return GetPropertyAttributes(&it); | 3977 return GetPropertyAttributes(&it); |
| 4017 } | 3978 } |
| 4018 | 3979 |
| 4019 | 3980 |
| 4020 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( | 3981 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
| 4021 LookupIterator* it) { | 3982 LookupIterator* it) { |
| 4022 for (; it->IsFound(); it->Next()) { | 3983 for (; it->IsFound(); it->Next()) { |
| 4023 switch (it->state()) { | 3984 switch (it->state()) { |
| 4024 case LookupIterator::NOT_FOUND: | 3985 case LookupIterator::NOT_FOUND: |
| 3986 case LookupIterator::TRANSITION: |
| 4025 UNREACHABLE(); | 3987 UNREACHABLE(); |
| 4026 case LookupIterator::JSPROXY: | 3988 case LookupIterator::JSPROXY: |
| 4027 return JSProxy::GetPropertyAttributesWithHandler( | 3989 return JSProxy::GetPropertyAttributesWithHandler( |
| 4028 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); | 3990 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); |
| 4029 case LookupIterator::INTERCEPTOR: { | 3991 case LookupIterator::INTERCEPTOR: { |
| 4030 Maybe<PropertyAttributes> result = | 3992 Maybe<PropertyAttributes> result = |
| 4031 JSObject::GetPropertyAttributesWithInterceptor( | 3993 JSObject::GetPropertyAttributesWithInterceptor( |
| 4032 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 3994 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 4033 if (!result.has_value) return result; | 3995 if (!result.has_value) return result; |
| 4034 if (result.value != ABSENT) return result; | 3996 if (result.value != ABSENT) return result; |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4954 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR | 4916 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR |
| 4955 : LookupIterator::CHECK_HIDDEN; | 4917 : LookupIterator::CHECK_HIDDEN; |
| 4956 | 4918 |
| 4957 LookupIterator it(object, name, config); | 4919 LookupIterator it(object, name, config); |
| 4958 | 4920 |
| 4959 bool is_observed = object->map()->is_observed() && | 4921 bool is_observed = object->map()->is_observed() && |
| 4960 *name != it.isolate()->heap()->hidden_string(); | 4922 *name != it.isolate()->heap()->hidden_string(); |
| 4961 | 4923 |
| 4962 for (; it.IsFound(); it.Next()) { | 4924 for (; it.IsFound(); it.Next()) { |
| 4963 switch (it.state()) { | 4925 switch (it.state()) { |
| 4926 case LookupIterator::JSPROXY: |
| 4964 case LookupIterator::NOT_FOUND: | 4927 case LookupIterator::NOT_FOUND: |
| 4965 case LookupIterator::JSPROXY: | 4928 case LookupIterator::TRANSITION: |
| 4966 UNREACHABLE(); | 4929 UNREACHABLE(); |
| 4967 case LookupIterator::ACCESS_CHECK: | 4930 case LookupIterator::ACCESS_CHECK: |
| 4968 if (it.HasAccess(v8::ACCESS_DELETE)) break; | 4931 if (it.HasAccess(v8::ACCESS_DELETE)) break; |
| 4969 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), | 4932 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
| 4970 v8::ACCESS_DELETE); | 4933 v8::ACCESS_DELETE); |
| 4971 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); | 4934 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); |
| 4972 return it.isolate()->factory()->false_value(); | 4935 return it.isolate()->factory()->false_value(); |
| 4973 case LookupIterator::INTERCEPTOR: { | 4936 case LookupIterator::INTERCEPTOR: { |
| 4974 MaybeHandle<Object> maybe_result = | 4937 MaybeHandle<Object> maybe_result = |
| 4975 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), | 4938 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5703 for (int i = 0; i < number_of_own_descriptors; i++) { | 5666 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 5704 if (descs->GetType(i) == FIELD) { | 5667 if (descs->GetType(i) == FIELD) { |
| 5705 int current_index = descs->GetFieldIndex(i); | 5668 int current_index = descs->GetFieldIndex(i); |
| 5706 if (current_index > max_index) max_index = current_index; | 5669 if (current_index > max_index) max_index = current_index; |
| 5707 } | 5670 } |
| 5708 } | 5671 } |
| 5709 return max_index + 1; | 5672 return max_index + 1; |
| 5710 } | 5673 } |
| 5711 | 5674 |
| 5712 | 5675 |
| 5713 void JSReceiver::LookupOwn(Handle<Name> name, LookupResult* result) { | |
| 5714 DisallowHeapAllocation no_gc; | |
| 5715 DCHECK(name->IsName()); | |
| 5716 | |
| 5717 if (IsJSGlobalProxy()) { | |
| 5718 PrototypeIterator iter(GetIsolate(), this); | |
| 5719 if (iter.IsAtEnd()) return result->NotFound(); | |
| 5720 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | |
| 5721 return JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result); | |
| 5722 } | |
| 5723 | |
| 5724 if (IsJSProxy()) { | |
| 5725 result->HandlerResult(JSProxy::cast(this)); | |
| 5726 return; | |
| 5727 } | |
| 5728 | |
| 5729 // Do not use inline caching if the object is a non-global object | |
| 5730 // that requires access checks. | |
| 5731 if (IsAccessCheckNeeded()) { | |
| 5732 result->DisallowCaching(); | |
| 5733 } | |
| 5734 | |
| 5735 JSObject* js_object = JSObject::cast(this); | |
| 5736 | |
| 5737 // Check for lookup interceptor except when bootstrapping. | |
| 5738 if (js_object->HasNamedInterceptor() && | |
| 5739 !GetIsolate()->bootstrapper()->IsActive()) { | |
| 5740 result->InterceptorResult(js_object); | |
| 5741 return; | |
| 5742 } | |
| 5743 | |
| 5744 js_object->LookupOwnRealNamedProperty(name, result); | |
| 5745 } | |
| 5746 | |
| 5747 | |
| 5748 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) { | |
| 5749 DisallowHeapAllocation no_gc; | |
| 5750 // Ecma-262 3rd 8.6.2.4 | |
| 5751 for (PrototypeIterator iter(GetIsolate(), this, | |
| 5752 PrototypeIterator::START_AT_RECEIVER); | |
| 5753 !iter.IsAtEnd(); iter.Advance()) { | |
| 5754 JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result); | |
| 5755 if (result->IsFound()) return; | |
| 5756 if (name->IsOwn()) { | |
| 5757 result->NotFound(); | |
| 5758 return; | |
| 5759 } | |
| 5760 } | |
| 5761 result->NotFound(); | |
| 5762 } | |
| 5763 | |
| 5764 | |
| 5765 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 5676 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 5766 int len = array->length(); | 5677 int len = array->length(); |
| 5767 for (int i = 0; i < len; i++) { | 5678 for (int i = 0; i < len; i++) { |
| 5768 Object* e = array->get(i); | 5679 Object* e = array->get(i); |
| 5769 if (!(e->IsString() || e->IsNumber())) return false; | 5680 if (!(e->IsString() || e->IsNumber())) return false; |
| 5770 } | 5681 } |
| 5771 return true; | 5682 return true; |
| 5772 } | 5683 } |
| 5773 | 5684 |
| 5774 | 5685 |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6390 isolate); | 6301 isolate); |
| 6391 } | 6302 } |
| 6392 } | 6303 } |
| 6393 } | 6304 } |
| 6394 } | 6305 } |
| 6395 } else { | 6306 } else { |
| 6396 LookupIterator it(object, name, | 6307 LookupIterator it(object, name, |
| 6397 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR); | 6308 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR); |
| 6398 for (; it.IsFound(); it.Next()) { | 6309 for (; it.IsFound(); it.Next()) { |
| 6399 switch (it.state()) { | 6310 switch (it.state()) { |
| 6311 case LookupIterator::INTERCEPTOR: |
| 6400 case LookupIterator::NOT_FOUND: | 6312 case LookupIterator::NOT_FOUND: |
| 6401 case LookupIterator::INTERCEPTOR: | 6313 case LookupIterator::TRANSITION: |
| 6402 UNREACHABLE(); | 6314 UNREACHABLE(); |
| 6403 | 6315 |
| 6404 case LookupIterator::ACCESS_CHECK: | 6316 case LookupIterator::ACCESS_CHECK: |
| 6405 if (it.HasAccess(v8::ACCESS_HAS)) continue; | 6317 if (it.HasAccess(v8::ACCESS_HAS)) continue; |
| 6406 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), | 6318 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
| 6407 v8::ACCESS_HAS); | 6319 v8::ACCESS_HAS); |
| 6408 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6320 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6409 return isolate->factory()->undefined_value(); | 6321 return isolate->factory()->undefined_value(); |
| 6410 | 6322 |
| 6411 case LookupIterator::JSPROXY: | 6323 case LookupIterator::JSPROXY: |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6828 return false; | 6740 return false; |
| 6829 } | 6741 } |
| 6830 | 6742 |
| 6831 | 6743 |
| 6832 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, | 6744 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, |
| 6833 Handle<Object> value) { | 6745 Handle<Object> value) { |
| 6834 // Dictionaries can store any property value. | 6746 // Dictionaries can store any property value. |
| 6835 if (map->is_dictionary_map()) return map; | 6747 if (map->is_dictionary_map()) return map; |
| 6836 | 6748 |
| 6837 // Migrate to the newest map before storing the property. | 6749 // Migrate to the newest map before storing the property. |
| 6838 if (map->is_deprecated()) map = Update(map); | 6750 map = Update(map); |
| 6839 | 6751 |
| 6840 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6752 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 6841 | 6753 |
| 6842 if (descriptors->CanHoldValue(descriptor, *value)) return map; | 6754 if (descriptors->CanHoldValue(descriptor, *value)) return map; |
| 6843 | 6755 |
| 6844 Isolate* isolate = map->GetIsolate(); | 6756 Isolate* isolate = map->GetIsolate(); |
| 6845 Representation representation = value->OptimalRepresentation(); | 6757 Representation representation = value->OptimalRepresentation(); |
| 6846 Handle<HeapType> type = value->OptimalType(isolate, representation); | 6758 Handle<HeapType> type = value->OptimalType(isolate, representation); |
| 6847 | 6759 |
| 6848 return GeneralizeRepresentation(map, descriptor, representation, type, | 6760 return GeneralizeRepresentation(map, descriptor, representation, type, |
| 6849 FORCE_FIELD); | 6761 FORCE_FIELD); |
| 6850 } | 6762 } |
| 6851 | 6763 |
| 6852 | 6764 |
| 6853 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 6765 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
| 6854 Handle<Object> value, | 6766 Handle<Object> value, |
| 6855 PropertyAttributes attributes, | 6767 PropertyAttributes attributes, |
| 6856 StoreFromKeyed store_mode) { | 6768 StoreFromKeyed store_mode) { |
| 6857 // Dictionary maps can always have additional data properties. | 6769 // Dictionary maps can always have additional data properties. |
| 6858 if (map->is_dictionary_map()) return map; | 6770 if (map->is_dictionary_map()) return map; |
| 6859 | 6771 |
| 6860 // Migrate to the newest map before transitioning to the new property. | 6772 // Migrate to the newest map before storing the property. |
| 6861 if (map->is_deprecated()) map = Update(map); | 6773 map = Update(map); |
| 6862 | 6774 |
| 6863 int index = map->SearchTransition(*name); | 6775 int index = map->SearchTransition(*name); |
| 6864 if (index != TransitionArray::kNotFound) { | 6776 if (index != TransitionArray::kNotFound) { |
| 6865 Handle<Map> transition(map->GetTransition(index)); | 6777 Handle<Map> transition(map->GetTransition(index)); |
| 6866 int descriptor = transition->LastAdded(); | 6778 int descriptor = transition->LastAdded(); |
| 6867 | 6779 |
| 6868 // TODO(verwaest): Handle attributes better. | 6780 // TODO(verwaest): Handle attributes better. |
| 6869 DescriptorArray* descriptors = transition->instance_descriptors(); | 6781 DescriptorArray* descriptors = transition->instance_descriptors(); |
| 6870 if (descriptors->GetDetails(descriptor).attributes() != attributes) { | 6782 if (descriptors->GetDetails(descriptor).attributes() != attributes) { |
| 6871 return CopyGeneralizeAllRepresentations(transition, descriptor, | 6783 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); |
| 6872 FORCE_FIELD, attributes, | |
| 6873 "attributes mismatch"); | |
| 6874 } | 6784 } |
| 6875 | 6785 |
| 6876 return Map::PrepareForDataProperty(transition, descriptor, value); | 6786 return Map::PrepareForDataProperty(transition, descriptor, value); |
| 6877 } | 6787 } |
| 6878 | 6788 |
| 6879 TransitionFlag flag = INSERT_TRANSITION; | 6789 TransitionFlag flag = INSERT_TRANSITION; |
| 6880 MaybeHandle<Map> maybe_map; | 6790 MaybeHandle<Map> maybe_map; |
| 6881 if (value->IsJSFunction()) { | 6791 if (value->IsJSFunction()) { |
| 6882 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); | 6792 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); |
| 6883 } else if (!map->TooManyFastProperties(store_mode)) { | 6793 } else if (!map->TooManyFastProperties(store_mode)) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6918 | 6828 |
| 6919 // Dictionary maps can always have additional data properties. | 6829 // Dictionary maps can always have additional data properties. |
| 6920 if (map->is_dictionary_map()) { | 6830 if (map->is_dictionary_map()) { |
| 6921 // For global objects, property cells are inlined. We need to change the | 6831 // For global objects, property cells are inlined. We need to change the |
| 6922 // map. | 6832 // map. |
| 6923 if (map->IsGlobalObjectMap()) return Copy(map); | 6833 if (map->IsGlobalObjectMap()) return Copy(map); |
| 6924 return map; | 6834 return map; |
| 6925 } | 6835 } |
| 6926 | 6836 |
| 6927 // Migrate to the newest map before transitioning to the new property. | 6837 // Migrate to the newest map before transitioning to the new property. |
| 6928 if (map->is_deprecated()) map = Update(map); | 6838 map = Update(map); |
| 6929 | 6839 |
| 6930 PropertyNormalizationMode mode = map->is_prototype_map() | 6840 PropertyNormalizationMode mode = map->is_prototype_map() |
| 6931 ? KEEP_INOBJECT_PROPERTIES | 6841 ? KEEP_INOBJECT_PROPERTIES |
| 6932 : CLEAR_INOBJECT_PROPERTIES; | 6842 : CLEAR_INOBJECT_PROPERTIES; |
| 6933 | 6843 |
| 6934 int index = map->SearchTransition(*name); | 6844 int index = map->SearchTransition(*name); |
| 6935 if (index != TransitionArray::kNotFound) { | 6845 if (index != TransitionArray::kNotFound) { |
| 6936 Handle<Map> transition(map->GetTransition(index)); | 6846 Handle<Map> transition(map->GetTransition(index)); |
| 6937 DescriptorArray* descriptors = transition->instance_descriptors(); | 6847 DescriptorArray* descriptors = transition->instance_descriptors(); |
| 6938 // Fast path, assume that we're modifying the last added descriptor. | 6848 // Fast path, assume that we're modifying the last added descriptor. |
| (...skipping 9588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16527 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16437 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16528 static const char* error_messages_[] = { | 16438 static const char* error_messages_[] = { |
| 16529 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16439 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16530 }; | 16440 }; |
| 16531 #undef ERROR_MESSAGES_TEXTS | 16441 #undef ERROR_MESSAGES_TEXTS |
| 16532 return error_messages_[reason]; | 16442 return error_messages_[reason]; |
| 16533 } | 16443 } |
| 16534 | 16444 |
| 16535 | 16445 |
| 16536 } } // namespace v8::internal | 16446 } } // namespace v8::internal |
| OLD | NEW |