Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Side by Side Diff: src/objects.cc

Issue 478043006: Rewrite StoreIC handling using the LookupIterator. Continued from patch 494153002 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
2909 // If the receiver is the JSGlobalObject, the store was contextual. In case
2910 // the property did not exist yet on the global object itself, we have to
2911 // throw a reference error in strict mode.
2912 if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) {
2913 Handle<Object> args[1] = {it->name()};
2914 Handle<Object> error = it->isolate()->factory()->NewReferenceError(
2915 "not_defined", HandleVector(args, 1));
2916 return it->isolate()->Throw<Object>(error);
2917 }
2918
2902 return AddDataProperty(it, value, NONE, strict_mode, store_mode); 2919 return AddDataProperty(it, value, NONE, strict_mode, store_mode);
2903 } 2920 }
2904 2921
2905 2922
2906 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, 2923 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it,
2907 Handle<Object> value, 2924 Handle<Object> value,
2908 StrictMode strict_mode) { 2925 StrictMode strict_mode) {
2909 if (strict_mode != STRICT) return value; 2926 if (strict_mode != STRICT) return value;
2910 2927
2911 Handle<Object> args[] = {it->name(), it->GetReceiver()}; 2928 Handle<Object> args[] = {it->name(), it->GetReceiver()};
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, 2970 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
2954 Handle<Object> value, 2971 Handle<Object> value,
2955 PropertyAttributes attributes, 2972 PropertyAttributes attributes,
2956 StrictMode strict_mode, 2973 StrictMode strict_mode,
2957 StoreFromKeyed store_mode) { 2974 StoreFromKeyed store_mode) {
2958 DCHECK(!it->GetReceiver()->IsJSProxy()); 2975 DCHECK(!it->GetReceiver()->IsJSProxy());
2959 if (!it->GetReceiver()->IsJSObject()) { 2976 if (!it->GetReceiver()->IsJSObject()) {
2960 // TODO(verwaest): Throw a TypeError with a more specific message. 2977 // TODO(verwaest): Throw a TypeError with a more specific message.
2961 return WriteToReadOnlyProperty(it, value, strict_mode); 2978 return WriteToReadOnlyProperty(it, value, strict_mode);
2962 } 2979 }
2963 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 2980
2981 Handle<JSObject> receiver = it->GetStoreTarget();
2964 2982
2965 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) 2983 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
2966 // instead. If the prototype is Null, the proxy is detached. 2984 // instead. If the prototype is Null, the proxy is detached.
2967 if (receiver->IsJSGlobalProxy()) { 2985 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 2986
2975 if (!it->name().is_identical_to(it->isolate()->factory()->hidden_string()) && 2987 // Possibly migrate to the most up-to-date map that will be able to store
2976 !receiver->map()->is_extensible()) { 2988 // |value| under it->name() with |attributes|.
2989 it->PrepareTransitionToDataProperty(value, attributes, store_mode);
2990 if (it->state() != LookupIterator::TRANSITION) {
2977 if (strict_mode == SLOPPY) return value; 2991 if (strict_mode == SLOPPY) return value;
2978 2992
2979 Handle<Object> args[1] = {it->name()}; 2993 Handle<Object> args[1] = {it->name()};
2980 Handle<Object> error = it->factory()->NewTypeError( 2994 Handle<Object> error = it->factory()->NewTypeError(
2981 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); 2995 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2982 return it->isolate()->Throw<Object>(error); 2996 return it->isolate()->Throw<Object>(error);
2983 } 2997 }
2984 2998 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 2999
2989 // TODO(verwaest): Encapsulate dictionary handling better. 3000 // TODO(verwaest): Encapsulate dictionary handling better.
2990 if (receiver->map()->is_dictionary_map()) { 3001 if (receiver->map()->is_dictionary_map()) {
2991 // TODO(verwaest): Probably should ensure this is done beforehand. 3002 // TODO(verwaest): Probably should ensure this is done beforehand.
2992 it->InternalizeName(); 3003 it->InternalizeName();
2993 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); 3004 JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
2994 } else { 3005 } else {
2995 // Write the property value. 3006 // Write the property value.
2996 it->WriteDataValue(value); 3007 it->WriteDataValue(value);
2997 } 3008 }
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 } 3383 }
3373 3384
3374 3385
3375 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, 3386 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
3376 ElementsKind to_kind) { 3387 ElementsKind to_kind) {
3377 Handle<Map> map(object->map()); 3388 Handle<Map> map(object->map());
3378 return Map::TransitionElementsTo(map, to_kind); 3389 return Map::TransitionElementsTo(map, to_kind);
3379 } 3390 }
3380 3391
3381 3392
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, 3393 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
3423 Handle<Name> name) { 3394 Handle<Name> name) {
3424 Isolate* isolate = proxy->GetIsolate(); 3395 Isolate* isolate = proxy->GetIsolate();
3425 3396
3426 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3397 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3427 if (name->IsSymbol()) return maybe(false); 3398 if (name->IsSymbol()) return maybe(false);
3428 3399
3429 Handle<Object> args[] = { name }; 3400 Handle<Object> args[] = { name };
3430 Handle<Object> result; 3401 Handle<Object> result;
3431 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3402 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 Handle<Object> value, 3811 Handle<Object> value,
3841 PropertyAttributes attributes, 3812 PropertyAttributes attributes,
3842 ExecutableAccessorInfoHandling handling) { 3813 ExecutableAccessorInfoHandling handling) {
3843 DCHECK(!value->IsTheHole()); 3814 DCHECK(!value->IsTheHole());
3844 LookupIterator it(object, name, 3815 LookupIterator it(object, name,
3845 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR); 3816 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR);
3846 bool is_observed = object->map()->is_observed() && 3817 bool is_observed = object->map()->is_observed() &&
3847 *name != it.isolate()->heap()->hidden_string(); 3818 *name != it.isolate()->heap()->hidden_string();
3848 for (; it.IsFound(); it.Next()) { 3819 for (; it.IsFound(); it.Next()) {
3849 switch (it.state()) { 3820 switch (it.state()) {
3821 case LookupIterator::INTERCEPTOR:
3822 case LookupIterator::JSPROXY:
3850 case LookupIterator::NOT_FOUND: 3823 case LookupIterator::NOT_FOUND:
3851 case LookupIterator::JSPROXY: 3824 case LookupIterator::TRANSITION:
3852 case LookupIterator::INTERCEPTOR:
3853 UNREACHABLE(); 3825 UNREACHABLE();
3854 3826
3855 case LookupIterator::ACCESS_CHECK: 3827 case LookupIterator::ACCESS_CHECK:
3856 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { 3828 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) {
3857 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); 3829 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY);
3858 } 3830 }
3859 break; 3831 break;
3860 3832
3861 case LookupIterator::PROPERTY: { 3833 case LookupIterator::PROPERTY: {
3862 if (!it.HasProperty()) break; 3834 if (!it.HasProperty()) break;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4015 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN); 3987 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN);
4016 return GetPropertyAttributes(&it); 3988 return GetPropertyAttributes(&it);
4017 } 3989 }
4018 3990
4019 3991
4020 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( 3992 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
4021 LookupIterator* it) { 3993 LookupIterator* it) {
4022 for (; it->IsFound(); it->Next()) { 3994 for (; it->IsFound(); it->Next()) {
4023 switch (it->state()) { 3995 switch (it->state()) {
4024 case LookupIterator::NOT_FOUND: 3996 case LookupIterator::NOT_FOUND:
3997 case LookupIterator::TRANSITION:
4025 UNREACHABLE(); 3998 UNREACHABLE();
4026 case LookupIterator::JSPROXY: 3999 case LookupIterator::JSPROXY:
4027 return JSProxy::GetPropertyAttributesWithHandler( 4000 return JSProxy::GetPropertyAttributesWithHandler(
4028 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); 4001 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name());
4029 case LookupIterator::INTERCEPTOR: { 4002 case LookupIterator::INTERCEPTOR: {
4030 Maybe<PropertyAttributes> result = 4003 Maybe<PropertyAttributes> result =
4031 JSObject::GetPropertyAttributesWithInterceptor( 4004 JSObject::GetPropertyAttributesWithInterceptor(
4032 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); 4005 it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
4033 if (!result.has_value) return result; 4006 if (!result.has_value) return result;
4034 if (result.value != ABSENT) return result; 4007 if (result.value != ABSENT) return result;
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
4954 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR 4927 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR
4955 : LookupIterator::CHECK_HIDDEN; 4928 : LookupIterator::CHECK_HIDDEN;
4956 4929
4957 LookupIterator it(object, name, config); 4930 LookupIterator it(object, name, config);
4958 4931
4959 bool is_observed = object->map()->is_observed() && 4932 bool is_observed = object->map()->is_observed() &&
4960 *name != it.isolate()->heap()->hidden_string(); 4933 *name != it.isolate()->heap()->hidden_string();
4961 4934
4962 for (; it.IsFound(); it.Next()) { 4935 for (; it.IsFound(); it.Next()) {
4963 switch (it.state()) { 4936 switch (it.state()) {
4937 case LookupIterator::JSPROXY:
4964 case LookupIterator::NOT_FOUND: 4938 case LookupIterator::NOT_FOUND:
4965 case LookupIterator::JSPROXY: 4939 case LookupIterator::TRANSITION:
4966 UNREACHABLE(); 4940 UNREACHABLE();
4967 case LookupIterator::ACCESS_CHECK: 4941 case LookupIterator::ACCESS_CHECK:
4968 if (it.HasAccess(v8::ACCESS_DELETE)) break; 4942 if (it.HasAccess(v8::ACCESS_DELETE)) break;
4969 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), 4943 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
4970 v8::ACCESS_DELETE); 4944 v8::ACCESS_DELETE);
4971 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); 4945 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object);
4972 return it.isolate()->factory()->false_value(); 4946 return it.isolate()->factory()->false_value();
4973 case LookupIterator::INTERCEPTOR: { 4947 case LookupIterator::INTERCEPTOR: {
4974 MaybeHandle<Object> maybe_result = 4948 MaybeHandle<Object> maybe_result =
4975 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), 4949 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(),
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
5703 for (int i = 0; i < number_of_own_descriptors; i++) { 5677 for (int i = 0; i < number_of_own_descriptors; i++) {
5704 if (descs->GetType(i) == FIELD) { 5678 if (descs->GetType(i) == FIELD) {
5705 int current_index = descs->GetFieldIndex(i); 5679 int current_index = descs->GetFieldIndex(i);
5706 if (current_index > max_index) max_index = current_index; 5680 if (current_index > max_index) max_index = current_index;
5707 } 5681 }
5708 } 5682 }
5709 return max_index + 1; 5683 return max_index + 1;
5710 } 5684 }
5711 5685
5712 5686
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) { 5687 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
5766 int len = array->length(); 5688 int len = array->length();
5767 for (int i = 0; i < len; i++) { 5689 for (int i = 0; i < len; i++) {
5768 Object* e = array->get(i); 5690 Object* e = array->get(i);
5769 if (!(e->IsString() || e->IsNumber())) return false; 5691 if (!(e->IsString() || e->IsNumber())) return false;
5770 } 5692 }
5771 return true; 5693 return true;
5772 } 5694 }
5773 5695
5774 5696
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
6390 isolate); 6312 isolate);
6391 } 6313 }
6392 } 6314 }
6393 } 6315 }
6394 } 6316 }
6395 } else { 6317 } else {
6396 LookupIterator it(object, name, 6318 LookupIterator it(object, name,
6397 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR); 6319 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR);
6398 for (; it.IsFound(); it.Next()) { 6320 for (; it.IsFound(); it.Next()) {
6399 switch (it.state()) { 6321 switch (it.state()) {
6322 case LookupIterator::INTERCEPTOR:
6400 case LookupIterator::NOT_FOUND: 6323 case LookupIterator::NOT_FOUND:
6401 case LookupIterator::INTERCEPTOR: 6324 case LookupIterator::TRANSITION:
6402 UNREACHABLE(); 6325 UNREACHABLE();
6403 6326
6404 case LookupIterator::ACCESS_CHECK: 6327 case LookupIterator::ACCESS_CHECK:
6405 if (it.HasAccess(v8::ACCESS_HAS)) continue; 6328 if (it.HasAccess(v8::ACCESS_HAS)) continue;
6406 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), 6329 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
6407 v8::ACCESS_HAS); 6330 v8::ACCESS_HAS);
6408 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 6331 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
6409 return isolate->factory()->undefined_value(); 6332 return isolate->factory()->undefined_value();
6410 6333
6411 case LookupIterator::JSPROXY: 6334 case LookupIterator::JSPROXY:
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
6828 return false; 6751 return false;
6829 } 6752 }
6830 6753
6831 6754
6832 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, 6755 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
6833 Handle<Object> value) { 6756 Handle<Object> value) {
6834 // Dictionaries can store any property value. 6757 // Dictionaries can store any property value.
6835 if (map->is_dictionary_map()) return map; 6758 if (map->is_dictionary_map()) return map;
6836 6759
6837 // Migrate to the newest map before storing the property. 6760 // Migrate to the newest map before storing the property.
6838 if (map->is_deprecated()) map = Update(map); 6761 map = Update(map);
6839 6762
6840 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 6763 Handle<DescriptorArray> descriptors(map->instance_descriptors());
6841 6764
6842 if (descriptors->CanHoldValue(descriptor, *value)) return map; 6765 if (descriptors->CanHoldValue(descriptor, *value)) return map;
6843 6766
6844 Isolate* isolate = map->GetIsolate(); 6767 Isolate* isolate = map->GetIsolate();
6845 Representation representation = value->OptimalRepresentation(); 6768 Representation representation = value->OptimalRepresentation();
6846 Handle<HeapType> type = value->OptimalType(isolate, representation); 6769 Handle<HeapType> type = value->OptimalType(isolate, representation);
6847 6770
6848 return GeneralizeRepresentation(map, descriptor, representation, type, 6771 return GeneralizeRepresentation(map, descriptor, representation, type,
6849 FORCE_FIELD); 6772 FORCE_FIELD);
6850 } 6773 }
6851 6774
6852 6775
6853 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, 6776 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
6854 Handle<Object> value, 6777 Handle<Object> value,
6855 PropertyAttributes attributes, 6778 PropertyAttributes attributes,
6856 StoreFromKeyed store_mode) { 6779 StoreFromKeyed store_mode) {
6857 // Dictionary maps can always have additional data properties. 6780 // Dictionary maps can always have additional data properties.
6858 if (map->is_dictionary_map()) return map; 6781 if (map->is_dictionary_map()) return map;
6859 6782
6860 // Migrate to the newest map before transitioning to the new property. 6783 // Migrate to the newest map before storing the property.
6861 if (map->is_deprecated()) map = Update(map); 6784 map = Update(map);
6862 6785
6863 int index = map->SearchTransition(*name); 6786 int index = map->SearchTransition(*name);
6864 if (index != TransitionArray::kNotFound) { 6787 if (index != TransitionArray::kNotFound) {
6865 Handle<Map> transition(map->GetTransition(index)); 6788 Handle<Map> transition(map->GetTransition(index));
6866 int descriptor = transition->LastAdded(); 6789 int descriptor = transition->LastAdded();
6867 6790
6868 // TODO(verwaest): Handle attributes better. 6791 // TODO(verwaest): Handle attributes better.
6869 DescriptorArray* descriptors = transition->instance_descriptors(); 6792 DescriptorArray* descriptors = transition->instance_descriptors();
6870 if (descriptors->GetDetails(descriptor).attributes() != attributes) { 6793 if (descriptors->GetDetails(descriptor).attributes() != attributes) {
6871 return CopyGeneralizeAllRepresentations(transition, descriptor, 6794 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
6872 FORCE_FIELD, attributes,
6873 "attributes mismatch");
6874 } 6795 }
6875 6796
6876 return Map::PrepareForDataProperty(transition, descriptor, value); 6797 return Map::PrepareForDataProperty(transition, descriptor, value);
6877 } 6798 }
6878 6799
6879 TransitionFlag flag = INSERT_TRANSITION; 6800 TransitionFlag flag = INSERT_TRANSITION;
6880 MaybeHandle<Map> maybe_map; 6801 MaybeHandle<Map> maybe_map;
6881 if (value->IsJSFunction()) { 6802 if (value->IsJSFunction()) {
6882 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); 6803 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
6883 } else if (!map->TooManyFastProperties(store_mode)) { 6804 } else if (!map->TooManyFastProperties(store_mode)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6918 6839
6919 // Dictionary maps can always have additional data properties. 6840 // Dictionary maps can always have additional data properties.
6920 if (map->is_dictionary_map()) { 6841 if (map->is_dictionary_map()) {
6921 // For global objects, property cells are inlined. We need to change the 6842 // For global objects, property cells are inlined. We need to change the
6922 // map. 6843 // map.
6923 if (map->IsGlobalObjectMap()) return Copy(map); 6844 if (map->IsGlobalObjectMap()) return Copy(map);
6924 return map; 6845 return map;
6925 } 6846 }
6926 6847
6927 // Migrate to the newest map before transitioning to the new property. 6848 // Migrate to the newest map before transitioning to the new property.
6928 if (map->is_deprecated()) map = Update(map); 6849 map = Update(map);
6929 6850
6930 PropertyNormalizationMode mode = map->is_prototype_map() 6851 PropertyNormalizationMode mode = map->is_prototype_map()
6931 ? KEEP_INOBJECT_PROPERTIES 6852 ? KEEP_INOBJECT_PROPERTIES
6932 : CLEAR_INOBJECT_PROPERTIES; 6853 : CLEAR_INOBJECT_PROPERTIES;
6933 6854
6934 int index = map->SearchTransition(*name); 6855 int index = map->SearchTransition(*name);
6935 if (index != TransitionArray::kNotFound) { 6856 if (index != TransitionArray::kNotFound) {
6936 Handle<Map> transition(map->GetTransition(index)); 6857 Handle<Map> transition(map->GetTransition(index));
6937 DescriptorArray* descriptors = transition->instance_descriptors(); 6858 DescriptorArray* descriptors = transition->instance_descriptors();
6938 // Fast path, assume that we're modifying the last added descriptor. 6859 // Fast path, assume that we're modifying the last added descriptor.
(...skipping 9612 matching lines...) Expand 10 before | Expand all | Expand 10 after
16551 #define ERROR_MESSAGES_TEXTS(C, T) T, 16472 #define ERROR_MESSAGES_TEXTS(C, T) T,
16552 static const char* error_messages_[] = { 16473 static const char* error_messages_[] = {
16553 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16474 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16554 }; 16475 };
16555 #undef ERROR_MESSAGES_TEXTS 16476 #undef ERROR_MESSAGES_TEXTS
16556 return error_messages_[reason]; 16477 return error_messages_[reason];
16557 } 16478 }
16558 16479
16559 16480
16560 } } // namespace v8::internal 16481 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698