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

Side by Side Diff: src/objects.cc

Issue 418383002: Change Has* and Get*Attributes to return Maybe<*>, indicating possible exceptions. (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
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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 return GetPropertyWithAccessor(it->GetReceiver(), it->name(), 587 return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
588 it->GetHolder<JSObject>(), 588 it->GetHolder<JSObject>(),
589 it->GetAccessors()); 589 it->GetAccessors());
590 } 590 }
591 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET); 591 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
592 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 592 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
593 return it->factory()->undefined_value(); 593 return it->factory()->undefined_value();
594 } 594 }
595 595
596 596
597 PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck( 597 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
598 LookupIterator* it) { 598 LookupIterator* it) {
599 Handle<JSObject> checked = it->GetHolder<JSObject>(); 599 Handle<JSObject> checked = it->GetHolder<JSObject>();
600 if (FindAllCanReadHolder(it)) return it->property_details().attributes(); 600 if (FindAllCanReadHolder(it))
601 return maybe(it->property_details().attributes());
601 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); 602 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
602 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 603 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
603 return ABSENT; 604 Maybe<PropertyAttributes>());
605 return maybe(ABSENT);
604 } 606 }
605 607
606 608
607 static bool FindAllCanWriteHolder(LookupIterator* it) { 609 static bool FindAllCanWriteHolder(LookupIterator* it) {
608 it->skip_interceptor(); 610 it->skip_interceptor();
609 it->skip_access_check(); 611 it->skip_access_check();
610 for (; it->IsFound(); it->Next()) { 612 for (; it->IsFound(); it->Next()) {
611 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && 613 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() &&
612 it->property_kind() == LookupIterator::ACCESSOR) { 614 it->property_kind() == LookupIterator::ACCESSOR) {
613 Handle<Object> accessors = it->GetAccessors(); 615 Handle<Object> accessors = it->GetAccessors();
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after
3012 case LookupIterator::INTERCEPTOR: 3014 case LookupIterator::INTERCEPTOR:
3013 if (it->HolderIsReceiver()) { 3015 if (it->HolderIsReceiver()) {
3014 MaybeHandle<Object> maybe_result = 3016 MaybeHandle<Object> maybe_result =
3015 JSObject::SetPropertyWithInterceptor(it, value); 3017 JSObject::SetPropertyWithInterceptor(it, value);
3016 if (!maybe_result.is_null()) return maybe_result; 3018 if (!maybe_result.is_null()) return maybe_result;
3017 if (it->isolate()->has_pending_exception()) return maybe_result; 3019 if (it->isolate()->has_pending_exception()) return maybe_result;
3018 } else { 3020 } else {
3019 Maybe<PropertyAttributes> maybe_attributes = 3021 Maybe<PropertyAttributes> maybe_attributes =
3020 JSObject::GetPropertyAttributesWithInterceptor( 3022 JSObject::GetPropertyAttributesWithInterceptor(
3021 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); 3023 it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
3022 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 3024 if (!maybe_attributes.has_value) return MaybeHandle<Object>();
3023 done = maybe_attributes.has_value; 3025 done = maybe_attributes.value != ABSENT;
3024 if (done && (maybe_attributes.value & READ_ONLY) != 0) { 3026 if (done && (maybe_attributes.value & READ_ONLY) != 0) {
3025 return WriteToReadOnlyProperty(it, value, strict_mode); 3027 return WriteToReadOnlyProperty(it, value, strict_mode);
3026 } 3028 }
3027 } 3029 }
3028 break; 3030 break;
3029 3031
3030 case LookupIterator::PROPERTY: 3032 case LookupIterator::PROPERTY:
3031 if (!it->HasProperty()) break; 3033 if (!it->HasProperty()) break;
3032 if (it->property_details().IsReadOnly()) { 3034 if (it->property_details().IsReadOnly()) {
3033 return WriteToReadOnlyProperty(it, value, strict_mode); 3035 return WriteToReadOnlyProperty(it, value, strict_mode);
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
3587 return result->HandlerResult(JSProxy::cast(iter.GetCurrent())); 3589 return result->HandlerResult(JSProxy::cast(iter.GetCurrent()));
3588 } 3590 }
3589 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result); 3591 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result);
3590 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); 3592 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
3591 if (result->IsFound()) return; 3593 if (result->IsFound()) return;
3592 } 3594 }
3593 result->NotFound(); 3595 result->NotFound();
3594 } 3596 }
3595 3597
3596 3598
3597 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { 3599 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
3600 Handle<Name> name) {
3598 Isolate* isolate = proxy->GetIsolate(); 3601 Isolate* isolate = proxy->GetIsolate();
3599 3602
3600 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3603 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3601 if (name->IsSymbol()) return false; 3604 if (name->IsSymbol()) return maybe(false);
3602 3605
3603 Handle<Object> args[] = { name }; 3606 Handle<Object> args[] = { name };
3604 Handle<Object> result; 3607 Handle<Object> result;
3605 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3608 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3606 isolate, result, 3609 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(),
3607 CallTrap(proxy, 3610 ARRAY_SIZE(args), args),
3608 "has", 3611 Maybe<bool>());
3609 isolate->derived_has_trap(),
3610 ARRAY_SIZE(args),
3611 args),
3612 false);
3613 3612
3614 return result->BooleanValue(); 3613 return maybe(result->BooleanValue());
3615 } 3614 }
3616 3615
3617 3616
3618 MaybeHandle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, 3617 MaybeHandle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
3619 Handle<Object> receiver, 3618 Handle<Object> receiver,
3620 Handle<Name> name, 3619 Handle<Name> name,
3621 Handle<Object> value, 3620 Handle<Object> value,
3622 StrictMode strict_mode) { 3621 StrictMode strict_mode) {
3623 Isolate* isolate = proxy->GetIsolate(); 3622 Isolate* isolate = proxy->GetIsolate();
3624 3623
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
3772 3771
3773 3772
3774 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( 3773 MaybeHandle<Object> JSProxy::DeleteElementWithHandler(
3775 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { 3774 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) {
3776 Isolate* isolate = proxy->GetIsolate(); 3775 Isolate* isolate = proxy->GetIsolate();
3777 Handle<String> name = isolate->factory()->Uint32ToString(index); 3776 Handle<String> name = isolate->factory()->Uint32ToString(index);
3778 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); 3777 return JSProxy::DeletePropertyWithHandler(proxy, name, mode);
3779 } 3778 }
3780 3779
3781 3780
3782 PropertyAttributes JSProxy::GetPropertyAttributesWithHandler( 3781 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
3783 Handle<JSProxy> proxy, 3782 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) {
3784 Handle<Object> receiver,
3785 Handle<Name> name) {
3786 Isolate* isolate = proxy->GetIsolate(); 3783 Isolate* isolate = proxy->GetIsolate();
3787 HandleScope scope(isolate); 3784 HandleScope scope(isolate);
3788 3785
3789 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3786 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3790 if (name->IsSymbol()) return ABSENT; 3787 if (name->IsSymbol()) return maybe(ABSENT);
3791 3788
3792 Handle<Object> args[] = { name }; 3789 Handle<Object> args[] = { name };
3793 Handle<Object> result; 3790 Handle<Object> result;
3794 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3791 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3795 isolate, result, 3792 isolate, result,
3796 proxy->CallTrap(proxy, 3793 proxy->CallTrap(proxy, "getPropertyDescriptor", Handle<Object>(),
3797 "getPropertyDescriptor", 3794 ARRAY_SIZE(args), args),
3798 Handle<Object>(), 3795 Maybe<PropertyAttributes>());
3799 ARRAY_SIZE(args),
3800 args),
3801 NONE);
3802 3796
3803 if (result->IsUndefined()) return ABSENT; 3797 if (result->IsUndefined()) return maybe(ABSENT);
3804 3798
3805 Handle<Object> argv[] = { result }; 3799 Handle<Object> argv[] = { result };
3806 Handle<Object> desc; 3800 Handle<Object> desc;
3807 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3801 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3808 isolate, desc, 3802 isolate, desc,
3809 Execution::Call(isolate, 3803 Execution::Call(isolate, isolate->to_complete_property_descriptor(),
3810 isolate->to_complete_property_descriptor(), 3804 result, ARRAY_SIZE(argv), argv),
3811 result, 3805 Maybe<PropertyAttributes>());
3812 ARRAY_SIZE(argv),
3813 argv),
3814 NONE);
3815 3806
3816 // Convert result to PropertyAttributes. 3807 // Convert result to PropertyAttributes.
3817 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( 3808 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
3818 STATIC_ASCII_VECTOR("enumerable_")); 3809 STATIC_ASCII_VECTOR("enumerable_"));
3819 Handle<Object> enumerable; 3810 Handle<Object> enumerable;
3820 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3811 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable,
3821 isolate, enumerable, Object::GetProperty(desc, enum_n), NONE); 3812 Object::GetProperty(desc, enum_n),
3813 Maybe<PropertyAttributes>());
3822 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( 3814 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
3823 STATIC_ASCII_VECTOR("configurable_")); 3815 STATIC_ASCII_VECTOR("configurable_"));
3824 Handle<Object> configurable; 3816 Handle<Object> configurable;
3825 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3817 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable,
3826 isolate, configurable, Object::GetProperty(desc, conf_n), NONE); 3818 Object::GetProperty(desc, conf_n),
3819 Maybe<PropertyAttributes>());
3827 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( 3820 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
3828 STATIC_ASCII_VECTOR("writable_")); 3821 STATIC_ASCII_VECTOR("writable_"));
3829 Handle<Object> writable; 3822 Handle<Object> writable;
3830 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3823 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable,
3831 isolate, writable, Object::GetProperty(desc, writ_n), NONE); 3824 Object::GetProperty(desc, writ_n),
3825 Maybe<PropertyAttributes>());
3832 if (!writable->BooleanValue()) { 3826 if (!writable->BooleanValue()) {
3833 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( 3827 Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
3834 STATIC_ASCII_VECTOR("set_")); 3828 STATIC_ASCII_VECTOR("set_"));
3835 Handle<Object> setter; 3829 Handle<Object> setter;
3836 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3830 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter,
3837 isolate, setter, Object::GetProperty(desc, set_n), NONE); 3831 Object::GetProperty(desc, set_n),
3832 Maybe<PropertyAttributes>());
3838 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); 3833 writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
3839 } 3834 }
3840 3835
3841 if (configurable->IsFalse()) { 3836 if (configurable->IsFalse()) {
3842 Handle<Object> handler(proxy->handler(), isolate); 3837 Handle<Object> handler(proxy->handler(), isolate);
3843 Handle<String> trap = isolate->factory()->InternalizeOneByteString( 3838 Handle<String> trap = isolate->factory()->InternalizeOneByteString(
3844 STATIC_ASCII_VECTOR("getPropertyDescriptor")); 3839 STATIC_ASCII_VECTOR("getPropertyDescriptor"));
3845 Handle<Object> args[] = { handler, trap, name }; 3840 Handle<Object> args[] = { handler, trap, name };
3846 Handle<Object> error = isolate->factory()->NewTypeError( 3841 Handle<Object> error = isolate->factory()->NewTypeError(
3847 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 3842 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
3848 isolate->Throw(*error); 3843 isolate->Throw(*error);
3849 return NONE; 3844 return maybe(NONE);
3850 } 3845 }
3851 3846
3852 int attributes = NONE; 3847 int attributes = NONE;
3853 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; 3848 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
3854 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; 3849 if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
3855 if (!writable->BooleanValue()) attributes |= READ_ONLY; 3850 if (!writable->BooleanValue()) attributes |= READ_ONLY;
3856 return static_cast<PropertyAttributes>(attributes); 3851 return maybe(static_cast<PropertyAttributes>(attributes));
3857 } 3852 }
3858 3853
3859 3854
3860 PropertyAttributes JSProxy::GetElementAttributeWithHandler( 3855 Maybe<PropertyAttributes> JSProxy::GetElementAttributeWithHandler(
3861 Handle<JSProxy> proxy, 3856 Handle<JSProxy> proxy, Handle<JSReceiver> receiver, uint32_t index) {
3862 Handle<JSReceiver> receiver,
3863 uint32_t index) {
3864 Isolate* isolate = proxy->GetIsolate(); 3857 Isolate* isolate = proxy->GetIsolate();
3865 Handle<String> name = isolate->factory()->Uint32ToString(index); 3858 Handle<String> name = isolate->factory()->Uint32ToString(index);
3866 return GetPropertyAttributesWithHandler(proxy, receiver, name); 3859 return GetPropertyAttributesWithHandler(proxy, receiver, name);
3867 } 3860 }
3868 3861
3869 3862
3870 void JSProxy::Fix(Handle<JSProxy> proxy) { 3863 void JSProxy::Fix(Handle<JSProxy> proxy) {
3871 Isolate* isolate = proxy->GetIsolate(); 3864 Isolate* isolate = proxy->GetIsolate();
3872 3865
3873 // Save identity hash. 3866 // Save identity hash.
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
4271 4264
4272 return value; 4265 return value;
4273 } 4266 }
4274 4267
4275 4268
4276 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( 4269 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
4277 Handle<JSObject> holder, 4270 Handle<JSObject> holder,
4278 Handle<Object> receiver, 4271 Handle<Object> receiver,
4279 Handle<Name> name) { 4272 Handle<Name> name) {
4280 // TODO(rossberg): Support symbols in the API. 4273 // TODO(rossberg): Support symbols in the API.
4281 if (name->IsSymbol()) return Maybe<PropertyAttributes>(); 4274 if (name->IsSymbol()) return maybe(ABSENT);
4282 4275
4283 Isolate* isolate = holder->GetIsolate(); 4276 Isolate* isolate = holder->GetIsolate();
4284 HandleScope scope(isolate); 4277 HandleScope scope(isolate);
4285 4278
4286 // Make sure that the top context does not change when doing 4279 // Make sure that the top context does not change when doing
4287 // callbacks or interceptor calls. 4280 // callbacks or interceptor calls.
4288 AssertNoContextChange ncc(isolate); 4281 AssertNoContextChange ncc(isolate);
4289 4282
4290 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); 4283 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
4291 PropertyCallbackArguments args( 4284 PropertyCallbackArguments args(
4292 isolate, interceptor->data(), *receiver, *holder); 4285 isolate, interceptor->data(), *receiver, *holder);
4293 if (!interceptor->query()->IsUndefined()) { 4286 if (!interceptor->query()->IsUndefined()) {
4294 v8::NamedPropertyQueryCallback query = 4287 v8::NamedPropertyQueryCallback query =
4295 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); 4288 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
4296 LOG(isolate, 4289 LOG(isolate,
4297 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); 4290 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name));
4298 v8::Handle<v8::Integer> result = 4291 v8::Handle<v8::Integer> result =
4299 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name))); 4292 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
4300 if (!result.IsEmpty()) { 4293 if (!result.IsEmpty()) {
4301 ASSERT(result->IsInt32()); 4294 ASSERT(result->IsInt32());
4302 return Maybe<PropertyAttributes>( 4295 return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
4303 static_cast<PropertyAttributes>(result->Int32Value()));
4304 } 4296 }
4305 } else if (!interceptor->getter()->IsUndefined()) { 4297 } else if (!interceptor->getter()->IsUndefined()) {
4306 v8::NamedPropertyGetterCallback getter = 4298 v8::NamedPropertyGetterCallback getter =
4307 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); 4299 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
4308 LOG(isolate, 4300 LOG(isolate,
4309 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); 4301 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name));
4310 v8::Handle<v8::Value> result = 4302 v8::Handle<v8::Value> result =
4311 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); 4303 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
4312 if (!result.IsEmpty()) return Maybe<PropertyAttributes>(DONT_ENUM); 4304 if (!result.IsEmpty()) return maybe(DONT_ENUM);
4313 } 4305 }
4314 return Maybe<PropertyAttributes>(); 4306
4307 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
4308 return maybe(ABSENT);
4315 } 4309 }
4316 4310
4317 4311
4318 PropertyAttributes JSReceiver::GetOwnPropertyAttributes( 4312 Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
4319 Handle<JSReceiver> object, Handle<Name> name) { 4313 Handle<JSReceiver> object, Handle<Name> name) {
4320 // Check whether the name is an array index. 4314 // Check whether the name is an array index.
4321 uint32_t index = 0; 4315 uint32_t index = 0;
4322 if (object->IsJSObject() && name->AsArrayIndex(&index)) { 4316 if (object->IsJSObject() && name->AsArrayIndex(&index)) {
4323 return GetOwnElementAttribute(object, index); 4317 return GetOwnElementAttribute(object, index);
4324 } 4318 }
4325 LookupIterator it(object, name, LookupIterator::CHECK_OWN); 4319 LookupIterator it(object, name, LookupIterator::CHECK_OWN);
4326 return GetPropertyAttributes(&it); 4320 return GetPropertyAttributes(&it);
4327 } 4321 }
4328 4322
4329 4323
4330 PropertyAttributes JSReceiver::GetPropertyAttributes(LookupIterator* it) { 4324 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
4325 LookupIterator* it) {
4331 for (; it->IsFound(); it->Next()) { 4326 for (; it->IsFound(); it->Next()) {
4332 switch (it->state()) { 4327 switch (it->state()) {
4333 case LookupIterator::NOT_FOUND: 4328 case LookupIterator::NOT_FOUND:
4334 UNREACHABLE(); 4329 UNREACHABLE();
4335 case LookupIterator::JSPROXY: 4330 case LookupIterator::JSPROXY:
4336 return JSProxy::GetPropertyAttributesWithHandler( 4331 return JSProxy::GetPropertyAttributesWithHandler(
4337 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); 4332 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name());
4338 case LookupIterator::INTERCEPTOR: { 4333 case LookupIterator::INTERCEPTOR: {
4339 Maybe<PropertyAttributes> result = 4334 Maybe<PropertyAttributes> result =
4340 JSObject::GetPropertyAttributesWithInterceptor( 4335 JSObject::GetPropertyAttributesWithInterceptor(
4341 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); 4336 it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
4342 if (result.has_value) return result.value; 4337 if (!result.has_value) return result;
4338 if (result.value != ABSENT) return result;
4343 break; 4339 break;
4344 } 4340 }
4345 case LookupIterator::ACCESS_CHECK: 4341 case LookupIterator::ACCESS_CHECK:
4346 if (it->HasAccess(v8::ACCESS_HAS)) break; 4342 if (it->HasAccess(v8::ACCESS_HAS)) break;
4347 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); 4343 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
4348 case LookupIterator::PROPERTY: 4344 case LookupIterator::PROPERTY:
4349 if (it->HasProperty()) return it->property_details().attributes(); 4345 if (it->HasProperty()) {
4346 return maybe(it->property_details().attributes());
4347 }
4350 break; 4348 break;
4351 } 4349 }
4352 } 4350 }
4353 return ABSENT; 4351 return maybe(ABSENT);
4354 } 4352 }
4355 4353
4356 4354
4357 PropertyAttributes JSObject::GetElementAttributeWithReceiver( 4355 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver(
4358 Handle<JSObject> object, 4356 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4359 Handle<JSReceiver> receiver,
4360 uint32_t index,
4361 bool check_prototype) { 4357 bool check_prototype) {
4362 Isolate* isolate = object->GetIsolate(); 4358 Isolate* isolate = object->GetIsolate();
4363 4359
4364 // Check access rights if needed. 4360 // Check access rights if needed.
4365 if (object->IsAccessCheckNeeded()) { 4361 if (object->IsAccessCheckNeeded()) {
4366 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { 4362 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
4367 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); 4363 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
4368 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 4364 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
4369 return ABSENT; 4365 return maybe(ABSENT);
4370 } 4366 }
4371 } 4367 }
4372 4368
4373 if (object->IsJSGlobalProxy()) { 4369 if (object->IsJSGlobalProxy()) {
4374 PrototypeIterator iter(isolate, object); 4370 PrototypeIterator iter(isolate, object);
4375 if (iter.IsAtEnd()) return ABSENT; 4371 if (iter.IsAtEnd()) return maybe(ABSENT);
4376 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 4372 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
4377 return JSObject::GetElementAttributeWithReceiver( 4373 return JSObject::GetElementAttributeWithReceiver(
4378 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, 4374 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
4379 index, check_prototype); 4375 index, check_prototype);
4380 } 4376 }
4381 4377
4382 // Check for lookup interceptor except when bootstrapping. 4378 // Check for lookup interceptor except when bootstrapping.
4383 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { 4379 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
4384 return JSObject::GetElementAttributeWithInterceptor( 4380 return JSObject::GetElementAttributeWithInterceptor(
4385 object, receiver, index, check_prototype); 4381 object, receiver, index, check_prototype);
4386 } 4382 }
4387 4383
4388 return GetElementAttributeWithoutInterceptor( 4384 return GetElementAttributeWithoutInterceptor(
4389 object, receiver, index, check_prototype); 4385 object, receiver, index, check_prototype);
4390 } 4386 }
4391 4387
4392 4388
4393 PropertyAttributes JSObject::GetElementAttributeWithInterceptor( 4389 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor(
4394 Handle<JSObject> object, 4390 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4395 Handle<JSReceiver> receiver,
4396 uint32_t index,
4397 bool check_prototype) { 4391 bool check_prototype) {
4398 Isolate* isolate = object->GetIsolate(); 4392 Isolate* isolate = object->GetIsolate();
4399 HandleScope scope(isolate); 4393 HandleScope scope(isolate);
4400 4394
4401 // Make sure that the top context does not change when doing 4395 // Make sure that the top context does not change when doing
4402 // callbacks or interceptor calls. 4396 // callbacks or interceptor calls.
4403 AssertNoContextChange ncc(isolate); 4397 AssertNoContextChange ncc(isolate);
4404 4398
4405 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); 4399 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4406 PropertyCallbackArguments args( 4400 PropertyCallbackArguments args(
4407 isolate, interceptor->data(), *receiver, *object); 4401 isolate, interceptor->data(), *receiver, *object);
4408 if (!interceptor->query()->IsUndefined()) { 4402 if (!interceptor->query()->IsUndefined()) {
4409 v8::IndexedPropertyQueryCallback query = 4403 v8::IndexedPropertyQueryCallback query =
4410 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); 4404 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4411 LOG(isolate, 4405 LOG(isolate,
4412 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index)); 4406 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
4413 v8::Handle<v8::Integer> result = args.Call(query, index); 4407 v8::Handle<v8::Integer> result = args.Call(query, index);
4414 if (!result.IsEmpty()) 4408 if (!result.IsEmpty())
4415 return static_cast<PropertyAttributes>(result->Int32Value()); 4409 return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
4416 } else if (!interceptor->getter()->IsUndefined()) { 4410 } else if (!interceptor->getter()->IsUndefined()) {
4417 v8::IndexedPropertyGetterCallback getter = 4411 v8::IndexedPropertyGetterCallback getter =
4418 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); 4412 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4419 LOG(isolate, 4413 LOG(isolate,
4420 ApiIndexedPropertyAccess( 4414 ApiIndexedPropertyAccess(
4421 "interceptor-indexed-get-has", *object, index)); 4415 "interceptor-indexed-get-has", *object, index));
4422 v8::Handle<v8::Value> result = args.Call(getter, index); 4416 v8::Handle<v8::Value> result = args.Call(getter, index);
4423 if (!result.IsEmpty()) return NONE; 4417 if (!result.IsEmpty()) return maybe(NONE);
4424 } 4418 }
4425 4419
4426 return GetElementAttributeWithoutInterceptor( 4420 return GetElementAttributeWithoutInterceptor(
4427 object, receiver, index, check_prototype); 4421 object, receiver, index, check_prototype);
4428 } 4422 }
4429 4423
4430 4424
4431 PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor( 4425 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor(
4432 Handle<JSObject> object, 4426 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4433 Handle<JSReceiver> receiver,
4434 uint32_t index,
4435 bool check_prototype) { 4427 bool check_prototype) {
4436 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes( 4428 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
4437 receiver, object, index); 4429 receiver, object, index);
4438 if (attr != ABSENT) return attr; 4430 if (attr != ABSENT) return maybe(attr);
4439 4431
4440 // Handle [] on String objects. 4432 // Handle [] on String objects.
4441 if (object->IsStringObjectWithCharacterAt(index)) { 4433 if (object->IsStringObjectWithCharacterAt(index)) {
4442 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 4434 return maybe(static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE));
4443 } 4435 }
4444 4436
4445 if (!check_prototype) return ABSENT; 4437 if (!check_prototype) return maybe(ABSENT);
4446 4438
4447 PrototypeIterator iter(object->GetIsolate(), object); 4439 PrototypeIterator iter(object->GetIsolate(), object);
4448 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { 4440 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
4449 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. 4441 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
4450 return JSProxy::GetElementAttributeWithHandler( 4442 return JSProxy::GetElementAttributeWithHandler(
4451 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver, 4443 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
4452 index); 4444 index);
4453 } 4445 }
4454 if (iter.IsAtEnd()) return ABSENT; 4446 if (iter.IsAtEnd()) return maybe(ABSENT);
4455 return GetElementAttributeWithReceiver( 4447 return GetElementAttributeWithReceiver(
4456 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, 4448 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
4457 index, true); 4449 index, true);
4458 } 4450 }
4459 4451
4460 4452
4461 Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) { 4453 Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
4462 Handle<FixedArray> array( 4454 Handle<FixedArray> array(
4463 isolate->factory()->NewFixedArray(kEntries, TENURED)); 4455 isolate->factory()->NewFixedArray(kEntries, TENURED));
4464 return Handle<NormalizedMapCache>::cast(array); 4456 return Handle<NormalizedMapCache>::cast(array);
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
5024 5016
5025 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); 5017 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
5026 bool was_present = false; 5018 bool was_present = false;
5027 ObjectHashTable::Remove(hashtable, key, &was_present); 5019 ObjectHashTable::Remove(hashtable, key, &was_present);
5028 } 5020 }
5029 5021
5030 5022
5031 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { 5023 bool JSObject::HasHiddenProperties(Handle<JSObject> object) {
5032 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); 5024 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
5033 LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL); 5025 LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL);
5034 return GetPropertyAttributes(&it) != ABSENT; 5026 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
5027 // Cannot get an exception since the hidden_string isn't accessible to JS.
5028 ASSERT(maybe.has_value);
5029 return maybe.value != ABSENT;
5035 } 5030 }
5036 5031
5037 5032
5038 Object* JSObject::GetHiddenPropertiesHashTable() { 5033 Object* JSObject::GetHiddenPropertiesHashTable() {
5039 ASSERT(!IsJSGlobalProxy()); 5034 ASSERT(!IsJSGlobalProxy());
5040 if (HasFastProperties()) { 5035 if (HasFastProperties()) {
5041 // If the object has fast properties, check whether the first slot 5036 // If the object has fast properties, check whether the first slot
5042 // in the descriptor array matches the hidden string. Since the 5037 // in the descriptor array matches the hidden string. Since the
5043 // hidden strings hash code is zero (and no other name has hash 5038 // hidden strings hash code is zero (and no other name has hash
5044 // code zero) it will always occupy the first entry if present. 5039 // code zero) it will always occupy the first entry if present.
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
5247 if (iter.IsAtEnd()) return factory->false_value(); 5242 if (iter.IsAtEnd()) return factory->false_value();
5248 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 5243 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
5249 return DeleteElement( 5244 return DeleteElement(
5250 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, 5245 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index,
5251 mode); 5246 mode);
5252 } 5247 }
5253 5248
5254 Handle<Object> old_value; 5249 Handle<Object> old_value;
5255 bool should_enqueue_change_record = false; 5250 bool should_enqueue_change_record = false;
5256 if (object->map()->is_observed()) { 5251 if (object->map()->is_observed()) {
5257 should_enqueue_change_record = HasOwnElement(object, index); 5252 Maybe<bool> maybe = HasOwnElement(object, index);
5253 if (!maybe.has_value) return MaybeHandle<Object>();
5254 should_enqueue_change_record = maybe.value;
5258 if (should_enqueue_change_record) { 5255 if (should_enqueue_change_record) {
5259 if (!GetOwnElementAccessorPair(object, index).is_null()) { 5256 if (!GetOwnElementAccessorPair(object, index).is_null()) {
5260 old_value = Handle<Object>::cast(factory->the_hole_value()); 5257 old_value = Handle<Object>::cast(factory->the_hole_value());
5261 } else { 5258 } else {
5262 old_value = Object::GetElement( 5259 old_value = Object::GetElement(
5263 isolate, object, index).ToHandleChecked(); 5260 isolate, object, index).ToHandleChecked();
5264 } 5261 }
5265 } 5262 }
5266 } 5263 }
5267 5264
5268 // Skip interceptor if forcing deletion. 5265 // Skip interceptor if forcing deletion.
5269 MaybeHandle<Object> maybe_result; 5266 MaybeHandle<Object> maybe_result;
5270 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { 5267 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
5271 maybe_result = DeleteElementWithInterceptor(object, index); 5268 maybe_result = DeleteElementWithInterceptor(object, index);
5272 } else { 5269 } else {
5273 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); 5270 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode);
5274 } 5271 }
5275 Handle<Object> result; 5272 Handle<Object> result;
5276 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); 5273 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
5277 5274
5278 if (should_enqueue_change_record && !HasOwnElement(object, index)) { 5275 if (should_enqueue_change_record) {
5279 Handle<String> name = factory->Uint32ToString(index); 5276 Maybe<bool> maybe = HasOwnElement(object, index);
5280 EnqueueChangeRecord(object, "delete", name, old_value); 5277 if (!maybe.has_value) return MaybeHandle<Object>();
5278 if (!maybe.value) {
5279 Handle<String> name = factory->Uint32ToString(index);
5280 EnqueueChangeRecord(object, "delete", name, old_value);
5281 }
5281 } 5282 }
5282 5283
5283 return result; 5284 return result;
5284 } 5285 }
5285 5286
5286 5287
5287 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, 5288 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
5288 Handle<Name> name, 5289 Handle<Name> name,
5289 DeleteMode mode) { 5290 DeleteMode mode) {
5290 Isolate* isolate = object->GetIsolate(); 5291 Isolate* isolate = object->GetIsolate();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5348 DeletePropertyWithInterceptor(object, name), 5349 DeletePropertyWithInterceptor(object, name),
5349 Object); 5350 Object);
5350 } 5351 }
5351 } else { 5352 } else {
5352 // Normalize object if needed. 5353 // Normalize object if needed.
5353 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 5354 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5354 // Make sure the properties are normalized before removing the entry. 5355 // Make sure the properties are normalized before removing the entry.
5355 result = DeleteNormalizedProperty(object, name, mode); 5356 result = DeleteNormalizedProperty(object, name, mode);
5356 } 5357 }
5357 5358
5358 if (is_observed && !HasOwnProperty(object, name)) { 5359 if (is_observed) {
5359 EnqueueChangeRecord(object, "delete", name, old_value); 5360 Maybe<bool> maybe = HasOwnProperty(object, name);
5361 if (!maybe.has_value) return MaybeHandle<Object>();
5362 if (!maybe.value) {
5363 EnqueueChangeRecord(object, "delete", name, old_value);
5364 }
5360 } 5365 }
5361 5366
5362 return result; 5367 return result;
5363 } 5368 }
5364 5369
5365 5370
5366 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, 5371 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
5367 uint32_t index, 5372 uint32_t index,
5368 DeleteMode mode) { 5373 DeleteMode mode) {
5369 if (object->IsJSProxy()) { 5374 if (object->IsJSProxy()) {
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
5832 copy->FastPropertyAtPut(index, *value); 5837 copy->FastPropertyAtPut(index, *value);
5833 } 5838 }
5834 } 5839 }
5835 } else { 5840 } else {
5836 Handle<FixedArray> names = 5841 Handle<FixedArray> names =
5837 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); 5842 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties());
5838 copy->GetOwnPropertyNames(*names, 0); 5843 copy->GetOwnPropertyNames(*names, 0);
5839 for (int i = 0; i < names->length(); i++) { 5844 for (int i = 0; i < names->length(); i++) {
5840 ASSERT(names->get(i)->IsString()); 5845 ASSERT(names->get(i)->IsString());
5841 Handle<String> key_string(String::cast(names->get(i))); 5846 Handle<String> key_string(String::cast(names->get(i)));
5842 PropertyAttributes attributes = 5847 Maybe<PropertyAttributes> maybe =
5843 JSReceiver::GetOwnPropertyAttributes(copy, key_string); 5848 JSReceiver::GetOwnPropertyAttributes(copy, key_string);
5849 ASSERT(maybe.has_value);
5850 PropertyAttributes attributes = maybe.value;
5844 // Only deep copy fields from the object literal expression. 5851 // Only deep copy fields from the object literal expression.
5845 // In particular, don't try to copy the length attribute of 5852 // In particular, don't try to copy the length attribute of
5846 // an array. 5853 // an array.
5847 if (attributes != NONE) continue; 5854 if (attributes != NONE) continue;
5848 Handle<Object> value = 5855 Handle<Object> value =
5849 Object::GetProperty(copy, key_string).ToHandleChecked(); 5856 Object::GetProperty(copy, key_string).ToHandleChecked();
5850 if (value->IsJSObject()) { 5857 if (value->IsJSObject()) {
5851 Handle<JSObject> result; 5858 Handle<JSObject> result;
5852 ASSIGN_RETURN_ON_EXCEPTION( 5859 ASSIGN_RETURN_ON_EXCEPTION(
5853 isolate, result, 5860 isolate, result,
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
6581 // object. 6588 // object.
6582 Deoptimizer::DeoptimizeGlobalObject(*object); 6589 Deoptimizer::DeoptimizeGlobalObject(*object);
6583 } 6590 }
6584 6591
6585 // Update the dictionary with the new CALLBACKS property. 6592 // Update the dictionary with the new CALLBACKS property.
6586 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6593 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6587 SetNormalizedProperty(object, name, structure, details); 6594 SetNormalizedProperty(object, name, structure, details);
6588 } 6595 }
6589 6596
6590 6597
6591 void JSObject::DefineAccessor(Handle<JSObject> object, 6598 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
6592 Handle<Name> name, 6599 Handle<Name> name,
6593 Handle<Object> getter, 6600 Handle<Object> getter,
6594 Handle<Object> setter, 6601 Handle<Object> setter,
6595 PropertyAttributes attributes) { 6602 PropertyAttributes attributes) {
6596 Isolate* isolate = object->GetIsolate(); 6603 Isolate* isolate = object->GetIsolate();
6597 // Check access rights if needed. 6604 // Check access rights if needed.
6598 if (object->IsAccessCheckNeeded() && 6605 if (object->IsAccessCheckNeeded() &&
6599 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { 6606 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
6600 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); 6607 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
6601 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 6608 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
6602 return; 6609 return isolate->factory()->undefined_value();
6603 } 6610 }
6604 6611
6605 if (object->IsJSGlobalProxy()) { 6612 if (object->IsJSGlobalProxy()) {
6606 PrototypeIterator iter(isolate, object); 6613 PrototypeIterator iter(isolate, object);
6607 if (iter.IsAtEnd()) return; 6614 if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
6608 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 6615 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
6609 DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), 6616 DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
6610 name, getter, setter, attributes); 6617 name, getter, setter, attributes);
6611 return; 6618 return isolate->factory()->undefined_value();
6612 } 6619 }
6613 6620
6614 // Make sure that the top context does not change when doing callbacks or 6621 // Make sure that the top context does not change when doing callbacks or
6615 // interceptor calls. 6622 // interceptor calls.
6616 AssertNoContextChange ncc(isolate); 6623 AssertNoContextChange ncc(isolate);
6617 6624
6618 // Try to flatten before operating on the string. 6625 // Try to flatten before operating on the string.
6619 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); 6626 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
6620 6627
6621 uint32_t index = 0; 6628 uint32_t index = 0;
6622 bool is_element = name->AsArrayIndex(&index); 6629 bool is_element = name->AsArrayIndex(&index);
6623 6630
6624 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6631 Handle<Object> old_value = isolate->factory()->the_hole_value();
6625 bool is_observed = object->map()->is_observed() && 6632 bool is_observed = object->map()->is_observed() &&
6626 *name != isolate->heap()->hidden_string(); 6633 *name != isolate->heap()->hidden_string();
6627 bool preexists = false; 6634 bool preexists = false;
6628 if (is_observed) { 6635 if (is_observed) {
6629 if (is_element) { 6636 if (is_element) {
6630 preexists = HasOwnElement(object, index); 6637 Maybe<bool> maybe = HasOwnElement(object, index);
6638 ASSERT(maybe.has_value);
6639 preexists = maybe.value;
6631 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) { 6640 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) {
6632 old_value = 6641 old_value =
6633 Object::GetElement(isolate, object, index).ToHandleChecked(); 6642 Object::GetElement(isolate, object, index).ToHandleChecked();
6634 } 6643 }
6635 } else { 6644 } else {
6636 LookupResult lookup(isolate); 6645 LookupResult lookup(isolate);
6637 object->LookupOwn(name, &lookup, true); 6646 object->LookupOwn(name, &lookup, true);
6638 preexists = lookup.IsProperty(); 6647 preexists = lookup.IsProperty();
6639 if (preexists && lookup.IsDataProperty()) { 6648 if (preexists && lookup.IsDataProperty()) {
6640 old_value = 6649 old_value =
6641 Object::GetPropertyOrElement(object, name).ToHandleChecked(); 6650 Object::GetPropertyOrElement(object, name).ToHandleChecked();
6642 } 6651 }
6643 } 6652 }
6644 } 6653 }
6645 6654
6646 if (is_element) { 6655 if (is_element) {
6647 DefineElementAccessor(object, index, getter, setter, attributes); 6656 DefineElementAccessor(object, index, getter, setter, attributes);
6648 } else { 6657 } else {
6649 DefinePropertyAccessor(object, name, getter, setter, attributes); 6658 DefinePropertyAccessor(object, name, getter, setter, attributes);
6650 } 6659 }
6651 6660
6652 if (is_observed) { 6661 if (is_observed) {
6653 const char* type = preexists ? "reconfigure" : "add"; 6662 const char* type = preexists ? "reconfigure" : "add";
6654 EnqueueChangeRecord(object, type, name, old_value); 6663 EnqueueChangeRecord(object, type, name, old_value);
6655 } 6664 }
6665
6666 return isolate->factory()->undefined_value();
6656 } 6667 }
6657 6668
6658 6669
6659 static bool TryAccessorTransition(Handle<JSObject> self, 6670 static bool TryAccessorTransition(Handle<JSObject> self,
6660 Handle<Map> transitioned_map, 6671 Handle<Map> transitioned_map,
6661 int target_descriptor, 6672 int target_descriptor,
6662 AccessorComponent component, 6673 AccessorComponent component,
6663 Handle<Object> accessor, 6674 Handle<Object> accessor,
6664 PropertyAttributes attributes) { 6675 PropertyAttributes attributes) {
6665 DescriptorArray* descs = transitioned_map->instance_descriptors(); 6676 DescriptorArray* descs = transitioned_map->instance_descriptors();
(...skipping 4982 matching lines...) Expand 10 before | Expand all | Expand 10 after
11648 11659
11649 11660
11650 // Returns false if the passed-in index is marked non-configurable, 11661 // Returns false if the passed-in index is marked non-configurable,
11651 // which will cause the ES5 truncation operation to halt, and thus 11662 // which will cause the ES5 truncation operation to halt, and thus
11652 // no further old values need be collected. 11663 // no further old values need be collected.
11653 static bool GetOldValue(Isolate* isolate, 11664 static bool GetOldValue(Isolate* isolate,
11654 Handle<JSObject> object, 11665 Handle<JSObject> object,
11655 uint32_t index, 11666 uint32_t index,
11656 List<Handle<Object> >* old_values, 11667 List<Handle<Object> >* old_values,
11657 List<uint32_t>* indices) { 11668 List<uint32_t>* indices) {
11658 PropertyAttributes attributes = 11669 Maybe<PropertyAttributes> maybe =
11659 JSReceiver::GetOwnElementAttribute(object, index); 11670 JSReceiver::GetOwnElementAttribute(object, index);
11660 ASSERT(attributes != ABSENT); 11671 ASSERT(maybe.has_value);
11661 if (attributes == DONT_DELETE) return false; 11672 ASSERT(maybe.value != ABSENT);
11673 if (maybe.value == DONT_DELETE) return false;
11662 Handle<Object> value; 11674 Handle<Object> value;
11663 if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) { 11675 if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) {
11664 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); 11676 value = Handle<Object>::cast(isolate->factory()->the_hole_value());
11665 } else { 11677 } else {
11666 value = Object::GetElement(isolate, object, index).ToHandleChecked(); 11678 value = Object::GetElement(isolate, object, index).ToHandleChecked();
11667 } 11679 }
11668 old_values->Add(value); 11680 old_values->Add(value);
11669 indices->Add(index); 11681 indices->Add(index);
11670 return true; 11682 return true;
11671 } 11683 }
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
12884 } 12896 }
12885 12897
12886 if (!object->map()->is_observed()) { 12898 if (!object->map()->is_observed()) {
12887 return object->HasIndexedInterceptor() 12899 return object->HasIndexedInterceptor()
12888 ? SetElementWithInterceptor(object, index, value, attributes, 12900 ? SetElementWithInterceptor(object, index, value, attributes,
12889 strict_mode, check_prototype, set_mode) 12901 strict_mode, check_prototype, set_mode)
12890 : SetElementWithoutInterceptor(object, index, value, attributes, 12902 : SetElementWithoutInterceptor(object, index, value, attributes,
12891 strict_mode, check_prototype, set_mode); 12903 strict_mode, check_prototype, set_mode);
12892 } 12904 }
12893 12905
12894 PropertyAttributes old_attributes = 12906 Maybe<PropertyAttributes> maybe =
12895 JSReceiver::GetOwnElementAttribute(object, index); 12907 JSReceiver::GetOwnElementAttribute(object, index);
12908 if (!maybe.has_value) return MaybeHandle<Object>();
12909 PropertyAttributes old_attributes = maybe.value;
12910
12896 Handle<Object> old_value = isolate->factory()->the_hole_value(); 12911 Handle<Object> old_value = isolate->factory()->the_hole_value();
12897 Handle<Object> old_length_handle; 12912 Handle<Object> old_length_handle;
12898 Handle<Object> new_length_handle; 12913 Handle<Object> new_length_handle;
12899 12914
12900 if (old_attributes != ABSENT) { 12915 if (old_attributes != ABSENT) {
12901 if (GetOwnElementAccessorPair(object, index).is_null()) { 12916 if (GetOwnElementAccessorPair(object, index).is_null()) {
12902 old_value = Object::GetElement(isolate, object, index).ToHandleChecked(); 12917 old_value = Object::GetElement(isolate, object, index).ToHandleChecked();
12903 } 12918 }
12904 } else if (object->IsJSArray()) { 12919 } else if (object->IsJSArray()) {
12905 // Store old array length in case adding an element grows the array. 12920 // Store old array length in case adding an element grows the array.
12906 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), 12921 old_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12907 isolate); 12922 isolate);
12908 } 12923 }
12909 12924
12910 // Check for lookup interceptor 12925 // Check for lookup interceptor
12911 Handle<Object> result; 12926 Handle<Object> result;
12912 ASSIGN_RETURN_ON_EXCEPTION( 12927 ASSIGN_RETURN_ON_EXCEPTION(
12913 isolate, result, 12928 isolate, result,
12914 object->HasIndexedInterceptor() 12929 object->HasIndexedInterceptor()
12915 ? SetElementWithInterceptor( 12930 ? SetElementWithInterceptor(
12916 object, index, value, attributes, 12931 object, index, value, attributes,
12917 strict_mode, check_prototype, set_mode) 12932 strict_mode, check_prototype, set_mode)
12918 : SetElementWithoutInterceptor( 12933 : SetElementWithoutInterceptor(
12919 object, index, value, attributes, 12934 object, index, value, attributes,
12920 strict_mode, check_prototype, set_mode), 12935 strict_mode, check_prototype, set_mode),
12921 Object); 12936 Object);
12922 12937
12923 Handle<String> name = isolate->factory()->Uint32ToString(index); 12938 Handle<String> name = isolate->factory()->Uint32ToString(index);
12924 PropertyAttributes new_attributes = GetOwnElementAttribute(object, index); 12939 maybe = GetOwnElementAttribute(object, index);
12940 if (!maybe.has_value) return MaybeHandle<Object>();
12941 PropertyAttributes new_attributes = maybe.value;
12942
12925 if (old_attributes == ABSENT) { 12943 if (old_attributes == ABSENT) {
12926 if (object->IsJSArray() && 12944 if (object->IsJSArray() &&
12927 !old_length_handle->SameValue( 12945 !old_length_handle->SameValue(
12928 Handle<JSArray>::cast(object)->length())) { 12946 Handle<JSArray>::cast(object)->length())) {
12929 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), 12947 new_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12930 isolate); 12948 isolate);
12931 uint32_t old_length = 0; 12949 uint32_t old_length = 0;
12932 uint32_t new_length = 0; 12950 uint32_t new_length = 0;
12933 CHECK(old_length_handle->ToArrayIndex(&old_length)); 12951 CHECK(old_length_handle->ToArrayIndex(&old_length));
12934 CHECK(new_length_handle->ToArrayIndex(&new_length)); 12952 CHECK(new_length_handle->ToArrayIndex(&new_length));
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
13684 if (result.IsEmpty()) return MaybeHandle<JSObject>(); 13702 if (result.IsEmpty()) return MaybeHandle<JSObject>();
13685 #if ENABLE_EXTRA_CHECKS 13703 #if ENABLE_EXTRA_CHECKS
13686 CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || 13704 CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
13687 v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements()); 13705 v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements());
13688 #endif 13706 #endif
13689 // Rebox before returning. 13707 // Rebox before returning.
13690 return handle(*v8::Utils::OpenHandle(*result), isolate); 13708 return handle(*v8::Utils::OpenHandle(*result), isolate);
13691 } 13709 }
13692 13710
13693 13711
13694 bool JSObject::HasRealNamedProperty(Handle<JSObject> object, 13712 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
13695 Handle<Name> key) { 13713 Handle<Name> key) {
13696 Isolate* isolate = object->GetIsolate(); 13714 Isolate* isolate = object->GetIsolate();
13697 SealHandleScope shs(isolate); 13715 SealHandleScope shs(isolate);
13698 // Check access rights if needed. 13716 // Check access rights if needed.
13699 if (object->IsAccessCheckNeeded()) { 13717 if (object->IsAccessCheckNeeded()) {
13700 if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) { 13718 if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
13701 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); 13719 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
13702 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 13720 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
13703 return false; 13721 return maybe(false);
13704 } 13722 }
13705 } 13723 }
13706 13724
13707 LookupResult result(isolate); 13725 LookupResult result(isolate);
13708 object->LookupOwnRealNamedProperty(key, &result); 13726 object->LookupOwnRealNamedProperty(key, &result);
13709 return result.IsFound() && !result.IsInterceptor(); 13727 return maybe(result.IsFound() && !result.IsInterceptor());
13710 } 13728 }
13711 13729
13712 13730
13713 bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) { 13731 Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
13732 uint32_t index) {
13714 Isolate* isolate = object->GetIsolate(); 13733 Isolate* isolate = object->GetIsolate();
13715 HandleScope scope(isolate); 13734 HandleScope scope(isolate);
13716 // Check access rights if needed. 13735 // Check access rights if needed.
13717 if (object->IsAccessCheckNeeded()) { 13736 if (object->IsAccessCheckNeeded()) {
13718 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { 13737 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
13719 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); 13738 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
13720 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 13739 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
13721 return false; 13740 return maybe(false);
13722 } 13741 }
13723 } 13742 }
13724 13743
13725 if (object->IsJSGlobalProxy()) { 13744 if (object->IsJSGlobalProxy()) {
13726 HandleScope scope(isolate); 13745 HandleScope scope(isolate);
13727 PrototypeIterator iter(isolate, object); 13746 PrototypeIterator iter(isolate, object);
13728 if (iter.IsAtEnd()) return false; 13747 if (iter.IsAtEnd()) return maybe(false);
13729 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 13748 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
13730 return HasRealElementProperty( 13749 return HasRealElementProperty(
13731 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); 13750 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index);
13732 } 13751 }
13733 13752
13734 return GetElementAttributeWithoutInterceptor( 13753 Maybe<PropertyAttributes> result =
13735 object, object, index, false) != ABSENT; 13754 GetElementAttributeWithoutInterceptor(object, object, index, false);
13755 if (!result.has_value) return Maybe<bool>();
13756 return maybe(result.value != ABSENT);
13736 } 13757 }
13737 13758
13738 13759
13739 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, 13760 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
13740 Handle<Name> key) { 13761 Handle<Name> key) {
13741 Isolate* isolate = object->GetIsolate(); 13762 Isolate* isolate = object->GetIsolate();
13742 SealHandleScope shs(isolate); 13763 SealHandleScope shs(isolate);
13743 // Check access rights if needed. 13764 // Check access rights if needed.
13744 if (object->IsAccessCheckNeeded()) { 13765 if (object->IsAccessCheckNeeded()) {
13745 if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) { 13766 if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
13746 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); 13767 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
13747 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 13768 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
13748 return false; 13769 return maybe(false);
13749 } 13770 }
13750 } 13771 }
13751 13772
13752 LookupResult result(isolate); 13773 LookupResult result(isolate);
13753 object->LookupOwnRealNamedProperty(key, &result); 13774 object->LookupOwnRealNamedProperty(key, &result);
13754 return result.IsPropertyCallbacks(); 13775 return maybe(result.IsPropertyCallbacks());
13755 } 13776 }
13756 13777
13757 13778
13758 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { 13779 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) {
13759 if (HasFastProperties()) { 13780 if (HasFastProperties()) {
13760 Map* map = this->map(); 13781 Map* map = this->map();
13761 if (filter == NONE) return map->NumberOfOwnDescriptors(); 13782 if (filter == NONE) return map->NumberOfOwnDescriptors();
13762 if (filter & DONT_ENUM) { 13783 if (filter & DONT_ENUM) {
13763 int result = map->EnumLength(); 13784 int result = map->EnumLength();
13764 if (result != kInvalidEnumCacheSentinel) return result; 13785 if (result != kInvalidEnumCacheSentinel) return result;
(...skipping 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after
16942 #define ERROR_MESSAGES_TEXTS(C, T) T, 16963 #define ERROR_MESSAGES_TEXTS(C, T) T,
16943 static const char* error_messages_[] = { 16964 static const char* error_messages_[] = {
16944 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16965 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16945 }; 16966 };
16946 #undef ERROR_MESSAGES_TEXTS 16967 #undef ERROR_MESSAGES_TEXTS
16947 return error_messages_[reason]; 16968 return error_messages_[reason];
16948 } 16969 }
16949 16970
16950 16971
16951 } } // namespace v8::internal 16972 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698