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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { | 132 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
133 for (; it->IsFound(); it->Next()) { | 133 for (; it->IsFound(); it->Next()) { |
134 switch (it->state()) { | 134 switch (it->state()) { |
135 case LookupIterator::NOT_FOUND: | 135 case LookupIterator::NOT_FOUND: |
136 UNREACHABLE(); | 136 UNREACHABLE(); |
137 case LookupIterator::JSPROXY: | 137 case LookupIterator::JSPROXY: |
138 return JSProxy::GetPropertyWithHandler( | 138 return JSProxy::GetPropertyWithHandler( |
139 it->GetJSProxy(), it->GetReceiver(), it->name()); | 139 it->GetJSProxy(), it->GetReceiver(), it->name()); |
140 case LookupIterator::INTERCEPTOR: { | 140 case LookupIterator::INTERCEPTOR: { |
141 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( | 141 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( |
142 it->GetHolder(), it->GetReceiver(), it->name()); | 142 it->GetNonJSProxyHolder(), it->GetReceiver(), it->name()); |
143 if (!maybe_result.is_null()) return maybe_result; | 143 if (!maybe_result.is_null()) return maybe_result; |
144 if (it->isolate()->has_pending_exception()) return maybe_result; | 144 if (it->isolate()->has_pending_exception()) return maybe_result; |
145 break; | 145 break; |
146 } | 146 } |
147 case LookupIterator::ACCESS_CHECK: | 147 case LookupIterator::ACCESS_CHECK: |
148 if (it->HasAccess(v8::ACCESS_GET)) break; | 148 if (it->HasAccess(v8::ACCESS_GET)) break; |
149 return JSObject::GetPropertyWithFailedAccessCheck(it); | 149 return JSObject::GetPropertyWithFailedAccessCheck(it); |
150 case LookupIterator::PROPERTY: | 150 case LookupIterator::PROPERTY: |
151 if (it->HasProperty()) { | 151 if (it->HasProperty()) { |
152 switch (it->property_kind()) { | 152 switch (it->property_kind()) { |
153 case LookupIterator::ACCESSOR: | 153 case LookupIterator::ACCESSOR: |
154 return GetPropertyWithAccessor( | 154 return GetPropertyWithAccessor(it->GetReceiver(), it->name(), |
155 it->GetReceiver(), it->name(), | 155 it->GetNonJSProxyHolder(), |
156 it->GetHolder(), it->GetAccessors()); | 156 it->GetAccessors()); |
157 case LookupIterator::DATA: | 157 case LookupIterator::DATA: |
158 return it->GetDataValue(); | 158 return it->GetDataValue(); |
159 } | 159 } |
160 } | 160 } |
161 break; | 161 break; |
162 } | 162 } |
163 } | 163 } |
164 return it->factory()->undefined_value(); | 164 return it->factory()->undefined_value(); |
165 } | 165 } |
166 | 166 |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; | 575 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; |
576 } | 576 } |
577 } | 577 } |
578 } | 578 } |
579 return false; | 579 return false; |
580 } | 580 } |
581 | 581 |
582 | 582 |
583 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 583 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
584 LookupIterator* it) { | 584 LookupIterator* it) { |
585 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); | 585 Handle<JSObject> checked = it->GetNonJSProxyHolder(); |
586 if (FindAllCanReadHolder(it)) { | 586 if (FindAllCanReadHolder(it)) { |
587 return GetPropertyWithAccessor( | 587 return GetPropertyWithAccessor(it->GetReceiver(), it->name(), |
588 it->GetReceiver(), it->name(), it->GetHolder(), it->GetAccessors()); | 588 it->GetNonJSProxyHolder(), |
| 589 it->GetAccessors()); |
589 } | 590 } |
590 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET); | 591 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET); |
591 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 592 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
592 return it->factory()->undefined_value(); | 593 return it->factory()->undefined_value(); |
593 } | 594 } |
594 | 595 |
595 | 596 |
596 PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck( | 597 PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck( |
597 LookupIterator* it) { | 598 LookupIterator* it) { |
598 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); | 599 Handle<JSObject> checked = it->GetNonJSProxyHolder(); |
599 if (FindAllCanReadHolder(it)) return it->property_details().attributes(); | 600 if (FindAllCanReadHolder(it)) return it->property_details().attributes(); |
600 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); | 601 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); |
601 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 602 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
602 return ABSENT; | 603 return ABSENT; |
603 } | 604 } |
604 | 605 |
605 | 606 |
606 static bool FindAllCanWriteHolder(LookupIterator* it) { | 607 static bool FindAllCanWriteHolder(LookupIterator* it) { |
607 it->skip_interceptor(); | 608 it->skip_interceptor(); |
608 it->skip_access_check(); | 609 it->skip_access_check(); |
609 for (; it->IsFound(); it->Next()) { | 610 for (; it->IsFound(); it->Next()) { |
610 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && | 611 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && |
611 it->property_kind() == LookupIterator::ACCESSOR) { | 612 it->property_kind() == LookupIterator::ACCESSOR) { |
612 Handle<Object> accessors = it->GetAccessors(); | 613 Handle<Object> accessors = it->GetAccessors(); |
613 if (accessors->IsAccessorInfo()) { | 614 if (accessors->IsAccessorInfo()) { |
614 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 615 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
615 } | 616 } |
616 } | 617 } |
617 } | 618 } |
618 return false; | 619 return false; |
619 } | 620 } |
620 | 621 |
621 | 622 |
622 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( | 623 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( |
623 LookupIterator* it, Handle<Object> value, StrictMode strict_mode) { | 624 LookupIterator* it, Handle<Object> value, StrictMode strict_mode) { |
624 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); | 625 Handle<JSObject> checked = it->GetNonJSProxyHolder(); |
625 if (FindAllCanWriteHolder(it)) { | 626 if (FindAllCanWriteHolder(it)) { |
626 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, | 627 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, |
627 it->GetHolder(), it->GetAccessors(), | 628 it->GetNonJSProxyHolder(), |
628 strict_mode); | 629 it->GetAccessors(), strict_mode); |
629 } | 630 } |
630 | 631 |
631 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); | 632 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); |
632 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 633 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
633 return value; | 634 return value; |
634 } | 635 } |
635 | 636 |
636 | 637 |
637 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { | 638 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { |
638 ASSERT(!HasFastProperties()); | 639 ASSERT(!HasFastProperties()); |
(...skipping 2295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2934 return handle(new_map); | 2935 return handle(new_map); |
2935 } | 2936 } |
2936 | 2937 |
2937 | 2938 |
2938 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it, | 2939 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
2939 Handle<Object> value) { | 2940 Handle<Object> value) { |
2940 // TODO(rossberg): Support symbols in the API. | 2941 // TODO(rossberg): Support symbols in the API. |
2941 if (it->name()->IsSymbol()) return value; | 2942 if (it->name()->IsSymbol()) return value; |
2942 | 2943 |
2943 Handle<String> name_string = Handle<String>::cast(it->name()); | 2944 Handle<String> name_string = Handle<String>::cast(it->name()); |
2944 Handle<JSObject> holder = it->GetHolder(); | 2945 Handle<JSObject> holder = it->GetNonJSProxyHolder(); |
2945 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); | 2946 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); |
2946 if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>(); | 2947 if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>(); |
2947 | 2948 |
2948 LOG(it->isolate(), | 2949 LOG(it->isolate(), |
2949 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name_string)); | 2950 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name_string)); |
2950 PropertyCallbackArguments args(it->isolate(), interceptor->data(), *holder, | 2951 PropertyCallbackArguments args(it->isolate(), interceptor->data(), *holder, |
2951 *holder); | 2952 *holder); |
2952 v8::NamedPropertySetterCallback setter = | 2953 v8::NamedPropertySetterCallback setter = |
2953 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); | 2954 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); |
2954 v8::Handle<v8::Value> result = args.Call( | 2955 v8::Handle<v8::Value> result = args.Call( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 | 3011 |
3011 case LookupIterator::INTERCEPTOR: | 3012 case LookupIterator::INTERCEPTOR: |
3012 if (it->HolderIsReceiver()) { | 3013 if (it->HolderIsReceiver()) { |
3013 MaybeHandle<Object> maybe_result = | 3014 MaybeHandle<Object> maybe_result = |
3014 JSObject::SetPropertyWithInterceptor(it, value); | 3015 JSObject::SetPropertyWithInterceptor(it, value); |
3015 if (!maybe_result.is_null()) return maybe_result; | 3016 if (!maybe_result.is_null()) return maybe_result; |
3016 if (it->isolate()->has_pending_exception()) return maybe_result; | 3017 if (it->isolate()->has_pending_exception()) return maybe_result; |
3017 } else { | 3018 } else { |
3018 Maybe<PropertyAttributes> maybe_attributes = | 3019 Maybe<PropertyAttributes> maybe_attributes = |
3019 JSObject::GetPropertyAttributesWithInterceptor( | 3020 JSObject::GetPropertyAttributesWithInterceptor( |
3020 it->GetHolder(), it->GetReceiver(), it->name()); | 3021 it->GetNonJSProxyHolder(), it->GetReceiver(), it->name()); |
3021 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 3022 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
3022 done = maybe_attributes.has_value; | 3023 done = maybe_attributes.has_value; |
3023 if (done && (maybe_attributes.value & READ_ONLY) != 0) { | 3024 if (done && (maybe_attributes.value & READ_ONLY) != 0) { |
3024 return WriteToReadOnlyProperty(it, value, strict_mode); | 3025 return WriteToReadOnlyProperty(it, value, strict_mode); |
3025 } | 3026 } |
3026 } | 3027 } |
3027 break; | 3028 break; |
3028 | 3029 |
3029 case LookupIterator::PROPERTY: | 3030 case LookupIterator::PROPERTY: |
3030 if (!it->HasProperty()) break; | 3031 if (!it->HasProperty()) break; |
3031 if (it->property_details().IsReadOnly()) { | 3032 if (it->property_details().IsReadOnly()) { |
3032 return WriteToReadOnlyProperty(it, value, strict_mode); | 3033 return WriteToReadOnlyProperty(it, value, strict_mode); |
3033 } | 3034 } |
3034 switch (it->property_kind()) { | 3035 switch (it->property_kind()) { |
3035 case LookupIterator::ACCESSOR: | 3036 case LookupIterator::ACCESSOR: |
3036 if (it->HolderIsReceiver() || | 3037 if (it->HolderIsReceiver() || |
3037 !it->GetAccessors()->IsDeclaredAccessorInfo()) { | 3038 !it->GetAccessors()->IsDeclaredAccessorInfo()) { |
3038 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), | 3039 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), |
3039 value, it->GetHolder(), | 3040 value, it->GetNonJSProxyHolder(), |
3040 it->GetAccessors(), strict_mode); | 3041 it->GetAccessors(), strict_mode); |
3041 } | 3042 } |
3042 break; | 3043 break; |
3043 case LookupIterator::DATA: | 3044 case LookupIterator::DATA: |
3044 if (it->HolderIsReceiver()) return SetDataProperty(it, value); | 3045 if (it->HolderIsReceiver()) return SetDataProperty(it, value); |
3045 } | 3046 } |
3046 done = true; | 3047 done = true; |
3047 break; | 3048 break; |
3048 } | 3049 } |
3049 | 3050 |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4330 for (; it->IsFound(); it->Next()) { | 4331 for (; it->IsFound(); it->Next()) { |
4331 switch (it->state()) { | 4332 switch (it->state()) { |
4332 case LookupIterator::NOT_FOUND: | 4333 case LookupIterator::NOT_FOUND: |
4333 UNREACHABLE(); | 4334 UNREACHABLE(); |
4334 case LookupIterator::JSPROXY: | 4335 case LookupIterator::JSPROXY: |
4335 return JSProxy::GetPropertyAttributesWithHandler( | 4336 return JSProxy::GetPropertyAttributesWithHandler( |
4336 it->GetJSProxy(), it->GetReceiver(), it->name()); | 4337 it->GetJSProxy(), it->GetReceiver(), it->name()); |
4337 case LookupIterator::INTERCEPTOR: { | 4338 case LookupIterator::INTERCEPTOR: { |
4338 Maybe<PropertyAttributes> result = | 4339 Maybe<PropertyAttributes> result = |
4339 JSObject::GetPropertyAttributesWithInterceptor( | 4340 JSObject::GetPropertyAttributesWithInterceptor( |
4340 it->GetHolder(), it->GetReceiver(), it->name()); | 4341 it->GetNonJSProxyHolder(), it->GetReceiver(), it->name()); |
4341 if (result.has_value) return result.value; | 4342 if (result.has_value) return result.value; |
4342 break; | 4343 break; |
4343 } | 4344 } |
4344 case LookupIterator::ACCESS_CHECK: | 4345 case LookupIterator::ACCESS_CHECK: |
4345 if (it->HasAccess(v8::ACCESS_HAS)) break; | 4346 if (it->HasAccess(v8::ACCESS_HAS)) break; |
4346 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); | 4347 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); |
4347 case LookupIterator::PROPERTY: | 4348 case LookupIterator::PROPERTY: |
4348 if (it->HasProperty()) return it->property_details().attributes(); | 4349 if (it->HasProperty()) return it->property_details().attributes(); |
4349 break; | 4350 break; |
4350 } | 4351 } |
(...skipping 12590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16941 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16942 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16942 static const char* error_messages_[] = { | 16943 static const char* error_messages_[] = { |
16943 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16944 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16944 }; | 16945 }; |
16945 #undef ERROR_MESSAGES_TEXTS | 16946 #undef ERROR_MESSAGES_TEXTS |
16946 return error_messages_[reason]; | 16947 return error_messages_[reason]; |
16947 } | 16948 } |
16948 | 16949 |
16949 | 16950 |
16950 } } // namespace v8::internal | 16951 } } // namespace v8::internal |
OLD | NEW |