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

Side by Side Diff: src/objects.cc

Issue 309653003: Clean up (Get|Set)Property(Attributes)WithFailedAccessChecks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment Created 6 years, 6 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') | no next file » | 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 "v8.h" 5 #include "v8.h"
6 6
7 #include "accessors.h" 7 #include "accessors.h"
8 #include "allocation-site-scopes.h" 8 #include "allocation-site-scopes.h"
9 #include "api.h" 9 #include "api.h"
10 #include "arguments.h" 10 #include "arguments.h"
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 533
534 Handle<Object> argv[] = { value }; 534 Handle<Object> argv[] = { value };
535 RETURN_ON_EXCEPTION( 535 RETURN_ON_EXCEPTION(
536 isolate, 536 isolate,
537 Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv), 537 Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv),
538 Object); 538 Object);
539 return value; 539 return value;
540 } 540 }
541 541
542 542
543 // Only deal with CALLBACKS and INTERCEPTOR 543 static bool FindAllCanReadHolder(LookupResult* result,
544 Handle<Name> name,
545 bool check_prototype) {
546 if (result->IsInterceptor()) {
547 result->holder()->LookupOwnRealNamedProperty(name, result);
548 }
549
550 while (result->IsProperty()) {
551 if (result->type() == CALLBACKS) {
552 Object* callback_obj = result->GetCallbackObject();
553 if (callback_obj->IsAccessorInfo()) {
554 if (AccessorInfo::cast(callback_obj)->all_can_read()) return true;
555 } else if (callback_obj->IsAccessorPair()) {
556 if (AccessorPair::cast(callback_obj)->all_can_read()) return true;
557 }
558 }
559 if (!check_prototype) break;
560 result->holder()->LookupRealNamedPropertyInPrototypes(name, result);
561 }
562 return false;
563 }
564
565
544 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( 566 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
545 Handle<JSObject> object, 567 Handle<JSObject> object,
546 Handle<Object> receiver, 568 Handle<Object> receiver,
547 LookupResult* result, 569 LookupResult* result,
548 Handle<Name> name, 570 Handle<Name> name,
549 PropertyAttributes* attributes) { 571 PropertyAttributes* attributes) {
550 Isolate* isolate = name->GetIsolate(); 572 if (FindAllCanReadHolder(result, name, true)) {
551 if (result->IsProperty()) { 573 *attributes = result->GetAttributes();
552 switch (result->type()) { 574 Handle<JSObject> holder(result->holder());
553 case CALLBACKS: { 575 Handle<Object> callbacks(result->GetCallbackObject(), result->isolate());
554 // Only allow API accessors. 576 return GetPropertyWithCallback(receiver, name, holder, callbacks);
555 Handle<Object> callback_obj(result->GetCallbackObject(), isolate);
556 if (callback_obj->IsAccessorInfo()) {
557 if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break;
558 *attributes = result->GetAttributes();
559 // Fall through to GetPropertyWithCallback.
560 } else if (callback_obj->IsAccessorPair()) {
561 if (!AccessorPair::cast(*callback_obj)->all_can_read()) break;
562 // Fall through to GetPropertyWithCallback.
563 } else {
564 break;
565 }
566 Handle<JSObject> holder(result->holder(), isolate);
567 return GetPropertyWithCallback(receiver, name, holder, callback_obj);
568 }
569 case NORMAL:
570 case FIELD:
571 case CONSTANT: {
572 // Search ALL_CAN_READ accessors in prototype chain.
573 LookupResult r(isolate);
574 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
575 if (r.IsProperty()) {
576 return GetPropertyWithFailedAccessCheck(
577 object, receiver, &r, name, attributes);
578 }
579 break;
580 }
581 case INTERCEPTOR: {
582 // If the object has an interceptor, try real named properties.
583 // No access check in GetPropertyAttributeWithInterceptor.
584 LookupResult r(isolate);
585 result->holder()->LookupRealNamedProperty(name, &r);
586 if (r.IsProperty()) {
587 return GetPropertyWithFailedAccessCheck(
588 object, receiver, &r, name, attributes);
589 }
590 break;
591 }
592 default:
593 UNREACHABLE();
594 }
595 } 577 }
596
597 // No accessible property found.
598 *attributes = ABSENT; 578 *attributes = ABSENT;
579 Isolate* isolate = result->isolate();
599 isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET); 580 isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
600 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 581 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
601 return isolate->factory()->undefined_value(); 582 return isolate->factory()->undefined_value();
602 } 583 }
603 584
604 585
605 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 586 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
606 Handle<JSObject> object, 587 Handle<JSObject> object,
607 LookupResult* result, 588 LookupResult* result,
608 Handle<Name> name, 589 Handle<Name> name,
609 bool continue_search) { 590 bool check_prototype) {
610 if (result->IsProperty()) { 591 if (FindAllCanReadHolder(result, name, check_prototype)) {
611 switch (result->type()) { 592 return result->GetAttributes();
612 case CALLBACKS: {
613 // Only allow API accessors.
614 Handle<Object> obj(result->GetCallbackObject(), object->GetIsolate());
615 if (obj->IsAccessorInfo()) {
616 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj);
617 if (info->all_can_read()) {
618 return result->GetAttributes();
619 }
620 } else if (obj->IsAccessorPair()) {
621 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(obj);
622 if (pair->all_can_read()) {
623 return result->GetAttributes();
624 }
625 }
626 break;
627 }
628
629 case NORMAL:
630 case FIELD:
631 case CONSTANT: {
632 if (!continue_search) break;
633 // Search ALL_CAN_READ accessors in prototype chain.
634 LookupResult r(object->GetIsolate());
635 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
636 if (r.IsProperty()) {
637 return GetPropertyAttributeWithFailedAccessCheck(
638 object, &r, name, continue_search);
639 }
640 break;
641 }
642
643 case INTERCEPTOR: {
644 // If the object has an interceptor, try real named properties.
645 // No access check in GetPropertyAttributeWithInterceptor.
646 LookupResult r(object->GetIsolate());
647 if (continue_search) {
648 result->holder()->LookupRealNamedProperty(name, &r);
649 } else {
650 result->holder()->LookupOwnRealNamedProperty(name, &r);
651 }
652 if (!r.IsFound()) break;
653 return GetPropertyAttributeWithFailedAccessCheck(
654 object, &r, name, continue_search);
655 }
656
657 case HANDLER:
658 case NONEXISTENT:
659 UNREACHABLE();
660 }
661 } 593 }
662 594 result->isolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
663 object->GetIsolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
664 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 595 // TODO(yangguo): Issue 3269, check for scheduled exception missing?
665 return ABSENT; 596 return ABSENT;
666 } 597 }
667 598
668 599
600 static bool FindAllCanWriteHolder(LookupResult* result,
601 Handle<Name> name,
602 bool check_prototype) {
603 if (result->IsInterceptor()) {
604 result->holder()->LookupOwnRealNamedProperty(name, result);
605 }
606
607 while (result->IsProperty()) {
608 if (result->type() == CALLBACKS) {
609 Object* callback_obj = result->GetCallbackObject();
610 if (callback_obj->IsAccessorInfo()) {
611 if (AccessorInfo::cast(callback_obj)->all_can_write()) return true;
612 } else if (callback_obj->IsAccessorPair()) {
613 if (AccessorPair::cast(callback_obj)->all_can_write()) return true;
614 }
615 }
616 if (!check_prototype) break;
617 result->holder()->LookupRealNamedPropertyInPrototypes(name, result);
618 }
619 return false;
620 }
621
622
623 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
624 Handle<JSObject> object,
625 LookupResult* result,
626 Handle<Name> name,
627 Handle<Object> value,
628 bool check_prototype,
629 StrictMode strict_mode) {
630 if (check_prototype && !result->IsProperty()) {
631 object->LookupRealNamedPropertyInPrototypes(name, result);
632 }
633
634 if (FindAllCanWriteHolder(result, name, check_prototype)) {
635 Handle<JSObject> holder(result->holder());
636 Handle<Object> callbacks(result->GetCallbackObject(), result->isolate());
637 return SetPropertyWithCallback(
638 object, name, value, holder, callbacks, strict_mode);
639 }
640
641 Isolate* isolate = object->GetIsolate();
642 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
643 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
644 return value;
645 }
646
647
669 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { 648 Object* JSObject::GetNormalizedProperty(const LookupResult* result) {
670 ASSERT(!HasFastProperties()); 649 ASSERT(!HasFastProperties());
671 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 650 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
672 if (IsGlobalObject()) { 651 if (IsGlobalObject()) {
673 value = PropertyCell::cast(value)->value(); 652 value = PropertyCell::cast(value)->value();
674 } 653 }
675 ASSERT(!value->IsPropertyCell() && !value->IsCell()); 654 ASSERT(!value->IsPropertyCell() && !value->IsCell());
676 return value; 655 return value;
677 } 656 }
678 657
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 // Traverse the prototype chain from the current object (this) to 806 // Traverse the prototype chain from the current object (this) to
828 // the holder and check for access rights. This avoids traversing the 807 // the holder and check for access rights. This avoids traversing the
829 // objects more than once in case of interceptors, because the 808 // objects more than once in case of interceptors, because the
830 // holder will always be the interceptor holder and the search may 809 // holder will always be the interceptor holder and the search may
831 // only continue with a current object just after the interceptor 810 // only continue with a current object just after the interceptor
832 // holder in the prototype chain. 811 // holder in the prototype chain.
833 // Proxy handlers do not use the proxy's prototype, so we can skip this. 812 // Proxy handlers do not use the proxy's prototype, so we can skip this.
834 if (!result->IsHandler()) { 813 if (!result->IsHandler()) {
835 ASSERT(*object != object->GetPrototype(isolate)); 814 ASSERT(*object != object->GetPrototype(isolate));
836 Handle<Object> last = result->IsProperty() 815 Handle<Object> last = result->IsProperty()
837 ? Handle<Object>(result->holder(), isolate) 816 ? handle(result->holder()->GetPrototype(), isolate)
838 : Handle<Object>::cast(factory->null_value()); 817 : Handle<Object>::cast(factory->null_value());
839 for (Handle<Object> current = object; 818 for (Handle<Object> current = object;
840 true; 819 !current.is_identical_to(last);
841 current = Handle<Object>(current->GetPrototype(isolate), isolate)) { 820 current = Object::GetPrototype(isolate, current)) {
842 if (current->IsAccessCheckNeeded()) { 821 if (current->IsAccessCheckNeeded()) {
843 // Check if we're allowed to read from the current object. Note 822 // Check if we're allowed to read from the current object. Note
844 // that even though we may not actually end up loading the named 823 // that even though we may not actually end up loading the named
845 // property from the current object, we still check that we have 824 // property from the current object, we still check that we have
846 // access to it. 825 // access to it.
847 Handle<JSObject> checked = Handle<JSObject>::cast(current); 826 Handle<JSObject> checked = Handle<JSObject>::cast(current);
848 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) { 827 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
849 return JSObject::GetPropertyWithFailedAccessCheck( 828 return JSObject::GetPropertyWithFailedAccessCheck(
850 checked, receiver, result, name, attributes); 829 checked, receiver, result, name, attributes);
851 } 830 }
852 } 831 }
853 // Stop traversing the chain once we reach the last object in the
854 // chain; either the holder of the result or null in case of an
855 // absent property.
856 if (current.is_identical_to(last)) break;
857 } 832 }
858 } 833 }
859 834
860 if (!result->IsProperty()) { 835 if (!result->IsProperty()) {
861 *attributes = ABSENT; 836 *attributes = ABSENT;
862 return factory->undefined_value(); 837 return factory->undefined_value();
863 } 838 }
864 *attributes = result->GetAttributes(); 839 *attributes = result->GetAttributes();
865 840
866 Handle<Object> value; 841 Handle<Object> value;
(...skipping 2729 matching lines...) Expand 10 before | Expand all | Expand 10 after
3596 return result->HandlerResult(JSProxy::cast(pt)); 3571 return result->HandlerResult(JSProxy::cast(pt));
3597 } 3572 }
3598 JSObject::cast(pt)->LookupOwnRealNamedProperty(name, result); 3573 JSObject::cast(pt)->LookupOwnRealNamedProperty(name, result);
3599 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); 3574 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
3600 if (result->IsFound()) return; 3575 if (result->IsFound()) return;
3601 } 3576 }
3602 result->NotFound(); 3577 result->NotFound();
3603 } 3578 }
3604 3579
3605 3580
3606 // We only need to deal with CALLBACKS and INTERCEPTORS
3607 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
3608 Handle<JSObject> object,
3609 LookupResult* result,
3610 Handle<Name> name,
3611 Handle<Object> value,
3612 bool check_prototype,
3613 StrictMode strict_mode) {
3614 if (check_prototype && !result->IsProperty()) {
3615 object->LookupRealNamedPropertyInPrototypes(name, result);
3616 }
3617
3618 if (result->IsProperty()) {
3619 if (!result->IsReadOnly()) {
3620 switch (result->type()) {
3621 case CALLBACKS: {
3622 Object* obj = result->GetCallbackObject();
3623 if (obj->IsAccessorInfo()) {
3624 Handle<AccessorInfo> info(AccessorInfo::cast(obj));
3625 if (info->all_can_write()) {
3626 return SetPropertyWithCallback(object, name, value,
3627 handle(result->holder()),
3628 info, strict_mode);
3629 }
3630 } else if (obj->IsAccessorPair()) {
3631 Handle<AccessorPair> pair(AccessorPair::cast(obj));
3632 if (pair->all_can_read()) {
3633 return SetPropertyWithCallback(object, name, value,
3634 handle(result->holder()),
3635 pair, strict_mode);
3636 }
3637 }
3638 break;
3639 }
3640 case INTERCEPTOR: {
3641 // Try lookup real named properties. Note that only property can be
3642 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
3643 LookupResult r(object->GetIsolate());
3644 object->LookupRealNamedProperty(name, &r);
3645 if (r.IsProperty()) {
3646 return SetPropertyWithFailedAccessCheck(object,
3647 &r,
3648 name,
3649 value,
3650 check_prototype,
3651 strict_mode);
3652 }
3653 break;
3654 }
3655 default: {
3656 break;
3657 }
3658 }
3659 }
3660 }
3661
3662 Isolate* isolate = object->GetIsolate();
3663 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
3664 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
3665 return value;
3666 }
3667
3668
3669 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 3581 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3670 LookupResult* result, 3582 LookupResult* result,
3671 Handle<Name> key, 3583 Handle<Name> key,
3672 Handle<Object> value, 3584 Handle<Object> value,
3673 PropertyAttributes attributes, 3585 PropertyAttributes attributes,
3674 StrictMode strict_mode, 3586 StrictMode strict_mode,
3675 StoreFromKeyed store_mode) { 3587 StoreFromKeyed store_mode) {
3676 if (result->IsHandler()) { 3588 if (result->IsHandler()) {
3677 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), 3589 return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
3678 object, key, value, attributes, strict_mode); 3590 object, key, value, attributes, strict_mode);
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
4498 } 4410 }
4499 4411
4500 return value; 4412 return value;
4501 } 4413 }
4502 4414
4503 4415
4504 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4416 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4505 Handle<JSObject> object, 4417 Handle<JSObject> object,
4506 Handle<JSObject> receiver, 4418 Handle<JSObject> receiver,
4507 Handle<Name> name, 4419 Handle<Name> name,
4508 bool continue_search) { 4420 bool check_prototype) {
4509 // Check own property, ignore interceptor. 4421 // Check own property, ignore interceptor.
4510 Isolate* isolate = object->GetIsolate(); 4422 Isolate* isolate = object->GetIsolate();
4511 LookupResult result(isolate); 4423 LookupResult result(isolate);
4512 object->LookupOwnRealNamedProperty(name, &result); 4424 object->LookupOwnRealNamedProperty(name, &result);
4513 if (result.IsFound()) return result.GetAttributes(); 4425 if (result.IsFound()) return result.GetAttributes();
4514 4426
4515 if (continue_search) { 4427 if (check_prototype) {
4516 // Continue searching via the prototype chain. 4428 // Continue searching via the prototype chain.
4517 Handle<Object> proto(object->GetPrototype(), isolate); 4429 Handle<Object> proto(object->GetPrototype(), isolate);
4518 if (!proto->IsNull()) { 4430 if (!proto->IsNull()) {
4519 return JSReceiver::GetPropertyAttributeWithReceiver( 4431 return JSReceiver::GetPropertyAttributeWithReceiver(
4520 Handle<JSObject>::cast(proto), receiver, name); 4432 Handle<JSObject>::cast(proto), receiver, name);
4521 } 4433 }
4522 } 4434 }
4523 return ABSENT; 4435 return ABSENT;
4524 } 4436 }
4525 4437
4526 4438
4527 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( 4439 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
4528 Handle<JSObject> object, 4440 Handle<JSObject> object,
4529 Handle<JSObject> receiver, 4441 Handle<JSObject> receiver,
4530 Handle<Name> name, 4442 Handle<Name> name,
4531 bool continue_search) { 4443 bool check_prototype) {
4532 // TODO(rossberg): Support symbols in the API. 4444 // TODO(rossberg): Support symbols in the API.
4533 if (name->IsSymbol()) return ABSENT; 4445 if (name->IsSymbol()) return ABSENT;
4534 4446
4535 Isolate* isolate = object->GetIsolate(); 4447 Isolate* isolate = object->GetIsolate();
4536 HandleScope scope(isolate); 4448 HandleScope scope(isolate);
4537 4449
4538 // Make sure that the top context does not change when doing 4450 // Make sure that the top context does not change when doing
4539 // callbacks or interceptor calls. 4451 // callbacks or interceptor calls.
4540 AssertNoContextChange ncc(isolate); 4452 AssertNoContextChange ncc(isolate);
4541 4453
(...skipping 14 matching lines...) Expand all
4556 } else if (!interceptor->getter()->IsUndefined()) { 4468 } else if (!interceptor->getter()->IsUndefined()) {
4557 v8::NamedPropertyGetterCallback getter = 4469 v8::NamedPropertyGetterCallback getter =
4558 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); 4470 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
4559 LOG(isolate, 4471 LOG(isolate,
4560 ApiNamedPropertyAccess("interceptor-named-get-has", *object, *name)); 4472 ApiNamedPropertyAccess("interceptor-named-get-has", *object, *name));
4561 v8::Handle<v8::Value> result = 4473 v8::Handle<v8::Value> result =
4562 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); 4474 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
4563 if (!result.IsEmpty()) return DONT_ENUM; 4475 if (!result.IsEmpty()) return DONT_ENUM;
4564 } 4476 }
4565 return GetPropertyAttributePostInterceptor( 4477 return GetPropertyAttributePostInterceptor(
4566 object, receiver, name, continue_search); 4478 object, receiver, name, check_prototype);
4567 } 4479 }
4568 4480
4569 4481
4570 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( 4482 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
4571 Handle<JSReceiver> object, 4483 Handle<JSReceiver> object,
4572 Handle<JSReceiver> receiver, 4484 Handle<JSReceiver> receiver,
4573 Handle<Name> key) { 4485 Handle<Name> key) {
4574 uint32_t index = 0; 4486 uint32_t index = 0;
4575 if (object->IsJSObject() && key->AsArrayIndex(&index)) { 4487 if (object->IsJSObject() && key->AsArrayIndex(&index)) {
4576 return JSObject::GetElementAttributeWithReceiver( 4488 return JSObject::GetElementAttributeWithReceiver(
4577 Handle<JSObject>::cast(object), receiver, index, true); 4489 Handle<JSObject>::cast(object), receiver, index, true);
4578 } 4490 }
4579 // Named property. 4491 // Named property.
4580 LookupResult lookup(object->GetIsolate()); 4492 LookupResult lookup(object->GetIsolate());
4581 object->Lookup(key, &lookup); 4493 object->Lookup(key, &lookup);
4582 return GetPropertyAttributeForResult(object, receiver, &lookup, key, true); 4494 return GetPropertyAttributeForResult(object, receiver, &lookup, key, true);
4583 } 4495 }
4584 4496
4585 4497
4586 PropertyAttributes JSReceiver::GetPropertyAttributeForResult( 4498 PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
4587 Handle<JSReceiver> object, 4499 Handle<JSReceiver> object,
4588 Handle<JSReceiver> receiver, 4500 Handle<JSReceiver> receiver,
4589 LookupResult* lookup, 4501 LookupResult* lookup,
4590 Handle<Name> name, 4502 Handle<Name> name,
4591 bool continue_search) { 4503 bool check_prototype) {
4592 // Check access rights if needed. 4504 // Check access rights if needed.
4593 if (object->IsAccessCheckNeeded()) { 4505 if (object->IsAccessCheckNeeded()) {
4594 Heap* heap = object->GetHeap(); 4506 Heap* heap = object->GetHeap();
4595 Handle<JSObject> obj = Handle<JSObject>::cast(object); 4507 Handle<JSObject> obj = Handle<JSObject>::cast(object);
4596 if (!heap->isolate()->MayNamedAccess(obj, name, v8::ACCESS_HAS)) { 4508 if (!heap->isolate()->MayNamedAccess(obj, name, v8::ACCESS_HAS)) {
4597 return JSObject::GetPropertyAttributeWithFailedAccessCheck( 4509 return JSObject::GetPropertyAttributeWithFailedAccessCheck(
4598 obj, lookup, name, continue_search); 4510 obj, lookup, name, check_prototype);
4599 } 4511 }
4600 } 4512 }
4601 if (lookup->IsFound()) { 4513 if (lookup->IsFound()) {
4602 switch (lookup->type()) { 4514 switch (lookup->type()) {
4603 case NORMAL: // fall through 4515 case NORMAL: // fall through
4604 case FIELD: 4516 case FIELD:
4605 case CONSTANT: 4517 case CONSTANT:
4606 case CALLBACKS: 4518 case CALLBACKS:
4607 return lookup->GetAttributes(); 4519 return lookup->GetAttributes();
4608 case HANDLER: { 4520 case HANDLER: {
4609 return JSProxy::GetPropertyAttributeWithHandler( 4521 return JSProxy::GetPropertyAttributeWithHandler(
4610 handle(lookup->proxy()), receiver, name); 4522 handle(lookup->proxy()), receiver, name);
4611 } 4523 }
4612 case INTERCEPTOR: 4524 case INTERCEPTOR:
4613 return JSObject::GetPropertyAttributeWithInterceptor( 4525 return JSObject::GetPropertyAttributeWithInterceptor(
4614 handle(lookup->holder()), 4526 handle(lookup->holder()),
4615 Handle<JSObject>::cast(receiver), 4527 Handle<JSObject>::cast(receiver),
4616 name, 4528 name,
4617 continue_search); 4529 check_prototype);
4618 case NONEXISTENT: 4530 case NONEXISTENT:
4619 UNREACHABLE(); 4531 UNREACHABLE();
4620 } 4532 }
4621 } 4533 }
4622 return ABSENT; 4534 return ABSENT;
4623 } 4535 }
4624 4536
4625 4537
4626 PropertyAttributes JSReceiver::GetOwnPropertyAttribute( 4538 PropertyAttributes JSReceiver::GetOwnPropertyAttribute(
4627 Handle<JSReceiver> object, Handle<Name> name) { 4539 Handle<JSReceiver> object, Handle<Name> name) {
4628 // Check whether the name is an array index. 4540 // Check whether the name is an array index.
4629 uint32_t index = 0; 4541 uint32_t index = 0;
4630 if (object->IsJSObject() && name->AsArrayIndex(&index)) { 4542 if (object->IsJSObject() && name->AsArrayIndex(&index)) {
4631 return GetOwnElementAttribute(object, index); 4543 return GetOwnElementAttribute(object, index);
4632 } 4544 }
4633 // Named property. 4545 // Named property.
4634 LookupResult lookup(object->GetIsolate()); 4546 LookupResult lookup(object->GetIsolate());
4635 object->LookupOwn(name, &lookup, true); 4547 object->LookupOwn(name, &lookup, true);
4636 return GetPropertyAttributeForResult(object, object, &lookup, name, false); 4548 return GetPropertyAttributeForResult(object, object, &lookup, name, false);
4637 } 4549 }
4638 4550
4639 4551
4640 PropertyAttributes JSObject::GetElementAttributeWithReceiver( 4552 PropertyAttributes JSObject::GetElementAttributeWithReceiver(
4641 Handle<JSObject> object, 4553 Handle<JSObject> object,
4642 Handle<JSReceiver> receiver, 4554 Handle<JSReceiver> receiver,
4643 uint32_t index, 4555 uint32_t index,
4644 bool continue_search) { 4556 bool check_prototype) {
4645 Isolate* isolate = object->GetIsolate(); 4557 Isolate* isolate = object->GetIsolate();
4646 4558
4647 // Check access rights if needed. 4559 // Check access rights if needed.
4648 if (object->IsAccessCheckNeeded()) { 4560 if (object->IsAccessCheckNeeded()) {
4649 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { 4561 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
4650 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); 4562 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
4651 // TODO(yangguo): Issue 3269, check for scheduled exception missing? 4563 // TODO(yangguo): Issue 3269, check for scheduled exception missing?
4652 return ABSENT; 4564 return ABSENT;
4653 } 4565 }
4654 } 4566 }
4655 4567
4656 if (object->IsJSGlobalProxy()) { 4568 if (object->IsJSGlobalProxy()) {
4657 Handle<Object> proto(object->GetPrototype(), isolate); 4569 Handle<Object> proto(object->GetPrototype(), isolate);
4658 if (proto->IsNull()) return ABSENT; 4570 if (proto->IsNull()) return ABSENT;
4659 ASSERT(proto->IsJSGlobalObject()); 4571 ASSERT(proto->IsJSGlobalObject());
4660 return JSObject::GetElementAttributeWithReceiver( 4572 return JSObject::GetElementAttributeWithReceiver(
4661 Handle<JSObject>::cast(proto), receiver, index, continue_search); 4573 Handle<JSObject>::cast(proto), receiver, index, check_prototype);
4662 } 4574 }
4663 4575
4664 // Check for lookup interceptor except when bootstrapping. 4576 // Check for lookup interceptor except when bootstrapping.
4665 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { 4577 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
4666 return JSObject::GetElementAttributeWithInterceptor( 4578 return JSObject::GetElementAttributeWithInterceptor(
4667 object, receiver, index, continue_search); 4579 object, receiver, index, check_prototype);
4668 } 4580 }
4669 4581
4670 return GetElementAttributeWithoutInterceptor( 4582 return GetElementAttributeWithoutInterceptor(
4671 object, receiver, index, continue_search); 4583 object, receiver, index, check_prototype);
4672 } 4584 }
4673 4585
4674 4586
4675 PropertyAttributes JSObject::GetElementAttributeWithInterceptor( 4587 PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
4676 Handle<JSObject> object, 4588 Handle<JSObject> object,
4677 Handle<JSReceiver> receiver, 4589 Handle<JSReceiver> receiver,
4678 uint32_t index, 4590 uint32_t index,
4679 bool continue_search) { 4591 bool check_prototype) {
4680 Isolate* isolate = object->GetIsolate(); 4592 Isolate* isolate = object->GetIsolate();
4681 HandleScope scope(isolate); 4593 HandleScope scope(isolate);
4682 4594
4683 // Make sure that the top context does not change when doing 4595 // Make sure that the top context does not change when doing
4684 // callbacks or interceptor calls. 4596 // callbacks or interceptor calls.
4685 AssertNoContextChange ncc(isolate); 4597 AssertNoContextChange ncc(isolate);
4686 4598
4687 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); 4599 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4688 PropertyCallbackArguments args( 4600 PropertyCallbackArguments args(
4689 isolate, interceptor->data(), *receiver, *object); 4601 isolate, interceptor->data(), *receiver, *object);
4690 if (!interceptor->query()->IsUndefined()) { 4602 if (!interceptor->query()->IsUndefined()) {
4691 v8::IndexedPropertyQueryCallback query = 4603 v8::IndexedPropertyQueryCallback query =
4692 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); 4604 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4693 LOG(isolate, 4605 LOG(isolate,
4694 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index)); 4606 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
4695 v8::Handle<v8::Integer> result = args.Call(query, index); 4607 v8::Handle<v8::Integer> result = args.Call(query, index);
4696 if (!result.IsEmpty()) 4608 if (!result.IsEmpty())
4697 return static_cast<PropertyAttributes>(result->Int32Value()); 4609 return static_cast<PropertyAttributes>(result->Int32Value());
4698 } else if (!interceptor->getter()->IsUndefined()) { 4610 } else if (!interceptor->getter()->IsUndefined()) {
4699 v8::IndexedPropertyGetterCallback getter = 4611 v8::IndexedPropertyGetterCallback getter =
4700 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); 4612 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4701 LOG(isolate, 4613 LOG(isolate,
4702 ApiIndexedPropertyAccess( 4614 ApiIndexedPropertyAccess(
4703 "interceptor-indexed-get-has", *object, index)); 4615 "interceptor-indexed-get-has", *object, index));
4704 v8::Handle<v8::Value> result = args.Call(getter, index); 4616 v8::Handle<v8::Value> result = args.Call(getter, index);
4705 if (!result.IsEmpty()) return NONE; 4617 if (!result.IsEmpty()) return NONE;
4706 } 4618 }
4707 4619
4708 return GetElementAttributeWithoutInterceptor( 4620 return GetElementAttributeWithoutInterceptor(
4709 object, receiver, index, continue_search); 4621 object, receiver, index, check_prototype);
4710 } 4622 }
4711 4623
4712 4624
4713 PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor( 4625 PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
4714 Handle<JSObject> object, 4626 Handle<JSObject> object,
4715 Handle<JSReceiver> receiver, 4627 Handle<JSReceiver> receiver,
4716 uint32_t index, 4628 uint32_t index,
4717 bool continue_search) { 4629 bool check_prototype) {
4718 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes( 4630 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
4719 receiver, object, index); 4631 receiver, object, index);
4720 if (attr != ABSENT) return attr; 4632 if (attr != ABSENT) return attr;
4721 4633
4722 // Handle [] on String objects. 4634 // Handle [] on String objects.
4723 if (object->IsStringObjectWithCharacterAt(index)) { 4635 if (object->IsStringObjectWithCharacterAt(index)) {
4724 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 4636 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
4725 } 4637 }
4726 4638
4727 if (!continue_search) return ABSENT; 4639 if (!check_prototype) return ABSENT;
4728 4640
4729 Handle<Object> proto(object->GetPrototype(), object->GetIsolate()); 4641 Handle<Object> proto(object->GetPrototype(), object->GetIsolate());
4730 if (proto->IsJSProxy()) { 4642 if (proto->IsJSProxy()) {
4731 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. 4643 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
4732 return JSProxy::GetElementAttributeWithHandler( 4644 return JSProxy::GetElementAttributeWithHandler(
4733 Handle<JSProxy>::cast(proto), receiver, index); 4645 Handle<JSProxy>::cast(proto), receiver, index);
4734 } 4646 }
4735 if (proto->IsNull()) return ABSENT; 4647 if (proto->IsNull()) return ABSENT;
4736 return GetElementAttributeWithReceiver( 4648 return GetElementAttributeWithReceiver(
4737 Handle<JSObject>::cast(proto), receiver, index, true); 4649 Handle<JSObject>::cast(proto), receiver, index, true);
(...skipping 12558 matching lines...) Expand 10 before | Expand all | Expand 10 after
17296 #define ERROR_MESSAGES_TEXTS(C, T) T, 17208 #define ERROR_MESSAGES_TEXTS(C, T) T,
17297 static const char* error_messages_[] = { 17209 static const char* error_messages_[] = {
17298 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17210 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17299 }; 17211 };
17300 #undef ERROR_MESSAGES_TEXTS 17212 #undef ERROR_MESSAGES_TEXTS
17301 return error_messages_[reason]; 17213 return error_messages_[reason];
17302 } 17214 }
17303 17215
17304 17216
17305 } } // namespace v8::internal 17217 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698